/**
  * 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: java DFSAdmin" + " [-report]");
   } else if ("-safemode".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-safemode enter | leave | get | wait]");
   } else if ("-saveNamespace".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-saveNamespace]");
   } else if ("-refreshNodes".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-refreshNodes]");
   } else if ("-finalizeUpgrade".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-finalizeUpgrade]");
   } else if ("-upgradeProgress".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-upgradeProgress status | details | force]");
   } else if ("-metasave".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-metasave filename]");
   } else if (SetQuotaCommand.matches(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [" + SetQuotaCommand.USAGE + "]");
   } else if (ClearQuotaCommand.matches(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [" + ClearQuotaCommand.USAGE + "]");
   } else if (SetSpaceQuotaCommand.matches(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [" + SetSpaceQuotaCommand.USAGE + "]");
   } else if (ClearSpaceQuotaCommand.matches(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [" + ClearSpaceQuotaCommand.USAGE + "]");
   } else if ("-refreshServiceAcl".equals(cmd)) {
     System.err.println("Usage: java DFSAdmin" + " [-refreshServiceAcl]");
   } else {
     System.err.println("Usage: java DFSAdmin");
     System.err.println("           [-report]");
     System.err.println("           [-safemode enter | leave | get | wait]");
     System.err.println("           [-saveNamespace]");
     System.err.println("           [-refreshNodes]");
     System.err.println("           [-finalizeUpgrade]");
     System.err.println("           [-upgradeProgress status | details | force]");
     System.err.println("           [-metasave filename]");
     System.err.println("           [-refreshServiceAcl]");
     System.err.println("           [" + SetQuotaCommand.USAGE + "]");
     System.err.println("           [" + ClearQuotaCommand.USAGE + "]");
     System.err.println("           [" + SetSpaceQuotaCommand.USAGE + "]");
     System.err.println("           [" + ClearSpaceQuotaCommand.USAGE + "]");
     System.err.println("           [-help [cmd]]");
     System.err.println();
     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 ("-report".equals(cmd)) {
      if (argv.length != 1) {
        printUsage(cmd);
        return exitCode;
      }
    } else if ("-saveNamespace".equals(cmd)) {
      if (argv.length != 1) {
        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 ("-upgradeProgress".equals(cmd)) {
      if (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;
      }
    }

    // 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;
    }

    exitCode = 0;
    try {
      if ("-report".equals(cmd)) {
        report();
      } else if ("-safemode".equals(cmd)) {
        setSafeMode(argv, i);
      } else if ("-saveNamespace".equals(cmd)) {
        exitCode = saveNamespace();
      } else if ("-refreshNodes".equals(cmd)) {
        exitCode = refreshNodes();
      } else if ("-finalizeUpgrade".equals(cmd)) {
        exitCode = finalizeUpgrade();
      } else if ("-upgradeProgress".equals(cmd)) {
        exitCode = upgradeProgress(argv, i);
      } else if ("-metasave".equals(cmd)) {
        exitCode = metaSave(argv, i);
      } else if (ClearQuotaCommand.matches(cmd)) {
        exitCode = new ClearQuotaCommand(argv, i, fs).runAll();
      } else if (SetQuotaCommand.matches(cmd)) {
        exitCode = new SetQuotaCommand(argv, i, fs).runAll();
      } else if (ClearSpaceQuotaCommand.matches(cmd)) {
        exitCode = new ClearSpaceQuotaCommand(argv, i, fs).runAll();
      } else if (SetSpaceQuotaCommand.matches(cmd)) {
        exitCode = new SetSpaceQuotaCommand(argv, i, fs).runAll();
      } else if ("-refreshServiceAcl".equals(cmd)) {
        exitCode = refreshServiceAcl();
      } 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) {
      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 mesage, ignore the stack trace.
      exitCode = -1;
      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());
      }
    } catch (Exception e) {
      exitCode = -1;
      System.err.println(cmd.substring(1) + ": " + e.getLocalizedMessage());
    }
    return exitCode;
  }
  private void printHelp(String cmd) {
    String summary =
        "hadoop dfsadmin is the command to execute DFS administrative commands.\n"
            + "The full syntax is: \n\n"
            + "hadoop dfsadmin [-report] [-safemode <enter | leave | get | wait>]\n"
            + "\t[-saveNamespace]\n"
            + "\t[-refreshNodes]\n"
            + "\t["
            + SetQuotaCommand.USAGE
            + "]\n"
            + "\t["
            + ClearQuotaCommand.USAGE
            + "]\n"
            + "\t["
            + SetSpaceQuotaCommand.USAGE
            + "]\n"
            + "\t["
            + ClearSpaceQuotaCommand.USAGE
            + "]\n"
            + "\t[-refreshServiceAcl]\n"
            + "\t[-help [cmd]]\n";

    String report = "-report: \tReports basic filesystem information and statistics.\n";

    String safemode =
        "-safemode <enter|leave|get|wait>:  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 superuser permissions and safe mode.\n";

    String refreshNodes =
        "-refreshNodes: \tUpdates the set of hosts allowed "
            + "to connect to namenode.\n\n"
            + "\t\tRe-reads the config file to update values defined by \n"
            + "\t\tdfs.hosts and dfs.host.exclude and reads the \n"
            + "\t\tentires (hostnames) in those files.\n\n"
            + "\t\tEach entry not defined in dfs.hosts but in \n"
            + "\t\tdfs.hosts.exclude is decommissioned. Each entry defined \n"
            + "\t\tin dfs.hosts and also in dfs.host.exclude is stopped from \n"
            + "\t\tdecommissioning if it has aleady been marked for decommission.\n"
            + "\t\tEntires not present in both the lists are decommissioned.\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 upgradeProgress =
        "-upgradeProgress <status|details|force>: \n"
            + "\t\trequest current distributed upgrade status, \n"
            + "\t\ta detailed status or force the upgrade to proceed.\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> 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 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 ("refreshNodes".equals(cmd)) {
      System.out.println(refreshNodes);
    } else if ("finalizeUpgrade".equals(cmd)) {
      System.out.println(finalizeUpgrade);
    } else if ("upgradeProgress".equals(cmd)) {
      System.out.println(upgradeProgress);
    } 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 ("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(refreshNodes);
      System.out.println(finalizeUpgrade);
      System.out.println(upgradeProgress);
      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(help);
      System.out.println();
      ToolRunner.printGenericCommandUsage(System.out);
    }
  }