summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2017-04-06 19:03:51 +1000
committerMartin Schwenke <martins@samba.org>2017-10-10 11:45:18 +0200
commit9c51535775c9564d0f908ede6cefc2998fe7b2c4 (patch)
tree3e8871f6c094dccea3ec18559561a29011cf6ffd /ctdb
parenta41571a7dac87481ef022b50903b6061f1a4f788 (diff)
downloadsamba-9c51535775c9564d0f908ede6cefc2998fe7b2c4.tar.gz
ctdb-daemon: Add implementation of tunnel controls
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/include/ctdb_private.h11
-rw-r--r--ctdb/include/ctdb_protocol.h8
-rw-r--r--ctdb/server/ctdb_control.c6
-rw-r--r--ctdb/server/ctdb_daemon.c36
-rw-r--r--ctdb/server/ctdb_tunnel.c90
-rw-r--r--ctdb/wscript3
6 files changed, 153 insertions, 1 deletions
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index 227d518c0ce..3c46ef025c9 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -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,
diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h
index 52ecc456947..7b6014fdff9 100644
--- a/ctdb/include/ctdb_protocol.h
+++ b/ctdb/include/ctdb_protocol.h
@@ -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
diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c
index 9aeaa235830..b537cd1aefa 100644
--- a/ctdb/server/ctdb_control.c
+++ b/ctdb/server/ctdb_control.c
@@ -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;
diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c
index 185982e65bd..dc2fd5d9695 100644
--- a/ctdb/server/ctdb_daemon.c
+++ b/ctdb/server/ctdb_daemon.c
@@ -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
index 00000000000..0f2e001005c
--- /dev/null
+++ b/ctdb/server/ctdb_tunnel.c
@@ -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;
+}
diff --git a/ctdb/wscript b/ctdb/wscript
index 255dbdc3978..1da1b2dade8 100644
--- a/ctdb/wscript
+++ b/ctdb/wscript
@@ -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