ctdb-scripts: Drop CTDB_NOTIFY_SCRIPT configuration option
[kai/samba-autobuild/.git] / ctdb / protocol / protocol_client.c
index f4bfe193990ba54554f92412b8112e574483bc14..a18af08e21a5bf74c8fe42066e051ebf980f2541 100644 (file)
@@ -40,8 +40,13 @@ void ctdb_req_call_fill(struct ctdb_req_call *c,
 }
 */
 
-static int ctdb_reply_control_generic(struct ctdb_reply_control *reply)
+static int ctdb_reply_control_generic(struct ctdb_reply_control *reply,
+                                     uint32_t opcode)
 {
+       if (reply->rdata.opcode != opcode) {
+               return EPROTO;
+       }
+
        return reply->status;
 }
 
@@ -64,11 +69,13 @@ void ctdb_req_control_process_exists(struct ctdb_req_control *request,
 int ctdb_reply_control_process_exists(struct ctdb_reply_control *reply,
                                      int *status)
 {
-       if (reply->rdata.opcode == CTDB_CONTROL_PROCESS_EXISTS) {
-               *status = reply->status;
-               reply->status = 0;
-
+       if (reply->rdata.opcode != CTDB_CONTROL_PROCESS_EXISTS) {
+               return EPROTO;
        }
+
+       *status = reply->status;
+       reply->status = 0;
+
        return reply->status;
 }
 
@@ -89,8 +96,11 @@ int ctdb_reply_control_statistics(struct ctdb_reply_control *reply,
                                  TALLOC_CTX *mem_ctx,
                                  struct ctdb_statistics **stats)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_STATISTICS) {
+       if (reply->rdata.opcode != CTDB_CONTROL_STATISTICS) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *stats = talloc_steal(mem_ctx, reply->rdata.data.stats);
        }
        return reply->status;
@@ -112,6 +122,10 @@ void ctdb_req_control_ping(struct ctdb_req_control *request)
 int ctdb_reply_control_ping(struct ctdb_reply_control *reply,
                            int *num_clients)
 {
+       if (reply->rdata.opcode != CTDB_CONTROL_PING) {
+               return EPROTO;
+       }
+
        if (reply->status >= 0) {
                *num_clients = reply->status;
                reply->status = 0;
@@ -137,8 +151,11 @@ void ctdb_req_control_getdbpath(struct ctdb_req_control *request,
 int ctdb_reply_control_getdbpath(struct ctdb_reply_control *reply,
                                 TALLOC_CTX *mem_ctx, const char **db_path)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GETDBPATH) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GETDBPATH) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *db_path = talloc_steal(mem_ctx, reply->rdata.data.db_path);
        }
        return reply->status;
@@ -161,8 +178,11 @@ int ctdb_reply_control_getvnnmap(struct ctdb_reply_control *reply,
                                 TALLOC_CTX *mem_ctx,
                                 struct ctdb_vnn_map **vnnmap)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GETVNNMAP) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GETVNNMAP) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *vnnmap = talloc_steal(mem_ctx, reply->rdata.data.vnnmap);
        }
        return reply->status;
@@ -185,7 +205,7 @@ void ctdb_req_control_setvnnmap(struct ctdb_req_control *request,
 
 int ctdb_reply_control_setvnnmap(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SETVNNMAP);
 }
 
 /* CTDB_CONTROL_GET_DEBUG */
@@ -202,11 +222,14 @@ void ctdb_req_control_get_debug(struct ctdb_req_control *request)
 }
 
 int ctdb_reply_control_get_debug(struct ctdb_reply_control *reply,
-                                uint32_t *loglevel)
+                                int *loglevel)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_DEBUG) {
-               *loglevel = reply->rdata.data.loglevel;
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_DEBUG) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
+               *loglevel = (int)reply->rdata.data.loglevel;
        }
        return reply->status;
 }
@@ -214,7 +237,7 @@ int ctdb_reply_control_get_debug(struct ctdb_reply_control *reply,
 /* CTDB_CONTROL_SET_DEBUG */
 
 void ctdb_req_control_set_debug(struct ctdb_req_control *request,
-                               uint32_t loglevel)
+                               int loglevel)
 {
        request->opcode = CTDB_CONTROL_SET_DEBUG;
        request->pad = 0;
@@ -223,12 +246,12 @@ void ctdb_req_control_set_debug(struct ctdb_req_control *request,
        request->flags = 0;
 
        request->rdata.opcode = CTDB_CONTROL_SET_DEBUG;
-       request->rdata.data.loglevel = loglevel;
+       request->rdata.data.loglevel = (uint32_t)loglevel;
 }
 
 int ctdb_reply_control_set_debug(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_DEBUG);
 }
 
 /* CTDB_CONTROL_GET_DBMAP */
@@ -248,8 +271,11 @@ int ctdb_reply_control_get_dbmap(struct ctdb_reply_control *reply,
                                 TALLOC_CTX *mem_ctx,
                                 struct ctdb_dbid_map **dbmap)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_DBMAP) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_DBMAP) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *dbmap = talloc_steal(mem_ctx, reply->rdata.data.dbmap);
        }
        return reply->status;
@@ -274,8 +300,11 @@ int ctdb_reply_control_pull_db(struct ctdb_reply_control *reply,
                               TALLOC_CTX *mem_ctx,
                               struct ctdb_rec_buffer **recbuf)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_PULL_DB) {
+       if (reply->rdata.opcode != CTDB_CONTROL_PULL_DB) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *recbuf = talloc_steal(mem_ctx, reply->rdata.data.recbuf);
        }
        return reply->status;
@@ -298,7 +327,7 @@ void ctdb_req_control_push_db(struct ctdb_req_control *request,
 
 int ctdb_reply_control_push_db(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_PUSH_DB);
 }
 
 /* CTDB_CONTROL_GET_RECMODE */
@@ -317,6 +346,10 @@ void ctdb_req_control_get_recmode(struct ctdb_req_control *request)
 int ctdb_reply_control_get_recmode(struct ctdb_reply_control *reply,
                                   int *recmode)
 {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_RECMODE) {
+               return EPROTO;
+       }
+
        if (reply->status >= 0) {
                *recmode = reply->status;
                reply->status = 0;
@@ -341,7 +374,7 @@ void ctdb_req_control_set_recmode(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_recmode(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_RECMODE);
 }
 
 /* CTDB_CONTROL_STATISTICS_RESET */
@@ -359,17 +392,18 @@ void ctdb_req_control_statistics_reset(struct ctdb_req_control *request)
 
 int ctdb_reply_control_statistics_reset(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_STATISTICS_RESET);
 }
 
 /* CTDB_CONTROL_DB_ATTACH */
 
 void ctdb_req_control_db_attach(struct ctdb_req_control *request,
-                               const char *db_name, uint32_t tdb_flags)
+                               const char *db_name)
 {
        request->opcode = CTDB_CONTROL_DB_ATTACH;
        request->pad = 0;
-       request->srvid = tdb_flags;
+       request->srvid = 0;
        request->client_id = 0;
        request->flags = 0;
 
@@ -380,8 +414,11 @@ void ctdb_req_control_db_attach(struct ctdb_req_control *request,
 int ctdb_reply_control_db_attach(struct ctdb_reply_control *reply,
                                 uint32_t *db_id)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_DB_ATTACH) {
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_ATTACH) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *db_id = reply->rdata.data.db_id;
        }
        return reply->status;
