Просмотр исходного кода

ZOOKEEPER-3085: define exit codes in enum

Define the used exit codes in one enum. contrib projects are excluded, as they can have seperate exit codes (and they do use it differently then in core ZK).
Some exit codes overlap, but refactoring the exit code used is not backward compatible.

Author: Norbert Kalmar <nkalmar@yahoo.com>

Reviewers: lvfangmin@apache.org, breed@apache.org, andor@apache.org

Closes #572 from nkalmar/ZOOKEEPER-3085 and squashes the following commits:

dbc18a62 [Norbert Kalmar] ZOOKEEPER-3085 change comments to javadoc comment in enum code defs
908c171e [Norbert Kalmar] ZOOKEEPER-3085 add missing enum usage and some renames
c49dcef9 [Norbert Kalmar] ZOOKEEPER-3085 use the enum value in ZooKeeperMain.exitCode as well
611aa4ed [Norbert Kalmar] ZOOKEEPER-3085 define exit codes in enum
Norbert Kalmar 7 лет назад
Родитель
Сommit
44d2736124
23 измененных файлов с 144 добавлено и 55 удалено
  1. 3 2
      src/java/main/org/apache/zookeeper/Shell.java
  2. 5 3
      src/java/main/org/apache/zookeeper/Version.java
  3. 3 2
      src/java/main/org/apache/zookeeper/ZooKeeperMain.java
  4. 38 3
      src/java/main/org/apache/zookeeper/server/ExitCode.java
  5. 2 2
      src/java/main/org/apache/zookeeper/server/LogFormatter.java
  6. 1 1
      src/java/main/org/apache/zookeeper/server/PurgeTxnLog.java
  7. 1 1
      src/java/main/org/apache/zookeeper/server/SnapshotFormatter.java
  8. 1 1
      src/java/main/org/apache/zookeeper/server/TraceFormatter.java
  9. 1 1
      src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java
  10. 1 1
      src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java
  11. 6 6
      src/java/main/org/apache/zookeeper/server/ZooKeeperServerMain.java
  12. 7 6
      src/java/main/org/apache/zookeeper/server/persistence/TxnLogToolkit.java
  13. 2 1
      src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java
  14. 3 4
      src/java/main/org/apache/zookeeper/server/quorum/Learner.java
  15. 2 1
      src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java
  16. 7 6
      src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerMain.java
  17. 7 5
      src/java/main/org/apache/zookeeper/version/util/VerGen.java
  18. 3 2
      src/java/systest/org/apache/zookeeper/test/system/GenerateLoad.java
  19. 3 2
      src/java/systest/org/apache/zookeeper/test/system/InstanceContainer.java
  20. 2 1
      src/java/test/org/apache/zookeeper/server/quorum/auth/MiniKdc.java
  21. 3 2
      src/java/test/org/apache/zookeeper/test/IntegrityCheck.java
  22. 3 2
      src/java/test/org/apache/zookeeper/test/SledgeHammer.java
  23. 40 0
      zookeeper-docs/src/documentation/content/xdocs/zookeeperAdmin.xml

+ 3 - 2
src/java/main/org/apache/zookeeper/Shell.java

@@ -40,6 +40,7 @@ import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 
 import org.apache.zookeeper.common.Time;
 import org.apache.zookeeper.common.Time;
+import org.apache.zookeeper.server.ExitCode;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 
 
