| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.hadoop.hdfs.tools; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.PrintStream; |
| import java.net.InetSocketAddress; |
| import java.net.URI; |
| import java.net.URL; |
| import java.security.PrivilegedExceptionAction; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeSet; |
| |
| import com.google.common.base.Joiner; |
| import com.google.common.base.Optional; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.hadoop.classification.InterfaceAudience; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.conf.ReconfigurationTaskStatus; |
| import org.apache.hadoop.conf.ReconfigurationUtil.PropertyChange; |
| import org.apache.hadoop.fs.CommonConfigurationKeys; |
| import org.apache.hadoop.fs.FileSystem; |
| import org.apache.hadoop.fs.FsShell; |
| import org.apache.hadoop.fs.FsStatus; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.fs.RemoteIterator; |
| import org.apache.hadoop.fs.shell.Command; |
| import org.apache.hadoop.fs.shell.CommandFormat; |
| import org.apache.hadoop.fs.shell.PathData; |
| import org.apache.hadoop.fs.StorageType; |
| import org.apache.hadoop.hdfs.DFSUtilClient; |
| import org.apache.hadoop.hdfs.HAUtilClient; |
| import org.apache.hadoop.hdfs.client.BlockReportOptions; |
| import org.apache.hadoop.hdfs.DFSConfigKeys; |
| import org.apache.hadoop.hdfs.DFSUtil; |
| import org.apache.hadoop.hdfs.DistributedFileSystem; |
| import org.apache.hadoop.hdfs.HAUtil; |
| import org.apache.hadoop.hdfs.HdfsConfiguration; |
| import org.apache.hadoop.hdfs.NameNodeProxies; |
| import org.apache.hadoop.hdfs.NameNodeProxiesClient.ProxyAndInfo; |
| import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol; |
| import org.apache.hadoop.hdfs.protocol.ClientProtocol; |
| import org.apache.hadoop.hdfs.protocol.DatanodeInfo; |
| import org.apache.hadoop.hdfs.protocol.DatanodeLocalInfo; |
| import org.apache.hadoop.hdfs.protocol.DatanodeVolumeInfo; |
| import org.apache.hadoop.hdfs.protocol.HdfsConstants; |
| import org.apache.hadoop.hdfs.protocol.HdfsConstants.DatanodeReportType; |
| import org.apache.hadoop.hdfs.protocol.HdfsConstants.RollingUpgradeAction; |
| import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction; |
| import org.apache.hadoop.hdfs.protocol.OpenFileEntry; |
| import org.apache.hadoop.hdfs.protocol.ReconfigurationProtocol; |
| import org.apache.hadoop.hdfs.protocol.RollingUpgradeInfo; |
| import org.apache.hadoop.hdfs.protocol.SnapshotException; |
| import org.apache.hadoop.hdfs.server.namenode.NameNode; |
| import org.apache.hadoop.hdfs.server.namenode.TransferFsImage; |
| import org.apache.hadoop.io.MultipleIOException; |
| import org.apache.hadoop.ipc.ProtobufRpcEngine; |
| import org.apache.hadoop.ipc.RPC; |
| import org.apache.hadoop.ipc.RefreshCallQueueProtocol; |
| import org.apache.hadoop.ipc.RefreshResponse; |
| import org.apache.hadoop.ipc.RemoteException; |
| import org.apache.hadoop.ipc.protocolPB.GenericRefreshProtocolClientSideTranslatorPB; |
| import org.apache.hadoop.ipc.protocolPB.GenericRefreshProtocolPB; |
| import org.apache.hadoop.net.NetUtils; |
| import org.apache.hadoop.security.RefreshUserMappingsProtocol; |
| import org.apache.hadoop.security.SecurityUtil; |
| import org.apache.hadoop.security.UserGroupInformation; |
| import org.apache.hadoop.security.authorize.RefreshAuthorizationPolicyProtocol; |
| import org.apache.hadoop.util.StringUtils; |
| import org.apache.hadoop.util.ToolRunner; |
| |
| import com.google.common.base.Preconditions; |
| |
| /** |
| * This class provides some DFS administrative access shell commands. |
| */ |
| @InterfaceAudience.Private |
| public class DFSAdmin extends FsShell { |
| |
| static { |
| HdfsConfiguration.init(); |
| } |
| |
| private static final Log LOG = LogFactory.getLog(DFSAdmin.class); |
| |
| /** |
| * An abstract class for the execution of a file system command |
| */ |
| abstract private static class DFSAdminCommand extends Command { |
| protected DistributedFileSystem dfs; |
| /** Constructor */ |
| public DFSAdminCommand(Configuration conf) { |
| super(conf); |
| } |
| |
| @Override |
| public void run(PathData pathData) throws IOException { |
| FileSystem fs = pathData.fs; |
| if (!(fs instanceof DistributedFileSystem)) { |
| throw new IllegalArgumentException("FileSystem " + fs.getUri() |
| + " is not an HDFS file system"); |
| } |
| this.dfs = (DistributedFileSystem) fs; |
| run(pathData.path); |
| } |
| } |
| |
| /** A class that supports command clearQuota */ |
| private static class ClearQuotaCommand extends DFSAdminCommand { |
| private static final String NAME = "clrQuota"; |
| private static final String USAGE = "-"+NAME+" <dirname>...<dirname>"; |
| private static final String DESCRIPTION = USAGE + ": " + |
| "Clear the quota for each directory <dirName>.\n" + |
| "\t\tFor each directory, attempt to clear the quota. An error will be reported if\n" + |
| "\t\t1. the directory does not exist or is a file, or\n" + |
| "\t\t2. user is not an administrator.\n" + |
| "\t\tIt does not fault if the directory has no quota."; |
| |
| /** Constructor */ |
| ClearQuotaCommand(String[] args, int pos, Configuration conf) { |
| super(conf); |
| CommandFormat c = new CommandFormat(1, Integer.MAX_VALUE); |
| List<String> parameters = c.parse(args, pos); |
| this.args = parameters.toArray(new String[parameters.size()]); |
| } |
| |
| /** Check if a command is the clrQuota command |
| * |
| * @param cmd A string representation of a command starting with "-" |
| * @return true if this is a clrQuota command; false otherwise |
| */ |
| public static boolean matches(String cmd) { |
| return ("-"+NAME).equals(cmd); |
| } |
| |
| @Override |
| public String getCommandName() { |
| return NAME; |
| } |
| |
| @Override |
| public void run(Path path) throws IOException { |
| dfs.setQuota(path, HdfsConstants.QUOTA_RESET, HdfsConstants.QUOTA_DONT_SET); |
| } |
| } |
| |
| /** A class that supports command setQuota */ |
| private static class SetQuotaCommand extends DFSAdminCommand { |
| private static final String NAME = "setQuota"; |
| private static final String USAGE = |
| "-"+NAME+" <quota> <dirname>...<dirname>"; |
| private static final String DESCRIPTION = |
| "-setQuota <quota> <dirname>...<dirname>: " + |
| "Set the quota <quota> for each directory <dirName>.\n" + |
| "\t\tThe directory quota is a long integer that puts a hard limit\n" + |
| "\t\ton the number of names in the directory tree\n" + |
| "\t\tFor each directory, attempt to set the quota. An error will be reported if\n" + |
| "\t\t1. quota is not a positive integer, or\n" + |
| "\t\t2. User is not an administrator, or\n" + |
| "\t\t3. The directory does not exist or is a file.\n" + |
| "\t\tNote: A quota of 1 would force the directory to remain empty.\n"; |
| |
| private final long quota; // the quota to be set |
| |
| /** Constructor */ |
| SetQuotaCommand(String[] args, int pos, Configuration conf) { |
| super(conf); |
| CommandFormat c = new CommandFormat(2, Integer.MAX_VALUE); |
| List<String> parameters = c.parse(args, pos); |
| this.quota = Long.parseLong(parameters.remove(0)); |
| this.args = parameters.toArray(new String[parameters.size()]); |
| } |
| |
| /** Check if a command is the setQuota command |
| * |
| * @param cmd A string representation of a command starting with "-" |
| * @return true if this is a count command; false otherwise |
| */ |
| public static boolean matches(String cmd) { |
| return ("-"+NAME).equals(cmd); |
| } |
| |
| @Override |
| public String getCommandName() { |
| return NAME; |
| } |
| |
| @Override |
| public void run(Path path) throws IOException { |
| dfs.setQuota(path, quota, HdfsConstants.QUOTA_DONT_SET); |
| } |
| } |
| |
| /** A class that supports command clearSpaceQuota */ |
| private static class ClearSpaceQuotaCommand extends DFSAdminCommand { |
| private static final String NAME = "clrSpaceQuota"; |
| private static final String USAGE = "-"+NAME+" [-storageType <storagetype>] <dirname>...<dirname>"; |
| private static final String DESCRIPTION = USAGE + ": " + |
| "Clear the space quota for each directory <dirName>.\n" + |
| "\t\tFor each directory, attempt to clear the quota. " + |
| "An error will be reported if\n" + |
| "\t\t1. the directory does not exist or is a file, or\n" + |
| "\t\t2. user is not an administrator.\n" + |
| "\t\tIt does not fault if the directory has no quota.\n" + |
| "\t\tThe storage type specific quota is cleared when -storageType " + |
| "option is specified.\n" + |
| "\t\tAvailable storageTypes are \n" + |
| "\t\t- RAM_DISK\n" + |
| "\t\t- DISK\n" + |
| "\t\t- SSD\n" + |
| "\t\t- ARCHIVE"; |
| |
| |
| private StorageType type; |
| |
| /** Constructor */ |
| ClearSpaceQuotaCommand(String[] args, int pos, Configuration conf) { |
| super(conf); |
| CommandFormat c = new CommandFormat(1, Integer.MAX_VALUE); |
| c.addOptionWithValue("storageType"); |
| List<String> parameters = c.parse(args, pos); |
| String storageTypeString = c.getOptValue("storageType"); |
| if (storageTypeString != null) { |
| this.type = StorageType.parseStorageType(storageTypeString); |
| } |
| this.args = parameters.toArray(new String[parameters.size()]); |
| } |
| |
| /** Check if a command is the clrQuota command |
| * |
| * @param cmd A string representation of a command starting with "-" |
| * @return true if this is a clrQuota command; false otherwise |
| */ |
| public static boolean matches(String cmd) { |
| return ("-"+NAME).equals(cmd); |
| } |
| |
| @Override |
| public String getCommandName() { |
| return NAME; |
| } |
| |
| @Override |
| public void run(Path path) throws IOException { |
| if (type != null) { |
| dfs.setQuotaByStorageType(path, type, HdfsConstants.QUOTA_RESET); |
| } else { |
| dfs.setQuota(path, HdfsConstants.QUOTA_DONT_SET, HdfsConstants.QUOTA_RESET); |
| } |
| } |
| } |
| |
| /** A class that supports command setQuota */ |
| private static class SetSpaceQuotaCommand extends DFSAdminCommand { |
| private static final String NAME = "setSpaceQuota"; |
| private static final String USAGE = |
| "-"+NAME+" <quota> [-storageType <storagetype>] <dirname>...<dirname>"; |
| private static final String DESCRIPTION = USAGE + ": " + |
| "Set the space quota <quota> for each directory <dirName>.\n" + |
| "\t\tThe space quota is a long integer that puts a hard limit\n" + |
| "\t\ton the total size of all the files under the directory tree.\n" + |
| "\t\tThe extra space required for replication is also counted. E.g.\n" + |
| "\t\ta 1GB file with replication of 3 consumes 3GB of the quota.\n\n" + |
| "\t\tQuota can also be specified with a binary prefix for terabytes,\n" + |
| "\t\tpetabytes etc (e.g. 50t is 50TB, 5m is 5MB, 3p is 3PB).\n" + |
| "\t\tFor each directory, attempt to set the quota. An error will be reported if\n" + |
| "\t\t1. quota is not a positive integer or zero, or\n" + |
| "\t\t2. user is not an administrator, or\n" + |
| "\t\t3. the directory does not exist or is a file.\n" + |
| "\t\tThe storage type specific quota is set when -storageType option is specified.\n" + |
| "\t\tAvailable storageTypes are \n" + |
| "\t\t- RAM_DISK\n" + |
| "\t\t- DISK\n" + |
| "\t\t- SSD\n" + |
| "\t\t- ARCHIVE"; |
| |
| private long quota; // the quota to be set |
| private StorageType type; |
| |
| /** Constructor */ |
| SetSpaceQuotaCommand(String[] args, int pos, Configuration conf) { |
| super(conf); |
| CommandFormat c = new CommandFormat(2, Integer.MAX_VALUE); |
| List<String> parameters = c.parse(args, pos); |
| String str = parameters.remove(0).trim(); |
| try { |
| quota = StringUtils.TraditionalBinaryPrefix.string2long(str); |
| } catch (NumberFormatException nfe) { |
| throw new IllegalArgumentException("\"" + str + "\" is not a valid value for a quota."); |
| } |
| String storageTypeString = |
| StringUtils.popOptionWithArgument("-storageType", parameters); |
| if (storageTypeString != null) { |
| try { |
| this.type = StorageType.parseStorageType(storageTypeString); |
| } catch (IllegalArgumentException e) { |
| throw new IllegalArgumentException("Storage type " |
| + storageTypeString |
| + " is not available. Available storage types are " |
| + StorageType.getTypesSupportingQuota()); |
| } |
| } |
| this.args = parameters.toArray(new String[parameters.size()]); |
| } |
| |
| /** Check if a command is the setQuota command |
| * |
| * @param cmd A string representation of a command starting with "-" |
| * @return true if this is a count command; false otherwise |
| */ |
| public static boolean matches(String cmd) { |
| return ("-"+NAME).equals(cmd); |
| } |
| |
| @Override |
| public String getCommandName() { |
| return NAME; |
| } |
| |
| @Override |
| public void run(Path path) throws IOException { |
| if (type != null) { |
| dfs.setQuotaByStorageType(path, type, quota); |
| } else { |
| dfs.setQuota(path, HdfsConstants.QUOTA_DONT_SET, quota); |
| } |
| } |
| } |
| |
| private static class RollingUpgradeCommand { |
| static final String NAME = "rollingUpgrade"; |
| static final String USAGE = "-"+NAME+" [<query|prepare|finalize>]"; |
| static final String DESCRIPTION = USAGE + ":\n" |
| + " query: query the current rolling upgrade status.\n" |
| + " prepare: prepare a new rolling upgrade.\n" |
| + " finalize: finalize the current rolling upgrade."; |
| |
| /** Check if a command is the rollingUpgrade command |
| * |
| * @param cmd A string representation of a command starting with "-" |
| * @return true if this is a clrQuota command; false otherwise |
| */ |
| static boolean matches(String cmd) { |
| return ("-"+NAME).equals(cmd); |
| } |
| |
| private static void printMessage(RollingUpgradeInfo info, |
| PrintStream out) { |
| if (info != null && info.isStarted()) { |
| if (!info.createdRollbackImages() && !info.isFinalized()) { |
| out.println( |
| "Preparing for upgrade. Data is being saved for rollback." |
| + "\nRun \"dfsadmin -rollingUpgrade query\" to check the status" |
| + "\nfor proceeding with rolling upgrade"); |
| out.println(info); |
| } else if (!info.isFinalized()) { |
| out.println("Proceed with rolling upgrade:"); |
| out.println(info); |
| } else { |
| out.println("Rolling upgrade is finalized."); |
| out.println(info); |
| } |
| } else { |
| out.println("There is no rolling upgrade in progress or rolling " + |
| "upgrade has already been finalized."); |
| } |
| } |
| |
| static int run(DistributedFileSystem dfs, String[] argv, int idx) throws IOException { |
| final RollingUpgradeAction action = RollingUpgradeAction.fromString( |
| argv.length >= 2? argv[1]: ""); |
| if (action == null) { |
| throw new IllegalArgumentException("Failed to convert \"" + argv[1] |
| +"\" to " + RollingUpgradeAction.class.getSimpleName()); |
| } |
| |
| System.out.println(action + " rolling upgrade ..."); |
| |
| final RollingUpgradeInfo info = dfs.rollingUpgrade(action); |
| switch(action){ |
| case QUERY: |
| break; |
| case PREPARE: |
| Preconditions.checkState(info.isStarted()); |
| break; |
| case FINALIZE: |
| Preconditions.checkState(info == null || info.isFinalized()); |
| break; |
| } |
| printMessage(info, System.out); |
| return 0; |
| } |
| } |
| |
| /** |
| * Common usage summary shared between "hdfs dfsadmin -help" and |
| * "hdfs dfsadmin" |
| */ |
| private static final String commonUsageSummary = |
| "\t[-report [-live] [-dead] [-decommissioning] " + |
| "[-enteringmaintenance] [-inmaintenance]]\n" + |
| "\t[-safemode <enter | leave | get | wait>]\n" + |
| "\t[-saveNamespace]\n" + |
| "\t[-rollEdits]\n" + |
| "\t[-restoreFailedStorage true|false|check]\n" + |
| "\t[-refreshNodes]\n" + |
| "\t[" + SetQuotaCommand.USAGE + "]\n" + |
| "\t[" + ClearQuotaCommand.USAGE +"]\n" + |
| "\t[" + SetSpaceQuotaCommand.USAGE + "]\n" + |
| "\t[" + ClearSpaceQuotaCommand.USAGE +"]\n" + |
| "\t[-finalizeUpgrade]\n" + |
| "\t[" + RollingUpgradeCommand.USAGE +"]\n" + |
| "\t[-refreshServiceAcl]\n" + |
| "\t[-refreshUserToGroupsMappings]\n" + |
| "\t[-refreshSuperUserGroupsConfiguration]\n" + |
| "\t[-refreshCallQueue]\n" + |
| "\t[-refresh <host:ipc_port> <key> [arg1..argn]\n" + |
| "\t[-reconfig <namenode|datanode> <host:ipc_port> " + |
| "<start|status|properties>]\n" + |
| "\t[-printTopology]\n" + |
| "\t[-refreshNamenodes datanode_host:ipc_port]\n" + |
| "\t[-getVolumeReport datanode_host:ipc_port]\n" + |
| "\t[-deleteBlockPool datanode_host:ipc_port blockpoolId [force]]\n"+ |
| "\t[-setBalancerBandwidth <bandwidth in bytes per second>]\n" + |
| "\t[-getBalancerBandwidth <datanode_host:ipc_port>]\n" + |
| "\t[-fetchImage <local directory>]\n" + |
| "\t[-allowSnapshot <snapshotDir>]\n" + |
| "\t[-disallowSnapshot <snapshotDir>]\n" + |
| "\t[-shutdownDatanode <datanode_host:ipc_port> [upgrade]]\n" + |
| "\t[-evictWriters <datanode_host:ipc_port>]\n" + |
| "\t[-getDatanodeInfo <datanode_host:ipc_port>]\n" + |
| "\t[-metasave filename]\n" + |
| "\t[-triggerBlockReport [-incremental] <datanode_host:ipc_port>]\n" + |
| "\t[-listOpenFiles]\n" + |
| "\t[-help [cmd]]\n"; |
| |
| /** |
| * Construct a DFSAdmin object. |
| */ |
| public DFSAdmin() { |
| this(new HdfsConfiguration()); |
| } |
| |
| /** |
| * Construct a DFSAdmin object. |
| */ |
| public DFSAdmin(Configuration conf) { |
| super(conf); |
| } |
| |
| protected DistributedFileSystem getDFS() throws IOException { |
| FileSystem fs = getFS(); |
| if (!(fs instanceof DistributedFileSystem)) { |
| throw new IllegalArgumentException("FileSystem " + fs.getUri() + |
| " is not an HDFS file system"); |
| } |
| return (DistributedFileSystem)fs; |
| } |
| |
| /** |
| * Gives a report on how the FileSystem is doing. |
| * @exception IOException if the filesystem does not exist. |
| */ |
| public void report(String[] argv, int i) throws IOException { |
| DistributedFileSystem dfs = getDFS(); |
| FsStatus ds = dfs.getStatus(); |
| long capacity = ds.getCapacity(); |
| long used = ds.getUsed(); |
| long remaining = ds.getRemaining(); |
| long bytesInFuture = dfs.getBytesWithFutureGenerationStamps(); |
| long presentCapacity = used + remaining; |
| boolean mode = dfs.setSafeMode(HdfsConstants.SafeModeAction.SAFEMODE_GET); |
| if (mode) { |
| System.out.println("Safe mode is ON"); |
| if (bytesInFuture > 0) { |
| System.out.println("\nWARNING: "); |
| System.out.println("Name node has detected blocks with generation " + |
| "stamps in future."); |
| System.out.println("Forcing exit from safemode will cause " + |
| bytesInFuture + " byte(s) to be deleted."); |
| System.out.println("If you are sure that the NameNode was started with" |
| + " the correct metadata files then you may proceed with " + |
| "'-safemode forceExit'\n"); |
| } |
| } |
| System.out.println("Configured Capacity: " + capacity |
| + " (" + StringUtils.byteDesc(capacity) + ")"); |
| System.out.println("Present Capacity: " + presentCapacity |
| + " (" + StringUtils.byteDesc(presentCapacity) + ")"); |
| System.out.println("DFS Remaining: " + remaining |
| + " (" + StringUtils.byteDesc(remaining) + ")"); |
| System.out.println("DFS Used: " + used |
| + " (" + StringUtils.byteDesc(used) + ")"); |
| double dfsUsedPercent = 0; |
| if (presentCapacity != 0) { |
| dfsUsedPercent = used/(double)presentCapacity; |
| } |
| System.out.println("DFS Used%: " |
| + StringUtils.formatPercent(dfsUsedPercent, 2)); |
| |
| /* These counts are not always upto date. They are updated after |
| * iteration of an internal list. Should be updated in a few seconds to |
| * minutes. Use "-metaSave" to list of all such blocks and accurate |
| * counts. |
| */ |
| System.out.println("Under replicated blocks: " + |
| dfs.getUnderReplicatedBlocksCount()); |
| System.out.println("Blocks with corrupt replicas: " + |
| dfs.getCorruptBlocksCount()); |
| System.out.println("Missing blocks: " + |
| dfs.getMissingBlocksCount()); |
| System.out.println("Missing blocks (with replication factor 1): " + |
| dfs.getMissingReplOneBlocksCount()); |
| System.out.println("Pending deletion blocks: " + |
| dfs.getPendingDeletionBlocksCount()); |
| |
| System.out.println(); |
| |
| System.out.println("-------------------------------------------------"); |
| |
| // Parse arguments for filtering the node list |
| List<String> args = Arrays.asList(argv); |
| // Truncate already handled arguments before parsing report()-specific ones |
| args = new ArrayList<String>(args.subList(i, args.size())); |
| final boolean listLive = StringUtils.popOption("-live", args); |
| final boolean listDead = StringUtils.popOption("-dead", args); |
| final boolean listDecommissioning = |
| StringUtils.popOption("-decommissioning", args); |
| final boolean listEnteringMaintenance = |
| StringUtils.popOption("-enteringmaintenance", args); |
| final boolean listInMaintenance = |
| StringUtils.popOption("-inmaintenance", args); |
| |
| |
| // If no filter flags are found, then list all DN types |
| boolean listAll = (!listLive && !listDead && !listDecommissioning |
| && !listEnteringMaintenance && !listInMaintenance); |
| |
| if (listAll || listLive) { |
| printDataNodeReports(dfs, DatanodeReportType.LIVE, listLive, "Live"); |
| } |
| |
| if (listAll || listDead) { |
| printDataNodeReports(dfs, DatanodeReportType.DEAD, listDead, "Dead"); |
| } |
| |
| if (listAll || listDecommissioning) { |
| printDataNodeReports(dfs, DatanodeReportType.DECOMMISSIONING, |
| listDecommissioning, "Decommissioning"); |
| } |
| |
| if (listAll || listEnteringMaintenance) { |
| printDataNodeReports(dfs, DatanodeReportType.ENTERING_MAINTENANCE, |
| listEnteringMaintenance, "Entering maintenance"); |
| } |
| |
| if (listAll || listInMaintenance) { |
| printDataNodeReports(dfs, DatanodeReportType.IN_MAINTENANCE, |
| listInMaintenance, "In maintenance"); |
| } |
| } |
| |
| private static void printDataNodeReports(DistributedFileSystem dfs, |
| DatanodeReportType type, boolean listNodes, String nodeState) |
| throws IOException { |
| DatanodeInfo[] nodes = dfs.getDataNodeStats(type); |
| if (nodes.length > 0 || listNodes) { |
| System.out.println(nodeState + " datanodes (" + nodes.length + "):\n"); |
| } |
| if (nodes.length > 0) { |
| for (DatanodeInfo dn : nodes) { |
| System.out.println(dn.getDatanodeReport()); |
| System.out.println(); |
| } |
| } |
| } |
| |
| /** |
| * Safe mode maintenance command. |
| * Usage: hdfs dfsadmin -safemode [enter | leave | get | wait | forceExit] |
| * @param argv List of of command line parameters. |
| * @param idx The index of the command that is being processed. |
| * @exception IOException if the filesystem does not exist. |
| */ |
| public void setSafeMode(String[] argv, int idx) throws IOException { |
| if (idx != argv.length - 1) { |
| printUsage("-safemode"); |
| return; |
| } |
| HdfsConstants.SafeModeAction action; |
| Boolean waitExitSafe = false; |
| |
| if ("leave".equalsIgnoreCase(argv[idx])) { |
| action = HdfsConstants.SafeModeAction.SAFEMODE_LEAVE; |
| } else if ("enter".equalsIgnoreCase(argv[idx])) { |
| action = HdfsConstants.SafeModeAction.SAFEMODE_ENTER; |
| } else if ("get".equalsIgnoreCase(argv[idx])) { |
| action = HdfsConstants.SafeModeAction.SAFEMODE_GET; |
| } else if ("wait".equalsIgnoreCase(argv[idx])) { |
| action = HdfsConstants.SafeModeAction.SAFEMODE_GET; |
| waitExitSafe = true; |
| } else if ("forceExit".equalsIgnoreCase(argv[idx])){ |
| action = HdfsConstants.SafeModeAction.SAFEMODE_FORCE_EXIT; |
| } else { |
| printUsage("-safemode"); |
| return; |
| } |
| |
| DistributedFileSystem dfs = getDFS(); |
| Configuration dfsConf = dfs.getConf(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(dfsConf, dfsUri); |
| |
| if (isHaEnabled) { |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<ClientProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice( |
| dfsConf, nsId, ClientProtocol.class); |
| for (ProxyAndInfo<ClientProtocol> proxy : proxies) { |
| ClientProtocol haNn = proxy.getProxy(); |
| boolean inSafeMode = haNn.setSafeMode(action, false); |
| if (waitExitSafe) { |
| inSafeMode = waitExitSafeMode(haNn, inSafeMode); |
| } |
| System.out.println("Safe mode is " + (inSafeMode ? "ON" : "OFF") |
| + " in " + proxy.getAddress()); |
| } |
| } else { |
| boolean inSafeMode = dfs.setSafeMode(action); |
| if (waitExitSafe) { |
| inSafeMode = waitExitSafeMode(dfs, inSafeMode); |
| } |
| System.out.println("Safe mode is " + (inSafeMode ? "ON" : "OFF")); |
| } |
| |
| } |
| |
| private boolean waitExitSafeMode(DistributedFileSystem dfs, boolean inSafeMode) |
| throws IOException { |
| while (inSafeMode) { |
| try { |
| Thread.sleep(5000); |
| } catch (java.lang.InterruptedException e) { |
| throw new IOException("Wait Interrupted"); |
| } |
| inSafeMode = dfs.setSafeMode(SafeModeAction.SAFEMODE_GET, false); |
| } |
| return inSafeMode; |
| } |
| |
| private boolean waitExitSafeMode(ClientProtocol nn, boolean inSafeMode) |
| throws IOException { |
| while (inSafeMode) { |
| try { |
| Thread.sleep(5000); |
| } catch (java.lang.InterruptedException e) { |
| throw new IOException("Wait Interrupted"); |
| } |
| inSafeMode = nn.setSafeMode(SafeModeAction.SAFEMODE_GET, false); |
| } |
| return inSafeMode; |
| } |
| |
| public int triggerBlockReport(String[] argv) throws IOException { |
| List<String> args = new LinkedList<String>(); |
| for (int j = 1; j < argv.length; j++) { |
| args.add(argv[j]); |
| } |
| boolean incremental = StringUtils.popOption("-incremental", args); |
| String hostPort = StringUtils.popFirstNonOption(args); |
| if (hostPort == null) { |
| System.err.println("You must specify a host:port pair."); |
| return 1; |
| } |
| if (!args.isEmpty()) { |
| System.err.print("Can't understand arguments: " + |
| Joiner.on(" ").join(args) + "\n"); |
| return 1; |
| } |
| ClientDatanodeProtocol dnProxy = getDataNodeProxy(hostPort); |
| try { |
| dnProxy.triggerBlockReport( |
| new BlockReportOptions.Factory(). |
| setIncremental(incremental). |
| build()); |
| } catch (IOException e) { |
| System.err.println("triggerBlockReport error: " + e); |
| return 1; |
| } |
| System.out.println("Triggering " + |
| (incremental ? "an incremental " : "a full ") + |
| "block report on " + hostPort + "."); |
| return 0; |
| } |
| |
| /** |
| * Allow snapshot on a directory. |
| * Usage: hdfs dfsadmin -allowSnapshot snapshotDir |
| * @param argv List of of command line parameters. |
| * @exception IOException |
| */ |
| public void allowSnapshot(String[] argv) throws IOException { |
| Path p = new Path(argv[1]); |
| final DistributedFileSystem dfs = AdminHelper.getDFS(p.toUri(), getConf()); |
| try { |
| dfs.allowSnapshot(p); |
| } catch (SnapshotException e) { |
| throw new RemoteException(e.getClass().getName(), e.getMessage()); |
| } |
| System.out.println("Allowing snaphot on " + argv[1] + " succeeded"); |
| } |
| |
| /** |
| * Disallow snapshot on a directory. |
| * Usage: hdfs dfsadmin -disallowSnapshot snapshotDir |
| * @param argv List of of command line parameters. |
| * @exception IOException |
| */ |
| public void disallowSnapshot(String[] argv) throws IOException { |
| Path p = new Path(argv[1]); |
| final DistributedFileSystem dfs = AdminHelper.getDFS(p.toUri(), getConf()); |
| try { |
| dfs.disallowSnapshot(p); |
| } catch (SnapshotException e) { |
| throw new RemoteException(e.getClass().getName(), e.getMessage()); |
| } |
| System.out.println("Disallowing snaphot on " + argv[1] + " succeeded"); |
| } |
| |
| /** |
| * Command to ask the namenode to save the namespace. |
| * Usage: hdfs dfsadmin -saveNamespace |
| * @exception IOException |
| * @see org.apache.hadoop.hdfs.protocol.ClientProtocol#saveNamespace() |
| */ |
| public int saveNamespace() throws IOException { |
| int exitCode = -1; |
| |
| DistributedFileSystem dfs = getDFS(); |
| Configuration dfsConf = dfs.getConf(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(dfsConf, dfsUri); |
| List<IOException> exceptions = new ArrayList<>(); |
| if (isHaEnabled) { |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<ClientProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(dfsConf, |
| nsId, ClientProtocol.class); |
| for (ProxyAndInfo<ClientProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().saveNamespace(); |
| System.out.println("Save namespace successful for " + |
| proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Save namespace failed for " + |
| proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| dfs.saveNamespace(); |
| System.out.println("Save namespace successful"); |
| } |
| exitCode = 0; |
| |
| return exitCode; |
| } |
| |
| public int rollEdits() throws IOException { |
| DistributedFileSystem dfs = getDFS(); |
| long txid = dfs.rollEdits(); |
| System.out.println("Successfully rolled edit logs."); |
| System.out.println("New segment starts at txid " + txid); |
| return 0; |
| } |
| |
| /** |
| * Command to enable/disable/check restoring of failed storage replicas in the namenode. |
| * Usage: hdfs dfsadmin -restoreFailedStorage true|false|check |
| * @exception IOException |
| * @see org.apache.hadoop.hdfs.protocol.ClientProtocol#restoreFailedStorage(String arg) |
| */ |
| public int restoreFailedStorage(String arg) throws IOException { |
| int exitCode = -1; |
| if(!arg.equals("check") && !arg.equals("true") && !arg.equals("false")) { |
| System.err.println("restoreFailedStorage valid args are true|false|check"); |
| return exitCode; |
| } |
| |
| DistributedFileSystem dfs = getDFS(); |
| Configuration dfsConf = dfs.getConf(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(dfsConf, dfsUri); |
| |
| if (isHaEnabled) { |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<ClientProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(dfsConf, |
| nsId, ClientProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<ClientProtocol> proxy : proxies) { |
| try{ |
| Boolean res = proxy.getProxy().restoreFailedStorage(arg); |
| System.out.println("restoreFailedStorage is set to " + res + " for " |
| + proxy.getAddress()); |
| } catch (IOException ioe){ |
| System.out.println("restoreFailedStorage failed for " |
| + proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| Boolean res = dfs.restoreFailedStorage(arg); |
| System.out.println("restoreFailedStorage is set to " + res); |
| } |
| exitCode = 0; |
| |
| return exitCode; |
| } |
| |
| /** |
| * Command to ask the namenode to reread the hosts and excluded hosts |
| * file. |
| * Usage: hdfs dfsadmin -refreshNodes |
| * @exception IOException |
| */ |
| public int refreshNodes() throws IOException { |
| int exitCode = -1; |
| |
| DistributedFileSystem dfs = getDFS(); |
| Configuration dfsConf = dfs.getConf(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(dfsConf, dfsUri); |
| |
| if (isHaEnabled) { |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<ClientProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(dfsConf, |
| nsId, ClientProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<ClientProtocol> proxy: proxies) { |
| try{ |
| proxy.getProxy().refreshNodes(); |
| System.out.println("Refresh nodes successful for " + |
| proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Refresh nodes failed for " + |
| proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| dfs.refreshNodes(); |
| System.out.println("Refresh nodes successful"); |
| } |
| exitCode = 0; |
| |
| return exitCode; |
| } |
| |
| /** |
| * Command to list all the open files currently managed by NameNode. |
| * Usage: hdfs dfsadmin -listOpenFiles |
| * |
| * @throws IOException |
| */ |
| public int listOpenFiles() throws IOException { |
| DistributedFileSystem dfs = getDFS(); |
| RemoteIterator<OpenFileEntry> openFilesRemoteIterator; |
| |
| try{ |
| openFilesRemoteIterator = dfs.listOpenFiles(); |
| printOpenFiles(openFilesRemoteIterator); |
| } catch (IOException ioe){ |
| System.out.println("List open files failed."); |
| throw ioe; |
| } |
| return 0; |
| } |
| |
| private void printOpenFiles(RemoteIterator<OpenFileEntry> openFilesIterator) |
| throws IOException { |
| System.out.println(String.format("%-20s\t%-20s\t%s", "Client Host", |
| "Client Name", "Open File Path")); |
| while (openFilesIterator.hasNext()) { |
| OpenFileEntry openFileEntry = openFilesIterator.next(); |
| System.out.println(String.format("%-20s\t%-20s\t%20s", |
| openFileEntry.getClientMachine(), |
| openFileEntry.getClientName(), |
| openFileEntry.getFilePath())); |
| } |
| } |
| |
| /** |
| * Command to ask the active namenode to set the balancer bandwidth. |
| * Usage: hdfs dfsadmin -setBalancerBandwidth bandwidth |
| * @param argv List of of command line parameters. |
| * @param idx The index of the command that is being processed. |
| * @exception IOException |
| */ |
| public int setBalancerBandwidth(String[] argv, int idx) throws IOException { |
| long bandwidth; |
| int exitCode = -1; |
| |
| try { |
| bandwidth = Long.parseLong(argv[idx]); |
| } catch (NumberFormatException nfe) { |
| System.err.println("NumberFormatException: " + nfe.getMessage()); |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-setBalancerBandwidth <bandwidth in bytes per second>]"); |
| return exitCode; |
| } |
| |
| if (bandwidth < 0) { |
| System.err.println("Bandwidth should be a non-negative integer"); |
| return exitCode; |
| } |
| |
| FileSystem fs = getFS(); |
| if (!(fs instanceof DistributedFileSystem)) { |
| System.err.println("FileSystem is " + fs.getUri()); |
| return exitCode; |
| } |
| |
| DistributedFileSystem dfs = (DistributedFileSystem) fs; |
| try{ |
| dfs.setBalancerBandwidth(bandwidth); |
| System.out.println("Balancer bandwidth is set to " + bandwidth); |
| } catch (IOException ioe){ |
| System.err.println("Balancer bandwidth is set failed."); |
| throw ioe; |
| } |
| |
| return 0; |
| } |
| |
| /** |
| * Command to get balancer bandwidth for the given datanode. Usage: hdfs |
| * dfsadmin -getBalancerBandwidth {@literal <datanode_host:ipc_port>} |
| * @param argv List of of command line parameters. |
| * @param idx The index of the command that is being processed. |
| * @exception IOException |
| */ |
| public int getBalancerBandwidth(String[] argv, int idx) throws IOException { |
| ClientDatanodeProtocol dnProxy = getDataNodeProxy(argv[idx]); |
| try { |
| long bandwidth = dnProxy.getBalancerBandwidth(); |
| System.out.println("Balancer bandwidth is " + bandwidth |
| + " bytes per second."); |
| } catch (IOException ioe) { |
| throw new IOException("Datanode unreachable. " + ioe, ioe); |
| } |
| return 0; |
| } |
| |
| /** |
| * Download the most recent fsimage from the name node, and save it to a local |
| * file in the given directory. |
| * |
| * @param argv |
| * List of of command line parameters. |
| * @param idx |
| * The index of the command that is being processed. |
| * @return an exit code indicating success or failure. |
| * @throws IOException |
| */ |
| public int fetchImage(final String[] argv, final int idx) throws IOException { |
| Configuration conf = getConf(); |
| final URL infoServer = DFSUtil.getInfoServer( |
| HAUtil.getAddressOfActive(getDFS()), conf, |
| DFSUtil.getHttpClientScheme(conf)).toURL(); |
| SecurityUtil.doAsCurrentUser(new PrivilegedExceptionAction<Void>() { |
| @Override |
| public Void run() throws Exception { |
| TransferFsImage.downloadMostRecentImageToDirectory(infoServer, |
| new File(argv[idx])); |
| return null; |
| } |
| }); |
| return 0; |
| } |
| |
| private void printHelp(String cmd) { |
| String summary = "hdfs dfsadmin performs DFS administrative commands.\n" + |
| "Note: Administrative commands can only be run with superuser permission.\n" + |
| "The full syntax is: \n\n" + |
| "hdfs dfsadmin\n" + |
| commonUsageSummary; |
| |
| String report ="-report [-live] [-dead] [-decommissioning] " |
| + "[-enteringmaintenance] [-inmaintenance]:\n" + |
| "\tReports basic filesystem information and statistics. \n" + |
| "\tThe dfs usage can be different from \"du\" usage, because it\n" + |
| "\tmeasures raw space used by replication, checksums, snapshots\n" + |
| "\tand etc. on all the DNs.\n" + |
| "\tOptional flags may be used to filter the list of displayed DNs.\n"; |
| |
| String safemode = "-safemode <enter|leave|get|wait|forceExit>: Safe mode " + |
| "maintenance command.\n" + |
| "\t\tSafe mode is a Namenode state in which it\n" + |
| "\t\t\t1. does not accept changes to the name space (read-only)\n" + |
| "\t\t\t2. does not replicate or delete blocks.\n" + |
| "\t\tSafe mode is entered automatically at Namenode startup, and\n" + |
| "\t\tleaves safe mode automatically when the configured minimum\n" + |
| "\t\tpercentage of blocks satisfies the minimum replication\n" + |
| "\t\tcondition. Safe mode can also be entered manually, but then\n" + |
| "\t\tit can only be turned off manually as well.\n"; |
| |
| String saveNamespace = "-saveNamespace:\t" + |
| "Save current namespace into storage directories and reset edits log.\n" + |
| "\t\tRequires safe mode.\n"; |
| |
| String rollEdits = "-rollEdits:\t" + |
| "Rolls the edit log.\n"; |
| |
| String restoreFailedStorage = "-restoreFailedStorage:\t" + |
| "Set/Unset/Check flag to attempt restore of failed storage replicas if they become available.\n"; |
| |
| String refreshNodes = "-refreshNodes: \tUpdates the namenode with the " + |
| "set of datanodes allowed to connect to the namenode.\n\n" + |
| "\t\tNamenode re-reads datanode hostnames from the file defined by \n" + |
| "\t\tdfs.hosts, dfs.hosts.exclude configuration parameters.\n" + |
| "\t\tHosts defined in dfs.hosts are the datanodes that are part of \n" + |
| "\t\tthe cluster. If there are entries in dfs.hosts, only the hosts \n" + |
| "\t\tin it are allowed to register with the namenode.\n\n" + |
| "\t\tEntries in dfs.hosts.exclude are datanodes that need to be \n" + |
| "\t\tdecommissioned. Datanodes complete decommissioning when \n" + |
| "\t\tall the replicas from them are replicated to other datanodes.\n" + |
| "\t\tDecommissioned nodes are not automatically shutdown and \n" + |
| "\t\tare not chosen for writing new replicas.\n"; |
| |
| String finalizeUpgrade = "-finalizeUpgrade: Finalize upgrade of HDFS.\n" + |
| "\t\tDatanodes delete their previous version working directories,\n" + |
| "\t\tfollowed by Namenode doing the same.\n" + |
| "\t\tThis completes the upgrade process.\n"; |
| |
| String metaSave = "-metasave <filename>: \tSave Namenode's primary data structures\n" + |
| "\t\tto <filename> in the directory specified by hadoop.log.dir property.\n" + |
| "\t\t<filename> is overwritten if it exists.\n" + |
| "\t\t<filename> will contain one line for each of the following\n" + |
| "\t\t\t1. Datanodes heart beating with Namenode\n" + |
| "\t\t\t2. Blocks waiting to be replicated\n" + |
| "\t\t\t3. Blocks currrently being replicated\n" + |
| "\t\t\t4. Blocks waiting to be deleted\n"; |
| |
| String refreshServiceAcl = "-refreshServiceAcl: Reload the service-level authorization policy file\n" + |
| "\t\tNamenode will reload the authorization policy file.\n"; |
| |
| String refreshUserToGroupsMappings = |
| "-refreshUserToGroupsMappings: Refresh user-to-groups mappings\n"; |
| |
| String refreshSuperUserGroupsConfiguration = |
| "-refreshSuperUserGroupsConfiguration: Refresh superuser proxy groups mappings\n"; |
| |
| String refreshCallQueue = "-refreshCallQueue: Reload the call queue from config\n"; |
| |
| String reconfig = "-reconfig <namenode|datanode> <host:ipc_port> " + |
| "<start|status|properties>:\n" + |
| "\tStarts or gets the status of a reconfiguration operation, \n" + |
| "\tor gets a list of reconfigurable properties.\n" + |
| |
| "\tThe second parameter specifies the node type\n"; |
| String genericRefresh = "-refresh: Arguments are <hostname:ipc_port>" + |
| " <resource_identifier> [arg1..argn]\n" + |
| "\tTriggers a runtime-refresh of the resource specified by " + |
| "<resource_identifier> on <hostname:ipc_port>.\n" + |
| "\tAll other args after are sent to the host.\n" + |
| "\tThe ipc_port is determined by 'dfs.datanode.ipc.address'," + |
| "default is DFS_DATANODE_IPC_DEFAULT_PORT.\n"; |
| |
| String printTopology = "-printTopology: Print a tree of the racks and their\n" + |
| "\t\tnodes as reported by the Namenode\n"; |
| |
| String refreshNamenodes = "-refreshNamenodes: Takes a " + |
| "datanodehost:ipc_port as argument,For the given datanode\n" + |
| "\t\treloads the configuration files,stops serving the removed\n" + |
| "\t\tblock-pools and starts serving new block-pools.\n" + |
| "\t\tThe ipc_port is determined by 'dfs.datanode.ipc.address'," + |
| "default is DFS_DATANODE_IPC_DEFAULT_PORT.\n"; |
| |
| String getVolumeReport = "-getVolumeReport: Takes a datanodehost:ipc_port"+ |
| " as argument,For the given datanode,get the volume report.\n" + |
| "\t\tThe ipc_port is determined by 'dfs.datanode.ipc.address'," + |
| "default is DFS_DATANODE_IPC_DEFAULT_PORT.\n"; |
| |
| String deleteBlockPool = "-deleteBlockPool: Arguments are " + |
| "datanodehost:ipc_port, blockpool id and an optional argument\n" + |
| "\t\t\"force\". If force is passed,block pool directory for\n" + |
| "\t\tthe given blockpool id on the given datanode is deleted\n" + |
| "\t\talong with its contents,otherwise the directory is deleted\n"+ |
| "\t\tonly if it is empty.The command will fail if datanode is\n" + |
| "\t\tstill serving the block pool.Refer to refreshNamenodes to\n" + |
| "\t\tshutdown a block pool service on a datanode.\n" + |
| "\t\tThe ipc_port is determined by 'dfs.datanode.ipc.address'," + |
| "default is DFS_DATANODE_IPC_DEFAULT_PORT.\n"; |
| |
| String setBalancerBandwidth = "-setBalancerBandwidth <bandwidth>:\n" + |
| "\tChanges the network bandwidth used by each datanode during\n" + |
| "\tHDFS block balancing.\n\n" + |
| "\t\t<bandwidth> is the maximum number of bytes per second\n" + |
| "\t\tthat will be used by each datanode. This value overrides\n" + |
| "\t\tthe dfs.balance.bandwidthPerSec parameter.\n\n" + |
| "\t\t--- NOTE: The new value is not persistent on the DataNode.---\n"; |
| |
| String getBalancerBandwidth = "-getBalancerBandwidth <datanode_host:ipc_port>:\n" + |
| "\tGet the network bandwidth for the given datanode.\n" + |
| "\tThis is the maximum network bandwidth used by the datanode\n" + |
| "\tduring HDFS block balancing.\n\n" + |
| "\t--- NOTE: This value is not persistent on the DataNode.---\n"; |
| |
| String fetchImage = "-fetchImage <local directory>:\n" + |
| "\tDownloads the most recent fsimage from the Name Node and saves it in" + |
| "\tthe specified local directory.\n"; |
| |
| String allowSnapshot = "-allowSnapshot <snapshotDir>:\n" + |
| "\tAllow snapshots to be taken on a directory.\n"; |
| |
| String disallowSnapshot = "-disallowSnapshot <snapshotDir>:\n" + |
| "\tDo not allow snapshots to be taken on a directory any more.\n"; |
| |
| String shutdownDatanode = "-shutdownDatanode <datanode_host:ipc_port> [upgrade]\n" |
| + "\tSubmit a shutdown request for the given datanode. If an optional\n" |
| + "\t\"upgrade\" argument is specified, clients accessing the datanode\n" |
| + "\twill be advised to wait for it to restart and the fast start-up\n" |
| + "\tmode will be enabled. When the restart does not happen in time,\n" |
| + "\tclients will timeout and ignore the datanode. In such case, the\n" |
| + "\tfast start-up mode will also be disabled.\n"; |
| |
| String evictWriters = "-evictWriters <datanode_host:ipc_port>\n" |
| + "\tMake the datanode evict all clients that are writing a block.\n" |
| + "\tThis is useful if decommissioning is hung due to slow writers.\n"; |
| |
| String getDatanodeInfo = "-getDatanodeInfo <datanode_host:ipc_port>\n" |
| + "\tGet the information about the given datanode. This command can\n" |
| + "\tbe used for checking if a datanode is alive.\n"; |
| |
| String triggerBlockReport = |
| "-triggerBlockReport [-incremental] <datanode_host:ipc_port>\n" |
| + "\tTrigger a block report for the datanode.\n" |
| + "\tIf 'incremental' is specified, it will be an incremental\n" |
| + "\tblock report; otherwise, it will be a full block report.\n"; |
| |
| String listOpenFiles = "-listOpenFiles\n" |
| + "\tList all open files currently managed by the NameNode along\n" |
| + "\twith client name and client machine accessing them.\n"; |
| |
| String help = "-help [cmd]: \tDisplays help for the given command or all commands if none\n" + |
| "\t\tis specified.\n"; |
| |
| if ("report".equals(cmd)) { |
| System.out.println(report); |
| } else if ("safemode".equals(cmd)) { |
| System.out.println(safemode); |
| } else if ("saveNamespace".equals(cmd)) { |
| System.out.println(saveNamespace); |
| } else if ("rollEdits".equals(cmd)) { |
| System.out.println(rollEdits); |
| } else if ("restoreFailedStorage".equals(cmd)) { |
| System.out.println(restoreFailedStorage); |
| } else if ("refreshNodes".equals(cmd)) { |
| System.out.println(refreshNodes); |
| } else if ("finalizeUpgrade".equals(cmd)) { |
| System.out.println(finalizeUpgrade); |
| } else if (RollingUpgradeCommand.matches("-"+cmd)) { |
| System.out.println(RollingUpgradeCommand.DESCRIPTION); |
| } else if ("metasave".equals(cmd)) { |
| System.out.println(metaSave); |
| } else if (SetQuotaCommand.matches("-"+cmd)) { |
| System.out.println(SetQuotaCommand.DESCRIPTION); |
| } else if (ClearQuotaCommand.matches("-"+cmd)) { |
| System.out.println(ClearQuotaCommand.DESCRIPTION); |
| } else if (SetSpaceQuotaCommand.matches("-"+cmd)) { |
| System.out.println(SetSpaceQuotaCommand.DESCRIPTION); |
| } else if (ClearSpaceQuotaCommand.matches("-"+cmd)) { |
| System.out.println(ClearSpaceQuotaCommand.DESCRIPTION); |
| } else if ("refreshServiceAcl".equals(cmd)) { |
| System.out.println(refreshServiceAcl); |
| } else if ("refreshUserToGroupsMappings".equals(cmd)) { |
| System.out.println(refreshUserToGroupsMappings); |
| } else if ("refreshSuperUserGroupsConfiguration".equals(cmd)) { |
| System.out.println(refreshSuperUserGroupsConfiguration); |
| } else if ("refreshCallQueue".equals(cmd)) { |
| System.out.println(refreshCallQueue); |
| } else if ("refresh".equals(cmd)) { |
| System.out.println(genericRefresh); |
| } else if ("reconfig".equals(cmd)) { |
| System.out.println(reconfig); |
| } else if ("printTopology".equals(cmd)) { |
| System.out.println(printTopology); |
| } else if ("refreshNamenodes".equals(cmd)) { |
| System.out.println(refreshNamenodes); |
| } else if ("getVolumeReport".equals(cmd)) { |
| System.out.println(getVolumeReport); |
| } else if ("deleteBlockPool".equals(cmd)) { |
| System.out.println(deleteBlockPool); |
| } else if ("setBalancerBandwidth".equals(cmd)) { |
| System.out.println(setBalancerBandwidth); |
| } else if ("getBalancerBandwidth".equals(cmd)) { |
| System.out.println(getBalancerBandwidth); |
| } else if ("fetchImage".equals(cmd)) { |
| System.out.println(fetchImage); |
| } else if ("allowSnapshot".equalsIgnoreCase(cmd)) { |
| System.out.println(allowSnapshot); |
| } else if ("disallowSnapshot".equalsIgnoreCase(cmd)) { |
| System.out.println(disallowSnapshot); |
| } else if ("shutdownDatanode".equalsIgnoreCase(cmd)) { |
| System.out.println(shutdownDatanode); |
| } else if ("evictWriters".equalsIgnoreCase(cmd)) { |
| System.out.println(evictWriters); |
| } else if ("getDatanodeInfo".equalsIgnoreCase(cmd)) { |
| System.out.println(getDatanodeInfo); |
| } else if ("listOpenFiles".equalsIgnoreCase(cmd)) { |
| System.out.println(listOpenFiles); |
| } else if ("help".equals(cmd)) { |
| System.out.println(help); |
| } else { |
| System.out.println(summary); |
| System.out.println(report); |
| System.out.println(safemode); |
| System.out.println(saveNamespace); |
| System.out.println(rollEdits); |
| System.out.println(restoreFailedStorage); |
| System.out.println(refreshNodes); |
| System.out.println(finalizeUpgrade); |
| System.out.println(RollingUpgradeCommand.DESCRIPTION); |
| System.out.println(metaSave); |
| System.out.println(SetQuotaCommand.DESCRIPTION); |
| System.out.println(ClearQuotaCommand.DESCRIPTION); |
| System.out.println(SetSpaceQuotaCommand.DESCRIPTION); |
| System.out.println(ClearSpaceQuotaCommand.DESCRIPTION); |
| System.out.println(refreshServiceAcl); |
| System.out.println(refreshUserToGroupsMappings); |
| System.out.println(refreshSuperUserGroupsConfiguration); |
| System.out.println(refreshCallQueue); |
| System.out.println(genericRefresh); |
| System.out.println(reconfig); |
| System.out.println(printTopology); |
| System.out.println(refreshNamenodes); |
| System.out.println(deleteBlockPool); |
| System.out.println(setBalancerBandwidth); |
| System.out.println(getBalancerBandwidth); |
| System.out.println(fetchImage); |
| System.out.println(allowSnapshot); |
| System.out.println(disallowSnapshot); |
| System.out.println(shutdownDatanode); |
| System.out.println(evictWriters); |
| System.out.println(getDatanodeInfo); |
| System.out.println(triggerBlockReport); |
| System.out.println(listOpenFiles); |
| System.out.println(help); |
| System.out.println(); |
| ToolRunner.printGenericCommandUsage(System.out); |
| } |
| |
| } |
| |
| /** |
| * Command to ask the namenode to finalize previously performed upgrade. |
| * Usage: hdfs dfsadmin -finalizeUpgrade |
| * @exception IOException |
| */ |
| public int finalizeUpgrade() throws IOException { |
| DistributedFileSystem dfs = getDFS(); |
| |
| Configuration dfsConf = dfs.getConf(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaAndLogicalUri = HAUtilClient.isLogicalUri(dfsConf, dfsUri); |
| if (isHaAndLogicalUri) { |
| // In the case of HA and logical URI, run finalizeUpgrade for all |
| // NNs in this nameservice. |
| String nsId = dfsUri.getHost(); |
| List<ClientProtocol> namenodes = |
| HAUtil.getProxiesForAllNameNodesInNameservice(dfsConf, nsId); |
| if (!HAUtil.isAtLeastOneActive(namenodes)) { |
| throw new IOException("Cannot finalize with no NameNode active"); |
| } |
| |
| List<ProxyAndInfo<ClientProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(dfsConf, |
| nsId, ClientProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<ClientProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().finalizeUpgrade(); |
| System.out.println("Finalize upgrade successful for " + |
| proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Finalize upgrade failed for " + |
| proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| dfs.finalizeUpgrade(); |
| System.out.println("Finalize upgrade successful"); |
| } |
| |
| return 0; |
| } |
| |
| /** |
| * Dumps DFS data structures into specified file. |
| * Usage: hdfs dfsadmin -metasave filename |
| * @param argv List of of command line parameters. |
| * @param idx The index of the command that is being processed. |
| * @exception IOException if an error occurred while accessing |
| * the file or path. |
| */ |
| public int metaSave(String[] argv, int idx) throws IOException { |
| String pathname = argv[idx]; |
| DistributedFileSystem dfs = getDFS(); |
| Configuration dfsConf = dfs.getConf(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(dfsConf, dfsUri); |
| |
| if (isHaEnabled) { |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<ClientProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(dfsConf, |
| nsId, ClientProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<ClientProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().metaSave(pathname); |
| System.out.println("Created metasave file " + pathname |
| + " in the log directory of namenode " + proxy.getAddress()); |
| } catch (IOException ioe){ |
| System.out.println("Created metasave file " + pathname |
| + " in the log directory of namenode " + proxy.getAddress() |
| + " failed"); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| dfs.metaSave(pathname); |
| System.out.println("Created metasave file " + pathname + " in the log " + |
| "directory of namenode " + dfs.getUri()); |
| } |
| return 0; |
| } |
| |
| /** |
| * Display each rack and the nodes assigned to that rack, as determined |
| * by the NameNode, in a hierarchical manner. The nodes and racks are |
| * sorted alphabetically. |
| * |
| * @throws IOException If an error while getting datanode report |
| */ |
| public int printTopology() throws IOException { |
| DistributedFileSystem dfs = getDFS(); |
| final DatanodeInfo[] report = dfs.getDataNodeStats(); |
| |
| // Build a map of rack -> nodes from the datanode report |
| HashMap<String, TreeSet<String> > tree = new HashMap<String, TreeSet<String>>(); |
| for(DatanodeInfo dni : report) { |
| String location = dni.getNetworkLocation(); |
| String name = dni.getName(); |
| |
| if(!tree.containsKey(location)) { |
| tree.put(location, new TreeSet<String>()); |
| } |
| |
| tree.get(location).add(name); |
| } |
| |
| // Sort the racks (and nodes) alphabetically, display in order |
| ArrayList<String> racks = new ArrayList<String>(tree.keySet()); |
| Collections.sort(racks); |
| |
| for(String r : racks) { |
| System.out.println("Rack: " + r); |
| TreeSet<String> nodes = tree.get(r); |
| |
| for(String n : nodes) { |
| System.out.print(" " + n); |
| String hostname = NetUtils.getHostNameOfIP(n); |
| if(hostname != null) |
| System.out.print(" (" + hostname + ")"); |
| System.out.println(); |
| } |
| |
| System.out.println(); |
| } |
| return 0; |
| } |
| |
| private static UserGroupInformation getUGI() |
| throws IOException { |
| return UserGroupInformation.getCurrentUser(); |
| } |
| |
| /** |
| * Refresh the authorization policy on the {@link NameNode}. |
| * @return exitcode 0 on success, non-zero on failure |
| * @throws IOException |
| */ |
| public int refreshServiceAcl() throws IOException { |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // for security authorization |
| // server principal for this call |
| // should be NN's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| DistributedFileSystem dfs = getDFS(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(conf, dfsUri); |
| |
| if (isHaEnabled) { |
| // Run refreshServiceAcl for all NNs if HA is enabled |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<RefreshAuthorizationPolicyProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(conf, nsId, |
| RefreshAuthorizationPolicyProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<RefreshAuthorizationPolicyProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().refreshServiceAcl(); |
| System.out.println("Refresh service acl successful for " |
| + proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Refresh service acl failed for " |
| + proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()) { |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| // Create the client |
| RefreshAuthorizationPolicyProtocol refreshProtocol = |
| NameNodeProxies.createProxy(conf, FileSystem.getDefaultUri(conf), |
| RefreshAuthorizationPolicyProtocol.class).getProxy(); |
| // Refresh the authorization policy in-effect |
| refreshProtocol.refreshServiceAcl(); |
| System.out.println("Refresh service acl successful"); |
| } |
| |
| return 0; |
| } |
| |
| /** |
| * Refresh the user-to-groups mappings on the {@link NameNode}. |
| * @return exitcode 0 on success, non-zero on failure |
| * @throws IOException |
| */ |
| public int refreshUserToGroupsMappings() throws IOException { |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // for security authorization |
| // server principal for this call |
| // should be NN's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| DistributedFileSystem dfs = getDFS(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(conf, dfsUri); |
| |
| if (isHaEnabled) { |
| // Run refreshUserToGroupsMapings for all NNs if HA is enabled |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<RefreshUserMappingsProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(conf, nsId, |
| RefreshUserMappingsProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<RefreshUserMappingsProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().refreshUserToGroupsMappings(); |
| System.out.println("Refresh user to groups mapping successful for " |
| + proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Refresh user to groups mapping failed for " |
| + proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| // Create the client |
| RefreshUserMappingsProtocol refreshProtocol = |
| NameNodeProxies.createProxy(conf, FileSystem.getDefaultUri(conf), |
| RefreshUserMappingsProtocol.class).getProxy(); |
| |
| // Refresh the user-to-groups mappings |
| refreshProtocol.refreshUserToGroupsMappings(); |
| System.out.println("Refresh user to groups mapping successful"); |
| } |
| |
| return 0; |
| } |
| |
| |
| /** |
| * refreshSuperUserGroupsConfiguration {@link NameNode}. |
| * @return exitcode 0 on success, non-zero on failure |
| * @throws IOException |
| */ |
| public int refreshSuperUserGroupsConfiguration() throws IOException { |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // for security authorization |
| // server principal for this call |
| // should be NAMENODE's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| DistributedFileSystem dfs = getDFS(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(conf, dfsUri); |
| |
| if (isHaEnabled) { |
| // Run refreshSuperUserGroupsConfiguration for all NNs if HA is enabled |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<RefreshUserMappingsProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(conf, nsId, |
| RefreshUserMappingsProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<RefreshUserMappingsProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().refreshSuperUserGroupsConfiguration(); |
| System.out.println("Refresh super user groups configuration " + |
| "successful for " + proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Refresh super user groups configuration " + |
| "failed for " + proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| // Create the client |
| RefreshUserMappingsProtocol refreshProtocol = |
| NameNodeProxies.createProxy(conf, FileSystem.getDefaultUri(conf), |
| RefreshUserMappingsProtocol.class).getProxy(); |
| |
| // Refresh the user-to-groups mappings |
| refreshProtocol.refreshSuperUserGroupsConfiguration(); |
| System.out.println("Refresh super user groups configuration successful"); |
| } |
| |
| return 0; |
| } |
| |
| public int refreshCallQueue() throws IOException { |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // for security authorization |
| // server principal for this call |
| // should be NN's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| DistributedFileSystem dfs = getDFS(); |
| URI dfsUri = dfs.getUri(); |
| boolean isHaEnabled = HAUtilClient.isLogicalUri(conf, dfsUri); |
| |
| if (isHaEnabled) { |
| // Run refreshCallQueue for all NNs if HA is enabled |
| String nsId = dfsUri.getHost(); |
| List<ProxyAndInfo<RefreshCallQueueProtocol>> proxies = |
| HAUtil.getProxiesForAllNameNodesInNameservice(conf, nsId, |
| RefreshCallQueueProtocol.class); |
| List<IOException> exceptions = new ArrayList<>(); |
| for (ProxyAndInfo<RefreshCallQueueProtocol> proxy : proxies) { |
| try{ |
| proxy.getProxy().refreshCallQueue(); |
| System.out.println("Refresh call queue successful for " |
| + proxy.getAddress()); |
| }catch (IOException ioe){ |
| System.out.println("Refresh call queue failed for " |
| + proxy.getAddress()); |
| exceptions.add(ioe); |
| } |
| } |
| if(!exceptions.isEmpty()){ |
| throw MultipleIOException.createIOException(exceptions); |
| } |
| } else { |
| // Create the client |
| RefreshCallQueueProtocol refreshProtocol = |
| NameNodeProxies.createProxy(conf, FileSystem.getDefaultUri(conf), |
| RefreshCallQueueProtocol.class).getProxy(); |
| |
| // Refresh the call queue |
| refreshProtocol.refreshCallQueue(); |
| System.out.println("Refresh call queue successful"); |
| } |
| |
| return 0; |
| } |
| |
| public int reconfig(String[] argv, int i) throws IOException { |
| String nodeType = argv[i]; |
| String address = argv[i + 1]; |
| String op = argv[i + 2]; |
| |
| if ("start".equals(op)) { |
| return startReconfiguration(nodeType, address, System.out, System.err); |
| } else if ("status".equals(op)) { |
| return getReconfigurationStatus(nodeType, address, System.out, System.err); |
| } else if ("properties".equals(op)) { |
| return getReconfigurableProperties(nodeType, address, System.out, |
| System.err); |
| } |
| System.err.println("Unknown operation: " + op); |
| return -1; |
| } |
| |
| int startReconfiguration(final String nodeThpe, final String address) |
| throws IOException { |
| return startReconfiguration(nodeThpe, address, System.out, System.err); |
| } |
| |
| int startReconfiguration(final String nodeType, final String address, |
| final PrintStream out, final PrintStream err) throws IOException { |
| String outMsg = null; |
| String errMsg = null; |
| int ret = 0; |
| |
| try { |
| ret = startReconfigurationDispatch(nodeType, address, out, err); |
| outMsg = String.format("Started reconfiguration task on node [%s].", |
| address); |
| } catch (IOException e) { |
| errMsg = String.format("Node [%s] reconfiguring: %s.", address, |
| e.toString()); |
| } |
| |
| if (errMsg != null) { |
| err.println(errMsg); |
| return 1; |
| } else { |
| out.println(outMsg); |
| return ret; |
| } |
| } |
| |
| int startReconfigurationDispatch(final String nodeType, |
| final String address, final PrintStream out, final PrintStream err) |
| throws IOException { |
| if ("namenode".equals(nodeType)) { |
| ReconfigurationProtocol reconfProxy = getNameNodeProxy(address); |
| reconfProxy.startReconfiguration(); |
| return 0; |
| } else if ("datanode".equals(nodeType)) { |
| ClientDatanodeProtocol reconfProxy = getDataNodeProxy(address); |
| reconfProxy.startReconfiguration(); |
| return 0; |
| } else { |
| System.err.println("Node type " + nodeType |
| + " does not support reconfiguration."); |
| return 1; |
| } |
| } |
| |
| int getReconfigurationStatus(final String nodeType, final String address, |
| final PrintStream out, final PrintStream err) throws IOException { |
| String outMsg = null; |
| String errMsg = null; |
| ReconfigurationTaskStatus status = null; |
| |
| try { |
| status = getReconfigurationStatusDispatch(nodeType, address, out, err); |
| outMsg = String.format("Reconfiguring status for node [%s]: ", address); |
| } catch (IOException e) { |
| errMsg = String.format("Node [%s] reloading configuration: %s.", address, |
| e.toString()); |
| } |
| |
| if (errMsg != null) { |
| err.println(errMsg); |
| return 1; |
| } else { |
| out.print(outMsg); |
| } |
| |
| if (status != null) { |
| if (!status.hasTask()) { |
| out.println("no task was found."); |
| return 0; |
| } |
| out.print("started at " + new Date(status.getStartTime())); |
| if (!status.stopped()) { |
| out.println(" and is still running."); |
| return 0; |
| } |
| |
| out.println(" and finished at " |
| + new Date(status.getEndTime()).toString() + "."); |
| if (status.getStatus() == null) { |
| // Nothing to report. |
| return 0; |
| } |
| for (Map.Entry<PropertyChange, Optional<String>> result : status |
| .getStatus().entrySet()) { |
| if (!result.getValue().isPresent()) { |
| out.printf( |
| "SUCCESS: Changed property %s%n\tFrom: \"%s\"%n\tTo: \"%s\"%n", |
| result.getKey().prop, result.getKey().oldVal, |
| result.getKey().newVal); |
| } else { |
| final String errorMsg = result.getValue().get(); |
| out.printf( |
| "FAILED: Change property %s%n\tFrom: \"%s\"%n\tTo: \"%s\"%n", |
| result.getKey().prop, result.getKey().oldVal, |
| result.getKey().newVal); |
| out.println("\tError: " + errorMsg + "."); |
| } |
| } |
| } else { |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| ReconfigurationTaskStatus getReconfigurationStatusDispatch( |
| final String nodeType, final String address, final PrintStream out, |
| final PrintStream err) throws IOException { |
| if ("namenode".equals(nodeType)) { |
| ReconfigurationProtocol reconfProxy = getNameNodeProxy(address); |
| return reconfProxy.getReconfigurationStatus(); |
| } else if ("datanode".equals(nodeType)) { |
| ClientDatanodeProtocol reconfProxy = getDataNodeProxy(address); |
| return reconfProxy.getReconfigurationStatus(); |
| } else { |
| err.println("Node type " + nodeType |
| + " does not support reconfiguration."); |
| return null; |
| } |
| } |
| |
| int getReconfigurableProperties(final String nodeType, final String address, |
| final PrintStream out, final PrintStream err) throws IOException { |
| String outMsg = null; |
| String errMsg = null; |
| List<String> properties = null; |
| |
| try { |
| properties = getReconfigurablePropertiesDispatch(nodeType, address, out, |
| err); |
| outMsg = String.format("Node [%s] Reconfigurable properties:", address); |
| } catch (IOException e) { |
| errMsg = String.format("Node [%s] reconfiguration: %s.", address, |
| e.toString()); |
| } |
| |
| if (errMsg != null) { |
| err.println(errMsg); |
| return 1; |
| } else if (properties == null) { |
| return 1; |
| } else { |
| out.println(outMsg); |
| for (String name : properties) { |
| out.println(name); |
| } |
| return 0; |
| } |
| } |
| |
| List<String> getReconfigurablePropertiesDispatch(final String nodeType, |
| final String address, final PrintStream out, final PrintStream err) |
| throws IOException { |
| if ("namenode".equals(nodeType)) { |
| ReconfigurationProtocol reconfProxy = getNameNodeProxy(address); |
| return reconfProxy.listReconfigurableProperties(); |
| } else if ("datanode".equals(nodeType)) { |
| ClientDatanodeProtocol reconfProxy = getDataNodeProxy(address); |
| return reconfProxy.listReconfigurableProperties(); |
| } else { |
| err.println("Node type " + nodeType |
| + " does not support reconfiguration."); |
| return null; |
| } |
| } |
| |
| public int genericRefresh(String[] argv, int i) throws IOException { |
| String hostport = argv[i++]; |
| String identifier = argv[i++]; |
| String[] args = Arrays.copyOfRange(argv, i, argv.length); |
| |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // for security authorization |
| // server principal for this call |
| // should be NN's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| // Create the client |
| Class<?> xface = GenericRefreshProtocolPB.class; |
| InetSocketAddress address = NetUtils.createSocketAddr(hostport); |
| UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); |
| |
| RPC.setProtocolEngine(conf, xface, ProtobufRpcEngine.class); |
| GenericRefreshProtocolPB proxy = (GenericRefreshProtocolPB) |
| RPC.getProxy(xface, RPC.getProtocolVersion(xface), address, |
| ugi, conf, NetUtils.getDefaultSocketFactory(conf), 0); |
| |
| Collection<RefreshResponse> responses = null; |
| try (GenericRefreshProtocolClientSideTranslatorPB xlator = |
| new GenericRefreshProtocolClientSideTranslatorPB(proxy);) { |
| // Refresh |
| responses = xlator.refresh(identifier, args); |
| |
| int returnCode = 0; |
| |
| // Print refresh responses |
| System.out.println("Refresh Responses:\n"); |
| for (RefreshResponse response : responses) { |
| System.out.println(response.toString()); |
| |
| if (returnCode == 0 && response.getReturnCode() != 0) { |
| // This is the first non-zero return code, so we should return this |
| returnCode = response.getReturnCode(); |
| } else if (returnCode != 0 && response.getReturnCode() != 0) { |
| // Then now we have multiple non-zero return codes, |
| // so we merge them into -1 |
| returnCode = - 1; |
| } |
| } |
| return returnCode; |
| } finally { |
| if (responses == null) { |
| System.out.println("Failed to get response.\n"); |
| return -1; |
| } |
| } |
| } |
| |
| /** |
| * Displays format of commands. |
| * @param cmd The command that is being executed. |
| */ |
| private static void printUsage(String cmd) { |
| if ("-report".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-report] [-live] [-dead] [-decommissioning]" |
| + " [-enteringmaintenance] [-inmaintenance]"); |
| } else if ("-safemode".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-safemode enter | leave | get | wait | forceExit]"); |
| } else if ("-allowSnapshot".equalsIgnoreCase(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-allowSnapshot <snapshotDir>]"); |
| } else if ("-disallowSnapshot".equalsIgnoreCase(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-disallowSnapshot <snapshotDir>]"); |
| } else if ("-saveNamespace".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-saveNamespace]"); |
| } else if ("-rollEdits".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-rollEdits]"); |
| } else if ("-restoreFailedStorage".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-restoreFailedStorage true|false|check ]"); |
| } else if ("-refreshNodes".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refreshNodes]"); |
| } else if ("-finalizeUpgrade".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-finalizeUpgrade]"); |
| } else if (RollingUpgradeCommand.matches(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [" + RollingUpgradeCommand.USAGE+"]"); |
| } else if ("-metasave".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-metasave filename]"); |
| } else if (SetQuotaCommand.matches(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [" + SetQuotaCommand.USAGE+"]"); |
| } else if (ClearQuotaCommand.matches(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " ["+ClearQuotaCommand.USAGE+"]"); |
| } else if (SetSpaceQuotaCommand.matches(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [" + SetSpaceQuotaCommand.USAGE+"]"); |
| } else if (ClearSpaceQuotaCommand.matches(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " ["+ClearSpaceQuotaCommand.USAGE+"]"); |
| } else if ("-refreshServiceAcl".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refreshServiceAcl]"); |
| } else if ("-refreshUserToGroupsMappings".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refreshUserToGroupsMappings]"); |
| } else if ("-refreshSuperUserGroupsConfiguration".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refreshSuperUserGroupsConfiguration]"); |
| } else if ("-refreshCallQueue".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refreshCallQueue]"); |
| } else if ("-reconfig".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-reconfig <namenode|datanode> <host:ipc_port> " |
| + "<start|status|properties>]"); |
| } else if ("-refresh".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refresh <hostname:ipc_port> " |
| + "<resource_identifier> [arg1..argn]"); |
| } else if ("-printTopology".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-printTopology]"); |
| } else if ("-refreshNamenodes".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-refreshNamenodes datanode-host:ipc_port]"); |
| } else if ("-getVolumeReport".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-getVolumeReport datanode-host:ipc_port]"); |
| } else if ("-deleteBlockPool".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-deleteBlockPool datanode-host:ipc_port blockpoolId [force]]"); |
| } else if ("-setBalancerBandwidth".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-setBalancerBandwidth <bandwidth in bytes per second>]"); |
| } else if ("-getBalancerBandwidth".equalsIgnoreCase(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-getBalancerBandwidth <datanode_host:ipc_port>]"); |
| } else if ("-fetchImage".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-fetchImage <local directory>]"); |
| } else if ("-shutdownDatanode".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-shutdownDatanode <datanode_host:ipc_port> [upgrade]]"); |
| } else if ("-evictWriters".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-evictWriters <datanode_host:ipc_port>]"); |
| } else if ("-getDatanodeInfo".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-getDatanodeInfo <datanode_host:ipc_port>]"); |
| } else if ("-triggerBlockReport".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin" |
| + " [-triggerBlockReport [-incremental] <datanode_host:ipc_port>]"); |
| } else if ("-listOpenFiles".equals(cmd)) { |
| System.err.println("Usage: hdfs dfsadmin [-listOpenFiles]"); |
| } else { |
| System.err.println("Usage: hdfs dfsadmin"); |
| System.err.println("Note: Administrative commands can only be run as the HDFS superuser."); |
| System.err.println(commonUsageSummary); |
| ToolRunner.printGenericCommandUsage(System.err); |
| } |
| } |
| |
| /** |
| * @param argv The parameters passed to this program. |
| * @exception Exception if the filesystem does not exist. |
| * @return 0 on success, non zero on error. |
| */ |
| @Override |
| public int run(String[] argv) throws Exception { |
| |
| if (argv.length < 1) { |
| printUsage(""); |
| return -1; |
| } |
| |
| int exitCode = -1; |
| int i = 0; |
| String cmd = argv[i++]; |
| |
| // |
| // verify that we have enough command line parameters |
| // |
| if ("-safemode".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-allowSnapshot".equalsIgnoreCase(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-disallowSnapshot".equalsIgnoreCase(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-report".equals(cmd)) { |
| if (argv.length > 6) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-saveNamespace".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-rollEdits".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-restoreFailedStorage".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-refreshNodes".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-finalizeUpgrade".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if (RollingUpgradeCommand.matches(cmd)) { |
| if (argv.length < 1 || argv.length > 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-metasave".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-refreshServiceAcl".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-refresh".equals(cmd)) { |
| if (argv.length < 3) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-refreshUserToGroupsMappings".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-printTopology".equals(cmd)) { |
| if(argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-refreshNamenodes".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-getVolumeReport".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-reconfig".equals(cmd)) { |
| if (argv.length != 4) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-deleteBlockPool".equals(cmd)) { |
| if ((argv.length != 3) && (argv.length != 4)) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-setBalancerBandwidth".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-getBalancerBandwidth".equalsIgnoreCase(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-fetchImage".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-shutdownDatanode".equals(cmd)) { |
| if ((argv.length != 2) && (argv.length != 3)) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-getDatanodeInfo".equals(cmd)) { |
| if (argv.length != 2) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-triggerBlockReport".equals(cmd)) { |
| if (argv.length < 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } else if ("-listOpenFiles".equals(cmd)) { |
| if (argv.length != 1) { |
| printUsage(cmd); |
| return exitCode; |
| } |
| } |
| |
| // initialize DFSAdmin |
| try { |
| init(); |
| } catch (RPC.VersionMismatch v) { |
| System.err.println("Version Mismatch between client and server" |
| + "... command aborted."); |
| return exitCode; |
| } catch (IOException e) { |
| System.err.println("Bad connection to DFS... command aborted."); |
| return exitCode; |
| } |
| |
| Exception debugException = null; |
| exitCode = 0; |
| try { |
| if ("-report".equals(cmd)) { |
| report(argv, i); |
| } else if ("-safemode".equals(cmd)) { |
| setSafeMode(argv, i); |
| } else if ("-allowSnapshot".equalsIgnoreCase(cmd)) { |
| allowSnapshot(argv); |
| } else if ("-disallowSnapshot".equalsIgnoreCase(cmd)) { |
| disallowSnapshot(argv); |
| } else if ("-saveNamespace".equals(cmd)) { |
| exitCode = saveNamespace(); |
| } else if ("-rollEdits".equals(cmd)) { |
| exitCode = rollEdits(); |
| } else if ("-restoreFailedStorage".equals(cmd)) { |
| exitCode = restoreFailedStorage(argv[i]); |
| } else if ("-refreshNodes".equals(cmd)) { |
| exitCode = refreshNodes(); |
| } else if ("-finalizeUpgrade".equals(cmd)) { |
| exitCode = finalizeUpgrade(); |
| } else if (RollingUpgradeCommand.matches(cmd)) { |
| exitCode = RollingUpgradeCommand.run(getDFS(), argv, i); |
| } else if ("-metasave".equals(cmd)) { |
| exitCode = metaSave(argv, i); |
| } else if (ClearQuotaCommand.matches(cmd)) { |
| exitCode = new ClearQuotaCommand(argv, i, getConf()).runAll(); |
| } else if (SetQuotaCommand.matches(cmd)) { |
| exitCode = new SetQuotaCommand(argv, i, getConf()).runAll(); |
| } else if (ClearSpaceQuotaCommand.matches(cmd)) { |
| exitCode = new ClearSpaceQuotaCommand(argv, i, getConf()).runAll(); |
| } else if (SetSpaceQuotaCommand.matches(cmd)) { |
| exitCode = new SetSpaceQuotaCommand(argv, i, getConf()).runAll(); |
| } else if ("-refreshServiceAcl".equals(cmd)) { |
| exitCode = refreshServiceAcl(); |
| } else if ("-refreshUserToGroupsMappings".equals(cmd)) { |
| exitCode = refreshUserToGroupsMappings(); |
| } else if ("-refreshSuperUserGroupsConfiguration".equals(cmd)) { |
| exitCode = refreshSuperUserGroupsConfiguration(); |
| } else if ("-refreshCallQueue".equals(cmd)) { |
| exitCode = refreshCallQueue(); |
| } else if ("-refresh".equals(cmd)) { |
| exitCode = genericRefresh(argv, i); |
| } else if ("-printTopology".equals(cmd)) { |
| exitCode = printTopology(); |
| } else if ("-refreshNamenodes".equals(cmd)) { |
| exitCode = refreshNamenodes(argv, i); |
| } else if ("-getVolumeReport".equals(cmd)) { |
| exitCode = getVolumeReport(argv, i); |
| } else if ("-deleteBlockPool".equals(cmd)) { |
| exitCode = deleteBlockPool(argv, i); |
| } else if ("-setBalancerBandwidth".equals(cmd)) { |
| exitCode = setBalancerBandwidth(argv, i); |
| } else if ("-getBalancerBandwidth".equals(cmd)) { |
| exitCode = getBalancerBandwidth(argv, i); |
| } else if ("-fetchImage".equals(cmd)) { |
| exitCode = fetchImage(argv, i); |
| } else if ("-shutdownDatanode".equals(cmd)) { |
| exitCode = shutdownDatanode(argv, i); |
| } else if ("-evictWriters".equals(cmd)) { |
| exitCode = evictWriters(argv, i); |
| } else if ("-getDatanodeInfo".equals(cmd)) { |
| exitCode = getDatanodeInfo(argv, i); |
| } else if ("-reconfig".equals(cmd)) { |
| exitCode = reconfig(argv, i); |
| } else if ("-triggerBlockReport".equals(cmd)) { |
| exitCode = triggerBlockReport(argv); |
| } else if ("-listOpenFiles".equals(cmd)) { |
| exitCode = listOpenFiles(); |
| } else if ("-help".equals(cmd)) { |
| if (i < argv.length) { |
| printHelp(argv[i]); |
| } else { |
| printHelp(""); |
| } |
| } else { |
| exitCode = -1; |
| System.err.println(cmd.substring(1) + ": Unknown command"); |
| printUsage(""); |
| } |
| } catch (IllegalArgumentException arge) { |
| debugException = arge; |
| exitCode = -1; |
| System.err.println(cmd.substring(1) + ": " + arge.getLocalizedMessage()); |
| printUsage(cmd); |
| } catch (RemoteException e) { |
| // |
| // This is a error returned by hadoop server. Print |
| // out the first line of the error message, ignore the stack trace. |
| exitCode = -1; |
| debugException = e; |
| try { |
| String[] content; |
| content = e.getLocalizedMessage().split("\n"); |
| System.err.println(cmd.substring(1) + ": " |
| + content[0]); |
| } catch (Exception ex) { |
| System.err.println(cmd.substring(1) + ": " |
| + ex.getLocalizedMessage()); |
| debugException = ex; |
| } |
| } catch (Exception e) { |
| exitCode = -1; |
| debugException = e; |
| System.err.println(cmd.substring(1) + ": " |
| + e.getLocalizedMessage()); |
| } |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Exception encountered:", debugException); |
| } |
| return exitCode; |
| } |
| |
| private int getVolumeReport(String[] argv, int i) throws IOException { |
| ClientDatanodeProtocol datanode = getDataNodeProxy(argv[i]); |
| List<DatanodeVolumeInfo> volumeReport = datanode |
| .getVolumeReport(); |
| System.out.println("Active Volumes : " + volumeReport.size()); |
| for (DatanodeVolumeInfo info : volumeReport) { |
| System.out.println("\n" + info.getDatanodeVolumeReport()); |
| } |
| return 0; |
| } |
| |
| private ClientDatanodeProtocol getDataNodeProxy(String datanode) |
| throws IOException { |
| InetSocketAddress datanodeAddr = NetUtils.createSocketAddr(datanode); |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // For datanode proxy the server principal should be DN's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_DATANODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| // Create the client |
| ClientDatanodeProtocol dnProtocol = |
| DFSUtilClient.createClientDatanodeProtocolProxy(datanodeAddr, getUGI(), conf, |
| NetUtils.getSocketFactory(conf, ClientDatanodeProtocol.class)); |
| return dnProtocol; |
| } |
| |
| private ReconfigurationProtocol getNameNodeProxy(String node) |
| throws IOException { |
| InetSocketAddress nodeAddr = NetUtils.createSocketAddr(node); |
| // Get the current configuration |
| Configuration conf = getConf(); |
| |
| // For namenode proxy the server principal should be NN's one. |
| conf.set(CommonConfigurationKeys.HADOOP_SECURITY_SERVICE_USER_NAME_KEY, |
| conf.get(DFSConfigKeys.DFS_NAMENODE_KERBEROS_PRINCIPAL_KEY, "")); |
| |
| // Create the client |
| ReconfigurationProtocol reconfigProtocol = DFSUtilClient |
| .createReconfigurationProtocolProxy(nodeAddr, getUGI(), conf, |
| NetUtils.getSocketFactory(conf, ReconfigurationProtocol.class)); |
| return reconfigProtocol; |
| } |
| |
| private int deleteBlockPool(String[] argv, int i) throws IOException { |
| ClientDatanodeProtocol dnProxy = getDataNodeProxy(argv[i]); |
| boolean force = false; |
| if (argv.length-1 == i+2) { |
| if ("force".equals(argv[i+2])) { |
| force = true; |
| } else { |
| printUsage("-deleteBlockPool"); |
| return -1; |
| } |
| } |
| dnProxy.deleteBlockPool(argv[i+1], force); |
| return 0; |
| } |
| |
| private int refreshNamenodes(String[] argv, int i) throws IOException { |
| String datanode = argv[i]; |
| ClientDatanodeProtocol refreshProtocol = getDataNodeProxy(datanode); |
| refreshProtocol.refreshNamenodes(); |
| |
| return 0; |
| } |
| |
| private int shutdownDatanode(String[] argv, int i) throws IOException { |
| final String dn = argv[i]; |
| ClientDatanodeProtocol dnProxy = getDataNodeProxy(dn); |
| boolean upgrade = false; |
| if (argv.length-1 == i+1) { |
| if ("upgrade".equalsIgnoreCase(argv[i+1])) { |
| upgrade = true; |
| } else { |
| printUsage("-shutdownDatanode"); |
| return -1; |
| } |
| } |
| dnProxy.shutdownDatanode(upgrade); |
| System.out.println("Submitted a shutdown request to datanode " + dn); |
| return 0; |
| } |
| |
| private int evictWriters(String[] argv, int i) throws IOException { |
| final String dn = argv[i]; |
| ClientDatanodeProtocol dnProxy = getDataNodeProxy(dn); |
| try { |
| dnProxy.evictWriters(); |
| System.out.println("Requested writer eviction to datanode " + dn); |
| } catch (IOException ioe) { |
| throw new IOException("Datanode unreachable. " + ioe, ioe); |
| } |
| return 0; |
| } |
| |
| private int getDatanodeInfo(String[] argv, int i) throws IOException { |
| ClientDatanodeProtocol dnProxy = getDataNodeProxy(argv[i]); |
| try { |
| DatanodeLocalInfo dnInfo = dnProxy.getDatanodeInfo(); |
| System.out.println(dnInfo.getDatanodeLocalReport()); |
| } catch (IOException ioe) { |
| throw new IOException("Datanode unreachable. " + ioe, ioe); |
| } |
| return 0; |
| } |
| |
| /** |
| * main() has some simple utility methods. |
| * @param argv Command line parameters. |
| * @exception Exception if the filesystem does not exist. |
| */ |
| public static void main(String[] argv) throws Exception { |
| int res = ToolRunner.run(new DFSAdmin(), argv); |
| System.exit(res); |
| } |
| } |