@@ -406,7 +443,7 @@ void ctdb_req_control_traverse_start(struct ctdb_req_control *request,
 
 int ctdb_reply_control_traverse_start(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TRAVERSE_START);
 }
 
 /* CTDB_CONTROL_TRAVERSE_ALL */
@@ -428,7 +465,7 @@ void ctdb_req_control_register_srvid(struct ctdb_req_control *request,
 
 int ctdb_reply_control_register_srvid(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_REGISTER_SRVID);
 }
 
 /* CTDB_CONTROL_DEREGISTER_SRVID */
@@ -447,7 +484,8 @@ void ctdb_req_control_deregister_srvid(struct ctdb_req_control *request,
 
 int ctdb_reply_control_deregister_srvid(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_DEREGISTER_SRVID);
 }
 
 /* CTDB_CONTROL_GET_DBNAME */
@@ -468,8 +506,11 @@ void ctdb_req_control_get_dbname(struct ctdb_req_control *request,
 int ctdb_reply_control_get_dbname(struct ctdb_reply_control *reply,
                                  TALLOC_CTX *mem_ctx, const char **db_name)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_DBNAME) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_DBNAME) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *db_name = talloc_steal(mem_ctx, reply->rdata.data.db_name);
        }
        return reply->status;
@@ -492,7 +533,7 @@ void ctdb_req_control_enable_seqnum(struct ctdb_req_control *request,
 
 int ctdb_reply_control_enable_seqnum(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_ENABLE_SEQNUM);
 }
 
 /* CTDB_CONTROL_UPDATE_SEQNUM */
@@ -512,7 +553,7 @@ void ctdb_req_control_update_seqnum(struct ctdb_req_control *request,
 
 int ctdb_reply_control_update_seqnum(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_UPDATE_SEQNUM);
 }
 
 /* CTDB_CONTROL_DUMP_MEMORY */
@@ -531,8 +572,11 @@ void ctdb_req_control_dump_memory(struct ctdb_req_control *request)
 int ctdb_reply_control_dump_memory(struct ctdb_reply_control *reply,
                                   TALLOC_CTX *mem_ctx, const char **mem_str)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_DUMP_MEMORY) {
+       if (reply->rdata.opcode != CTDB_CONTROL_DUMP_MEMORY) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *mem_str = talloc_steal(mem_ctx, reply->rdata.data.mem_str);
        }
        return reply->status;
@@ -554,10 +598,13 @@ void ctdb_req_control_get_pid(struct ctdb_req_control *request)
 int ctdb_reply_control_get_pid(struct ctdb_reply_control *reply,
                               pid_t *pid)
 {
-       if (reply->rdata.opcode == CTDB_CONTROL_GET_PID) {
-               *pid = reply->status;
-               reply->status = 0;
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_PID) {
+               return EPROTO;
        }
+
+       *pid = reply->status;
+       reply->status = 0;
+
        return reply->status;
 }
 
@@ -577,10 +624,13 @@ void ctdb_req_control_get_recmaster(struct ctdb_req_control *request)
 int ctdb_reply_control_get_recmaster(struct ctdb_reply_control *reply,
                                     uint32_t *recmaster)
 {
-       if (reply->rdata.opcode == CTDB_CONTROL_GET_RECMASTER) {
-               *recmaster = reply->status;
-               reply->status = 0;
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_RECMASTER) {
+               return EPROTO;
        }
+
+       *recmaster = reply->status;
+       reply->status = 0;
+
        return reply->status;
 }
 
@@ -601,7 +651,7 @@ void ctdb_req_control_set_recmaster(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_recmaster(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_RECMASTER);
 }
 
 /* CTDB_CONTROL_FREEZE */
@@ -620,26 +670,7 @@ void ctdb_req_control_freeze(struct ctdb_req_control *request,
 
 int ctdb_reply_control_freeze(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_THAW */
-
-void ctdb_req_control_thaw(struct ctdb_req_control *request,
-                          uint32_t priority)
-{
-       request->opcode = CTDB_CONTROL_THAW;
-       request->pad = 0;
-       request->srvid = priority;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_THAW;
-}
-
-int ctdb_reply_control_thaw(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_FREEZE);
 }
 
 /* CTDB_CONTROL_GET_PNN */
@@ -658,6 +689,10 @@ void ctdb_req_control_get_pnn(struct ctdb_req_control *request)
 int ctdb_reply_control_get_pnn(struct ctdb_reply_control *reply,
                               uint32_t *pnn)
 {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_PNN) {
+               return EPROTO;
+       }
+
        if (reply->status >= 0) {
                *pnn = reply->status;
                reply->status = 0;
@@ -673,39 +708,18 @@ void ctdb_req_control_shutdown(struct ctdb_req_control *request)
        request->pad = 0;
        request->srvid = 0;
        request->client_id = 0;
-       request->flags = 0;
+       request->flags = CTDB_CTRL_FLAG_NOREPLY;
 
        request->rdata.opcode = CTDB_CONTROL_SHUTDOWN;
 }
 
 int ctdb_reply_control_shutdown(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SHUTDOWN);
 }
 
 /* CTDB_CONTROL_GET_MONMODE */
 