@@ -151,7 +152,7 @@ abstract public class Shell {
   protected void run() throws IOException {
   protected void run() throws IOException {
     if (lastTime + interval > Time.currentElapsedTime())
     if (lastTime + interval > Time.currentElapsedTime())
       return;
       return;
-    exitCode = 0; // reset for next run
+    exitCode = ExitCode.EXECUTION_FINISHED.getValue(); // reset for next run
     runCommand();
     runCommand();
   }
   }
 
 
@@ -224,7 +225,7 @@ abstract public class Shell {
       completed.set(true);
       completed.set(true);
       //the timeout thread handling
       //the timeout thread handling
       //taken care in finally block
       //taken care in finally block
-      if (exitCode != 0) {
+      if (exitCode != ExitCode.EXECUTION_FINISHED.getValue()) {
         throw new ExitCodeException(exitCode, errMsg.toString());
         throw new ExitCodeException(exitCode, errMsg.toString());
       }
       }
     } catch (InterruptedException ie) {
     } catch (InterruptedException ie) {

+ 5 - 3
src/java/main/org/apache/zookeeper/Version.java

@@ -18,6 +18,8 @@
 
 
 package org.apache.zookeeper;
 package org.apache.zookeeper;
 
 
+import org.apache.zookeeper.server.ExitCode;
+
 public class Version implements org.apache.zookeeper.version.Info {
 public class Version implements org.apache.zookeeper.version.Info {
 
 
     /*
     /*
@@ -57,7 +59,7 @@ public class Version implements org.apache.zookeeper.version.Info {
                 .print("Usage:\tjava -cp ... org.apache.zookeeper.Version "
                 .print("Usage:\tjava -cp ... org.apache.zookeeper.Version "
                         + "[--full | --short | --revision],\n\tPrints --full version "
                         + "[--full | --short | --revision],\n\tPrints --full version "
                         + "info if no arg specified.");
                         + "info if no arg specified.");
-        System.exit(1);
+        System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
     }
     }
 
 
     /**
     /**
@@ -77,7 +79,7 @@ public class Version implements org.apache.zookeeper.version.Info {
         }
         }
         if (args.length == 0 || (args.length == 1 && args[0].equals("--full"))) {
         if (args.length == 0 || (args.length == 1 && args[0].equals("--full"))) {
             System.out.println(getFullVersion());
             System.out.println(getFullVersion());
-            System.exit(0);
+            System.exit(ExitCode.EXECUTION_FINISHED.getValue());
         }
         }
         if (args[0].equals("--short"))
         if (args[0].equals("--short"))
             System.out.println(getVersion());
             System.out.println(getVersion());
@@ -85,6 +87,6 @@ public class Version implements org.apache.zookeeper.version.Info {
             System.out.println(getVersionRevision());
             System.out.println(getVersionRevision());
         else
         else
             printUsage();
             printUsage();
-        System.exit(0);
+        System.exit(ExitCode.EXECUTION_FINISHED.getValue());
     }
     }
 }
 }

+ 3 - 2
src/java/main/org/apache/zookeeper/ZooKeeperMain.java

@@ -68,6 +68,7 @@ import org.apache.zookeeper.cli.StatCommand;
 import org.apache.zookeeper.cli.SyncCommand;
 import org.apache.zookeeper.cli.SyncCommand;
 import org.apache.zookeeper.client.ZKClientConfig;
 import org.apache.zookeeper.client.ZKClientConfig;
 import org.apache.zookeeper.admin.ZooKeeperAdmin;
 import org.apache.zookeeper.admin.ZooKeeperAdmin;
+import org.apache.zookeeper.server.ExitCode;
 
 
 /**
 /**
  * The command line client to ZooKeeper.
  * The command line client to ZooKeeper.
@@ -84,7 +85,7 @@ public class ZooKeeperMain {
     protected HashMap<Integer,String> history = new HashMap<Integer,String>( );
     protected HashMap<Integer,String> history = new HashMap<Integer,String>( );
     protected int commandCount = 0;
     protected int commandCount = 0;
     protected boolean printWatches = true;
     protected boolean printWatches = true;
-    protected int exitCode = 0;
+    protected int exitCode = ExitCode.EXECUTION_FINISHED.getValue();
 
 
     protected ZooKeeper zk;
     protected ZooKeeper zk;
     protected String host = "";
     protected String host = "";
@@ -586,7 +587,7 @@ public class ZooKeeperMain {
         boolean watch = false;
         boolean watch = false;
         try {
         try {
             watch = processZKCmd(co);
             watch = processZKCmd(co);
-            exitCode = 0;
+            exitCode = ExitCode.EXECUTION_FINISHED.getValue();
         } catch (CliException ex) {
         } catch (CliException ex) {
             exitCode = ex.getExitCode();
             exitCode = ex.getExitCode();
             System.err.println(ex.getMessage());
             System.err.println(ex.getMessage());

+ 38 - 3
src/java/main/org/apache/zookeeper/server/ExitCode.java

@@ -20,8 +20,43 @@ package org.apache.zookeeper.server;
 /**
 /**
  * Exit code used to exit server
  * Exit code used to exit server
  */
  */
-public class ExitCode {
+public enum ExitCode {
+
+    /** Execution finished normally */
+    EXECUTION_FINISHED(0),
+
+    /** Unexpected errors like IO Exceptions */
+    UNEXPECTED_ERROR(1),
+
+    /** Invalid arguments during invocations */
+    INVALID_INVOCATION(2),
+
+    /** Cannot access datadir when trying to replicate server */
+    UNABLE_TO_ACCESS_DATADIR(3),
+
+    /** Unable to start admin server at ZooKeeper startup */
+    ERROR_STARTING_ADMIN_SERVER(4),
+
+    /** Severe error during snapshot IO */
+    TXNLOG_ERROR_TAKING_SNAPSHOT(10),
+
+    /** zxid from COMMIT does not match the one from pendingTxns queue */
+    UNMATCHED_TXN_COMMIT(12),
+
+    /** Unexpected packet from leader, or unable to truncate log on Leader.TRUNC */
+    QUORUM_PACKET_ERROR(13),
+
+    /** Unable to bind to the quorum (election) port after multiple retry */
+    UNABLE_TO_BIND_QUORUM_PORT(14);
+
+    private final int value;
+
+    ExitCode(final int newValue) {
+        value = newValue;
+    }
+
+    public int getValue() {
+        return value;
+    }
 
 
-    /* Represents unexpected error */
-    public final static int UNEXPECTED_ERROR = 1;
 }
 }

+ 2 - 2
src/java/main/org/apache/zookeeper/server/LogFormatter.java

@@ -46,7 +46,7 @@ public class LogFormatter {
     public static void main(String[] args) throws Exception {
     public static void main(String[] args) throws Exception {
         if (args.length != 1) {
         if (args.length != 1) {
             System.err.println("USAGE: LogFormatter log_file");
             System.err.println("USAGE: LogFormatter log_file");
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         }
         }
         FileInputStream fis = new FileInputStream(args[0]);
         FileInputStream fis = new FileInputStream(args[0]);
         BinaryInputArchive logStream = BinaryInputArchive.getArchive(fis);
         BinaryInputArchive logStream = BinaryInputArchive.getArchive(fis);
@@ -55,7 +55,7 @@ public class LogFormatter {
 
 
         if (fhdr.getMagic() != FileTxnLog.TXNLOG_MAGIC) {
         if (fhdr.getMagic() != FileTxnLog.TXNLOG_MAGIC) {
             System.err.println("Invalid magic number for " + args[0]);
             System.err.println("Invalid magic number for " + args[0]);
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         }
         }
         System.out.println("ZooKeeper Transactional Log File with dbid "
         System.out.println("ZooKeeper Transactional Log File with dbid "
                 + fhdr.getDbid() + " txnlog format version "
                 + fhdr.getDbid() + " txnlog format version "

+ 1 - 1
src/java/main/org/apache/zookeeper/server/PurgeTxnLog.java

@@ -231,6 +231,6 @@ public class PurgeTxnLog {
 
 
     private static void printUsageThenExit() {
     private static void printUsageThenExit() {
         printUsage();
         printUsage();
-        System.exit(1);
+        System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
     }
     }
 }
 }

+ 1 - 1
src/java/main/org/apache/zookeeper/server/SnapshotFormatter.java

@@ -47,7 +47,7 @@ public class SnapshotFormatter {
     public static void main(String[] args) throws Exception {
     public static void main(String[] args) throws Exception {
         if (args.length != 1) {
         if (args.length != 1) {
             System.err.println("USAGE: SnapshotFormatter snapshot_file");
             System.err.println("USAGE: SnapshotFormatter snapshot_file");
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         }
         }
 
 
         new SnapshotFormatter().run(args[0]);
         new SnapshotFormatter().run(args[0]);

+ 1 - 1
src/java/main/org/apache/zookeeper/server/TraceFormatter.java

@@ -83,7 +83,7 @@ public class TraceFormatter {
     public static void main(String[] args) throws IOException {
     public static void main(String[] args) throws IOException {
         if (args.length != 1) {
         if (args.length != 1) {
             System.err.println("USAGE: TraceFormatter trace_file");
             System.err.println("USAGE: TraceFormatter trace_file");
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         }
         }
         FileChannel fc = new FileInputStream(args[0]).getChannel();
         FileChannel fc = new FileInputStream(args[0]).getChannel();
         while (true) {
         while (true) {

+ 1 - 1
src/java/main/org/apache/zookeeper/server/ZooKeeperCriticalThread.java

@@ -46,6 +46,6 @@ public class ZooKeeperCriticalThread extends ZooKeeperThread {
     @Override
     @Override
     protected void handleException(String threadName, Throwable e) {
     protected void handleException(String threadName, Throwable e) {
         LOG.error("Severe unrecoverable error, from thread : {}", threadName, e);
         LOG.error("Severe unrecoverable error, from thread : {}", threadName, e);
-        listener.notifyStopping(threadName, ExitCode.UNEXPECTED_ERROR);
+        listener.notifyStopping(threadName, ExitCode.UNEXPECTED_ERROR.getValue());
     }
     }
 }
 }

+ 1 - 1
src/java/main/org/apache/zookeeper/server/ZooKeeperServer.java

@@ -317,7 +317,7 @@ public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
             LOG.error("Severe unrecoverable error, exiting", e);
             LOG.error("Severe unrecoverable error, exiting", e);
             // This is a severe error that we cannot recover from,
             // This is a severe error that we cannot recover from,
             // so we need to exit
             // so we need to exit
-            System.exit(10);
+            System.exit(ExitCode.TXNLOG_ERROR_TAKING_SNAPSHOT.getValue());
         }
         }
     }
     }
 
 

+ 6 - 6
src/java/main/org/apache/zookeeper/server/ZooKeeperServerMain.java

@@ -66,25 +66,25 @@ public class ZooKeeperServerMain {
             LOG.error("Invalid arguments, exiting abnormally", e);
             LOG.error("Invalid arguments, exiting abnormally", e);
             LOG.info(USAGE);
             LOG.info(USAGE);
             System.err.println(USAGE);
             System.err.println(USAGE);
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         } catch (ConfigException e) {
         } catch (ConfigException e) {
             LOG.error("Invalid config, exiting abnormally", e);
             LOG.error("Invalid config, exiting abnormally", e);
             System.err.println("Invalid config, exiting abnormally");
             System.err.println("Invalid config, exiting abnormally");
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         } catch (DatadirException e) {
         } catch (DatadirException e) {
             LOG.error("Unable to access datadir, exiting abnormally", e);
             LOG.error("Unable to access datadir, exiting abnormally", e);
             System.err.println("Unable to access datadir, exiting abnormally");
             System.err.println("Unable to access datadir, exiting abnormally");
-            System.exit(3);
+            System.exit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue());
         } catch (AdminServerException e) {
         } catch (AdminServerException e) {
             LOG.error("Unable to start AdminServer, exiting abnormally", e);
             LOG.error("Unable to start AdminServer, exiting abnormally", e);
             System.err.println("Unable to start AdminServer, exiting abnormally");
             System.err.println("Unable to start AdminServer, exiting abnormally");
-            System.exit(4);
+            System.exit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue());
         } catch (Exception e) {
         } catch (Exception e) {
             LOG.error("Unexpected exception, exiting abnormally", e);
             LOG.error("Unexpected exception, exiting abnormally", e);
-            System.exit(1);
+            System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
         }
         }
         LOG.info("Exiting normally");
         LOG.info("Exiting normally");
-        System.exit(0);
+        System.exit(ExitCode.EXECUTION_FINISHED.getValue());
     }
     }
 
 
     protected void initializeAndRun(String[] args)
     protected void initializeAndRun(String[] args)

+ 7 - 6
src/java/main/org/apache/zookeeper/server/persistence/TxnLogToolkit.java

@@ -28,6 +28,7 @@ import org.apache.commons.cli.PosixParser;
 import org.apache.jute.BinaryInputArchive;
 import org.apache.jute.BinaryInputArchive;
 import org.apache.jute.BinaryOutputArchive;
 import org.apache.jute.BinaryOutputArchive;
 import org.apache.jute.Record;
 import org.apache.jute.Record;
+import org.apache.zookeeper.server.ExitCode;
 import org.apache.zookeeper.server.TraceFormatter;
 import org.apache.zookeeper.server.TraceFormatter;
 import org.apache.zookeeper.server.util.SerializeUtils;
 import org.apache.zookeeper.server.util.SerializeUtils;
 import org.apache.zookeeper.txn.TxnHeader;
 import org.apache.zookeeper.txn.TxnHeader;
@@ -114,12 +115,12 @@ public class TxnLogToolkit implements Closeable {
         this.force = force;
         this.force = force;
         txnLogFile = new File(txnLogFileName);
         txnLogFile = new File(txnLogFileName);
         if (!txnLogFile.exists() || !txnLogFile.canRead()) {
         if (!txnLogFile.exists() || !txnLogFile.canRead()) {
-            throw new TxnLogToolkitException(1, "File doesn't exist or not readable: %s", txnLogFile);
+            throw new TxnLogToolkitException(ExitCode.UNEXPECTED_ERROR.getValue(), "File doesn't exist or not readable: %s", txnLogFile);
         }
         }
         if (recoveryMode) {
         if (recoveryMode) {
             recoveryLogFile = new File(txnLogFile.toString() + ".fixed");
             recoveryLogFile = new File(txnLogFile.toString() + ".fixed");
             if (recoveryLogFile.exists()) {
             if (recoveryLogFile.exists()) {
-                throw new TxnLogToolkitException(1, "Recovery file %s already exists or not writable", recoveryLogFile);
+                throw new TxnLogToolkitException(ExitCode.UNEXPECTED_ERROR.getValue(), "Recovery file %s already exists or not writable", recoveryLogFile);
             }
             }
         }
         }
 
 
@@ -135,7 +136,7 @@ public class TxnLogToolkit implements Closeable {
         FileHeader fhdr = new FileHeader();
         FileHeader fhdr = new FileHeader();
         fhdr.deserialize(logStream, "fileheader");
         fhdr.deserialize(logStream, "fileheader");
         if (fhdr.getMagic() != TXNLOG_MAGIC) {
         if (fhdr.getMagic() != TXNLOG_MAGIC) {
-            throw new TxnLogToolkitException(2, "Invalid magic number for %s", txnLogFile.getName());
+            throw new TxnLogToolkitException(ExitCode.INVALID_INVOCATION.getValue(), "Invalid magic number for %s", txnLogFile.getName());
         }
         }
         System.out.println("ZooKeeper Transactional Log File with dbid "
         System.out.println("ZooKeeper Transactional Log File with dbid "
                 + fhdr.getDbid() + " txnlog format version "
                 + fhdr.getDbid() + " txnlog format version "
@@ -187,7 +188,7 @@ public class TxnLogToolkit implements Closeable {
                 printTxn(bytes);
                 printTxn(bytes);
             }
             }
             if (logStream.readByte("EOR") != 'B') {
             if (logStream.readByte("EOR") != 'B') {
-                throw new TxnLogToolkitException(1, "Last transaction was partial.");
+                throw new TxnLogToolkitException(ExitCode.UNEXPECTED_ERROR.getValue(), "Last transaction was partial.");
             }
             }
             if (recoveryMode) {
             if (recoveryMode) {
                 filePadding.padFile(recoveryFos.getChannel());
                 filePadding.padFile(recoveryFos.getChannel());
@@ -209,7 +210,7 @@ public class TxnLogToolkit implements Closeable {
                 case 'N':
                 case 'N':
                     return false;
                     return false;
                 case 'A':
                 case 'A':
-                    throw new TxnLogToolkitException(0, "Recovery aborted.");
+                    throw new TxnLogToolkitException(ExitCode.EXECUTION_FINISHED.getValue(), "Recovery aborted.");
             }
             }
         }
         }
     }
     }
@@ -289,7 +290,7 @@ public class TxnLogToolkit implements Closeable {
             }
             }
             return new TxnLogToolkit(cli.hasOption("recover"), cli.hasOption("verbose"), cli.getArgs()[0], cli.hasOption("yes"));
             return new TxnLogToolkit(cli.hasOption("recover"), cli.hasOption("verbose"), cli.getArgs()[0], cli.hasOption("yes"));
         } catch (ParseException e) {
         } catch (ParseException e) {
-            throw new TxnLogToolkitParseException(options, 1, e.getMessage());
+            throw new TxnLogToolkitParseException(options, ExitCode.UNEXPECTED_ERROR.getValue(), e.getMessage());
         }
         }
     }
     }
 
 

+ 2 - 1
src/java/main/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java

@@ -25,6 +25,7 @@ import java.util.concurrent.LinkedBlockingQueue;
 import org.apache.jute.Record;
 import org.apache.jute.Record;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.server.ExitCode;
 import org.apache.zookeeper.server.FinalRequestProcessor;
 import org.apache.zookeeper.server.FinalRequestProcessor;
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.Request;
 import org.apache.zookeeper.server.RequestProcessor;
 import org.apache.zookeeper.server.RequestProcessor;
@@ -105,7 +106,7 @@ public class FollowerZooKeeperServer extends LearnerZooKeeperServer {
             LOG.error("Committing zxid 0x" + Long.toHexString(zxid)
             LOG.error("Committing zxid 0x" + Long.toHexString(zxid)
                     + " but next pending txn 0x"
                     + " but next pending txn 0x"
                     + Long.toHexString(firstElementZxid));
                     + Long.toHexString(firstElementZxid));
-            System.exit(12);
+            System.exit(ExitCode.UNMATCHED_TXN_COMMIT.getValue());
         }
         }
         Request request = pendingTxns.remove();
         Request request = pendingTxns.remove();
         commitProcessor.commit(request);
         commitProcessor.commit(request);

+ 3 - 4
src/java/main/org/apache/zookeeper/server/quorum/Learner.java

@@ -38,6 +38,7 @@ import org.apache.jute.BinaryOutputArchive;
 import org.apache.jute.InputArchive;
 import org.apache.jute.InputArchive;
 import org.apache.jute.OutputArchive;
 import org.apache.jute.OutputArchive;
 import org.apache.jute.Record;
 import org.apache.jute.Record;
+import org.apache.zookeeper.server.ExitCode;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.ZooDefs.OpCode;
 import org.apache.zookeeper.ZooDefs.OpCode;
@@ -50,8 +51,6 @@ import org.apache.zookeeper.server.util.SerializeUtils;
 import org.apache.zookeeper.server.util.ZxidUtils;
 import org.apache.zookeeper.server.util.ZxidUtils;
 import org.apache.zookeeper.txn.SetDataTxn;
 import org.apache.zookeeper.txn.SetDataTxn;
 import org.apache.zookeeper.txn.TxnHeader;
 import org.apache.zookeeper.txn.TxnHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
 /**
  * This class is the superclass of two of the three main actors in a ZK
  * This class is the superclass of two of the three main actors in a ZK
@@ -409,7 +408,7 @@ public class Learner {
                     // not able to truncate the log
                     // not able to truncate the log
                     LOG.error("Not able to truncate the log "
                     LOG.error("Not able to truncate the log "
                             + Long.toHexString(qp.getZxid()));
                             + Long.toHexString(qp.getZxid()));
-                    System.exit(13);
+                    System.exit(ExitCode.QUORUM_PACKET_ERROR.getValue());
                 }
                 }
                 zk.getZKDatabase().setlastProcessedZxid(qp.getZxid());
                 zk.getZKDatabase().setlastProcessedZxid(qp.getZxid());
 
 
@@ -417,7 +416,7 @@ public class Learner {
             else {
             else {
                 LOG.error("Got unexpected packet from leader: {}, exiting ... ",
                 LOG.error("Got unexpected packet from leader: {}, exiting ... ",
                           LearnerHandler.packetToString(qp));
                           LearnerHandler.packetToString(qp));
-                System.exit(13);
+                System.exit(ExitCode.QUORUM_PACKET_ERROR.getValue());
 
 
             }
             }
             zk.getZKDatabase().initConfigInZKDatabase(self.getQuorumVerifier());
             zk.getZKDatabase().initConfigInZKDatabase(self.getQuorumVerifier());

+ 2 - 1
src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java

@@ -47,6 +47,7 @@ import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicLong;
 
 
+import org.apache.zookeeper.server.ExitCode;
 import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException;
 import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException;
 import org.apache.zookeeper.server.util.ConfigUtils;
 import org.apache.zookeeper.server.util.ConfigUtils;
 import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.ZooKeeperThread;
@@ -921,7 +922,7 @@ public class QuorumCnxManager {
                     // After leaving listener thread, the host cannot join the
                     // After leaving listener thread, the host cannot join the
                     // quorum anymore, this is a severe error that we cannot
                     // quorum anymore, this is a severe error that we cannot
                     // recover from, so we need to exit
                     // recover from, so we need to exit
-                    System.exit(14);
+                    System.exit(ExitCode.UNABLE_TO_BIND_QUORUM_PORT.getValue());
                 }
                 }
             } else if (ss != null) {
             } else if (ss != null) {
                 // Clean up for shutdown.
                 // Clean up for shutdown.

+ 7 - 6
src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerMain.java

@@ -26,6 +26,7 @@ import org.apache.yetus.audience.InterfaceAudience;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.jmx.ManagedUtil;
 import org.apache.zookeeper.jmx.ManagedUtil;
+import org.apache.zookeeper.server.ExitCode;
 import org.apache.zookeeper.server.ServerCnxnFactory;
 import org.apache.zookeeper.server.ServerCnxnFactory;
 import org.apache.zookeeper.server.ZKDatabase;
 import org.apache.zookeeper.server.ZKDatabase;
 import org.apache.zookeeper.server.DatadirCleanupManager;
 import org.apache.zookeeper.server.DatadirCleanupManager;
@@ -84,25 +85,25 @@ public class QuorumPeerMain {
             LOG.error("Invalid arguments, exiting abnormally", e);
             LOG.error("Invalid arguments, exiting abnormally", e);
             LOG.info(USAGE);
             LOG.info(USAGE);
             System.err.println(USAGE);
             System.err.println(USAGE);
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         } catch (ConfigException e) {
         } catch (ConfigException e) {
             LOG.error("Invalid config, exiting abnormally", e);
             LOG.error("Invalid config, exiting abnormally", e);
             System.err.println("Invalid config, exiting abnormally");
             System.err.println("Invalid config, exiting abnormally");
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         } catch (DatadirException e) {
         } catch (DatadirException e) {
             LOG.error("Unable to access datadir, exiting abnormally", e);
             LOG.error("Unable to access datadir, exiting abnormally", e);
             System.err.println("Unable to access datadir, exiting abnormally");
             System.err.println("Unable to access datadir, exiting abnormally");
-            System.exit(3);
+            System.exit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue());
         } catch (AdminServerException e) {
         } catch (AdminServerException e) {
             LOG.error("Unable to start AdminServer, exiting abnormally", e);
             LOG.error("Unable to start AdminServer, exiting abnormally", e);
             System.err.println("Unable to start AdminServer, exiting abnormally");
             System.err.println("Unable to start AdminServer, exiting abnormally");
-            System.exit(4);
+            System.exit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue());
         } catch (Exception e) {
         } catch (Exception e) {
             LOG.error("Unexpected exception, exiting abnormally", e);
             LOG.error("Unexpected exception, exiting abnormally", e);
-            System.exit(1);
+            System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
         }
         }
         LOG.info("Exiting normally");
         LOG.info("Exiting normally");
-        System.exit(0);
+        System.exit(ExitCode.EXECUTION_FINISHED.getValue());
     }
     }
 
 
     protected void initializeAndRun(String[] args)
     protected void initializeAndRun(String[] args)

+ 7 - 5
src/java/main/org/apache/zookeeper/version/util/VerGen.java

@@ -18,6 +18,8 @@
 
 
 package org.apache.zookeeper.version.util;
 package org.apache.zookeeper.version.util;
 
 
+import org.apache.zookeeper.server.ExitCode;
+
 import java.io.File;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.IOException;
@@ -31,7 +33,7 @@ public class VerGen {
     static void printUsage() {
     static void printUsage() {
         System.out.print("Usage:\tjava  -cp <classpath> org.apache.zookeeper."
         System.out.print("Usage:\tjava  -cp <classpath> org.apache.zookeeper."
                 + "version.util.VerGen maj.min.micro[-qualifier] rev buildDate");
                 + "version.util.VerGen maj.min.micro[-qualifier] rev buildDate");
-        System.exit(1);
+        System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
     }
     }
 
 
     public static void generateFile(File outputDir, Version version, String rev, String buildDate)
     public static void generateFile(File outputDir, Version version, String rev, String buildDate)
@@ -43,12 +45,12 @@ public class VerGen {
             boolean ret = pkgdir.mkdirs();
             boolean ret = pkgdir.mkdirs();
             if (!ret) {
             if (!ret) {
                 System.out.println("Cannnot create directory: " + path);
                 System.out.println("Cannnot create directory: " + path);
-                System.exit(1);
+                System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
             }
             }
         } else if (!pkgdir.isDirectory()) {
         } else if (!pkgdir.isDirectory()) {
             // not a directory
             // not a directory
             System.out.println(path + " is not a directory.");
             System.out.println(path + " is not a directory.");
-            System.exit(1);
+            System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
         }
         }
 
 
         try (FileWriter w = new FileWriter(new File(pkgdir, TYPE_NAME + ".java"))) {
         try (FileWriter w = new FileWriter(new File(pkgdir, TYPE_NAME + ".java"))) {
@@ -92,7 +94,7 @@ public class VerGen {
         } catch (IOException e) {
         } catch (IOException e) {
             System.out.println("Unable to generate version.Info file: "
             System.out.println("Unable to generate version.Info file: "
                     + e.getMessage());
                     + e.getMessage());
-            System.exit(1);
+            System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
         }
         }
     }
     }
 
 
@@ -148,7 +150,7 @@ public class VerGen {
             if (version == null) {
             if (version == null) {
                 System.err.println(
                 System.err.println(
                         "Invalid version number format, must be \"x.y.z(-.*)?\"");
                         "Invalid version number format, must be \"x.y.z(-.*)?\"");
-                System.exit(1);
+                System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
             }
             }
             String rev = args[1];
             String rev = args[1];
             if (rev == null || rev.trim().isEmpty()) {
             if (rev == null || rev.trim().isEmpty()) {

+ 3 - 2
src/java/systest/org/apache/zookeeper/test/system/GenerateLoad.java

@@ -40,6 +40,7 @@ import java.util.Map;
 import java.util.Random;
 import java.util.Random;
 import java.util.Set;
 import java.util.Set;
 
 
+import org.apache.zookeeper.server.ExitCode;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.AsyncCallback.DataCallback;
 import org.apache.zookeeper.AsyncCallback.DataCallback;
@@ -684,7 +685,7 @@ public class GenerateLoad {
                 doUsage();
                 doUsage();
             } catch (IOException e) {
             } catch (IOException e) {
                 e.printStackTrace();
                 e.printStackTrace();
-                System.exit(2);
+                System.exit(ExitCode.INVALID_INVOCATION.getValue());
             }
             }
         } else {
         } else {
             doUsage();
             doUsage();
@@ -713,6 +714,6 @@ public class GenerateLoad {
     private static void doUsage() {
     private static void doUsage() {
         System.err.println("USAGE: " + GenerateLoad.class.getName()
         System.err.println("USAGE: " + GenerateLoad.class.getName()
                 + " [--leaderOnly] [--leaderServes] zookeeper_host:port containerPrefix #ofServers #ofClients requestSize");
                 + " [--leaderOnly] [--leaderServes] zookeeper_host:port containerPrefix #ofServers #ofClients requestSize");
-        System.exit(2);
+        System.exit(ExitCode.INVALID_INVOCATION.getValue());
     }
     }
 }
 }

+ 3 - 2
src/java/systest/org/apache/zookeeper/test/system/InstanceContainer.java

@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
+import org.apache.zookeeper.server.ExitCode;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.AsyncCallback;
 import org.apache.zookeeper.AsyncCallback;
@@ -205,7 +206,7 @@ public class InstanceContainer implements Watcher, AsyncCallback.ChildrenCallbac
     public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException, KeeperException {
     public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException, KeeperException {
         if (args.length != 3) {
         if (args.length != 3) {
             System.err.println("USAGE: " + InstanceContainer.class.getName() + " name zkHostPort znodePrefix");
             System.err.println("USAGE: " + InstanceContainer.class.getName() + " name zkHostPort znodePrefix");
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         }
         }
         new InstanceContainer(args[0], args[1], args[2]).run();
         new InstanceContainer(args[0], args[1], args[2]).run();
         while(true) {
         while(true) {
@@ -217,7 +218,7 @@ public class InstanceContainer implements Watcher, AsyncCallback.ChildrenCallbac
         if (KeeperState.Expired == event.getState()) {
         if (KeeperState.Expired == event.getState()) {
             // It's all over
             // It's all over
             LOG.error("Lost session");
             LOG.error("Lost session");
-            System.exit(4);
+            System.exit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue());
         }
         }
         if (event.getPath() != null && event.getPath().equals(assignmentsNode)) {
         if (event.getPath() != null && event.getPath().equals(assignmentsNode)) {
             // children have changed, so read in the new list
             // children have changed, so read in the new list

+ 2 - 1
src/java/test/org/apache/zookeeper/server/quorum/auth/MiniKdc.java

@@ -23,6 +23,7 @@ import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
 import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer;
 import org.apache.kerby.kerberos.kerb.server.SimpleKdcServer;
 import org.apache.kerby.util.IOUtil;
 import org.apache.kerby.util.IOUtil;
 import org.apache.kerby.util.NetworkUtil;
 import org.apache.kerby.util.NetworkUtil;
+import org.apache.zookeeper.server.ExitCode;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 
 
@@ -86,7 +87,7 @@ public class MiniKdc {
         if (args.length < 4) {
         if (args.length < 4) {
             System.out.println("Arguments: <WORKDIR> <MINIKDCPROPERTIES> " +
             System.out.println("Arguments: <WORKDIR> <MINIKDCPROPERTIES> " +
                     "<KEYTABFILE> [<PRINCIPALS>]+");
                     "<KEYTABFILE> [<PRINCIPALS>]+");
-            System.exit(1);
+            System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
         }
         }
         File workDir = new File(args[0]);
         File workDir = new File(args[0]);
         if (!workDir.exists()) {
         if (!workDir.exists()) {

+ 3 - 2
src/java/test/org/apache/zookeeper/test/IntegrityCheck.java

@@ -35,6 +35,7 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 
 
+import org.apache.zookeeper.server.ExitCode;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.CreateMode;
@@ -167,7 +168,7 @@ public class IntegrityCheck implements StatCallback, DataCallback {
             childrenCount=Integer.parseInt(args[2]);
             childrenCount=Integer.parseInt(args[2]);
         } catch (NumberFormatException e) {
         } catch (NumberFormatException e) {
             e.printStackTrace();
             e.printStackTrace();
-            System.exit(1);
+            System.exit(ExitCode.UNEXPECTED_ERROR.getValue());
         }
         }
 
 
         try{
         try{
@@ -187,7 +188,7 @@ public class IntegrityCheck implements StatCallback, DataCallback {
             }
             }
         } catch (Exception e) {
         } catch (Exception e) {
             e.printStackTrace();
             e.printStackTrace();
-            System.exit(2);
+            System.exit(ExitCode.INVALID_INVOCATION.getValue());
         }
         }
     }
     }
 
 

+ 3 - 2
src/java/test/org/apache/zookeeper/test/SledgeHammer.java

@@ -27,6 +27,7 @@ import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.ZooDefs.Ids;
 import org.apache.zookeeper.ZooDefs.Ids;
 import org.apache.zookeeper.data.Stat;
 import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.ExitCode;
 
 
 public class SledgeHammer extends Thread{
 public class SledgeHammer extends Thread{
     ZooKeeper zk;
     ZooKeeper zk;
@@ -100,11 +101,11 @@ public class SledgeHammer extends Thread{
         if (args.length != 3) {
         if (args.length != 3) {
             System.err
             System.err
                     .println("USAGE: SledgeHammer zookeeper_server reps reads_per_rep");
                     .println("USAGE: SledgeHammer zookeeper_server reps reads_per_rep");
-            System.exit(3);
+            System.exit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue());
         }
         }
         SledgeHammer h = new SledgeHammer(args[0], Integer.parseInt(args[1]),
         SledgeHammer h = new SledgeHammer(args[0], Integer.parseInt(args[1]),
                 Integer.parseInt(args[2]));
                 Integer.parseInt(args[2]));
         h.start();
         h.start();
-        System.exit(0);
+        System.exit(ExitCode.EXECUTION_FINISHED.getValue());
     }
     }
 }
 }

+ 40 - 0
zookeeper-docs/src/documentation/content/xdocs/zookeeperAdmin.xml

@@ -387,6 +387,10 @@ server.3=zoo3:2888:3888</programlisting>
           <para><xref linkend="sc_troubleshooting" /></para>
           <para><xref linkend="sc_troubleshooting" /></para>
         </listitem>
         </listitem>
 
 
+        <listitem>
+          <para><xref linkend="sc_exitcodes" /></para>
+        </listitem>
+
         <listitem>
         <listitem>
           <para><xref linkend="sc_configuration" /></para>
           <para><xref linkend="sc_configuration" /></para>
         </listitem>
         </listitem>
@@ -674,6 +678,42 @@ server.3=zoo3:2888:3888</programlisting>
 		</variablelist>
 		</variablelist>
     </section>
     </section>
 
 
+    <section id="sc_exitcodes">
+      <title>Exit Codes</title>
+      <para> ZooKeeper has several exit codes. From 3.6.0, these codes will be gathered in ExitCode (excluding contrib projects).
+      As the codes themselves were not changed to keep backward compatibility, some codes may overlap.
+      A good example is error code 1 and 2. They can both indicate invalid arguments passed to ZooKeeper or other
+      runtime errors.
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>1: Unexpected errors like IO Exceptions</para>
+        </listitem>
+        <listitem>
+          <para>2: Invalid arguments during invocations</para>
+        </listitem>
+        <listitem>
+          <para>3: Cannot access datadir when trying to replicate server</para>
+        </listitem>
+        <listitem>
+          <para>4: Unable to start admin server at ZooKeeper startup</para>
+        </listitem>
+        <listitem>
+          <para>10: Severe error during snapshot IO</para>
+        </listitem>
+        <listitem>
+          <para>12: zxid from COMMIT does not match the one from pendingTxns queue</para>
+        </listitem>
+        <listitem>
+          <para>13: Unexpected packet from leader, or unable to truncate log on Leader.TRUNC</para>
+        </listitem>
+        <listitem>
+          <para>14: After listener thread tried to bind to election port 3 times, it will exit -
+            leaving the server unable to join the quorum</para>
+        </listitem>
+      </itemizedlist>
+    </section>
+
     <section id="sc_configuration">
     <section id="sc_configuration">
       <title>Configuration Parameters</title>
       <title>Configuration Parameters</title>