001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hdfs.server.blockmanagement;
019
020import com.google.common.annotations.VisibleForTesting;
021import com.google.common.base.Preconditions;
022import com.google.common.collect.Lists;
023
024import org.apache.hadoop.fs.StorageType;
025import org.apache.hadoop.fs.XAttr;
026import org.apache.hadoop.hdfs.XAttrHelper;
027import org.apache.hadoop.hdfs.protocol.BlockStoragePolicy;
028import org.apache.hadoop.hdfs.protocol.HdfsConstants;
029import org.apache.hadoop.util.StringUtils;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033import java.util.List;
034
035/** A collection of block storage policies. */
036public class BlockStoragePolicySuite {
037  static final Logger LOG = LoggerFactory.getLogger(BlockStoragePolicySuite
038      .class);
039
040  public static final String STORAGE_POLICY_XATTR_NAME
041      = "hsm.block.storage.policy.id";
042  public static final XAttr.NameSpace XAttrNS = XAttr.NameSpace.SYSTEM;
043
044  public static final int ID_BIT_LENGTH = 4;
045  public static final byte ID_UNSPECIFIED = 0;
046
047  @VisibleForTesting
048  public static BlockStoragePolicySuite createDefaultSuite() {
049    final BlockStoragePolicy[] policies =
050        new BlockStoragePolicy[1 << ID_BIT_LENGTH];
051    final byte lazyPersistId = HdfsConstants.MEMORY_STORAGE_POLICY_ID;
052    policies[lazyPersistId] = new BlockStoragePolicy(lazyPersistId, 
053        HdfsConstants.MEMORY_STORAGE_POLICY_NAME,
054        new StorageType[]{StorageType.RAM_DISK, StorageType.DISK},
055        new StorageType[]{StorageType.DISK},
056        new StorageType[]{StorageType.DISK},
057        true);    // Cannot be changed on regular files, but inherited.
058    final byte allssdId = HdfsConstants.ALLSSD_STORAGE_POLICY_ID;
059    policies[allssdId] = new BlockStoragePolicy(allssdId,
060        HdfsConstants.ALLSSD_STORAGE_POLICY_NAME,
061        new StorageType[]{StorageType.SSD},
062        new StorageType[]{StorageType.DISK},
063        new StorageType[]{StorageType.DISK});
064    final byte onessdId = HdfsConstants.ONESSD_STORAGE_POLICY_ID;
065    policies[onessdId] = new BlockStoragePolicy(onessdId,
066        HdfsConstants.ONESSD_STORAGE_POLICY_NAME,
067        new StorageType[]{StorageType.SSD, StorageType.DISK},
068        new StorageType[]{StorageType.SSD, StorageType.DISK},
069        new StorageType[]{StorageType.SSD, StorageType.DISK});
070    final byte hotId = HdfsConstants.HOT_STORAGE_POLICY_ID;
071    policies[hotId] = new BlockStoragePolicy(hotId,
072        HdfsConstants.HOT_STORAGE_POLICY_NAME,
073        new StorageType[]{StorageType.DISK}, StorageType.EMPTY_ARRAY,
074        new StorageType[]{StorageType.ARCHIVE});
075    final byte warmId = HdfsConstants.WARM_STORAGE_POLICY_ID;
076    policies[warmId] = new BlockStoragePolicy(warmId,
077        HdfsConstants.WARM_STORAGE_POLICY_NAME,
078        new StorageType[]{StorageType.DISK, StorageType.ARCHIVE},
079        new StorageType[]{StorageType.DISK, StorageType.ARCHIVE},
080        new StorageType[]{StorageType.DISK, StorageType.ARCHIVE});
081    final byte coldId = HdfsConstants.COLD_STORAGE_POLICY_ID;
082    policies[coldId] = new BlockStoragePolicy(coldId,
083        HdfsConstants.COLD_STORAGE_POLICY_NAME,
084        new StorageType[]{StorageType.ARCHIVE}, StorageType.EMPTY_ARRAY,
085        StorageType.EMPTY_ARRAY);
086    return new BlockStoragePolicySuite(hotId, policies);
087  }
088
089  private final byte defaultPolicyID;
090  private final BlockStoragePolicy[] policies;
091
092  public BlockStoragePolicySuite(byte defaultPolicyID,
093      BlockStoragePolicy[] policies) {
094    this.defaultPolicyID = defaultPolicyID;
095    this.policies = policies;
096  }
097
098  /** @return the corresponding policy. */
099  public BlockStoragePolicy getPolicy(byte id) {
100    // id == 0 means policy not specified.
101    return id == 0? getDefaultPolicy(): policies[id];
102  }
103
104  /** @return the default policy. */
105  public BlockStoragePolicy getDefaultPolicy() {
106    return getPolicy(defaultPolicyID);
107  }
108
109  public BlockStoragePolicy getPolicy(String policyName) {
110    Preconditions.checkNotNull(policyName);
111
112    if (policies != null) {
113      for (BlockStoragePolicy policy : policies) {
114        if (policy != null && policy.getName().equalsIgnoreCase(policyName)) {
115          return policy;
116        }
117      }
118    }
119    return null;
120  }
121
122  public BlockStoragePolicy[] getAllPolicies() {
123    List<BlockStoragePolicy> list = Lists.newArrayList();
124    if (policies != null) {
125      for (BlockStoragePolicy policy : policies) {
126        if (policy != null) {
127          list.add(policy);
128        }
129      }
130    }
131    return list.toArray(new BlockStoragePolicy[list.size()]);
132  }
133
134  public static String buildXAttrName() {
135    return StringUtils.toLowerCase(XAttrNS.toString())
136        + "." + STORAGE_POLICY_XATTR_NAME;
137  }
138
139  public static XAttr buildXAttr(byte policyId) {
140    final String name = buildXAttrName();
141    return XAttrHelper.buildXAttr(name, new byte[]{policyId});
142  }
143
144  public static boolean isStoragePolicyXAttr(XAttr xattr) {
145    return xattr != null && xattr.getNameSpace() == XAttrNS
146        && xattr.getName().equals(STORAGE_POLICY_XATTR_NAME);
147  }
148}