-void ctdb_req_control_get_monmode(struct ctdb_req_control *request)
-{
-       request->opcode = CTDB_CONTROL_GET_MONMODE;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_GET_MONMODE;
-}
-
-int ctdb_reply_control_get_monmode(struct ctdb_reply_control *reply,
-                                  int *mon_mode)
-{
-       if (reply->status >= 0) {
-               *mon_mode = reply->status;
-               reply->status = 0;
-       }
-       return reply->status;
-}
-
 /* CTDB_CONTROL_TCP_CLIENT */
 
 void ctdb_req_control_tcp_client(struct ctdb_req_control *request,
@@ -723,7 +737,7 @@ void ctdb_req_control_tcp_client(struct ctdb_req_control *request,
 
 int ctdb_reply_control_tcp_client(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TCP_CLIENT);
 }
 
 /* CTDB_CONTROL_TCP_ADD */
@@ -743,7 +757,7 @@ void ctdb_req_control_tcp_add(struct ctdb_req_control *request,
 
 int ctdb_reply_control_tcp_add(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TCP_ADD);
 }
 
 /* CTDB_CONTROL_TCP_REMOVE */
@@ -763,7 +777,7 @@ void ctdb_req_control_tcp_remove(struct ctdb_req_control *request,
 
 int ctdb_reply_control_tcp_remove(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TCP_REMOVE);
 }
 
 /* CTDB_CONTROL_STARTUP */
@@ -781,7 +795,7 @@ void ctdb_req_control_startup(struct ctdb_req_control *request)
 
 int ctdb_reply_control_startup(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_STARTUP);
 }
 
 /* CTDB_CONTROL_SET_TUNABLE */
@@ -801,7 +815,7 @@ void ctdb_req_control_set_tunable(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_tunable(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_TUNABLE);
 }
 
 /* CTDB_CONTROL_GET_TUNABLE */
@@ -822,8 +836,11 @@ void ctdb_req_control_get_tunable(struct ctdb_req_control *request,
 int ctdb_reply_control_get_tunable(struct ctdb_reply_control *reply,
                                   uint32_t *value)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_TUNABLE) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_TUNABLE) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *value = reply->rdata.data.tun_value;
        }
        return reply->status;
@@ -846,8 +863,11 @@ int ctdb_reply_control_list_tunables(struct ctdb_reply_control *reply,
                                     TALLOC_CTX *mem_ctx,
                                     struct ctdb_var_list **tun_var_list)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_LIST_TUNABLES) {
+       if (reply->rdata.opcode != CTDB_CONTROL_LIST_TUNABLES) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *tun_var_list = talloc_steal(mem_ctx,
                                             reply->rdata.data.tun_var_list);
        }
@@ -871,7 +891,7 @@ void ctdb_req_control_modify_flags(struct ctdb_req_control *request,
 
 int ctdb_reply_control_modify_flags(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_MODIFY_FLAGS);
 }
 
 /* CTDB_CONTROL_GET_ALL_TUNABLES */
@@ -891,33 +911,16 @@ int ctdb_reply_control_get_all_tunables(struct ctdb_reply_control *reply,
                                        TALLOC_CTX *mem_ctx,
                                        struct ctdb_tunable_list **tun_list)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_ALL_TUNABLES) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_ALL_TUNABLES) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *tun_list = talloc_steal(mem_ctx, reply->rdata.data.tun_list);
        }
        return reply->status;
 }
 
-/* CTDB_CONTROL_KILL_TCP */
-
-void ctdb_req_control_kill_tcp(struct ctdb_req_control *request,
-                              struct ctdb_connection *conn)
-{
-       request->opcode = CTDB_CONTROL_KILL_TCP;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_KILL_TCP;
-       request->rdata.data.conn = conn;
-}
-
-int ctdb_reply_control_kill_tcp(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
 /* CTDB_CONTROL_GET_TCP_TICKLE_LIST */
 
 void ctdb_req_control_get_tcp_tickle_list(struct ctdb_req_control *request,
@@ -937,8 +940,11 @@ int ctdb_reply_control_get_tcp_tickle_list(struct ctdb_reply_control *reply,
                                           TALLOC_CTX *mem_ctx,
                                           struct ctdb_tickle_list **tickles)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_TCP_TICKLE_LIST) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_TCP_TICKLE_LIST) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *tickles = talloc_steal(mem_ctx, reply->rdata.data.tickles);
        }
        return reply->status;
@@ -961,102 +967,18 @@ void ctdb_req_control_set_tcp_tickle_list(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_tcp_tickle_list(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_REGISTER_SERVER_ID */
-
-void ctdb_req_control_register_server_id(struct ctdb_req_control *request,
-                                        struct ctdb_client_id *cid)
-{
-       request->opcode = CTDB_CONTROL_REGISTER_SERVER_ID;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_REGISTER_SERVER_ID;
-       request->rdata.data.cid = cid;
-}
-
-int ctdb_reply_control_register_server_id(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_UNREGISTER_SERVER_ID */
-
-void ctdb_req_control_unregister_server_id(struct ctdb_req_control *request,
-                                          struct ctdb_client_id *cid)
-{
-       request->opcode = CTDB_CONTROL_UNREGISTER_SERVER_ID;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_UNREGISTER_SERVER_ID;
-       request->rdata.data.cid = cid;
-}
-
-int ctdb_reply_control_unregister_server_id(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_CHECK_SERVER_ID */
-
-void ctdb_req_control_check_server_id(struct ctdb_req_control *request,
-                                     struct ctdb_client_id *cid)
-{
-       request->opcode = CTDB_CONTROL_CHECK_SERVER_ID;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_CHECK_SERVER_ID;
-       request->rdata.data.cid = cid;
-}
-
-int ctdb_reply_control_check_server_id(struct ctdb_reply_control *reply)
-{
-       return reply->status;
-}
-
-/* CTDB_CONTROL_GET_SERVER_ID_LIST */
-
-void ctdb_req_control_get_server_id_list(struct ctdb_req_control *request)
-{
-       request->opcode = CTDB_CONTROL_GET_SERVER_ID_LIST;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_GET_SERVER_ID_LIST;
-}
-
-int ctdb_reply_control_get_server_id_list(struct ctdb_reply_control *reply,
-                                         TALLOC_CTX *mem_ctx,
-                                         struct ctdb_client_id_map **cid_map)
-{
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_SERVER_ID_LIST) {
-               *cid_map = talloc_steal(mem_ctx, reply->rdata.data.cid_map);
-       }
-       return reply->status;
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_SET_TCP_TICKLE_LIST);
 }
 
 /* CTDB_CONTROL_DB_ATTACH_PERSISTENT */
 
 void ctdb_req_control_db_attach_persistent(struct ctdb_req_control *request,
-                                          const char *db_name,
-                                          uint32_t tdb_flags)
+                                          const char *db_name)
 {
        request->opcode = CTDB_CONTROL_DB_ATTACH_PERSISTENT;
        request->pad = 0;
-       request->srvid = tdb_flags;
+       request->srvid = 0;
        request->client_id = 0;
        request->flags = 0;
 
@@ -1067,8 +989,11 @@ void ctdb_req_control_db_attach_persistent(struct ctdb_req_control *request,
 int ctdb_reply_control_db_attach_persistent(struct ctdb_reply_control *reply,
                                            uint32_t *db_id)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_DB_ATTACH_PERSISTENT) {
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_ATTACH_PERSISTENT) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *db_id = reply->rdata.data.db_id;
        }
        return reply->status;
@@ -1091,7 +1016,7 @@ void ctdb_req_control_update_record(struct ctdb_req_control *request,
 
 int ctdb_reply_control_update_record(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_UPDATE_RECORD);
 }
 
 /* CTDB_CONTROL_SEND_GRATUITOUS_ARP */
@@ -1111,47 +1036,8 @@ void ctdb_req_control_send_gratuitous_arp(struct ctdb_req_control *request,
 
 int ctdb_reply_control_send_gratuitous_arp(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_TRANSACTION_START */
-
-void ctdb_req_control_transaction_start(struct ctdb_req_control *request,
-                                       uint32_t tid)
-{
-       request->opcode = CTDB_CONTROL_TRANSACTION_START;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_TRANSACTION_START;
-       request->rdata.data.tid = tid;
-}
-
-int ctdb_reply_control_transaction_start(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_TRANSACTION_COMMIT */
-
-void ctdb_req_control_transaction_commit(struct ctdb_req_control *request,
-                                        uint32_t tid)
-{
-       request->opcode = CTDB_CONTROL_TRANSACTION_COMMIT;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_TRANSACTION_COMMIT;
-       request->rdata.data.tid = tid;
-}
-
-int ctdb_reply_control_transaction_commit(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_SEND_GRATUITOUS_ARP);
 }
 
 /* CTDB_CONTROL_WIPE_DATABASE */
@@ -1171,7 +1057,7 @@ void ctdb_req_control_wipe_database(struct ctdb_req_control *request,
 
 int ctdb_reply_control_wipe_database(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_WIPE_DATABASE);
 }
 
 /* CTDB_CONTROL_UPTIME */
@@ -1190,8 +1076,11 @@ void ctdb_req_control_uptime(struct ctdb_req_control *request)
 int ctdb_reply_control_uptime(struct ctdb_reply_control *reply,
                              TALLOC_CTX *mem_ctx, struct ctdb_uptime **uptime)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_UPTIME) {
+       if (reply->rdata.opcode != CTDB_CONTROL_UPTIME) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *uptime = talloc_steal(mem_ctx, reply->rdata.data.uptime);
        }
        return reply->status;
@@ -1212,7 +1101,7 @@ void ctdb_req_control_start_recovery(struct ctdb_req_control *request)
 
 int ctdb_reply_control_start_recovery(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_START_RECOVERY);
 }
 
 /* CTDB_CONTROL_END_RECOVERY */
@@ -1230,7 +1119,7 @@ void ctdb_req_control_end_recovery(struct ctdb_req_control *request)
 
 int ctdb_reply_control_end_recovery(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_END_RECOVERY);
 }
 
 /* CTDB_CONTROL_RELOAD_NODES_FILE */
