You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by br...@apache.org on 2013/03/07 07:01:50 UTC

svn commit: r1453693 [1/5] - in /zookeeper/trunk: ./ src/ src/c/ src/c/include/ src/c/src/ src/c/tests/ src/java/main/org/apache/zookeeper/ src/java/main/org/apache/zookeeper/cli/ src/java/main/org/apache/zookeeper/common/ src/java/main/org/apache/zook...

Author: breed
Date: Thu Mar  7 06:01:49 2013
New Revision: 1453693

URL: http://svn.apache.org/r1453693
Log:
ZOOKEEPER-107. Allow dynamic changes to server cluster membership (Alex Shraer via breed)

Added:
    zookeeper/trunk/src/c/tests/TestReconfigServer.cc
    zookeeper/trunk/src/c/tests/ZooKeeperQuorumServer.cc
    zookeeper/trunk/src/c/tests/ZooKeeperQuorumServer.h
    zookeeper/trunk/src/java/main/org/apache/zookeeper/cli/GetConfigCommand.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/cli/ReconfigCommand.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/util/ConfigUtils.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/ReconfigRecoveryTest.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumMajorityTest.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ReconfigTest.java
Modified:
    zookeeper/trunk/.gitignore
    zookeeper/trunk/CHANGES.txt
    zookeeper/trunk/build.xml
    zookeeper/trunk/src/c/Makefile.am
    zookeeper/trunk/src/c/README
    zookeeper/trunk/src/c/include/proto.h
    zookeeper/trunk/src/c/include/zookeeper.h
    zookeeper/trunk/src/c/src/cli.c
    zookeeper/trunk/src/c/src/zookeeper.c
    zookeeper/trunk/src/java/main/org/apache/zookeeper/KeeperException.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooDefs.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeper.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/ZooKeeperMain.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/common/StringUtils.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/DataTree.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NIOServerCnxnFactory.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/NettyServerCnxnFactory.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/PrepRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/Request.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ServerCnxnFactory.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/TraceFormatter.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/ZKDatabase.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/CommitProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FastLeaderElection.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Follower.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/FollowerRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Learner.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/LearnerHandler.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/Observer.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ObserverRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumBean.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumCnxManager.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerMain.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumZooKeeperServer.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/ReadOnlyRequestProcessor.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/flexible/QuorumHierarchical.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/flexible/QuorumMaj.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/flexible/QuorumVerifier.java
    zookeeper/trunk/src/java/main/org/apache/zookeeper/server/util/SerializeUtils.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerTestBase.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/Zab1_0Test.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/CnxManagerTest.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumUtil.java
    zookeeper/trunk/src/zookeeper.jute

Modified: zookeeper/trunk/.gitignore
URL: http://svn.apache.org/viewvc/zookeeper/trunk/.gitignore?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/.gitignore (original)
+++ zookeeper/trunk/.gitignore Thu Mar  7 06:01:49 2013
@@ -4,6 +4,11 @@
 .revision/
 .settings/
 build/
+src/c/core.*
+src/c/TEST-*.txt
+src/c/*.la
+src/c/*.lo
+src/c/*.o
 src/c/generated/
 src/java/generated/
 src/java/lib/ant-eclipse-*

Modified: zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/trunk/CHANGES.txt?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/CHANGES.txt (original)
+++ zookeeper/trunk/CHANGES.txt Thu Mar  7 06:01:49 2013
@@ -10,6 +10,8 @@ NEW FEATURES:
   ZOOKEEPER-1355. Add zk.updateServerList(newServerList) (Alex Shraer, Marshall McMullen via fpj)
 
   ZOOKEEPER-1572. Add an async (Java) interface for multi request (Sijie Guo via camille)
+
+  ZOOKEEPER-107. Allow dynamic changes to server cluster membership (Alex Shraer via breed)
   
 BUGFIXES:
 

Modified: zookeeper/trunk/build.xml
URL: http://svn.apache.org/viewvc/zookeeper/trunk/build.xml?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/build.xml (original)
+++ zookeeper/trunk/build.xml Thu Mar  7 06:01:49 2013
@@ -1326,7 +1326,7 @@ xmlns:maven="antlib:org.apache.maven.art
                 <env key="CALLER" value="ANT"/>
                 <env key="CLOVER_HOME" value="${clover.home}"/>
                 <env key="base_dir" value="${basedir}"/>
-		<arg line="clean run-check"/>
+		<arg line="clean check"/>
 	</exec>
     </target>
    

Modified: zookeeper/trunk/src/c/Makefile.am
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/Makefile.am?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/src/c/Makefile.am (original)
+++ zookeeper/trunk/src/c/Makefile.am Thu Mar  7 06:01:49 2013
@@ -86,15 +86,19 @@ TEST_SOURCES = \
 	tests/TestZookeeperInit.cc \
 	tests/TestZookeeperClose.cc \
 	tests/TestReconfig.cc \
+	tests/TestReconfigServer.cc \
     tests/TestClientRetry.cc \
 	tests/TestOperations.cc \
 	tests/TestMulti.cc \
 	tests/TestClient.cc \
-	tests/TestWatchers.cc
+	tests/TestWatchers.cc \
+	tests/ZooKeeperQuorumServer.cc \
+	tests/ZooKeeperQuorumServer.h
 
 SYMBOL_WRAPPERS=$(shell cat ${srcdir}/tests/wrappers.opt)
 
 check_PROGRAMS = zktest-st
+TESTS_ENVIRONMENT = ZKROOT=${srcdir}/../..
 nodist_zktest_st_SOURCES = $(TEST_SOURCES)
 zktest_st_LDADD = libzkst.la libhashtable.la $(CPPUNIT_LIBS)
 zktest_st_CXXFLAGS = -DUSE_STATIC_LIB $(CPPUNIT_CFLAGS) $(USEIPV6)
@@ -109,11 +113,7 @@ if WANT_SYNCAPI
   zktest_mt_LDFLAGS = -static-libtool-libs $(SYMBOL_WRAPPERS_MT)
 endif
 
-run-check: check
-	./zktest-st $(TEST_OPTIONS)
-if WANT_SYNCAPI
-	./zktest-mt $(TEST_OPTIONS)
-endif
+TESTS = $(check_PROGRAMS)
 
 clean-local: clean-check
 	$(RM) $(DX_CLEANFILES)

Modified: zookeeper/trunk/src/c/README
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/README?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/src/c/README (original)
+++ zookeeper/trunk/src/c/README Thu Mar  7 06:01:49 2013
@@ -64,7 +64,7 @@ tar downloaded from Apache please skip t
    Alternatively, you can also build and run a unit test suite (and
    you probably should).  Please make sure you have cppunit-1.10.x or
    higher installed before you execute step 4.  Once ./configure has
-   finished, do a "make run-check". It will build the libraries, build
+   finished, do a "make check". It will build the libraries, build
    the tests and run them.
 6) to generate doxygen documentation do a "make doxygen-doc". All
    documentations will be placed to a new subfolder named docs. By

Modified: zookeeper/trunk/src/c/include/proto.h
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/include/proto.h?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/src/c/include/proto.h (original)
+++ zookeeper/trunk/src/c/include/proto.h Thu Mar  7 06:01:49 2013
@@ -37,6 +37,7 @@ extern "C" {
 #define ZOO_CHECK_OP 13
 #define ZOO_MULTI_OP 14
 #define ZOO_CREATE2_OP 15
+#define ZOO_RECONFIG_OP 16
 #define ZOO_CLOSE_OP -11
 #define ZOO_SETAUTH_OP 100
 #define ZOO_SETWATCHES_OP 101

Modified: zookeeper/trunk/src/c/include/zookeeper.h
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/c/include/zookeeper.h?rev=1453693&r1=1453692&r2=1453693&view=diff
==============================================================================
--- zookeeper/trunk/src/c/include/zookeeper.h (original)
+++ zookeeper/trunk/src/c/include/zookeeper.h Thu Mar  7 06:01:49 2013
@@ -35,26 +35,26 @@
 #include "zookeeper.jute.h"
 
 /**
- * \file zookeeper.h 
+ * \file zookeeper.h
  * \brief ZooKeeper functions and definitions.
- * 
+ *
  * ZooKeeper is a network service that may be backed by a cluster of
  * synchronized servers. The data in the service is represented as a tree
  * of data nodes. Each node has data, children, an ACL, and status information.
  * The data for a node is read and write in its entirety.
- * 
+ *
  * ZooKeeper clients can leave watches when they queries the data or children
  * of a node. If a watch is left, that client will be notified of the change.
  * The notification is a one time trigger. Subsequent chances to the node will
  * not trigger a notification unless the client issues a query with the watch
- * flag set. If the client is ever disconnected from the service, the watches do 
+ * flag set. If the client is ever disconnected from the service, the watches do
  * not need to be reset. The client automatically resets the watches.
- * 
+ *
  * When a node is created, it may be flagged as an ephemeral node. Ephemeral
  * nodes are automatically removed when a client session is closed or when
  * a session times out due to inactivity (the ZooKeeper runtime fills in
  * periods of inactivity with pings). Ephemeral nodes cannot have children.
- * 
+ *
  * ZooKeeper clients are identified by a server assigned session id. For
  * security reasons The server
  * also generates a corresponding password for a session. A client may save its
@@ -64,7 +64,7 @@
 
 /* Support for building on various platforms */
 
