struct ctdb_client {
struct ctdb_context *ctdb;
int fd;
+ uint32_t id;
struct ctdb_queue *queue;
};
}
+
+/*
+ we have received a register message from hte client
+ */
+static void client_register_message(struct ctdb_client *client, struct ctdb_register_call *r)
+{
+ client->id = *((uint32_t *)r->data);
+}
+
+
/* data contains a packet from the client */
static void client_incoming_packet(struct ctdb_client *client, void *data, size_t nread)
{
case CTDB_REQ_CALL:
client_request_call(client, (struct ctdb_req_call *)hdr);
break;
-
+ case CTDB_REGISTER_CALL:
+ client_register_message(client, (struct ctdb_register_call *)hdr);
+ break;
}
talloc_free(data);
return state;
}
+int ctdb_register_message_local_id(struct ctdb_context *ctdb, uint32_t id)
+{
+ int res;
+ struct ctdb_register_call rc;
+
+ if (!(ctdb->flags&CTDB_FLAG_DAEMON_MODE)) {
+ return 0;
+ }
+
+ /* if the domain socket is not yet open, open it */
+ if (ctdb->daemon.sd==-1) {
+ ux_socket_connect(ctdb);
+ }
+
+ ZERO_STRUCT(rc);
+ rc.hdr.ctdb_magic = CTDB_MAGIC;
+ rc.hdr.ctdb_version = CTDB_VERSION;
+ rc.hdr.operation = CTDB_REGISTER_CALL;
+ rc.datalen=4;
+ *((uint32_t *)rc.data) = id;
+ rc.hdr.length = offsetof(struct ctdb_register_call, data) + rc.datalen;
+
+/*XXX need to handle the case of partial writes logic for partial writes in tcp/ctdb_tcp_node_write */
+ res = write(ctdb->daemon.sd, &rc, rc.hdr.length);
+
+ return 0;
+}
*/
int ctdb_record_store(struct ctdb_record_handle *rec, TDB_DATA data);
+/* when running in daemon mode this function is used by a client to tell
+ ctdb daemon what its local identifier is.
+ when in non-daemon mode this is a noop.
+ */
+int ctdb_register_message_local_id(struct ctdb_context *ctdb, uint32_t id);
+
#endif
operation IDs
*/
enum ctdb_operation {
- CTDB_REQ_CALL = 0,
- CTDB_REPLY_CALL = 1,
- CTDB_REPLY_REDIRECT = 2,
- CTDB_REQ_DMASTER = 3,
- CTDB_REPLY_DMASTER = 4,
- CTDB_REPLY_ERROR = 5,
- CTDB_REQ_MESSAGE = 6
+ CTDB_REQ_CALL = 0,
+ CTDB_REPLY_CALL = 1,
+ CTDB_REPLY_REDIRECT = 2,
+ CTDB_REQ_DMASTER = 3,
+ CTDB_REPLY_DMASTER = 4,
+ CTDB_REPLY_ERROR = 5,
+ CTDB_REGISTER_CALL = 6,
+ CTDB_REQ_MESSAGE = 7
};
#define CTDB_MAGIC 0x43544442 /* CTDB */
uint8_t data[1];
};
+struct ctdb_register_call {
+ struct ctdb_req_header hdr;
+ uint32_t datalen;
+ uint8_t data[4];
+};
+
struct ctdb_req_message {
struct ctdb_req_header hdr;
uint32_t srvid;
killall -q ctdb_bench
echo "Trying 2 nodes"
-bin/ctdb_bench --nlist tests/nodes.txt --listen 127.0.0.2:9001 $* &
-bin/ctdb_bench --nlist tests/nodes.txt --listen 127.0.0.1:9001 $*
+bin/ctdb_bench --nlist tests/nodes.txt --listen 127.0.0.2:9001 --pid=55 $* &
+bin/ctdb_bench --nlist tests/nodes.txt --listen 127.0.0.1:9001 --pid=66 $*
killall -q ctdb_bench
const char *myaddress = NULL;
int self_connect=0;
int daemon_mode=0;
+ int pid;
struct poptOption popt_options[] = {
POPT_AUTOHELP
{ "timelimit", 't', POPT_ARG_INT, &timelimit, 0, "timelimit", "integer" },
{ "num-records", 'r', POPT_ARG_INT, &num_records, 0, "num_records", "integer" },
{ "num-msgs", 'n', POPT_ARG_INT, &num_msgs, 0, "num_msgs", "integer" },
+ { "pid", 0, POPT_ARG_INT, &pid, 0, "pid", "integer" },
POPT_TABLEEND
};
int opt;
/* start the protocol running */
ret = ctdb_start(ctdb);
+ /* register our 'pid' so that ctdb knows who we are */
+ if (!pid) {
+ pid = getpid();
+ printf("no pid specified, using real pid:%d\n",pid);
+ }
+ ctdb_register_message_local_id(ctdb, pid);
+
/* wait until all nodes are connected (should not be needed
outside of test code) */
ctdb_connect_wait(ctdb);