@@ -1248,7 +1137,8 @@ void ctdb_req_control_reload_nodes_file(struct ctdb_req_control *request)
 
 int ctdb_reply_control_reload_nodes_file(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_RELOAD_NODES_FILE);
 }
 
 /* CTDB_CONTROL_TRY_DELETE_RECORDS */
@@ -1270,49 +1160,19 @@ int ctdb_reply_control_try_delete_records(struct ctdb_reply_control *reply,
                                          TALLOC_CTX *mem_ctx,
                                          struct ctdb_rec_buffer **recbuf)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_TRY_DELETE_RECORDS) {
+       if (reply->rdata.opcode != CTDB_CONTROL_TRY_DELETE_RECORDS) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *recbuf = talloc_steal(mem_ctx, reply->rdata.data.recbuf);
        }
        return reply->status;
 }
 
 /* CTDB_CONTROL_ENABLE_MONITOR */
-
-void ctdb_req_control_enable_monitor(struct ctdb_req_control *request)
-{
-       request->opcode = CTDB_CONTROL_ENABLE_MONITOR;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_ENABLE_MONITOR;
-}
-
-int ctdb_reply_control_enable_monitor(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
 /* CTDB_CONTROL_DISABLE_MONITOR */
 
-void ctdb_req_control_disable_monitor(struct ctdb_req_control *request)
-{
-       request->opcode = CTDB_CONTROL_DISABLE_MONITOR;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_DISABLE_MONITOR;
-}
-
-int ctdb_reply_control_disable_monitor(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
 /* CTDB_CONTROL_ADD_PUBLIC_IP */
 
 void ctdb_req_control_add_public_ip(struct ctdb_req_control *request,
@@ -1330,7 +1190,7 @@ void ctdb_req_control_add_public_ip(struct ctdb_req_control *request,
 
 int ctdb_reply_control_add_public_ip(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_ADD_PUBLIC_IP);
 }
 
 /* CTDB_CONTROL_DEL_PUBLIC_IP */
@@ -1350,27 +1210,7 @@ void ctdb_req_control_del_public_ip(struct ctdb_req_control *request,
 
 int ctdb_reply_control_del_public_ip(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_RUN_EVENTSCRIPTS */
-
-void ctdb_req_control_run_eventscripts(struct ctdb_req_control *request,
-                                      const char *event_str)
-{
-       request->opcode = CTDB_CONTROL_RUN_EVENTSCRIPTS;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_RUN_EVENTSCRIPTS;
-       request->rdata.data.event_str = event_str;
-}
-
-int ctdb_reply_control_run_eventscripts(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_DEL_PUBLIC_IP);
 }
 
 /* CTDB_CONTROL_GET_CAPABILITIES */
@@ -1389,8 +1229,11 @@ void ctdb_req_control_get_capabilities(struct ctdb_req_control *request)
 int ctdb_reply_control_get_capabilities(struct ctdb_reply_control *reply,
                                        uint32_t *caps)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_CAPABILITIES) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_CAPABILITIES) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *caps = reply->rdata.data.caps;
        }
        return reply->status;
@@ -1411,7 +1254,7 @@ void ctdb_req_control_recd_ping(struct ctdb_req_control *request)
 
 int ctdb_reply_control_recd_ping(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_RECD_PING);
 }
 
 /* CTDB_CONTROL_RELEASE_IP */
@@ -1431,7 +1274,7 @@ void ctdb_req_control_release_ip(struct ctdb_req_control *request,
 
 int ctdb_reply_control_release_ip(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_RELEASE_IP);
 }
 
 /* CTDB_CONTROL_TAKEOVER_IP */
@@ -1451,12 +1294,13 @@ void ctdb_req_control_takeover_ip(struct ctdb_req_control *request,
 
 int ctdb_reply_control_takeover_ip(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TAKEOVER_IP);
 }
 
 /* CTDB_CONTROL_GET_PUBLIC_IPS */
 
