server/ctdb_tunables.o server/ctdb_monitor.o server/ctdb_server.o \
server/ctdb_control.o server/ctdb_call.o server/ctdb_ltdb_server.o \
server/ctdb_traverse.o server/eventscript.o server/ctdb_takeover.o \
+ server/ctdb_serverids.o \
$(CTDB_CLIENT_OBJ) $(CTDB_TCP_OBJ) @INFINIBAND_WRAPPER_OBJ@
TEST_BINS=bin/ctdb_bench bin/ctdb_fetch bin/ctdb_store bin/rb_test \
return status;
}
+/*
+ register a server id
+ */
+int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
+ struct timeval timeout,
+ struct ctdb_server_id *id)
+{
+ TDB_DATA data;
+ int32_t res;
+ int ret;
+
+ data.dsize = sizeof(struct ctdb_server_id);
+ data.dptr = (unsigned char *)id;
+
+ ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
+ CTDB_CONTROL_REGISTER_SERVER_ID,
+ 0, data, NULL,
+ NULL, &res, &timeout, NULL);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_control for register server id failed\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ unregister a server id
+ */
+int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
+ struct timeval timeout,
+ struct ctdb_server_id *id)
+{
+ TDB_DATA data;
+ int32_t res;
+ int ret;
+
+ data.dsize = sizeof(struct ctdb_server_id);
+ data.dptr = (unsigned char *)id;
+
+ ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
+ CTDB_CONTROL_UNREGISTER_SERVER_ID,
+ 0, data, NULL,
+ NULL, &res, &timeout, NULL);
+ if (ret != 0 || res != 0) {
+ DEBUG(0,(__location__ " ctdb_control for unregister server id failed\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ check if a server id exists
+ */
+int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
+ struct timeval timeout,
+ uint32_t destnode,
+ struct ctdb_server_id *id,
+ uint32_t *status)
+{
+ TDB_DATA data;
+ int32_t res;
+ int ret;
+
+ data.dsize = sizeof(struct ctdb_server_id);
+ data.dptr = (unsigned char *)id;
+
+ ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
+ 0, data, NULL,
+ NULL, &res, &timeout, NULL);
+ if (ret != 0) {
+ DEBUG(0,(__location__ " ctdb_control for check server id failed\n"));
+ return -1;
+ }
+
+ if (res) {
+ *status = 1;
+ } else {
+ *status = 0;
+ }
+
+ return 0;
+}
+
+
/*
initialise the ctdb daemon for client applications
#include "popt.h"
#include "../include/ctdb.h"
#include "../include/ctdb_private.h"
+#include "../common/rb_tree.h"
/* Handle common command line options for ctdb test progs
*/
exit(1);
}
+ /* set up the tree to store server ids */
+ ctdb->server_ids = trbt_create(ctdb, 0);
+
return ctdb;
}
uint32_t destnode,
uint32_t set, uint32_t clear);
+enum ctdb_server_id_type { SERVER_TYPE_SAMBA=1 };
+
+struct ctdb_server_id {
+ enum ctdb_server_id_type type;
+ uint32_t vnn;
+ uint32_t server_id;
+};
+int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
+ struct timeval timeout,
+ struct ctdb_server_id *id);
+int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
+ struct timeval timeout,
+ struct ctdb_server_id *id);
+int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
+ struct timeval timeout, uint32_t destnode,
+ struct ctdb_server_id *id, uint32_t *status);
+
int ctdb_socket_connect(struct ctdb_context *ctdb);
#endif
bool do_setsched;
void *saved_scheduler_param;
struct ctdb_kill_tcp *killtcp;
+ struct _trbt_tree_t *server_ids;
};
struct ctdb_db_context {
CTDB_CONTROL_KILL_TCP = 54,
CTDB_CONTROL_GET_TCP_TICKLE_LIST = 55,
CTDB_CONTROL_SET_TCP_TICKLE_LIST = 56,
-};
+ CTDB_CONTROL_REGISTER_SERVER_ID = 57,
+ CTDB_CONTROL_UNREGISTER_SERVER_ID = 58,
+ CTDB_CONTROL_CHECK_SERVER_ID = 59,
+ CTDB_CONTROL_GET_SERVER_ID_LIST = 60,
+};
/*
structure passed in ctdb_control_set_rsn_nonempty
uint32_t vnn,
struct ctdb_control_tcp_tickle_list **list);
+
+int32_t ctdb_control_register_server_id(struct ctdb_context *ctdb,
+ uint32_t client_id,
+ TDB_DATA indata);
+int32_t ctdb_control_check_server_id(struct ctdb_context *ctdb,
+ TDB_DATA indata);
+int32_t ctdb_control_unregister_server_id(struct ctdb_context *ctdb,
+ TDB_DATA indata);
+
#endif
#include "lib/util/dlinklist.h"
#include "db_wrap.h"
+
struct ctdb_control_state {
struct ctdb_context *ctdb;
uint32_t reqid;
unsigned flags;
};
+
/*
process a control request
*/
/* data size is verified in the called function */
return ctdb_control_set_tcp_tickle_list(ctdb, indata);
+ case CTDB_CONTROL_REGISTER_SERVER_ID:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
+ return ctdb_control_register_server_id(ctdb, client_id, indata);
+
+ case CTDB_CONTROL_UNREGISTER_SERVER_ID:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
+ return ctdb_control_unregister_server_id(ctdb, indata);
+
+ case CTDB_CONTROL_CHECK_SERVER_ID:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
+ return ctdb_control_check_server_id(ctdb, indata);
+
default:
DEBUG(0,(__location__ " Unknown CTDB control opcode %u\n", opcode));
return -1;
--- /dev/null
+/*
+ ctdb_control protocol code to manage server ids
+
+ Copyright (C) Ronnie Sahlberg 2007
+
+ 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 "includes.h"
+#include "../include/ctdb_private.h"
+#include "../common/rb_tree.h"
+
+
+#define SERVER_ID_KEY_SIZE 3
+static uint32_t *get_server_id_key(struct ctdb_server_id *server_id)
+{
+ static uint32_t key[SERVER_ID_KEY_SIZE];
+
+ key[0] = server_id->type;
+ key[1] = server_id->vnn;
+ key[2] = server_id->server_id;
+
+ return &key[0];
+}
+
+/* add a server_id to the tree.
+ if we had already 'data' in the tree then this is a duplicate and we can
+ just talloc_free the structure in parm and leave data in the tree.
+ othervise if this is a new node we return parm and that is inserted
+ into the tree.
+*/
+static void *add_server_id_callback(void *parm, void *data)
+{
+ if (data) {
+ talloc_free(parm);
+ return data;
+ }
+ return parm;
+}
+
+/*
+ register a server id
+ a serverid that is registered with ctdb will be automatically unregistered
+ once the client domain socket dissappears.
+ */
+int32_t ctdb_control_register_server_id(struct ctdb_context *ctdb,
+ uint32_t client_id,
+ TDB_DATA indata)
+{
+ struct ctdb_server_id *server_id;
+ struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
+
+
+ if (client == NULL) {
+ DEBUG(0,(__location__ " Could not find client parent structure. You can not send this control to a remote node\n"));
+ return 1;
+ }
+
+ /* hang the server_id structure off client before storing it in the
+ tree so that is will be automatically destroyed when client
+ is destroyed.
+ when the structure is free'd it will be automatically
+ removed from the tree
+ */
+ server_id = talloc_memdup(client, indata.dptr, indata.dsize);
+ CTDB_NO_MEMORY(ctdb, server_id);
+
+ trbt_insertarray32_callback(ctdb->server_ids, SERVER_ID_KEY_SIZE,
+ get_server_id_key(server_id),
+ add_server_id_callback, server_id);
+
+ return 0;
+}
+
+
+/*
+ check whether a server id exists
+ */
+int32_t ctdb_control_check_server_id(struct ctdb_context *ctdb,
+ TDB_DATA indata)
+{
+ struct ctdb_server_id *server_id = (struct ctdb_server_id *)indata.dptr;
+
+ return (int32_t)trbt_lookuparray32(ctdb->server_ids,
+ SERVER_ID_KEY_SIZE,
+ get_server_id_key(server_id));
+}
+
+/*
+ unregisters a server id
+ */
+int32_t ctdb_control_unregister_server_id(struct ctdb_context *ctdb,
+ TDB_DATA indata)
+{
+ struct ctdb_server_id *server_id = (struct ctdb_server_id *)indata.dptr;
+
+ talloc_free(trbt_lookuparray32(ctdb->server_ids,
+ SERVER_ID_KEY_SIZE,
+ get_server_id_key(server_id)));
+ return 0;
+}
+
+
return -1;
}
+
+/*
+ register a server id
+ */
+static int regsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+ struct ctdb_server_id server_id;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ server_id.vnn = strtoul(argv[0], NULL, 0);
+ server_id.type = strtoul(argv[1], NULL, 0);
+ server_id.server_id = strtoul(argv[2], NULL, 0);
+
+ ret = ctdb_ctrl_register_server_id(ctdb, TIMELIMIT(), &server_id);
+ if (ret != 0) {
+ DEBUG(0, ("Unable to register server_id from node %u\n", options.vnn));
+ return ret;
+ }
+ return -1;
+}
+
+/*
+ unregister a server id
+ */
+static int unregsrvid(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ int ret;
+ struct ctdb_server_id server_id;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ server_id.vnn = strtoul(argv[0], NULL, 0);
+ server_id.type = strtoul(argv[1], NULL, 0);
+ server_id.server_id = strtoul(argv[2], NULL, 0);
+
+ ret = ctdb_ctrl_unregister_server_id(ctdb, TIMELIMIT(), &server_id);
+ if (ret != 0) {
+ DEBUG(0, ("Unable to unregister server_id from node %u\n", options.vnn));
+ return ret;
+ }
+ return -1;
+}
+
+/*
+ check if a server id exists
+ */
+static int chksrvid(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+ uint32_t status;
+ int ret;
+ struct ctdb_server_id server_id;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ server_id.vnn = strtoul(argv[0], NULL, 0);
+ server_id.type = strtoul(argv[1], NULL, 0);
+ server_id.server_id = strtoul(argv[2], NULL, 0);
+
+ ret = ctdb_ctrl_check_server_id(ctdb, TIMELIMIT(), options.vnn, &server_id, &status);
+ if (ret != 0) {
+ DEBUG(0, ("Unable to check server_id from node %u\n", options.vnn));
+ return ret;
+ }
+
+ if (status) {
+ printf("Server id %d:%d:%d EXISTS\n", server_id.vnn, server_id.type, server_id.server_id);
+ } else {
+ printf("Server id %d:%d:%d does NOT exist\n", server_id.vnn, server_id.type, server_id.server_id);
+ }
+ return 0;
+}
+
/*
send a tcp tickle ack
*/
{ "killtcp", kill_tcp, false, "kill a tcp connection.", "<srcip:port> <dstip:port>" },
{ "tickle", tickle_tcp, false, "send a tcp tickle ack", "<srcip:port> <dstip:port>" },
{ "gettickles", control_get_tickles, false, "get the list of tickles registered for this vnn", "<vnn>" },
+
+ { "regsrvid", regsrvid, false, "register a server id", "<vnn> <type> <id>" },
+ { "unregsrvid", unregsrvid, false, "unregister a server id", "<vnn> <type> <id>" },
+ { "chksrvid", chksrvid, false, "check if a server id exists", "<vnn> <type> <id>" },
};
/*