ctdb-daemon: Add implementation of tunnel controls
authorAmitay Isaacs <amitay@gmail.com>
Thu, 6 Apr 2017 09:03:51 +0000 (19:03 +1000)
committerMartin Schwenke <martins@samba.org>
Tue, 10 Oct 2017 09:45:18 +0000 (11:45 +0200)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/include/ctdb_private.h
ctdb/include/ctdb_protocol.h
ctdb/server/ctdb_control.c
ctdb/server/ctdb_daemon.c
ctdb/server/ctdb_tunnel.c [new file with mode: 0644]
ctdb/wscript

index 227d518c0ceae853839d06f5b218f6a15e778b91..3c46ef025c99b6034209fc6d26a7decb0cac6049 100644 (file)
@@ -289,6 +289,7 @@ struct ctdb_context {
        void *private_data; /* private to transport */
        struct ctdb_db_context *db_list;
        struct srvid_context *srv;
+       struct srvid_context *tunnels;
        struct ctdb_daemon_data daemon;
        struct ctdb_statistics statistics;
        struct ctdb_statistics statistics_current;
@@ -552,6 +553,9 @@ int daemon_register_message_handler(struct ctdb_context *ctdb,
 int daemon_deregister_message_handler(struct ctdb_context *ctdb,
                                      uint32_t client_id, uint64_t srvid);
 
+void daemon_tunnel_handler(uint64_t tunnel_id, TDB_DATA data,
+                          void *private_data);
+
 int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork);
 
 struct ctdb_req_header *_ctdb_transport_allocate(struct ctdb_context *ctdb,
@@ -961,6 +965,13 @@ int32_t ctdb_control_set_tunable(struct ctdb_context *ctdb, TDB_DATA indata);
 int32_t ctdb_control_list_tunables(struct ctdb_context *ctdb,
                                   TDB_DATA *outdata);
 
+/* from ctdb_tunnel.c */
+
+int32_t ctdb_control_tunnel_register(struct ctdb_context *ctdb,
+                                    uint32_t client_id, uint64_t tunnel_id);
+int32_t ctdb_control_tunnel_deregister(struct ctdb_context *ctdb,
+                                      uint32_t client_id, uint64_t tunnel_id);
+
 /* from ctdb_update_record.c */
 
 int32_t ctdb_control_update_record(struct ctdb_context *ctdb,
index 52ecc4569474ce0480d0e92717fa37dea0f7e14d..7b6014fdff9a3f5bf9bd1ba0a3d6e5fa54c67935 100644 (file)
@@ -134,6 +134,14 @@ struct ctdb_req_keepalive_old {
        uint32_t uptime;
 };
 
+struct ctdb_req_tunnel_old {
+       struct ctdb_req_header hdr;
+       uint64_t tunnel_id;
+       uint32_t flags;
+       uint32_t datalen;
+       uint8_t data[1];
+};
+
 /*
    Structure used for a nodemap. 
    The nodemap is the structure containing a list of all nodes
index 9aeaa235830f8a2461efdd2fa1d2799c2eceb7fc..b537cd1aefa05d67afdfe9afa3aa3cd4d3a63918 100644 (file)
@@ -700,6 +700,12 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                CHECK_CONTROL_DATA_SIZE((sizeof(pid_t) + sizeof(uint64_t)));
                return ctdb_control_check_pid_srvid(ctdb, indata);
 
+       case CTDB_CONTROL_TUNNEL_REGISTER:
+               return ctdb_control_tunnel_register(ctdb, client_id, srvid);
+
+       case CTDB_CONTROL_TUNNEL_DEREGISTER:
+               return ctdb_control_tunnel_deregister(ctdb, client_id, srvid);
+
        default:
                DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
                return -1;
index 185982e65bdfdb463c4321856bd62bdabdbe2248..dc2fd5d9695c3e50c4b70029514b8eef4f172fa7 100644 (file)
@@ -209,6 +209,36 @@ int daemon_deregister_message_handler(struct ctdb_context *ctdb, uint32_t client
        return srvid_deregister(ctdb->srv, srvid, client);
 }
 
+void daemon_tunnel_handler(uint64_t tunnel_id, TDB_DATA data,
+                          void *private_data)
+{
+       struct ctdb_client *client =
+               talloc_get_type_abort(private_data, struct ctdb_client);
+       struct ctdb_req_tunnel_old *c, *pkt;
+       size_t len;
+
+       pkt = (struct ctdb_req_tunnel_old *)data.dptr;
+
+       len = offsetof(struct ctdb_req_tunnel_old, data) + pkt->datalen;
+       c = ctdbd_allocate_pkt(client->ctdb, client->ctdb, CTDB_REQ_TUNNEL,
+                              len, struct ctdb_req_tunnel_old);
+       if (c == NULL) {
+               DEBUG(DEBUG_ERR, ("Memory error in daemon_tunnel_handler\n"));
+               return;
+       }
+
+       talloc_set_name_const(c, "req_tunnel packet");
+
+       c->tunnel_id = tunnel_id;
+       c->flags = pkt->flags;
+       c->datalen = pkt->datalen;
+       memcpy(c->data, pkt->data, pkt->datalen);
+
+       daemon_queue_send(client, &c->hdr);
+
+       talloc_free(c);
+}
+
 /*
   destroy a ctdb_client
 */
@@ -1256,6 +1286,12 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork)
                exit(1);
        }
 
+       TALLOC_FREE(ctdb->tunnels);
+       if (srvid_init(ctdb, &ctdb->tunnels) != 0) {
+               DEBUG(DEBUG_ERR, ("Failed to setup tunnels context\n"));
+               exit(1);
+       }
+
        /* initialize statistics collection */
        ctdb_statistics_init(ctdb);
 
diff --git a/ctdb/server/ctdb_tunnel.c b/ctdb/server/ctdb_tunnel.c
new file mode 100644 (file)
index 0000000..0f2e001
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+   ctdb_tunnel protocol code
+
+   Copyright (C) Amitay Isaacs  2017
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+
+#include <talloc.h>
+#include <tevent.h>
+#include <tdb.h>
+
+#include "lib/util/debug.h"
+
+#include "common/logging.h"
+#include "common/reqid.h"
+#include "common/srvid.h"
+
+#include "ctdb_private.h"
+
+int32_t ctdb_control_tunnel_register(struct ctdb_context *ctdb,
+                                    uint32_t client_id, uint64_t tunnel_id)
+{
+       struct ctdb_client *client;
+       int ret;
+
+       client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
+       if (client == NULL) {
+               DEBUG(DEBUG_ERR, ("Bad client_id in ctdb_tunnel_register\n"));
+               return -1;
+       }
+
+       ret = srvid_exists(ctdb->tunnels, tunnel_id, NULL);
+       if (ret == 0) {
+               DEBUG(DEBUG_ERR,
+                     ("Tunnel id 0x%"PRIx64" already registered\n",
+                      tunnel_id));
+               return -1;
+       }
+
+       ret = srvid_register(ctdb->tunnels, client, tunnel_id,
+                            daemon_tunnel_handler, client);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,
+                     ("Failed to register tunnel id 0x%"PRIx64"\n",
+                      tunnel_id));
+               return -1;
+       }
+
+       DEBUG(DEBUG_INFO, ("Registered tunnel for id 0x%"PRIx64"\n",
+                          tunnel_id));
+       return 0;
+}
+
+int32_t ctdb_control_tunnel_deregister(struct ctdb_context *ctdb,
+                                      uint32_t client_id, uint64_t tunnel_id)
+{
+       struct ctdb_client *client;
+       int ret;
+
+       client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
+       if (client == NULL) {
+               DEBUG(DEBUG_ERR, ("Bad client_id in ctdb_tunnel_deregister\n"));
+               return -1;
+       }
+
+       ret = srvid_deregister(ctdb->tunnels, tunnel_id, client);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,
+                     ("Failed to deregister tunnel id 0x%"PRIx64"\n",
+                      tunnel_id));
+               return -1;
+       }
+
+       return 0;
+}
index 255dbdc39780d2d66bcdda67030c11b2c226479e..1da1b2dade8f96de33a99bb7d353e139811986f5 100644 (file)
@@ -462,7 +462,8 @@ def build(bld):
                                              ctdb_vacuum.c ctdb_banning.c
                                              ctdb_statistics.c
                                              ctdb_update_record.c
-                                             ctdb_lock.c ctdb_fork.c'''),
+                                             ctdb_lock.c ctdb_fork.c
+                                             ctdb_tunnel.c'''),
                      includes='include',
                      deps='''ctdb-client ctdb-common ctdb-system ctdb-protocol
                              ctdb-tcp ctdb-util replace sys_rw popt