-void ctdb_req_control_get_public_ips(struct ctdb_req_control *request)
+void ctdb_req_control_get_public_ips(struct ctdb_req_control *request,
+                                    bool available_only)
 {
        request->opcode = CTDB_CONTROL_GET_PUBLIC_IPS;
        request->pad = 0;
@@ -1465,15 +1309,22 @@ void ctdb_req_control_get_public_ips(struct ctdb_req_control *request)
        request->flags = 0;
 
        request->rdata.opcode = CTDB_CONTROL_GET_PUBLIC_IPS;
+       if (available_only) {
+               request->flags = CTDB_PUBLIC_IP_FLAGS_ONLY_AVAILABLE;
+       }
 }
 
 int ctdb_reply_control_get_public_ips(struct ctdb_reply_control *reply,
                                      TALLOC_CTX *mem_ctx,
                                      struct ctdb_public_ip_list **pubip_list)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_PUBLIC_IPS) {
-               *pubip_list = talloc_steal(mem_ctx, reply->rdata.data.pubip_list);
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_PUBLIC_IPS) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
+               *pubip_list = talloc_steal(mem_ctx,
+                                          reply->rdata.data.pubip_list);
        }
        return reply->status;
 }
@@ -1495,35 +1346,12 @@ int ctdb_reply_control_get_nodemap(struct ctdb_reply_control *reply,
                                   TALLOC_CTX *mem_ctx,
                                   struct ctdb_node_map **nodemap)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_NODEMAP) {
-               *nodemap = talloc_steal(mem_ctx, reply->rdata.data.nodemap);
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_NODEMAP) {
+               return EPROTO;
        }
-       return reply->status;
-}
-
-/* CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS */
-
-void ctdb_req_control_get_event_script_status(struct ctdb_req_control *request,
-                                             uint32_t event)
-{
-       request->opcode = CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS;
-       request->rdata.data.event = event;
-}
 
-int ctdb_reply_control_get_event_script_status(struct ctdb_reply_control *reply,
-                                              TALLOC_CTX *mem_ctx,
-                                              struct ctdb_script_list **slist)
-{
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS) {
-               *slist = talloc_steal(mem_ctx, reply->rdata.data.script_list);
+       if (reply->status == 0) {
+               *nodemap = talloc_steal(mem_ctx, reply->rdata.data.nodemap);
        }
        return reply->status;
 }
@@ -1545,7 +1373,7 @@ void ctdb_req_control_traverse_kill(struct ctdb_req_control *request,
 
 int ctdb_reply_control_traverse_kill(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TRAVERSE_KILL);
 }
 
 /* CTDB_CONTROL_RECD_RECLOCK_LATENCY */
@@ -1565,7 +1393,8 @@ void ctdb_req_control_recd_reclock_latency(struct ctdb_req_control *request,
 
 int ctdb_reply_control_recd_reclock_latency(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_RECD_RECLOCK_LATENCY);
 }
 
 /* CTDB_CONTROL_GET_RECLOCK_FILE */
@@ -1585,35 +1414,17 @@ int ctdb_reply_control_get_reclock_file(struct ctdb_reply_control *reply,
                                        TALLOC_CTX *mem_ctx,
                                        const char **reclock_file)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_RECLOCK_FILE) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_RECLOCK_FILE) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *reclock_file = talloc_steal(mem_ctx,
                                             reply->rdata.data.reclock_file);
        }
        return reply->status;
 }
 
-/* CTDB_CONTROL_SET_RECLOCK_FILE */
-
-void ctdb_req_control_set_reclock_file(struct ctdb_req_control *request,
-                                      const char *reclock_file)
-{
-       request->opcode = CTDB_CONTROL_SET_RECLOCK_FILE;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_SET_RECLOCK_FILE;
-       request->rdata.data.reclock_file = reclock_file;
-}
-
-int ctdb_reply_control_set_reclock_file(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-
 /* CTDB_CONTROL_STOP_NODE */
 
 void ctdb_req_control_stop_node(struct ctdb_req_control *request)
@@ -1629,7 +1440,7 @@ void ctdb_req_control_stop_node(struct ctdb_req_control *request)
 
 int ctdb_reply_control_stop_node(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_STOP_NODE);
 }
 
 /* CTDB_CONTROL_CONTINUE_NODE */
@@ -1647,27 +1458,7 @@ void ctdb_req_control_continue_node(struct ctdb_req_control *request)
 
 int ctdb_reply_control_continue_node(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_SET_NATGWSTATE */
-
-void ctdb_req_control_set_natgwstate(struct ctdb_req_control *request,
-                                    uint32_t natgw_role)
-{
-       request->opcode = CTDB_CONTROL_SET_NATGWSTATE;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_SET_NATGWSTATE;
-       request->rdata.data.role = natgw_role;
-}
-
-int ctdb_reply_control_set_natgwstate(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_CONTINUE_NODE);
 }
 
 /* CTDB_CONTROL_SET_LMASTERROLE */
@@ -1687,7 +1478,7 @@ void ctdb_req_control_set_lmasterrole(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_lmasterrole(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_LMASTERROLE);
 }
 
 /* CTDB_CONTROL_SET_RECMASTERROLE */
@@ -1707,67 +1498,28 @@ void ctdb_req_control_set_recmasterrole(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_recmasterrole(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_SET_RECMASTERROLE);
 }
 
-/* CTDB_CONTROL_ENABLE_SCRIPT */
+/* CTDB_CONTROL_SET_BAN_STATE */
 
-void ctdb_req_control_enable_script(struct ctdb_req_control *request,
-                                   const char *script)
+void ctdb_req_control_set_ban_state(struct ctdb_req_control *request,
+                                   struct ctdb_ban_state *ban_state)
 {
-       request->opcode = CTDB_CONTROL_ENABLE_SCRIPT;
+       request->opcode = CTDB_CONTROL_SET_BAN_STATE;
        request->pad = 0;
        request->srvid = 0;
        request->client_id = 0;
        request->flags = 0;
 
-       request->rdata.opcode = CTDB_CONTROL_ENABLE_SCRIPT;
-       request->rdata.data.script = script;
-}
-
-int ctdb_reply_control_enable_script(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_DISABLE_SCRIPT */
-
-void ctdb_req_control_disable_script(struct ctdb_req_control *request,
-                                    const char *script)
-{
-       request->opcode = CTDB_CONTROL_DISABLE_SCRIPT;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_DISABLE_SCRIPT;
-       request->rdata.data.script = script;
-}
-
-int ctdb_reply_control_disable_script(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_SET_BAN_STATE */
-
-void ctdb_req_control_set_ban_state(struct ctdb_req_control *request,
-                                   struct ctdb_ban_state *ban_state)
-{
-       request->opcode = CTDB_CONTROL_SET_BAN_STATE;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_SET_BAN_STATE;
-       request->rdata.data.ban_state = ban_state;
+       request->rdata.opcode = CTDB_CONTROL_SET_BAN_STATE;
+       request->rdata.data.ban_state = ban_state;
 }
 
 int ctdb_reply_control_set_ban_state(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_BAN_STATE);
 }
 
 /* CTDB_CONTROL_GET_BAN_STATE */
@@ -1787,79 +1539,17 @@ int ctdb_reply_control_get_ban_state(struct ctdb_reply_control *reply,
                                     TALLOC_CTX *mem_ctx,
                                     struct ctdb_ban_state **ban_state)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_BAN_STATE) {
-               *ban_state = talloc_steal(mem_ctx,
-                                         reply->rdata.data.ban_state);
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_BAN_STATE) {
+               return EPROTO;
        }
