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}