-// on cygwin we should take care of exporting/importing symbols properly 
+// on cygwin we should take care of exporting/importing symbols properly
 #ifdef DLL_EXPORT
 #    define ZOOAPI __declspec(dllexport)
 #else
@@ -97,7 +97,7 @@ enum ZOO_ERRORS {
   /** API errors.
    * This is never thrown by the server, it shouldn't be used other than
    * to indicate a range. Specifically error codes greater than this
-   * value are API errors (while values less than this indicate a 
+   * value are API errors (while values less than this indicate a
    * {@link #ZSYSTEMERROR}).
    */
   ZAPIERROR = -100,
@@ -113,7 +113,11 @@ enum ZOO_ERRORS {
   ZAUTHFAILED = -115, /*!< Client authentication failed */
   ZCLOSING = -116, /*!< ZooKeeper is closing */
   ZNOTHING = -117, /*!< (not error) no server responses to process */
-  ZSESSIONMOVED = -118 /*!<session moved to another server, so operation is ignored */ 
+  ZSESSIONMOVED = -118, /*!<session moved to another server, so operation is ignored */
+  ZNEWCONFIGNOQUORUM = -120,  /*!< No quorum of new config is connected and up-to-date with the leader of last commmitted config - try
+                                 invoking reconfiguration after new servers are connected and synced */
+  ZRECONFIGINPROGRESS = -121  /*!< Reconfiguration requested while another reconfiguration is currently in progress. This is currently
+                                       not supported. Please retry. */
 };
 
 #ifdef __cplusplus
@@ -135,6 +139,9 @@ extern ZOOAPI const int ZOO_PERM_DELETE;
 extern ZOOAPI const int ZOO_PERM_ADMIN;
 extern ZOOAPI const int ZOO_PERM_ALL;
 
+
+#define ZOO_CONFIG_NODE "/zookeeper/config"
+
 /** This Id represents anyone. */
 extern ZOOAPI struct Id ZOO_ANYONE_ID_UNSAFE;
 /** This Id is only usable to set ACLs. It will get substituted with the
@@ -154,7 +161,7 @@ extern ZOOAPI struct ACL_vector ZOO_CREA
  * These constants are used to express interest in an event and to
  * indicate to zookeeper which events have occurred. They can
  * be ORed together to express multiple interests. These flags are
- * used in the interest and event parameters of 
+ * used in the interest and event parameters of
  * \ref zookeeper_interest and \ref zookeeper_process.
  */
 // @{
@@ -164,7 +171,7 @@ extern ZOOAPI const int ZOOKEEPER_READ;
 
 /**
  * @name Create Flags
- * 
+ *
  * These flags are used by zoo_create to affect node create. They may
  * be ORed together to combine effects.
  */
@@ -195,42 +202,42 @@ extern ZOOAPI const int ZOO_NOTCONNECTED
 // @{
 /**
  * \brief a node has been created.
- * 
+ *
  * This is only generated by watches on non-existent nodes. These watches
  * are set using \ref zoo_exists.
  */
 extern ZOOAPI const int ZOO_CREATED_EVENT;
 /**
  * \brief a node has been deleted.
- * 
+ *
  * This is only generated by watches on nodes. These watches
  * are set using \ref zoo_exists and \ref zoo_get.
  */
 extern ZOOAPI const int ZOO_DELETED_EVENT;
 /**
  * \brief a node has changed.
- * 
+ *
  * This is only generated by watches on nodes. These watches
  * are set using \ref zoo_exists and \ref zoo_get.
  */
 extern ZOOAPI const int ZOO_CHANGED_EVENT;
 /**
  * \brief a change as occurred in the list of children.
- * 
+ *
  * This is only generated by watches on the child list of a node. These watches
  * are set using \ref zoo_get_children or \ref zoo_get_children2.
  */
 extern ZOOAPI const int ZOO_CHILD_EVENT;
 /**
  * \brief a session has been lost.
- * 
+ *
  * This is generated when a client loses contact or reconnects with a server.
  */
 extern ZOOAPI const int ZOO_SESSION_EVENT;
 
 /**
  * \brief a watch has been removed.
- * 
+ *
  * This is generated when the server for some reason, probably a resource
  * constraint, will no longer watch a node for a client.
  */
@@ -239,7 +246,7 @@ extern ZOOAPI const int ZOO_NOTWATCHING_
 
 /**
  * \brief ZooKeeper handle.
- * 
+ *
  * This is the handle that represents a connection to the ZooKeeper service.
  * It is needed to invoke any ZooKeeper function. A handle is obtained using
  * \ref zookeeper_init.
@@ -248,7 +255,7 @@ typedef struct _zhandle zhandle_t;
 
 /**
  * \brief client id structure.
- * 
+ *
  * This structure holds the id and password for the session. This structure
  * should be treated as opaque. It is received from the server when a session
  * is established and needs to be sent back as-is when reconnecting a session.
@@ -263,7 +270,7 @@ typedef struct {
  *
  * This structure holds all the arguments necessary for one op as part
  * of a containing multi_op via \ref zoo_multi or \ref zoo_amulti.
- * This structure should be treated as opaque and initialized via 
+ * This structure should be treated as opaque and initialized via
  * \ref zoo_create_op_init, \ref zoo_delete_op_init, \ref zoo_set_op_init
  * and \ref zoo_check_op_init.
  */
@@ -281,12 +288,12 @@ typedef struct zoo_op {
             int flags;
         } create_op;
 
-        // DELETE 
+        // DELETE
         struct {
             const char *path;
             int version;
         } delete_op;
-        
+
         // SET
         struct {
             const char *path;
@@ -295,7 +302,7 @@ typedef struct zoo_op {
             int version;
             struct Stat *stat;
         } set_op;
-        
+
         // CHECK
         struct {
             const char *path;
@@ -310,7 +317,7 @@ typedef struct zoo_op {
  * This function initializes a zoo_op_t with the arguments for a ZOO_CREATE_OP.
  *
  * \param op A pointer to the zoo_op_t to be initialized.
- * \param path The name of the node. Expressed as a file name with slashes 
+ * \param path The name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param value The data to be stored in the node.
  * \param valuelen The number of bytes in data. To set the data to be NULL use
@@ -329,7 +336,7 @@ typedef struct zoo_op {
  *    The path string will always be null-terminated.
  */
 void zoo_create_op_init(zoo_op_t *op, const char *path, const char *value,
-        int valuelen,  const struct ACL_vector *acl, int flags, 
+        int valuelen,  const struct ACL_vector *acl, int flags,
         char *path_buffer, int path_buffer_len);
 
 /**
@@ -338,11 +345,11 @@ void zoo_create_op_init(zoo_op_t *op, co
  * This function initializes a zoo_op_t with the arguments for a ZOO_DELETE_OP.
  *
  * \param op A pointer to the zoo_op_t to be initialized.
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param version the expected version of the node. The function will fail if the
  *    actual version of the node does not match the expected version.
- *  If -1 is used the version check will not take place. 
+ *  If -1 is used the version check will not take place.
  */
 void zoo_delete_op_init(zoo_op_t *op, const char *path, int version);
 
@@ -352,16 +359,16 @@ void zoo_delete_op_init(zoo_op_t *op, co
  * This function initializes an zoo_op_t with the arguments for a ZOO_SETDATA_OP.
  *
  * \param op A pointer to the zoo_op_t to be initialized.
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write. To set NULL as data 
+ * \param buflen the number of bytes from buffer to write. To set NULL as data
  * use buffer as NULL and buflen as -1.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. 
+ * \param version the expected version of the node. The function will fail if
+ * the actual version of the node does not match the expected version. If -1 is
+ * used the version check will not take place.
  */
-void zoo_set_op_init(zoo_op_t *op, const char *path, const char *buffer, 
+void zoo_set_op_init(zoo_op_t *op, const char *path, const char *buffer,
         int buflen, int version, struct Stat *stat);
 
 /**
@@ -370,7 +377,7 @@ void zoo_set_op_init(zoo_op_t *op, const
  * This function initializes an zoo_op_t with the arguments for a ZOO_CHECK_OP.
  *
  * \param op A pointer to the zoo_op_t to be initialized.
- * \param path The name of the node. Expressed as a file name with slashes 
+ * \param path The name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param version the expected version of the node. The function will fail if the
  *    actual version of the node does not match the expected version.
@@ -388,40 +395,40 @@ typedef struct zoo_op_result {
     char *value;
 	int valuelen;
     struct Stat *stat;
-} zoo_op_result_t; 
+} zoo_op_result_t;
 
 /**
  * \brief signature of a watch function.
- * 
+ *
  * There are two ways to receive watch notifications: legacy and watcher object.
  * <p>
- * The legacy style, an application wishing to receive events from ZooKeeper must 
- * first implement a function with this signature and pass a pointer to the function 
- * to \ref zookeeper_init. Next, the application sets a watch by calling one of 
- * the getter API that accept the watch integer flag (for example, \ref zoo_aexists, 
+ * The legacy style, an application wishing to receive events from ZooKeeper must
+ * first implement a function with this signature and pass a pointer to the function
+ * to \ref zookeeper_init. Next, the application sets a watch by calling one of
+ * the getter API that accept the watch integer flag (for example, \ref zoo_aexists,
  * \ref zoo_get, etc).
  * <p>
- * The watcher object style uses an instance of a "watcher object" which in 
+ * The watcher object style uses an instance of a "watcher object" which in
  * the C world is represented by a pair: a pointer to a function implementing this
- * signature and a pointer to watcher context -- handback user-specific data. 
- * When a watch is triggered this function will be called along with 
+ * signature and a pointer to watcher context -- handback user-specific data.
+ * When a watch is triggered this function will be called along with
  * the watcher context. An application wishing to use this style must use
  * the getter API functions with the "w" prefix in their names (for example, \ref
  * zoo_awexists, \ref zoo_wget, etc).
- * 
+ *
  * \param zh zookeeper handle
- * \param type event type. This is one of the *_EVENT constants. 
+ * \param type event type. This is one of the *_EVENT constants.
  * \param state connection state. The state value will be one of the *_STATE constants.
- * \param path znode path for which the watcher is triggered. NULL if the event 
+ * \param path znode path for which the watcher is triggered. NULL if the event
  * type is ZOO_SESSION_EVENT
  * \param watcherCtx watcher context.
  */
-typedef void (*watcher_fn)(zhandle_t *zh, int type, 
+typedef void (*watcher_fn)(zhandle_t *zh, int type,
         int state, const char *path,void *watcherCtx);
 
 /**
  * \brief create a handle to used communicate with zookeeper.
- * 
+ *
  * This method creates a new handle and a zookeeper session that corresponds
  * to that handle. Session establishment is asynchronous, meaning that the
  * session should not be considered established until (and unless) an
@@ -434,17 +441,17 @@ typedef void (*watcher_fn)(zhandle_t *zh
  *   client will be reconnecting to. Pass 0 if not reconnecting to a previous
  *   session. Clients can access the session id of an established, valid,
  *   connection by calling \ref zoo_client_id. If the session corresponding to
- *   the specified clientid has expired, or if the clientid is invalid for 
- *   any reason, the returned zhandle_t will be invalid -- the zhandle_t 
+ *   the specified clientid has expired, or if the clientid is invalid for
+ *   any reason, the returned zhandle_t will be invalid -- the zhandle_t
  *   state will indicate the reason for failure (typically
  *   ZOO_EXPIRED_SESSION_STATE).
- * \param context the handback object that will be associated with this instance 
- *   of zhandle_t. Application can access it (for example, in the watcher 
- *   callback) using \ref zoo_get_context. The object is not used by zookeeper 
+ * \param context the handback object that will be associated with this instance
+ *   of zhandle_t. Application can access it (for example, in the watcher
+ *   callback) using \ref zoo_get_context. The object is not used by zookeeper
  *   internally and can be null.
  * \param flags reserved for future use. Should be set to zero.
- * \return a pointer to the opaque zhandle structure. If it fails to create 
- * a new zhandle the function returns NULL and the errno variable 
+ * \return a pointer to the opaque zhandle structure. If it fails to create
+ * a new zhandle the function returns NULL and the errno variable
  * indicates the reason.
  */
 ZOOAPI zhandle_t *zookeeper_init(const char *host, watcher_fn fn,
@@ -452,27 +459,27 @@ ZOOAPI zhandle_t *zookeeper_init(const c
 
 /**
  * \brief update the list of servers this client will connect to.
- * 
+ *
  * This method allows a client to update the connection string by providing
  * a new comma separated list of host:port pairs, each corresponding to a
- * ZooKeeper server. 
- * 
+ * ZooKeeper server.
+ *
  * This function invokes a probabilistic load-balancing algorithm which may cause
- * the client to disconnect from its current host to achieve expected uniform 
+ * the client to disconnect from its current host to achieve expected uniform
  * connections per server in the new list. In case the current host to which the
  * client is connected is not in the new list this call will always cause the
- * connection to be dropped. Otherwise, the decision is based on whether the 
+ * connection to be dropped. Otherwise, the decision is based on whether the
  * number of servers has increased or decreased and by how much.
- * 
+ *
  * If the connection is dropped, the client moves to a special "reconfig" mode
  * where he chooses a new server to connect to using the probabilistic algorithm.
  * After finding a server or exhaustively trying all the servers in the new list,
  * the client moves back to the normal mode of operation where it will pick an
  * arbitrary server from the 'host' string.
- * 
- * See {@link https://issues.apache.org/jira/browse/ZOOKEEPER-1355} for the 
+ *
+ * See {@link https://issues.apache.org/jira/browse/ZOOKEEPER-1355} for the
  * protocol and its evaluation,
- * 
+ *
  * \param host comma separated host:port pairs, each corresponding to a zk
  *   server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
  * \return ZOK on success or one of the following errcodes on failure:
@@ -484,7 +491,7 @@ ZOOAPI int zoo_set_servers(zhandle_t *zh
 
 /**
  * \brief cycle to the next server on the next connection attempt.
- * 
+ *
  * Note: typically this method should NOT be used outside of testing.
  *
  * This method allows a client to cycle through the list of servers in it's
@@ -497,7 +504,7 @@ ZOOAPI void zoo_cycle_next_server(zhandl
 
 /**
  * \brief get current host:port this client is connecting/connected to.
- * 
+ *
  * Note: typically this method should NOT be used outside of testing.
  *
  * This method allows a client to get the current host:port that this client
@@ -509,9 +516,9 @@ ZOOAPI const char* zoo_get_current_serve
 
 /**
  * \brief close the zookeeper handle and free up any resources.
- * 
+ *
  * After this call, the client session will no longer be valid. The function
- * will flush any outstanding send requests before return. As a result it may 
+ * will flush any outstanding send requests before return. As a result it may
  * block.
  *
  * This method should only be called only once on a zookeeper handle. Calling
@@ -519,8 +526,8 @@ ZOOAPI const char* zoo_get_current_serve
  * zookeeper method after calling close is undefined behaviour and should be avoided.
  *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \return a result code. Regardless of the error code returned, the zhandle 
- * will be destroyed and all resources freed. 
+ * \return a result code. Regardless of the error code returned, the zhandle
+ * will be destroyed and all resources freed.
  *
  * ZOK - success
  * ZBADARGUMENTS - invalid input parameters
@@ -571,7 +578,7 @@ ZOOAPI struct sockaddr* zookeeper_get_co
 #ifndef THREADED
 /**
  * \brief Returns the events that zookeeper is interested in.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
  * \param fd is the file descriptor of interest
  * \param interest is an or of the ZOOKEEPER_WRITE and ZOOKEEPER_READ flags to
@@ -581,7 +588,7 @@ ZOOAPI struct sockaddr* zookeeper_get_co
  * ZOK - success
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZCONNECTIONLOSS - a network error occured while attempting to establish 
+ * ZCONNECTIONLOSS - a network error occured while attempting to establish
  * a connection to the server
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  * ZOPERATIONTIMEOUT - hasn't received anything from the server for 2/3 of the
@@ -589,19 +596,19 @@ ZOOAPI struct sockaddr* zookeeper_get_co
  * ZSYSTEMERROR -- a system (OS) error occured; it's worth checking errno to get details
  */
 #ifdef WIN32
-ZOOAPI int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest, 
+ZOOAPI int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
 	struct timeval *tv);
 #else
-ZOOAPI int zookeeper_interest(zhandle_t *zh, int *fd, int *interest, 
+ZOOAPI int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
 	struct timeval *tv);
 #endif
 
 /**
  * \brief Notifies zookeeper that an event of interest has happened.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
  * \param events will be an OR of the ZOOKEEPER_WRITE and ZOOKEEPER_READ flags.
- * \return a result code. 
+ * \return a result code.
  * ZOK - success
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
@@ -610,7 +617,7 @@ ZOOAPI int zookeeper_interest(zhandle_t 
  * ZAUTHFAILED - authentication request failed, e.i. invalid credentials
  * ZRUNTIMEINCONSISTENCY - a server response came out of order
  * ZSYSTEMERROR -- a system (OS) error occured; it's worth checking errno to get details
- * ZNOTHING -- not an error; simply indicates that there no more data from the server 
+ * ZNOTHING -- not an error; simply indicates that there no more data from the server
  *              to be processed (when called with ZOOKEEPER_READ flag).
  */
 ZOOAPI int zookeeper_process(zhandle_t *zh, int events);
@@ -618,14 +625,14 @@ ZOOAPI int zookeeper_process(zhandle_t *
 
 /**
  * \brief signature of a completion function for a call that returns void.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
  * \param data the pointer that was passed by the caller when the function
@@ -637,14 +644,14 @@ typedef void (*void_completion_t)(int rc
 
 /**
  * \brief signature of a completion function that returns a Stat structure.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
  * \param stat a pointer to the stat information for the node involved in
@@ -660,14 +667,14 @@ typedef void (*stat_completion_t)(int rc
 
 /**
  * \brief signature of a completion function that returns data.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
  * \param value the value of the information returned by the asynchronous call.
@@ -687,14 +694,14 @@ typedef void (*data_completion_t)(int rc
 
 /**
  * \brief signature of a completion function that returns a list of strings.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
  * \param strings a pointer to the structure containng the list of strings of the
@@ -737,14 +744,14 @@ typedef void (*string_stat_completion_t)
 /**
  * \brief signature of a completion function that returns a list of strings and stat.
  * .
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
  * \param strings a pointer to the structure containng the list of strings of the
@@ -765,14 +772,14 @@ typedef void (*strings_stat_completion_t
 
 /**
  * \brief signature of a completion function that returns a list of strings.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
  * \param value the value of the string returned.
@@ -786,17 +793,17 @@ typedef void
 
 /**
  * \brief signature of a completion function that returns an ACL.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
+ *
+ * This method will be invoked at the end of a asynchronous call and also as
  * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
+ * \param rc the error code of the call. Connection loss/timeout triggers
  * the completion with one of the following error codes:
  * ZCONNECTIONLOSS -- lost connection to the server
  * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
+ * Data related events trigger the completion with error codes listed the
  * Exceptions section of the documentation of the function that initiated the
  * call. (Zero indicates call was successful.)
- * \param acl a pointer to the structure containng the ACL of a node. If a non 
+ * \param acl a pointer to the structure containng the ACL of a node. If a non
  *   zero error code is returned, the content of strings is undefined. The
  *   programmer is NOT responsible for freeing acl.
  * \param stat a pointer to the stat information for the node involved in
@@ -812,23 +819,23 @@ typedef void (*acl_completion_t)(int rc,
 
 /**
  * \brief get the state of the zookeeper connection.
- * 
+ *
  * The return value will be one of the \ref State Consts.
  */
 ZOOAPI int zoo_state(zhandle_t *zh);
 
 /**
  * \brief create a node.
- * 
+ *
  * This method will create a node in ZooKeeper. A node can only be created if
  * it does not already exists. The Create Flags affect the creation of nodes.
  * If ZOO_EPHEMERAL flag is set, the node will automatically get removed if the
  * client session goes away. If the ZOO_SEQUENCE flag is set, a unique
  * monotonically increasing sequence number is appended to the path name. The
  * sequence number is always fixed length of 10 digits, 0 padded.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path The name of the node. Expressed as a file name with slashes 
+ * \param path The name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param value The data to be stored in the node.
  * \param valuelen The number of bytes in data.
@@ -905,53 +912,53 @@ ZOOAPI int zoo_acreate2(zhandle_t *zh, c
  * ZNOAUTH the client does not have permission.
  * ZBADVERSION expected version does not match actual version.
  * ZNOTEMPTY children are present; node cannot be deleted.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_adelete(zhandle_t *zh, const char *path, int version, 
+ZOOAPI int zoo_adelete(zhandle_t *zh, const char *path, int version,
         void_completion_t completion, const void *data);
 
 /**
  * \brief checks the existence of a node in zookeeper.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify the 
- * client if the node changes. The watch will be set even if the node does not 
+ * \param watch if nonzero, a watch will be set at the server to notify the
+ * client if the node changes. The watch will be set even if the node does not
  * exist. This allows clients to watch for nodes to appear.
  * \param completion the routine to invoke when the request completes. The completion
  * will be triggered with one of the following codes passed in as the rc argument:
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when the 
+ * \param data the data that will be passed to the completion routine when the
  * function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aexists(zhandle_t *zh, const char *path, int watch, 
+ZOOAPI int zoo_aexists(zhandle_t *zh, const char *path, int watch,
         stat_completion_t completion, const void *data);
 
 /**
  * \brief checks the existence of a node in zookeeper.
- * 
- * This function is similar to \ref zoo_axists except it allows one specify 
+ *
+ * This function is similar to \ref zoo_axists except it allows one specify
  * a watcher object - a function pointer and associated context. The function
- * will be called once the watch has fired. The associated context data will be 
- * passed to the function as the watcher context parameter. 
- * 
+ * will be called once the watch has fired. The associated context data will be
+ * passed to the function as the watcher context parameter.
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param watcher if non-null a watch will set on the specified znode on the server.
- * The watch will be set even if the node does not exist. This allows clients 
+ * The watch will be set even if the node does not exist. This allows clients
  * to watch for nodes to appear.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -961,50 +968,50 @@ ZOOAPI int zoo_aexists(zhandle_t *zh, co
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when the 
+ * \param data the data that will be passed to the completion routine when the
  * function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_awexists(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx, 
+ZOOAPI int zoo_awexists(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx,
         stat_completion_t completion, const void *data);
 
 /**
  * \brief gets the data associated with a node.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
+ * \param watch if nonzero, a watch will be set at the server to notify
  * the client if the node changes.
  * \param completion the routine to invoke when the request completes. The completion
  * will be triggered with one of the following codes passed in as the rc argument:
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aget(zhandle_t *zh, const char *path, int watch, 
+ZOOAPI int zoo_aget(zhandle_t *zh, const char *path, int watch,
         data_completion_t completion, const void *data);
 
 /**
  * \brief gets the data associated with a node.
- * 
- * This function is similar to \ref zoo_aget except it allows one specify 
- * a watcher object rather than a boolean watch flag. 
+ *
+ * This function is similar to \ref zoo_aget except it allows one specify
+ * a watcher object rather than a boolean watch flag.
  *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
+ * \param watcher if non-null, a watch will be set at the server to notify
  * the client if the node changes.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1014,29 +1021,115 @@ ZOOAPI int zoo_aget(zhandle_t *zh, const
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_awget(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx,
+        data_completion_t completion, const void *data);
+
+/**
+ * \brief gets the last committed configuration of the ZooKeeper cluster as it is known to
+ * the server to which the client is connected.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param watch if nonzero, a watch will be set at the server to notify
+ * the client if the configuration changes.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the configuration node (/zookeeper/config) does not exist.
+ * ZNOAUTH the client does not have permission to access the configuration node.
+ * \param data the configuration data that will be passed to the completion routine when
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_agetconfig(zhandle_t *zh, int watch,
+        data_completion_t completion, const void *data);
+
+/**
+ * \brief gets the last committed configuration of the ZooKeeper cluster as it is known to
+ * the server to which the client is connected.
+ *
+ * This function is similar to \ref zoo_agetconfig except it allows one specify
+ * a watcher object rather than a boolean watch flag.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param watcher if non-null, a watch will be set at the server to notify
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the configuration node (/zookeeper/config) does not exist.
+ * ZNOAUTH the client does not have permission to access the configuration node.
+ * \param data the configuration data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_awget(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx, 
+ZOOAPI int zoo_awgetconfig(zhandle_t *zh, watcher_fn watcher, void* watcherCtx,
         data_completion_t completion, const void *data);
 
 /**
+ * \brief asynchronous reconfiguration interface - allows changing ZK cluster
+ * ensemble membership and roles of ensemble peers.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param joining - comma separated list of servers to be added to the ensemble.
+ * Each has a configuration line for a server to be added (as would appear in a
+ * configuration file), only for maj. quorums.  NULL for non-incremental reconfiguration.
+ * \param leaving - comma separated list of server IDs to be removed from the ensemble.
+ * Each has an id of a server to be removed, only for maj. quorums.  NULL for
+ * non-incremental reconfiguration.
+ * \param members - comma separated list of new membership (e.g., contents of a
+ * membership configuration file) - for use only with a non-incremental
+ * reconfiguration. NULL for incremental reconfiguration.
+ * \param version - version of config from which we want to reconfigure - if
+ * current config is different reconfiguration will fail. Should be -1 to disable
+ * this option.
+ * \param completion - the routine to invoke when the request completes. The
+ * completion will be triggered with one of the following codes passed in as the
+ * rc argument:
+ * ZOK operation completed successfully
+ * \param data the configuration data that will be passed to the completion routine
+ * when the function completes.
+ * \return return value of the function call.
+ * ZOK operation completed successfully
+ * ZBADARGUMENTS - invalid input parameters (one case when this is returned is
+ * when the new config has less than 2 servers)
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ * ZNEWCONFIGNOQUORUM - no quorum of new config is connected and up-to-date with
+ * the leader of last committed config - try invoking reconfiguration after new servers are connected and synced
+ * ZRECONFIGINPROGRESS - another reconfig is currently in progress
+ */
+ZOOAPI int zoo_areconfig(zhandle_t *zh, const char *joining, const char *leaving,
+       const char *members, int64_t version, data_completion_t dc, const void *data);
+
+/**
  * \brief sets the data associated with a node.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param buffer the buffer holding data to be written to the node.
  * \param buflen the number of bytes from buffer to write.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. * completion: If null, 
- * the function will execute synchronously. Otherwise, the function will return 
+ * \param version the expected version of the node. The function will fail if
+ * the actual version of the node does not match the expected version. If -1 is
+ * used the version check will not take place. * completion: If null,
+ * the function will execute synchronously. Otherwise, the function will return
  * immediately and invoke the completion routine when the request completes.
  * \param completion the routine to invoke when the request completes. The completion
  * will be triggered with one of the following codes passed in as the rc argument:
@@ -1044,49 +1137,49 @@ ZOOAPI int zoo_awget(zhandle_t *zh, cons
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
  * ZBADVERSION expected version does not match actual version.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aset(zhandle_t *zh, const char *path, const char *buffer, int buflen, 
+ZOOAPI int zoo_aset(zhandle_t *zh, const char *path, const char *buffer, int buflen,
         int version, stat_completion_t completion, const void *data);
 
 /**
  * \brief lists the children of a node.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
+ * \param watch if nonzero, a watch will be set at the server to notify
  * the client if the node changes.
  * \param completion the routine to invoke when the request completes. The completion
  * will be triggered with one of the following codes passed in as the rc argument:
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aget_children(zhandle_t *zh, const char *path, int watch, 
+ZOOAPI int zoo_aget_children(zhandle_t *zh, const char *path, int watch,
         strings_completion_t completion, const void *data);
 
 /**
  * \brief lists the children of a node.
- * 
- * This function is similar to \ref zoo_aget_children except it allows one specify 
+ *
+ * This function is similar to \ref zoo_aget_children except it allows one specify
  * a watcher object rather than a boolean watch flag.
- *  
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
+ * \param watcher if non-null, a watch will be set at the server to notify
  * the client if the node changes.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1096,7 +1189,7 @@ ZOOAPI int zoo_aget_children(zhandle_t *
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
@@ -1104,46 +1197,46 @@ ZOOAPI int zoo_aget_children(zhandle_t *
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
 ZOOAPI int zoo_awget_children(zhandle_t *zh, const char *path,
-        watcher_fn watcher, void* watcherCtx, 
+        watcher_fn watcher, void* watcherCtx,
         strings_completion_t completion, const void *data);
 
 /**
  * \brief lists the children of a node, and get the parent stat.
- * 
+ *
  * This function is new in version 3.3.0
  *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
+ * \param watch if nonzero, a watch will be set at the server to notify
  * the client if the node changes.
  * \param completion the routine to invoke when the request completes. The completion
  * will be triggered with one of the following codes passed in as the rc argument:
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aget_children2(zhandle_t *zh, const char *path, int watch, 
+ZOOAPI int zoo_aget_children2(zhandle_t *zh, const char *path, int watch,
         strings_stat_completion_t completion, const void *data);
 
 /**
  * \brief lists the children of a node, and get the parent stat.
- * 
- * This function is similar to \ref zoo_aget_children2 except it allows one specify 
+ *
+ * This function is similar to \ref zoo_aget_children2 except it allows one specify
  * a watcher object rather than a boolean watch flag.
- *  
+ *
  * This function is new in version 3.3.0
  *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
+ * \param watcher if non-null, a watch will be set at the server to notify
  * the client if the node changes.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1153,7 +1246,7 @@ ZOOAPI int zoo_aget_children2(zhandle_t 
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
@@ -1161,7 +1254,7 @@ ZOOAPI int zoo_aget_children2(zhandle_t 
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
 ZOOAPI int zoo_awget_children2(zhandle_t *zh, const char *path,
-        watcher_fn watcher, void* watcherCtx, 
+        watcher_fn watcher, void* watcherCtx,
         strings_stat_completion_t completion, const void *data);
 
 /**
@@ -1183,36 +1276,36 @@ ZOOAPI int zoo_awget_children2(zhandle_t
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
 
-ZOOAPI int zoo_async(zhandle_t *zh, const char *path, 
+ZOOAPI int zoo_async(zhandle_t *zh, const char *path,
         string_completion_t completion, const void *data);
 
 
 /**
  * \brief gets the acl associated with a node.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param completion the routine to invoke when the request completes. The completion
  * will be triggered with one of the following codes passed in as the rc argument:
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
  * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aget_acl(zhandle_t *zh, const char *path, acl_completion_t completion, 
+ZOOAPI int zoo_aget_acl(zhandle_t *zh, const char *path, acl_completion_t completion,
         const void *data);
 
 /**
  * \brief sets the acl associated with a node.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param buffer the buffer holding the acls to be written to the node.
  * \param buflen the number of bytes from buffer to write.
@@ -1223,14 +1316,14 @@ ZOOAPI int zoo_aget_acl(zhandle_t *zh, c
  * ZNOAUTH the client does not have permission.
  * ZINVALIDACL invalid ACL specified
  * ZBADVERSION expected version does not match actual version.
- * \param data the data that will be passed to the completion routine when 
+ * \param data the data that will be passed to the completion routine when
  * the function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_aset_acl(zhandle_t *zh, const char *path, int version, 
+ZOOAPI int zoo_aset_acl(zhandle_t *zh, const char *path, int version,
         struct ACL_vector *acl, void_completion_t, const void *data);
 
 /**
@@ -1241,7 +1334,7 @@ ZOOAPI int zoo_aset_acl(zhandle_t *zh, c
  * \param ops an array of operations to commit
  * \param results an array to hold the results of the operations
  * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with any of the error codes that can that can be returned by the 
+ * will be triggered with any of the error codes that can that can be returned by the
  * ops supported by a multi op (see \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
  * \param data the data that will be passed to the completion routine when
  * the function completes.
@@ -1249,12 +1342,12 @@ ZOOAPI int zoo_aset_acl(zhandle_t *zh, c
  * values that can be returned by the ops supported by a multi op (see
  * \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
  */
-ZOOAPI int zoo_amulti(zhandle_t *zh, int count, const zoo_op_t *ops, 
+ZOOAPI int zoo_amulti(zhandle_t *zh, int count, const zoo_op_t *ops,
         zoo_op_result_t *results, void_completion_t, const void *data);
 
 /**
  * \brief return an error string.
- * 
+ *
  * \param return code
  * \return string corresponding to the return code
  */
@@ -1262,24 +1355,24 @@ ZOOAPI const char* zerror(int c);
 
 /**
  * \brief specify application credentials.
- * 
+ *
  * The application calls this function to specify its credentials for purposes
- * of authentication. The server will use the security provider specified by 
- * the scheme parameter to authenticate the client connection. If the 
+ * of authentication. The server will use the security provider specified by
+ * the scheme parameter to authenticate the client connection. If the
  * authentication request has failed:
  * - the server connection is dropped
- * - the watcher is called with the ZOO_AUTH_FAILED_STATE value as the state 
+ * - the watcher is called with the ZOO_AUTH_FAILED_STATE value as the state
  * parameter.
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
  * \param scheme the id of authentication scheme. Natively supported:
  * "digest" password-based authentication
  * \param cert application credentials. The actual value depends on the scheme.
  * \param certLen the length of the data parameter
- * \param completion the routine to invoke when the request completes. One of 
+ * \param completion the routine to invoke when the request completes. One of
  * the following result codes may be passed into the completion callback:
  * ZOK operation completed successfully
- * ZAUTHFAILED authentication failed 
- * \param data the data that will be passed to the completion routine when the 
+ * ZAUTHFAILED authentication failed
+ * \param data the data that will be passed to the completion routine when the
  * function completes.
  * \return ZOK on success or one of the following errcodes on failure:
  * ZBADARGUMENTS - invalid input parameters
@@ -1287,57 +1380,57 @@ ZOOAPI const char* zerror(int c);
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  * ZSYSTEMERROR - a system error occured
  */
-ZOOAPI int zoo_add_auth(zhandle_t *zh,const char* scheme,const char* cert, 
+ZOOAPI int zoo_add_auth(zhandle_t *zh,const char* scheme,const char* cert,
 	int certLen, void_completion_t completion, const void *data);
 
 /**
  * \brief checks if the current zookeeper connection state can't be recovered.
- * 
+ *
  *  The application must close the zhandle and try to reconnect.
- * 
+ *
  * \param zh the zookeeper handle (see \ref zookeeper_init)
  * \return ZINVALIDSTATE if connection is unrecoverable
  */
 ZOOAPI int is_unrecoverable(zhandle_t *zh);
 
 /**
- * \brief sets the debugging level for the library 
+ * \brief sets the debugging level for the library
  */
 ZOOAPI void zoo_set_debug_level(ZooLogLevel logLevel);
 
 /**
- * \brief sets the stream to be used by the library for logging 
- * 
+ * \brief sets the stream to be used by the library for logging
+ *
  * The zookeeper library uses stderr as its default log stream. Application
- * must make sure the stream is writable. Passing in NULL resets the stream 
+ * must make sure the stream is writable. Passing in NULL resets the stream
  * to its default value (stderr).
  */
 ZOOAPI void zoo_set_log_stream(FILE* logStream);
 
 /**
  * \brief enable/disable quorum endpoint order randomization
- * 
+ *
  * Note: typically this method should NOT be used outside of testing.
  *
  * If passed a non-zero value, will make the client connect to quorum peers
  * in the order as specified in the zookeeper_init() call.
  * A zero value causes zookeeper_init() to permute the peer endpoints
- * which is good for more even client connection distribution among the 
+ * which is good for more even client connection distribution among the
  * quorum peers.
  */
 ZOOAPI void zoo_deterministic_conn_order(int yesOrNo);
 
 /**
  * \brief create a node synchronously.
- * 
+ *
  * This method will create a node in ZooKeeper. A node can only be created if
  * it does not already exists. The Create Flags affect the creation of nodes.
  * If ZOO_EPHEMERAL flag is set, the node will automatically get removed if the
  * client session goes away. If the ZOO_SEQUENCE flag is set, a unique
  * monotonically increasing sequence number is appended to the path name.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path The name of the node. Expressed as a file name with slashes 
+ * \param path The name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param value The data to be stored in the node.
  * \param valuelen The number of bytes in data. To set the data to be NULL use
@@ -1412,13 +1505,13 @@ ZOOAPI int zoo_create2(zhandle_t *zh, co
 
 /**
  * \brief delete a node in zookeeper synchronously.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param version the expected version of the node. The function will fail if the
  *    actual version of the node does not match the expected version.
- *  If -1 is used the version check will not take place. 
+ *  If -1 is used the version check will not take place.
  * \return one of the following values is returned.
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
@@ -1434,12 +1527,12 @@ ZOOAPI int zoo_delete(zhandle_t *zh, con
 
 /**
  * \brief checks the existence of a node in zookeeper synchronously.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify the 
- * client if the node changes. The watch will be set even if the node does not 
+ * \param watch if nonzero, a watch will be set at the server to notify the
+ * client if the node changes. The watch will be set even if the node does not
  * exist. This allows clients to watch for nodes to appear.
  * \param the return stat value of the node.
  * \return  return code of the function call.
@@ -1454,15 +1547,15 @@ ZOOAPI int zoo_exists(zhandle_t *zh, con
 
 /**
  * \brief checks the existence of a node in zookeeper synchronously.
- * 
- * This function is similar to \ref zoo_exists except it allows one specify 
+ *
+ * This function is similar to \ref zoo_exists except it allows one specify
  * a watcher object rather than a boolean watch flag.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param watcher if non-null a watch will set on the specified znode on the server.
- * The watch will be set even if the node does not exist. This allows clients 
+ * The watch will be set even if the node does not exist. This allows clients
  * to watch for nodes to appear.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1481,11 +1574,11 @@ ZOOAPI int zoo_wexists(zhandle_t *zh, co
 
 /**
  * \brief gets the data associated with a node synchronously.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
+ * \param watch if nonzero, a watch will be set at the server to notify
  * the client if the node changes.
  * \param buffer the buffer holding the node data returned by the server
  * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
@@ -1499,19 +1592,18 @@ ZOOAPI int zoo_wexists(zhandle_t *zh, co
  * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer,   
+ZOOAPI int zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer,
                    int* buffer_len, struct Stat *stat);
-
 /**
  * \brief gets the data associated with a node synchronously.
- * 
- * This function is similar to \ref zoo_get except it allows one specify 
+ *
+ * This function is similar to \ref zoo_get except it allows one specify
  * a watcher object rather than a boolean watch flag.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
+ * \param watcher if non-null, a watch will be set at the server to notify
  * the client if the node changes.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1528,23 +1620,111 @@ ZOOAPI int zoo_get(zhandle_t *zh, const 
  * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_wget(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx, 
+ZOOAPI int zoo_wget(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx,
+        char *buffer, int* buffer_len, struct Stat *stat);
+
+/**
+ * \brief gets the last committed configuration of the ZooKeeper cluster as it is known to
+ * the server to which the client is connected, synchronously.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param watch if nonzero, a watch will be set at the server to notify
+ * the client if the node changes.
+ * \param buffer the buffer holding the configuration data returned by the server
+ * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
+ * It'll be set to the actual data length upon return. If the data is NULL, length is -1.
+ * \param stat if not NULL, will hold the value of stat for the path on return.
+ * \return return value of the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the configuration node (/zookeeper/config) does not exist.
+ * ZNOAUTH the client does not have permission to access the configuration node.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_getconfig(zhandle_t *zh, int watch, char *buffer,
+                         int* buffer_len, struct Stat *stat);
+
+/**
+ * \brief gets the last committed configuration of the ZooKeeper cluster as it is known to
+ * the server to which the client is connected, synchronously.
+ *
+ * This function is similar to \ref zoo_getconfig except it allows one specify
+ * a watcher object rather than a boolean watch flag.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param watcher if non-null, a watch will be set at the server to notify
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param buffer the buffer holding the configuration data returned by the server
+ * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
+ * It'll be set to the actual data length upon return. If the data is NULL, length is -1.
+ * \param stat if not NULL, will hold the value of stat for the path on return.
+ * \return return value of the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the configuration node (/zookeeper/config) does not exist.
+ * ZNOAUTH the client does not have permission to access the configuration node.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_wgetconfig(zhandle_t *zh, watcher_fn watcher, void* watcherCtx,
         char *buffer, int* buffer_len, struct Stat *stat);
 
 /**
+ * \brief synchronous reconfiguration interface - allows changing ZK cluster
+ * ensemble membership and roles of ensemble peers.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param joining - comma separated list of servers to be added to the ensemble.
+ * Each has a configuration line for a server to be added (as would appear in a
+ * configuration file), only for maj. quorums.  NULL for non-incremental reconfiguration.
+ * \param leaving - comma separated list of server IDs to be removed from the ensemble.
+ * Each has an id of a server to be removed, only for maj. quorums.  NULL for
+ * non-incremental reconfiguration.
+ * \param members - comma separated list of new membership (e.g., contents of a
+ *  membership configuration file) - for use only with a non-incremental
+ * reconfiguration. NULL for incremental reconfiguration.
+ * \param version - zxid of config from which we want to reconfigure - if
+ * current config is different reconfiguration will fail. Should be -1 to
+ * disable this option.
+ * \param buffer the buffer holding the configuration data returned by the server
+ * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
+ * It'll be set to the actual data length upon return. If the data is NULL, length
+ * is -1.
+ * \param stat if not NULL, will hold the value of stat for the path on return.
+ * \return return value of the function call.
+ * ZOK operation completed successfully
+ * ZBADARGUMENTS - invalid input parameters (one case when this is returned is
+ * when the new config has less than 2 servers)
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or
+ * ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ * ZNEWCONFIGNOQUORUM - no quorum of new config is connected and up-to-date with
+ * the leader of last committed config - try invoking reconfiguration after new
+ * servers are connected and synced
+ * ZRECONFIGINPROGRESS - another reconfig is currently in progress
+ */
+ZOOAPI int zoo_reconfig(zhandle_t *zh, const char *joining, const char *leaving,
+       const char *members, int64_t version, char *buffer, int* buffer_len,
+       struct Stat *stat);
+
+/**
  * \brief sets the data associated with a node. See zoo_set2 function if
  * you require access to the stat information associated with the znode.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write. To set NULL as data 
+ * \param buflen the number of bytes from buffer to write. To set NULL as data
  * use buffer as NULL and buflen as -1.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. 
+ * \param version the expected version of the node. The function will fail if
+ * the actual version of the node does not match the expected version. If -1 is
+ * used the version check will not take place.
  * \return the return code for the function call.
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
@@ -1561,16 +1741,16 @@ ZOOAPI int zoo_set(zhandle_t *zh, const 
  * \brief sets the data associated with a node. This function is the same
  * as zoo_set except that it also provides access to stat information
  * associated with the znode.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param buffer the buffer holding data to be written to the node.
  * \param buflen the number of bytes from buffer to write. To set NULL as data
  * use buffer as NULL and buflen as -1.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. 
+ * \param version the expected version of the node. The function will fail if
+ * the actual version of the node does not match the expected version. If -1 is
+ * used the version check will not take place.
  * \param stat if not NULL, will hold the value of stat for the path on return.
  * \return the return code for the function call.
  * ZOK operation completed successfully
@@ -1586,11 +1766,11 @@ ZOOAPI int zoo_set2(zhandle_t *zh, const
 
 /**
  * \brief lists the children of a node synchronously.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
+ * \param watch if nonzero, a watch will be set at the server to notify
  * the client if the node changes.
  * \param strings return value of children paths.
  * \return the return code of the function.
@@ -1606,14 +1786,14 @@ ZOOAPI int zoo_get_children(zhandle_t *z
 
 /**
  * \brief lists the children of a node synchronously.
- * 
- * This function is similar to \ref zoo_get_children except it allows one specify 
+ *
+ * This function is similar to \ref zoo_get_children except it allows one specify
  * a watcher object rather than a boolean watch flag.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
+ * \param watcher if non-null, a watch will be set at the server to notify
  * the client if the node changes.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1627,19 +1807,19 @@ ZOOAPI int zoo_get_children(zhandle_t *z
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_wget_children(zhandle_t *zh, const char *path, 
+ZOOAPI int zoo_wget_children(zhandle_t *zh, const char *path,
         watcher_fn watcher, void* watcherCtx,
         struct String_vector *strings);
 
 /**
  * \brief lists the children of a node and get its stat synchronously.
- * 
+ *
  * This function is new in version 3.3.0
  *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
+ * \param watch if nonzero, a watch will be set at the server to notify
  * the client if the node changes.
  * \param strings return value of children paths.
  * \param stat return value of node stat.
@@ -1656,16 +1836,16 @@ ZOOAPI int zoo_get_children2(zhandle_t *
 
 /**
  * \brief lists the children of a node and get its stat synchronously.
- * 
- * This function is similar to \ref zoo_get_children except it allows one specify 
+ *
+ * This function is similar to \ref zoo_get_children except it allows one specify
  * a watcher object rather than a boolean watch flag.
- * 
+ *
  * This function is new in version 3.3.0
  *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
+ * \param watcher if non-null, a watch will be set at the server to notify
  * the client if the node changes.
  * \param watcherCtx user specific data, will be passed to the watcher callback.
  * Unlike the global context set by \ref zookeeper_init, this watcher context
@@ -1680,15 +1860,15 @@ ZOOAPI int zoo_get_children2(zhandle_t *
  * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
  * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
  */
-ZOOAPI int zoo_wget_children2(zhandle_t *zh, const char *path, 
+ZOOAPI int zoo_wget_children2(zhandle_t *zh, const char *path,
         watcher_fn watcher, void* watcherCtx,
         struct String_vector *strings, struct Stat *stat);
 
 /**
  * \brief gets the acl associated with a node synchronously.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param acl the return value of acls on the path.
  * \param stat returns the stat of the path specified.
@@ -1705,12 +1885,12 @@ ZOOAPI int zoo_get_acl(zhandle_t *zh, co
 
 /**
  * \brief sets the acl associated with a node synchronously.
- * 
+ *
  * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
+ * \param path the name of the node. Expressed as a file name with slashes
  * separating ancestors of the node.
  * \param version the expected version of the path.
- * \param acl the acl to be set on the path. 
+ * \param acl the acl to be set on the path.
  * \return the return code for the function call.
  * ZOK operation completed successfully
  * ZNONODE the node does not exist.
@@ -1734,7 +1914,7 @@ ZOOAPI int zoo_set_acl(zhandle_t *zh, co
  * \return the return code for the function call. This can be any of the
  * values that can be returned by the ops supported by a multi op (see
  * \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
- */ 
+ */
 ZOOAPI int zoo_multi(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results);
 
 #ifdef __cplusplus