-       return reply->status;
-}
-
-/* CTDB_CONTROL_SET_DB_PRIORITY */
-
-void ctdb_req_control_set_db_priority(struct ctdb_req_control *request,
-                                     struct ctdb_db_priority *db_prio)
-{
-       request->opcode = CTDB_CONTROL_SET_DB_PRIORITY;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_SET_DB_PRIORITY;
-       request->rdata.data.db_prio = db_prio;
-}
-
-int ctdb_reply_control_set_db_priority(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
-/* CTDB_CONTROL_GET_DB_PRIORITY */
 
-void ctdb_req_control_get_db_priority(struct ctdb_req_control *request,
-                                     uint32_t db_id)
-{
-       request->opcode = CTDB_CONTROL_GET_DB_PRIORITY;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_GET_DB_PRIORITY;
-       request->rdata.data.db_id = db_id;
-}
-
-int ctdb_reply_control_get_db_priority(struct ctdb_reply_control *reply,
-                                      uint32_t *priority)
-{
-       if (reply->rdata.opcode == CTDB_CONTROL_GET_DB_PRIORITY) {
-               *priority = reply->status;
-               reply->status = 0;
+       if (reply->status == 0) {
+               *ban_state = talloc_steal(mem_ctx,
+                                         reply->rdata.data.ban_state);
        }
        return reply->status;
 }
 
-/* CTDB_CONTROL_TRANSACTION_CANCEL */
-
-void ctdb_req_control_transaction_cancel(struct ctdb_req_control *request,
-                                        uint32_t tid)
-{
-       request->opcode = CTDB_CONTROL_TRANSACTION_CANCEL;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_TRANSACTION_CANCEL;
-       request->rdata.data.tid = tid;
-}
-
-int ctdb_reply_control_transaction_cancel(struct ctdb_reply_control *reply)
-{
-       return ctdb_reply_control_generic(reply);
-}
-
 /* CTDB_CONTROL_REGISTER_NOTIFY */
 
 void ctdb_req_control_register_notify(struct ctdb_req_control *request,
@@ -1877,7 +1567,7 @@ void ctdb_req_control_register_notify(struct ctdb_req_control *request,
 
 int ctdb_reply_control_register_notify(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_REGISTER_NOTIFY);
 }
 
 /* CTDB_CONTROL_DEREGISTER_NOTIFY */
@@ -1897,7 +1587,8 @@ void ctdb_req_control_deregister_notify(struct ctdb_req_control *request,
 
 int ctdb_reply_control_deregister_notify(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_DEREGISTER_NOTIFY);
 }
 
 /* CTDB_CONTROL_TRANS3_COMMIT */
@@ -1917,7 +1608,7 @@ void ctdb_req_control_trans3_commit(struct ctdb_req_control *request,
 
 int ctdb_reply_control_trans3_commit(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_TRANS3_COMMIT);
 }
 
 /* CTDB_CONTROL_GET_DB_SEQNUM */
@@ -1938,8 +1629,11 @@ void ctdb_req_control_get_db_seqnum(struct ctdb_req_control *request,
 int ctdb_reply_control_get_db_seqnum(struct ctdb_reply_control *reply,
                                     uint64_t *seqnum)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_DB_SEQNUM) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_DB_SEQNUM) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *seqnum = reply->rdata.data.seqnum;
        }
        return reply->status;
@@ -1962,7 +1656,7 @@ void ctdb_req_control_db_set_healthy(struct ctdb_req_control *request,
 
 int ctdb_reply_control_db_set_healthy(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_DB_SET_HEALTHY);
 }
 
 /* CTDB_CONTROL_DB_GET_HEALTH */
@@ -1983,8 +1677,11 @@ void ctdb_req_control_db_get_health(struct ctdb_req_control *request,
 int ctdb_reply_control_db_get_health(struct ctdb_reply_control *reply,
                                     TALLOC_CTX *mem_ctx, const char **reason)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_DB_GET_HEALTH) {
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_GET_HEALTH) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *reason = talloc_steal(mem_ctx, reply->rdata.data.reason);
        }
        return reply->status;
@@ -2009,8 +1706,11 @@ int ctdb_reply_control_get_public_ip_info(struct ctdb_reply_control *reply,
                                          TALLOC_CTX *mem_ctx,
                                          struct ctdb_public_ip_info **ipinfo)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_PUBLIC_IP_INFO) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_PUBLIC_IP_INFO) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *ipinfo = talloc_steal(mem_ctx, reply->rdata.data.ipinfo);
        }
        return reply->status;
@@ -2033,8 +1733,11 @@ int ctdb_reply_control_get_ifaces(struct ctdb_reply_control *reply,
                                  TALLOC_CTX *mem_ctx,
                                  struct ctdb_iface_list **iface_list)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_IFACES) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_IFACES) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *iface_list = talloc_steal(mem_ctx,
                                           reply->rdata.data.iface_list);
        }
@@ -2058,7 +1761,8 @@ void ctdb_req_control_set_iface_link_state(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_iface_link_state(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_SET_IFACE_LINK_STATE);
 }
 
 /* CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE */
@@ -2078,7 +1782,8 @@ void ctdb_req_control_tcp_add_delayed_update(struct ctdb_req_control *request,
 
 int ctdb_reply_control_tcp_add_delayed_update(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_TCP_ADD_DELAYED_UPDATE);
 }
 
 /* CTDB_CONTROL_GET_STAT_HISTORY */
@@ -2098,8 +1803,11 @@ int ctdb_reply_control_get_stat_history(struct ctdb_reply_control *reply,
                                        TALLOC_CTX *mem_ctx,
                                        struct ctdb_statistics_list **stats_list)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_STAT_HISTORY) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_STAT_HISTORY) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *stats_list = talloc_steal(mem_ctx,
                                           reply->rdata.data.stats_list);
        }
