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 */ 018 package org.apache.hadoop.hdfs.server.common; 019 020 import java.io.DataInput; 021 import java.io.DataOutput; 022 import java.io.IOException; 023 import java.util.regex.Matcher; 024 import java.util.regex.Pattern; 025 026 import org.apache.hadoop.classification.InterfaceAudience; 027 import org.apache.hadoop.hdfs.server.namenode.MetaRecoveryContext; 028 029 import com.google.common.base.Preconditions; 030 031 /************************************ 032 * Some handy internal HDFS constants 033 * 034 ************************************/ 035 036 @InterfaceAudience.Private 037 public final class HdfsServerConstants { 038 /* Hidden constructor */ 039 private HdfsServerConstants() { } 040 041 /** 042 * Type of the node 043 */ 044 static public enum NodeType { 045 NAME_NODE, 046 DATA_NODE, 047 JOURNAL_NODE; 048 } 049 050 /** Startup options for rolling upgrade. */ 051 public static enum RollingUpgradeStartupOption{ 052 ROLLBACK, DOWNGRADE, STARTED; 053 054 public String getOptionString() { 055 return StartupOption.ROLLINGUPGRADE.getName() + " " 056 + name().toLowerCase(); 057 } 058 059 public boolean matches(StartupOption option) { 060 return option == StartupOption.ROLLINGUPGRADE 061 && option.getRollingUpgradeStartupOption() == this; 062 } 063 064 private static final RollingUpgradeStartupOption[] VALUES = values(); 065 066 static RollingUpgradeStartupOption fromString(String s) { 067 for(RollingUpgradeStartupOption opt : VALUES) { 068 if (opt.name().equalsIgnoreCase(s)) { 069 return opt; 070 } 071 } 072 throw new IllegalArgumentException("Failed to convert \"" + s 073 + "\" to " + RollingUpgradeStartupOption.class.getSimpleName()); 074 } 075 } 076 077 /** Startup options */ 078 static public enum StartupOption{ 079 FORMAT ("-format"), 080 CLUSTERID ("-clusterid"), 081 GENCLUSTERID ("-genclusterid"), 082 REGULAR ("-regular"), 083 BACKUP ("-backup"), 084 CHECKPOINT("-checkpoint"), 085 UPGRADE ("-upgrade"), 086 ROLLBACK("-rollback"), 087 FINALIZE("-finalize"), 088 ROLLINGUPGRADE("-rollingUpgrade"), 089 IMPORT ("-importCheckpoint"), 090 BOOTSTRAPSTANDBY("-bootstrapStandby"), 091 INITIALIZESHAREDEDITS("-initializeSharedEdits"), 092 RECOVER ("-recover"), 093 FORCE("-force"), 094 NONINTERACTIVE("-nonInteractive"), 095 RENAMERESERVED("-renameReserved"); 096 097 private static final Pattern ENUM_WITH_ROLLING_UPGRADE_OPTION = Pattern.compile( 098 "(\\w+)\\((\\w+)\\)"); 099 100 private final String name; 101 102 // Used only with format and upgrade options 103 private String clusterId = null; 104 105 // Used only by rolling upgrade 106 private RollingUpgradeStartupOption rollingUpgradeStartupOption; 107 108 // Used only with format option 109 private boolean isForceFormat = false; 110 private boolean isInteractiveFormat = true; 111 112 // Used only with recovery option 113 private int force = 0; 114 115 private StartupOption(String arg) {this.name = arg;} 116 public String getName() {return name;} 117 public NamenodeRole toNodeRole() { 118 switch(this) { 119 case BACKUP: 120 return NamenodeRole.BACKUP; 121 case CHECKPOINT: 122 return NamenodeRole.CHECKPOINT; 123 default: 124 return NamenodeRole.NAMENODE; 125 } 126 } 127 128 public void setClusterId(String cid) { 129 clusterId = cid; 130 } 131 132 public String getClusterId() { 133 return clusterId; 134 } 135 136 public void setRollingUpgradeStartupOption(String opt) { 137 Preconditions.checkState(this == ROLLINGUPGRADE); 138 rollingUpgradeStartupOption = RollingUpgradeStartupOption.fromString(opt); 139 } 140 141 public RollingUpgradeStartupOption getRollingUpgradeStartupOption() { 142 Preconditions.checkState(this == ROLLINGUPGRADE); 143 return rollingUpgradeStartupOption; 144 } 145 146 public MetaRecoveryContext createRecoveryContext() { 147 if (!name.equals(RECOVER.name)) 148 return null; 149 return new MetaRecoveryContext(force); 150 } 151 152 public void setForce(int force) { 153 this.force = force; 154 } 155 156 public int getForce() { 157 return this.force; 158 } 159 160 public boolean getForceFormat() { 161 return isForceFormat; 162 } 163 164 public void setForceFormat(boolean force) { 165 isForceFormat = force; 166 } 167 168 public boolean getInteractiveFormat() { 169 return isInteractiveFormat; 170 } 171 172 public void setInteractiveFormat(boolean interactive) { 173 isInteractiveFormat = interactive; 174 } 175 176 @Override 177 public String toString() { 178 if (this == ROLLINGUPGRADE) { 179 return new StringBuilder(super.toString()) 180 .append("(").append(getRollingUpgradeStartupOption()).append(")") 181 .toString(); 182 } 183 return super.toString(); 184 } 185 186 static public StartupOption getEnum(String value) { 187 Matcher matcher = ENUM_WITH_ROLLING_UPGRADE_OPTION.matcher(value); 188 if (matcher.matches()) { 189 StartupOption option = StartupOption.valueOf(matcher.group(1)); 190 option.setRollingUpgradeStartupOption(matcher.group(2)); 191 return option; 192 } else { 193 return StartupOption.valueOf(value); 194 } 195 } 196 } 197 198 // Timeouts for communicating with DataNode for streaming writes/reads 199 public static final int READ_TIMEOUT = 60 * 1000; 200 public static final int READ_TIMEOUT_EXTENSION = 5 * 1000; 201 public static final int WRITE_TIMEOUT = 8 * 60 * 1000; 202 public static final int WRITE_TIMEOUT_EXTENSION = 5 * 1000; //for write pipeline 203 204 /** 205 * Defines the NameNode role. 206 */ 207 static public enum NamenodeRole { 208 NAMENODE ("NameNode"), 209 BACKUP ("Backup Node"), 210 CHECKPOINT("Checkpoint Node"); 211 212 private String description = null; 213 private NamenodeRole(String arg) {this.description = arg;} 214 215 @Override 216 public String toString() { 217 return description; 218 } 219 } 220 221 /** 222 * Block replica states, which it can go through while being constructed. 223 */ 224 static public enum ReplicaState { 225 /** Replica is finalized. The state when replica is not modified. */ 226 FINALIZED(0), 227 /** Replica is being written to. */ 228 RBW(1), 229 /** Replica is waiting to be recovered. */ 230 RWR(2), 231 /** Replica is under recovery. */ 232 RUR(3), 233 /** Temporary replica: created for replication and relocation only. */ 234 TEMPORARY(4); 235 236 private final int value; 237 238 private ReplicaState(int v) { 239 value = v; 240 } 241 242 public int getValue() { 243 return value; 244 } 245 246 public static ReplicaState getState(int v) { 247 return ReplicaState.values()[v]; 248 } 249 250 /** Read from in */ 251 public static ReplicaState read(DataInput in) throws IOException { 252 return values()[in.readByte()]; 253 } 254 255 /** Write to out */ 256 public void write(DataOutput out) throws IOException { 257 out.writeByte(ordinal()); 258 } 259 } 260 261 /** 262 * States, which a block can go through while it is under construction. 263 */ 264 static public enum BlockUCState { 265 /** 266 * Block construction completed.<br> 267 * The block has at least one {@link ReplicaState#FINALIZED} replica, 268 * and is not going to be modified. 269 */ 270 COMPLETE, 271 /** 272 * The block is under construction.<br> 273 * It has been recently allocated for write or append. 274 */ 275 UNDER_CONSTRUCTION, 276 /** 277 * The block is under recovery.<br> 278 * When a file lease expires its last block may not be {@link #COMPLETE} 279 * and needs to go through a recovery procedure, 280 * which synchronizes the existing replicas contents. 281 */ 282 UNDER_RECOVERY, 283 /** 284 * The block is committed.<br> 285 * The client reported that all bytes are written to data-nodes 286 * with the given generation stamp and block length, but no 287 * {@link ReplicaState#FINALIZED} 288 * replicas has yet been reported by data-nodes themselves. 289 */ 290 COMMITTED; 291 } 292 293 public static final String NAMENODE_LEASE_HOLDER = "HDFS_NameNode"; 294 public static final long NAMENODE_LEASE_RECHECK_INTERVAL = 2000; 295 } 296