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.namenode; 019 020import java.util.HashMap; 021import java.util.Map; 022import java.util.SortedSet; 023 024import org.apache.hadoop.classification.InterfaceAudience; 025import org.apache.hadoop.hdfs.protocol.LayoutVersion; 026import org.apache.hadoop.hdfs.protocol.LayoutVersion.FeatureInfo; 027import org.apache.hadoop.hdfs.protocol.LayoutVersion.LayoutFeature; 028 029 030@InterfaceAudience.Private 031public class NameNodeLayoutVersion { 032 /** Build layout version and corresponding feature matrix */ 033 public final static Map<Integer, SortedSet<LayoutFeature>> FEATURES 034 = new HashMap<Integer, SortedSet<LayoutFeature>>(); 035 036 public static final int CURRENT_LAYOUT_VERSION 037 = LayoutVersion.getCurrentLayoutVersion(Feature.values()); 038 public static final int MINIMUM_COMPATIBLE_LAYOUT_VERSION 039 = LayoutVersion.getMinimumCompatibleLayoutVersion(Feature.values()); 040 041 static { 042 LayoutVersion.updateMap(FEATURES, LayoutVersion.Feature.values()); 043 LayoutVersion.updateMap(FEATURES, NameNodeLayoutVersion.Feature.values()); 044 } 045 046 public static SortedSet<LayoutFeature> getFeatures(int lv) { 047 return FEATURES.get(lv); 048 } 049 050 public static boolean supports(final LayoutFeature f, final int lv) { 051 return LayoutVersion.supports(FEATURES, f, lv); 052 } 053 054 /** 055 * Enums for features that change the layout version. 056 * <br><br> 057 * To add a new layout version: 058 * <ul> 059 * <li>Define a new enum constant with a short enum name, the new layout version 060 * and description of the added feature.</li> 061 * <li>When adding a layout version with an ancestor that is not same as 062 * its immediate predecessor, use the constructor where a specific ancestor 063 * can be passed. 064 * </li> 065 * <li>Specify a minimum compatible layout version. The minimum compatible 066 * layout version is the earliest prior version to which a downgrade is 067 * possible after initiating rolling upgrade. If the feature cannot satisfy 068 * compatibility with any prior version, then set its minimum compatible 069 * lqyout version to itself to indicate that downgrade is impossible. 070 * Satisfying compatibility might require adding logic to the new feature to 071 * reject operations or handle them differently while rolling upgrade is in 072 * progress. In general, it's possible to satisfy compatiblity for downgrade 073 * if the new feature just involves adding new edit log ops. Deeper 074 * structural changes, such as changing the way we place files in the metadata 075 * directories, might be incompatible. Feature implementations should strive 076 * for compatibility, because it's in the best interest of our users to 077 * support downgrade. 078 * </ul> 079 */ 080 public static enum Feature implements LayoutFeature { 081 ROLLING_UPGRADE(-55, -53, -55, "Support rolling upgrade", false), 082 EDITLOG_LENGTH(-56, -56, "Add length field to every edit log op"), 083 XATTRS(-57, -57, "Extended attributes"), 084 CREATE_OVERWRITE(-58, -58, "Use single editlog record for " + 085 "creating file with overwrite"), 086 XATTRS_NAMESPACE_EXT(-59, -59, "Increase number of xattr namespaces"), 087 BLOCK_STORAGE_POLICY(-60, -60, "Block Storage policy"), 088 TRUNCATE(-61, -61, "Truncate"), 089 APPEND_NEW_BLOCK(-62, -61, "Support appending to new block"), 090 QUOTA_BY_STORAGE_TYPE(-63, -61, "Support quota for specific storage types"); 091 092 private final FeatureInfo info; 093 094 /** 095 * Feature that is added at layout version {@code lv} - 1. 096 * @param lv new layout version with the addition of this feature 097 * @param minCompatLV minimium compatible layout version 098 * @param description description of the feature 099 */ 100 Feature(final int lv, int minCompatLV, final String description) { 101 this(lv, lv + 1, minCompatLV, description, false); 102 } 103 104 /** 105 * NameNode feature that is added at layout version {@code ancestoryLV}. 106 * @param lv new layout version with the addition of this feature 107 * @param ancestorLV layout version from which the new lv is derived from. 108 * @param minCompatLV minimum compatible layout version 109 * @param description description of the feature 110 * @param reserved true when this is a layout version reserved for previous 111 * versions 112 * @param features set of features that are to be enabled for this version 113 */ 114 Feature(final int lv, final int ancestorLV, int minCompatLV, 115 final String description, boolean reserved, Feature... features) { 116 info = new FeatureInfo(lv, ancestorLV, minCompatLV, description, reserved, 117 features); 118 } 119 120 @Override 121 public FeatureInfo getInfo() { 122 return info; 123 } 124 } 125}