@@ -2123,7 +1831,8 @@ void ctdb_req_control_schedule_for_deletion(struct ctdb_req_control *request,
 
 int ctdb_reply_control_schedule_for_deletion(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_SCHEDULE_FOR_DELETION);
 }
 
 /* CTDB_CONTROL_SET_DB_READONLY */
@@ -2143,35 +1852,11 @@ void ctdb_req_control_set_db_readonly(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_db_readonly(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_DB_READONLY);
 }
 
 /* CTDB_CONTROL_CHECK_SRVIDS */
 
-void ctdb_req_control_check_srvids(struct ctdb_req_control *request,
-                                  struct ctdb_uint64_array *u64_array)
-{
-       request->opcode = CTDB_CONTROL_CHECK_SRVIDS;
-       request->pad = 0;
-       request->srvid = 0;
-       request->client_id = 0;
-       request->flags = 0;
-
-       request->rdata.opcode = CTDB_CONTROL_CHECK_SRVIDS;
-       request->rdata.data.u64_array = u64_array;
-}
-
-int ctdb_reply_control_check_srvids(struct ctdb_reply_control *reply,
-                                   TALLOC_CTX *mem_ctx,
-                                   struct ctdb_uint8_array **u8_array)
-{
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_CHECK_SRVIDS) {
-               *u8_array = talloc_steal(mem_ctx, reply->rdata.data.u8_array);
-       }
-       return reply->status;
-}
-
 /* CTDB_CONTROL_TRAVERSE_START_EXT */
 
 void ctdb_req_control_traverse_start_ext(struct ctdb_req_control *request,
@@ -2189,7 +1874,8 @@ void ctdb_req_control_traverse_start_ext(struct ctdb_req_control *request,
 
 int ctdb_reply_control_traverse_start_ext(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_TRAVERSE_START_EXT);
 }
 
 /* CTDB_CONTROL_GET_DB_STATISTICS */
@@ -2211,8 +1897,11 @@ int ctdb_reply_control_get_db_statistics(struct ctdb_reply_control *reply,
                                         TALLOC_CTX *mem_ctx,
                                         struct ctdb_db_statistics **dbstats)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_DB_STATISTICS) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_DB_STATISTICS) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *dbstats = talloc_steal(mem_ctx, reply->rdata.data.dbstats);
        }
        return reply->status;
@@ -2235,7 +1924,7 @@ void ctdb_req_control_set_db_sticky(struct ctdb_req_control *request,
 
 int ctdb_reply_control_set_db_sticky(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_SET_DB_STICKY);
 }
 
 /* CTDB_CONTROL_RELOAD_PUBLIC_IPS */
@@ -2253,7 +1942,8 @@ void ctdb_req_control_reload_public_ips(struct ctdb_req_control *request)
 
 int ctdb_reply_control_reload_public_ips(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_RELOAD_PUBLIC_IPS);
 }
 
 /* CTDB_CONTROL_TRAVERSE_ALL_EXT */
@@ -2277,8 +1967,11 @@ int ctdb_reply_control_receive_records(struct ctdb_reply_control *reply,
                                       TALLOC_CTX *mem_ctx,
                                       struct ctdb_rec_buffer **recbuf)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_RECEIVE_RECORDS) {
+       if (reply->rdata.opcode != CTDB_CONTROL_RECEIVE_RECORDS) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *recbuf = talloc_steal(mem_ctx, reply->rdata.data.recbuf);
        }
        return reply->status;
@@ -2299,7 +1992,7 @@ void ctdb_req_control_ipreallocated(struct ctdb_req_control *request)
 
 int ctdb_reply_control_ipreallocated(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_IPREALLOCATED);
 }
 
 /* CTDB_CONTROL_GET_RUNSTATE */
@@ -2318,8 +2011,11 @@ void ctdb_req_control_get_runstate(struct ctdb_req_control *request)
 int ctdb_reply_control_get_runstate(struct ctdb_reply_control *reply,
                                    enum ctdb_runstate *runstate)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_RUNSTATE) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_RUNSTATE) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *runstate = reply->rdata.data.runstate;
        }
        return reply->status;
@@ -2342,7 +2038,7 @@ void ctdb_req_control_db_detach(struct ctdb_req_control *request,
 
 int ctdb_reply_control_db_detach(struct ctdb_reply_control *reply)
 {
-       return ctdb_reply_control_generic(reply);
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_DB_DETACH);
 }
 
 /* CTDB_CONTROL_GET_NODES_FILE */
@@ -2362,9 +2058,316 @@ int ctdb_reply_control_get_nodes_file(struct ctdb_reply_control *reply,
                                      TALLOC_CTX *mem_ctx,
                                      struct ctdb_node_map **nodemap)
 {
-       if (reply->status == 0 &&
-           reply->rdata.opcode == CTDB_CONTROL_GET_NODES_FILE) {
+       if (reply->rdata.opcode != CTDB_CONTROL_GET_NODES_FILE) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
                *nodemap = talloc_steal(mem_ctx, reply->rdata.data.nodemap);
        }
        return reply->status;
 }
+
+/* CTDB_CONTROL_DB_FREEZE */
+
+void ctdb_req_control_db_freeze(struct ctdb_req_control *request,
+                               uint32_t db_id)
+{
+       request->opcode = CTDB_CONTROL_DB_FREEZE;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_FREEZE;
+       request->rdata.data.db_id = db_id;
+}
+
+int ctdb_reply_control_db_freeze(struct ctdb_reply_control *reply)
+{
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_DB_FREEZE);
+}
+
+/* CTDB_CONTROL_DB_THAW */
+
+void ctdb_req_control_db_thaw(struct ctdb_req_control *request,
+                             uint32_t db_id)
+{
+       request->opcode = CTDB_CONTROL_DB_THAW;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_THAW;
+       request->rdata.data.db_id = db_id;
+}
+
+int ctdb_reply_control_db_thaw(struct ctdb_reply_control *reply)
+{
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_DB_THAW);
+}
+
+/* CTDB_CONTROL_DB_TRANSACTION_START */
+
+void ctdb_req_control_db_transaction_start(struct ctdb_req_control *request,
+                                          struct ctdb_transdb *transdb)
+{
+       request->opcode = CTDB_CONTROL_DB_TRANSACTION_START;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_TRANSACTION_START;
+       request->rdata.data.transdb = transdb;
+}
+
+int ctdb_reply_control_db_transaction_start(struct ctdb_reply_control *reply)
+{
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_DB_TRANSACTION_START);
+}
+
+/* CTDB_CONTROL_DB_TRANSACTION_COMMIT */
+
+void ctdb_req_control_db_transaction_commit(struct ctdb_req_control *request,
+                                           struct ctdb_transdb *transdb)
+{
+       request->opcode = CTDB_CONTROL_DB_TRANSACTION_COMMIT;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_TRANSACTION_COMMIT;
+       request->rdata.data.transdb = transdb;
+}
+
+int ctdb_reply_control_db_transaction_commit(struct ctdb_reply_control *reply)
+{
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_DB_TRANSACTION_COMMIT);
+}
+
+/* CTDB_CONTROL_DB_TRANSACTION_CANCEL */
+
+void ctdb_req_control_db_transaction_cancel(struct ctdb_req_control *request,
+                                           uint32_t db_id)
+{
+       request->opcode = CTDB_CONTROL_DB_TRANSACTION_CANCEL;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_TRANSACTION_CANCEL;
+       request->rdata.data.db_id = db_id;
+}
+
+int ctdb_reply_control_db_transaction_cancel(struct ctdb_reply_control *reply)
+{
+       return ctdb_reply_control_generic(reply,
+                                         CTDB_CONTROL_DB_TRANSACTION_CANCEL);
+}
+
+/* CTDB_CONTROL_DB_PULL */
+
+void ctdb_req_control_db_pull(struct ctdb_req_control *request,
+                             struct ctdb_pulldb_ext *pulldb_ext)
+{
+       request->opcode = CTDB_CONTROL_DB_PULL;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_PULL;
+       request->rdata.data.pulldb_ext = pulldb_ext;
+}
+
+int ctdb_reply_control_db_pull(struct ctdb_reply_control *reply,
+                              uint32_t *num_records)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_PULL) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
+               *num_records = reply->rdata.data.num_records;
+       }
+       return reply->status;
+}
+
+/* CTDB_CONTROL_DB_PUSH_START */
+
+void ctdb_req_control_db_push_start(struct ctdb_req_control *request,
+                                   struct ctdb_pulldb_ext *pulldb_ext)
+{
+       request->opcode = CTDB_CONTROL_DB_PUSH_START;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_PUSH_START;
+       request->rdata.data.pulldb_ext = pulldb_ext;
+}
+
+int ctdb_reply_control_db_push_start(struct ctdb_reply_control *reply)
+{
+       return ctdb_reply_control_generic(reply, CTDB_CONTROL_DB_PUSH_START);
+}
+
+/* CTDB_CONTROL_DB_PUSH_CONFIRM */
+
+void ctdb_req_control_db_push_confirm(struct ctdb_req_control *request,
+                                     uint32_t db_id)
+{
+       request->opcode = CTDB_CONTROL_DB_PUSH_CONFIRM;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_PUSH_CONFIRM;
+       request->rdata.data.db_id = db_id;
+}
+
+int ctdb_reply_control_db_push_confirm(struct ctdb_reply_control *reply,
+                                      uint32_t *num_records)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_PUSH_CONFIRM) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
+               *num_records = reply->rdata.data.num_records;
+       }
+       return reply->status;
+}
+
+/* CTDB_CONTROL_DB_OPEN_FLAGS */
+
+void ctdb_req_control_db_open_flags(struct ctdb_req_control *request,
+                                   uint32_t db_id)
+{
+       request->opcode = CTDB_CONTROL_DB_OPEN_FLAGS;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_OPEN_FLAGS;
+       request->rdata.data.db_id = db_id;
+}
+
+int ctdb_reply_control_db_open_flags(struct ctdb_reply_control *reply,
+                                    int *tdb_flags)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_OPEN_FLAGS) {
+               return EPROTO;
+       }
+
+       if (reply->status == 0) {
+               *tdb_flags = reply->rdata.data.tdb_flags;
+       }
+       return reply->status;
+}
+
+/* CTDB_CONTROL_DB_ATTACH_REPLICATED */
+
+void ctdb_req_control_db_attach_replicated(struct ctdb_req_control *request,
+                                          const char *db_name)
+{
+       request->opcode = CTDB_CONTROL_DB_ATTACH_REPLICATED;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_DB_ATTACH_REPLICATED;
+       request->rdata.data.db_name = db_name;
+}
+
+int ctdb_reply_control_db_attach_replicated(struct ctdb_reply_control *reply,
+                                           uint32_t *db_id)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_DB_ATTACH_REPLICATED) {
+               return EPROTO;
+       }
+       if (reply->status == 0) {
+               *db_id = reply->rdata.data.db_id;
+       }
+       return reply->status;
+}
+
+/* CTDB_CONTROL_CHECK_PID_SRVID */
+
+void ctdb_req_control_check_pid_srvid(struct ctdb_req_control *request,
+                                     struct ctdb_pid_srvid *pid_srvid)
+{
+       request->opcode = CTDB_CONTROL_CHECK_PID_SRVID;
+       request->pad = 0;
+       request->srvid = 0;
+       request->client_id = 0;
+       request->flags = 0;
+
+       request->rdata.opcode = CTDB_CONTROL_CHECK_PID_SRVID;
+       request->rdata.data.pid_srvid = pid_srvid;
+}
+
+int ctdb_reply_control_check_pid_srvid(struct ctdb_reply_control *reply,
+                                      int *status)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_CHECK_PID_SRVID) {
+               return EPROTO;
+       }
+
+       *status = reply->status;
+       reply->status = 0;
+
+       return reply->status;
+}
+
+/* CTDB_CONTROL_TUNNEL_REGISTER */
+
+void ctdb_req_control_tunnel_register(struct ctdb_req_control *request,
+                                     uint64_t tunnel_id)
+{
+       request->opcode = CTDB_CONTROL_TUNNEL_REGISTER;
+       request->pad = 0;
+       request->srvid = tunnel_id;
+       request->client_id = 0;
+       request->flags = 0;
+}
+
+int ctdb_reply_control_tunnel_register(struct ctdb_reply_control *reply)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_TUNNEL_REGISTER) {
+               return EPROTO;
+       }
+
+       return reply->status;
+}
+
+/* CTDB_CONTROL_TUNNEL_DEREGISTER */
+
+void ctdb_req_control_tunnel_deregister(struct ctdb_req_control *request,
+                                       uint64_t tunnel_id)
+{
+       request->opcode = CTDB_CONTROL_TUNNEL_DEREGISTER;
+       request->pad = 0;
+       request->srvid = tunnel_id;
+       request->client_id = 0;
+       request->flags = 0;
+}
+
+int ctdb_reply_control_tunnel_deregister(struct ctdb_reply_control *reply)
+{
+       if (reply->rdata.opcode != CTDB_CONTROL_TUNNEL_DEREGISTER) {
+               return EPROTO;
+       }
+
+       return reply->status;
+}