From 13b72d8630ab5eaca531a4904f2de7fdfafaf5ae Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 13:27:12 +1000 Subject: [PATCH 01/16] ctdb-common: Extend srvid_exists() check to support optional private_data BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit e675f346805de1754a6b18cf0dfbc71df9c7a05d) --- ctdb/common/srvid.c | 13 ++++++++++++- ctdb/common/srvid.h | 8 +++++++- ctdb/server/ctdb_daemon.c | 2 +- ctdb/tests/src/srvid_test.c | 12 ++++++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ctdb/common/srvid.c b/ctdb/common/srvid.c index f9cd49b4ea3..33049941e69 100644 --- a/ctdb/common/srvid.c +++ b/ctdb/common/srvid.c @@ -221,9 +221,10 @@ int srvid_deregister(struct srvid_context *srv, uint64_t srvid, /* * Check if a message handler exists */ -int srvid_exists(struct srvid_context *srv, uint64_t srvid) +int srvid_exists(struct srvid_context *srv, uint64_t srvid, void *private_data) { struct srvid_handler_list *list; + struct srvid_handler *h; int ret; ret = srvid_fetch(srv, srvid, &list); @@ -234,6 +235,16 @@ int srvid_exists(struct srvid_context *srv, uint64_t srvid) return ENOENT; } + if (private_data != NULL) { + for (h = list->h; h != NULL; h = h->next) { + if (h->private_data == private_data) { + return 0; + } + } + + return ENOENT; + } + return 0; } diff --git a/ctdb/common/srvid.h b/ctdb/common/srvid.h index f048b5c6cbf..702724ff93a 100644 --- a/ctdb/common/srvid.h +++ b/ctdb/common/srvid.h @@ -91,11 +91,17 @@ int srvid_deregister(struct srvid_context *srv, uint64_t srvid, /** * @brief Check if any message handler is registered for srvid * + * If private_data is NULL, then check if there is any registration + * for * specified srvid. If private_data is not NULL, then check for + * registration that matches the specified private data. + * * @param[in] srv The srvid message handler database context * @param[in] srvid The srvid + * @param[in] private_data Private data * @return 0 on success, errno on failure */ -int srvid_exists(struct srvid_context *srv, uint64_t srvid); +int srvid_exists(struct srvid_context *srv, uint64_t srvid, + void *private_data); /** * @brief Call message handlers for given srvid diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c index 90f0e546831..8e9c1c649cd 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -230,7 +230,7 @@ int daemon_check_srvids(struct ctdb_context *ctdb, TDB_DATA indata, return -1; } for (i=0; isrv, ids[i]) == 0) { + if (srvid_exists(ctdb->srv, ids[i], NULL) == 0) { results[i/8] |= (1 << (i%8)); } } diff --git a/ctdb/tests/src/srvid_test.c b/ctdb/tests/src/srvid_test.c index b979c19c2f5..2367c6c7691 100644 --- a/ctdb/tests/src/srvid_test.c +++ b/ctdb/tests/src/srvid_test.c @@ -52,7 +52,10 @@ int main(void) ret = srvid_register(srv, tmp_ctx, TEST_SRVID, test_handler, &count); assert(ret == 0); - ret = srvid_exists(srv, TEST_SRVID); + ret = srvid_exists(srv, TEST_SRVID, NULL); + assert(ret == 0); + + ret = srvid_exists(srv, TEST_SRVID, &count); assert(ret == 0); ret = srvid_dispatch(srv, TEST_SRVID, 0, tdb_null); @@ -73,7 +76,7 @@ int main(void) assert(ret == 0); talloc_free(tmp_ctx); - ret = srvid_exists(srv, TEST_SRVID); + ret = srvid_exists(srv, TEST_SRVID, NULL); assert(ret == ENOENT); ret = srvid_dispatch(srv, TEST_SRVID, 0, tdb_null); @@ -84,8 +87,13 @@ int main(void) ret = srvid_register(srv, tmp_ctx, TEST_SRVID, test_handler, NULL); assert(ret == 0); + ret = srvid_exists(srv, TEST_SRVID, &count); + assert(ret == ENOENT); + ret = srvid_register(srv, tmp_ctx, TEST_SRVID, test_handler, &count); assert(ret == 0); + ret = srvid_exists(srv, TEST_SRVID, &count); + assert(ret == 0); talloc_free(srv); assert(talloc_get_size(mem_ctx) == 0); -- 2.13.5 From 94beabdec90a55c455868093937a8dbb311720b2 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 15:10:56 +1000 Subject: [PATCH 02/16] ctdb-protocol: Add new control CTDB_CONTROL_CHECK_PID_SRVID BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit e5b133a127ff2a34689e679397bdd211fa2aada6) --- ctdb/protocol/protocol.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ctdb/protocol/protocol.h b/ctdb/protocol/protocol.h index ee409f7ec55..e116b3a98b8 100644 --- a/ctdb/protocol/protocol.h +++ b/ctdb/protocol/protocol.h @@ -369,6 +369,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0, CTDB_CONTROL_DB_PUSH_CONFIRM = 148, CTDB_CONTROL_DB_OPEN_FLAGS = 149, CTDB_CONTROL_DB_ATTACH_REPLICATED = 150, + CTDB_CONTROL_CHECK_PID_SRVID = 151, }; #define CTDB_MONITORING_ENABLED 0 @@ -842,6 +843,11 @@ enum ctdb_runstate { CTDB_RUNSTATE_SHUTDOWN, }; +struct ctdb_pid_srvid { + pid_t pid; + uint64_t srvid; +}; + struct ctdb_req_control_data { uint32_t opcode; union { @@ -879,6 +885,7 @@ struct ctdb_req_control_data { struct ctdb_uint64_array *u64_array; struct ctdb_traverse_start_ext *traverse_start_ext; struct ctdb_traverse_all_ext *traverse_all_ext; + struct ctdb_pid_srvid *pid_srvid; } data; }; -- 2.13.5 From c67e6ce39a8dc9cc94f892e302cf4d5f399eacff Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 15:13:12 +1000 Subject: [PATCH 03/16] ctdb-protocol: Add marshalling for struct ctdb_pid_srvid BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit 5d12006e29a898c503a885115069fe26f2e084bc) --- ctdb/protocol/protocol_private.h | 5 ++++ ctdb/protocol/protocol_types.c | 47 ++++++++++++++++++++++++++++++++++++ ctdb/tests/src/protocol_types_test.c | 15 ++++++++++++ 3 files changed, 67 insertions(+) diff --git a/ctdb/protocol/protocol_private.h b/ctdb/protocol/protocol_private.h index f887ce5e093..ecbd627c33b 100644 --- a/ctdb/protocol/protocol_private.h +++ b/ctdb/protocol/protocol_private.h @@ -240,6 +240,11 @@ void ctdb_db_statistics_push(struct ctdb_db_statistics *dbstats, void *buf); int ctdb_db_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, struct ctdb_db_statistics **out); +size_t ctdb_pid_srvid_len(struct ctdb_pid_srvid *in); +void ctdb_pid_srvid_push(struct ctdb_pid_srvid *in, uint8_t *buf); +int ctdb_pid_srvid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, + struct ctdb_pid_srvid **out); + size_t ctdb_election_message_len(struct ctdb_election_message *election); void ctdb_election_message_push(struct ctdb_election_message *election, uint8_t *buf); diff --git a/ctdb/protocol/protocol_types.c b/ctdb/protocol/protocol_types.c index 4115e381c0b..2fbfcdc81be 100644 --- a/ctdb/protocol/protocol_types.c +++ b/ctdb/protocol/protocol_types.c @@ -2394,6 +2394,53 @@ int ctdb_db_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, return 0; } +size_t ctdb_pid_srvid_len(struct ctdb_pid_srvid *in) +{ + return ctdb_pid_len(in->pid) + + ctdb_uint64_len(in->srvid); +} + +void ctdb_pid_srvid_push(struct ctdb_pid_srvid *in, uint8_t *buf) +{ + size_t offset = 0; + + ctdb_pid_push(in->pid, buf+offset); + offset += ctdb_pid_len(in->pid); + + ctdb_uint64_push(in->srvid, buf+offset); +} + +int ctdb_pid_srvid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, + struct ctdb_pid_srvid **out) +{ + struct ctdb_pid_srvid *val; + size_t offset = 0; + int ret; + + val = talloc(mem_ctx, struct ctdb_pid_srvid); + if (val == NULL) { + return ENOMEM; + } + + ret = ctdb_pid_pull(buf+offset, buflen-offset, val, &val->pid); + if (ret != 0) { + goto fail; + } + offset += ctdb_pid_len(val->pid); + + ret = ctdb_uint64_pull(buf+offset, buflen-offset, val, &val->srvid); + if (ret != 0) { + goto fail; + } + + *out = val; + return 0; + +fail: + talloc_free(val); + return ret; +} + size_t ctdb_election_message_len(struct ctdb_election_message *election) { return sizeof(struct ctdb_election_message); diff --git a/ctdb/tests/src/protocol_types_test.c b/ctdb/tests/src/protocol_types_test.c index 94108ead04c..46976d46a35 100644 --- a/ctdb/tests/src/protocol_types_test.c +++ b/ctdb/tests/src/protocol_types_test.c @@ -1018,6 +1018,19 @@ static void verify_ctdb_event_reply_script_list( #ifndef PROTOCOL_TEST +static void fill_ctdb_pid_srvid(TALLOC_CTX *mem_ctx, struct ctdb_pid_srvid *p) +{ + p->pid = rand32(); + p->srvid = rand64(); +} + +static void verify_ctdb_pid_srvid(struct ctdb_pid_srvid *p1, + struct ctdb_pid_srvid *p2) +{ + assert(p1->pid == p2->pid); + assert(p1->srvid == p2->srvid); +} + static void fill_ctdb_election_message(TALLOC_CTX *mem_ctx, struct ctdb_election_message *p) { @@ -1322,6 +1335,7 @@ DEFINE_TEST(struct ctdb_key_data, ctdb_key_data); DEFINE_TEST(struct ctdb_uint8_array, ctdb_uint8_array); DEFINE_TEST(struct ctdb_uint64_array, ctdb_uint64_array); DEFINE_TEST(struct ctdb_db_statistics, ctdb_db_statistics); +DEFINE_TEST(struct ctdb_pid_srvid, ctdb_pid_srvid); DEFINE_TEST(struct ctdb_election_message, ctdb_election_message); DEFINE_TEST(struct ctdb_srvid_message, ctdb_srvid_message); DEFINE_TEST(struct ctdb_disable_message, ctdb_disable_message); @@ -1438,6 +1452,7 @@ int main(int argc, char *argv[]) TEST_FUNC(ctdb_uint8_array)(); TEST_FUNC(ctdb_uint64_array)(); TEST_FUNC(ctdb_db_statistics)(); + TEST_FUNC(ctdb_pid_srvid)(); TEST_FUNC(ctdb_election_message)(); TEST_FUNC(ctdb_srvid_message)(); TEST_FUNC(ctdb_disable_message)(); -- 2.13.5 From 5292ca6ed8a01ddc78839ddb547531863ed0ab71 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 15:13:53 +1000 Subject: [PATCH 04/16] ctdb-protocol: Add marshalling for control CHECK_PID_SRVID BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit 7115378f7534f79043ab1b5d2b8fb265145537aa) --- ctdb/protocol/protocol_api.h | 5 +++++ ctdb/protocol/protocol_client.c | 28 ++++++++++++++++++++++++++++ ctdb/protocol/protocol_control.c | 22 ++++++++++++++++++++++ ctdb/protocol/protocol_debug.c | 1 + ctdb/tests/cunit/protocol_test_002.sh | 2 +- ctdb/tests/src/protocol_client_test.c | 15 ++++++++++++++- ctdb/tests/src/protocol_types_test.c | 26 +++++++++++++------------- 7 files changed, 84 insertions(+), 15 deletions(-) diff --git a/ctdb/protocol/protocol_api.h b/ctdb/protocol/protocol_api.h index a8875446a7c..59615270001 100644 --- a/ctdb/protocol/protocol_api.h +++ b/ctdb/protocol/protocol_api.h @@ -606,6 +606,11 @@ void ctdb_req_control_db_attach_replicated(struct ctdb_req_control *request, int ctdb_reply_control_db_attach_replicated(struct ctdb_reply_control *reply, uint32_t *db_id); +void ctdb_req_control_check_pid_srvid(struct ctdb_req_control *request, + struct ctdb_pid_srvid *pid_srvid); +int ctdb_reply_control_check_pid_srvid(struct ctdb_reply_control *reply, + int *status); + /* From protocol/protocol_debug.c */ void ctdb_packet_print(uint8_t *buf, size_t buflen, FILE *fp); diff --git a/ctdb/protocol/protocol_client.c b/ctdb/protocol/protocol_client.c index daa70cc513b..70bf1f5b03d 100644 --- a/ctdb/protocol/protocol_client.c +++ b/ctdb/protocol/protocol_client.c @@ -2386,3 +2386,31 @@ int ctdb_reply_control_db_attach_replicated(struct ctdb_reply_control *reply, } 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; +} diff --git a/ctdb/protocol/protocol_control.c b/ctdb/protocol/protocol_control.c index 3c5c7ce93cf..a98c8eac3de 100644 --- a/ctdb/protocol/protocol_control.c +++ b/ctdb/protocol/protocol_control.c @@ -434,6 +434,10 @@ static size_t ctdb_req_control_data_len(struct ctdb_req_control_data *cd) case CTDB_CONTROL_DB_ATTACH_REPLICATED: len = ctdb_string_len(cd->data.db_name); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + len = ctdb_pid_srvid_len(cd->data.pid_srvid); + break; } return len; @@ -705,6 +709,10 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd, case CTDB_CONTROL_DB_ATTACH_REPLICATED: ctdb_string_push(cd->data.db_name, buf); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + ctdb_pid_srvid_push(cd->data.pid_srvid, buf); + break; } } @@ -1045,6 +1053,11 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen, ret = ctdb_string_pull(buf, buflen, mem_ctx, &cd->data.db_name); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + ret = ctdb_pid_srvid_pull(buf, buflen, mem_ctx, + &cd->data.pid_srvid); + break; } return ret; @@ -1414,6 +1427,9 @@ static size_t ctdb_reply_control_data_len(struct ctdb_reply_control_data *cd) case CTDB_CONTROL_DB_ATTACH_REPLICATED: len = ctdb_uint32_len(cd->data.db_id); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + break; } return len; @@ -1574,6 +1590,9 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd, case CTDB_CONTROL_DB_ATTACH_REPLICATED: ctdb_uint32_push(cd->data.db_id, buf); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + break; } } @@ -1771,6 +1790,9 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen, ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &cd->data.db_id); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + break; } return ret; diff --git a/ctdb/protocol/protocol_debug.c b/ctdb/protocol/protocol_debug.c index 574f903b2c0..7c6d862a500 100644 --- a/ctdb/protocol/protocol_debug.c +++ b/ctdb/protocol/protocol_debug.c @@ -239,6 +239,7 @@ static void ctdb_opcode_print(uint32_t opcode, FILE *fp) { CTDB_CONTROL_DB_PUSH_CONFIRM, "DB_PUSH_CONFIRM" }, { CTDB_CONTROL_DB_OPEN_FLAGS, "DB_OPEN_FLAGS" }, { CTDB_CONTROL_DB_ATTACH_REPLICATED, "DB_ATTACH_REPLICATED" }, + { CTDB_CONTROL_CHECK_PID_SRVID, "CHECK_PID_SRVID" }, { MAP_END, "" }, }; diff --git a/ctdb/tests/cunit/protocol_test_002.sh b/ctdb/tests/cunit/protocol_test_002.sh index ac0eeefa9df..c94ea5d6178 100755 --- a/ctdb/tests/cunit/protocol_test_002.sh +++ b/ctdb/tests/cunit/protocol_test_002.sh @@ -2,7 +2,7 @@ . "${TEST_SCRIPTS_DIR}/unit.sh" -last_control=150 +last_control=151 control_output=$( for i in $(seq 0 $last_control) ; do diff --git a/ctdb/tests/src/protocol_client_test.c b/ctdb/tests/src/protocol_client_test.c index e34879fd601..0cbed8dbe93 100644 --- a/ctdb/tests/src/protocol_client_test.c +++ b/ctdb/tests/src/protocol_client_test.c @@ -600,6 +600,12 @@ static void fill_ctdb_req_control_data(TALLOC_CTX *mem_ctx, fill_ctdb_string(mem_ctx, &cd->data.db_name); assert(cd->data.db_name != NULL); break; + + case CTDB_CONTROL_CHECK_PID_SRVID: + cd->data.pid_srvid = talloc(mem_ctx, struct ctdb_pid_srvid); + assert(cd->data.pid_srvid != NULL); + fill_ctdb_pid_srvid(mem_ctx, cd->data.pid_srvid); + break; } } @@ -1004,6 +1010,9 @@ static void verify_ctdb_req_control_data(struct ctdb_req_control_data *cd, verify_ctdb_string(cd->data.db_name, cd2->data.db_name); break; + case CTDB_CONTROL_CHECK_PID_SRVID: + verify_ctdb_pid_srvid(cd->data.pid_srvid, cd2->data.pid_srvid); + break; } } @@ -1420,6 +1429,8 @@ static void fill_ctdb_reply_control_data(TALLOC_CTX *mem_ctx, cd->data.db_id = rand32(); break; + case CTDB_CONTROL_CHECK_PID_SRVID: + break; } } @@ -1766,6 +1777,8 @@ static void verify_ctdb_reply_control_data(struct ctdb_reply_control_data *cd, assert(cd->data.db_id == cd2->data.db_id); break; + case CTDB_CONTROL_CHECK_PID_SRVID: + break; } } @@ -2208,7 +2221,7 @@ static void test_ctdb_reply_dmaster(void) talloc_free(mem_ctx); } -#define NUM_CONTROLS 151 +#define NUM_CONTROLS 152 static void test_ctdb_req_control_data(void) { diff --git a/ctdb/tests/src/protocol_types_test.c b/ctdb/tests/src/protocol_types_test.c index 46976d46a35..7c95a3abfa6 100644 --- a/ctdb/tests/src/protocol_types_test.c +++ b/ctdb/tests/src/protocol_types_test.c @@ -915,6 +915,19 @@ static void verify_ctdb_db_statistics(struct ctdb_db_statistics *p1, } } +static void fill_ctdb_pid_srvid(TALLOC_CTX *mem_ctx, struct ctdb_pid_srvid *p) +{ + p->pid = rand32(); + p->srvid = rand64(); +} + +static void verify_ctdb_pid_srvid(struct ctdb_pid_srvid *p1, + struct ctdb_pid_srvid *p2) +{ + assert(p1->pid == p2->pid); + assert(p1->srvid == p2->srvid); +} + static void fill_ctdb_event_request_run(TALLOC_CTX *mem_ctx, struct ctdb_event_request_run *p) { @@ -1018,19 +1031,6 @@ static void verify_ctdb_event_reply_script_list( #ifndef PROTOCOL_TEST -static void fill_ctdb_pid_srvid(TALLOC_CTX *mem_ctx, struct ctdb_pid_srvid *p) -{ - p->pid = rand32(); - p->srvid = rand64(); -} - -static void verify_ctdb_pid_srvid(struct ctdb_pid_srvid *p1, - struct ctdb_pid_srvid *p2) -{ - assert(p1->pid == p2->pid); - assert(p1->srvid == p2->srvid); -} - static void fill_ctdb_election_message(TALLOC_CTX *mem_ctx, struct ctdb_election_message *p) { -- 2.13.5 From 29fb01ab2c3844c7481f0279f21626faaee56ab0 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 16:18:02 +1000 Subject: [PATCH 05/16] ctdb-daemon: Add implementation of control CHECK_PID_SRVID BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit 02ae3d9fab6cdaaa1a2999a57a37ecc281f7f608) --- ctdb/include/ctdb_private.h | 2 ++ ctdb/server/ctdb_control.c | 4 ++++ ctdb/server/ctdb_daemon.c | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 043149eedd9..da3760da7b2 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -584,6 +584,8 @@ struct ctdb_client *ctdb_find_client_by_pid(struct ctdb_context *ctdb, pid_t pid); int32_t ctdb_control_process_exists(struct ctdb_context *ctdb, pid_t pid); +int32_t ctdb_control_check_pid_srvid(struct ctdb_context *ctdb, + TDB_DATA indata); int ctdb_control_getnodesfile(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata); diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c index 40484434b4a..6835ccaf063 100644 --- a/ctdb/server/ctdb_control.c +++ b/ctdb/server/ctdb_control.c @@ -701,6 +701,10 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, return 0; } + case CTDB_CONTROL_CHECK_PID_SRVID: + CHECK_CONTROL_DATA_SIZE((sizeof(pid_t) + sizeof(uint64_t))); + return ctdb_control_check_pid_srvid(ctdb, indata); + 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 8e9c1c649cd..a81f8c2d7a2 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -1813,6 +1813,30 @@ int32_t ctdb_control_process_exists(struct ctdb_context *ctdb, pid_t pid) return kill(pid, 0); } +int32_t ctdb_control_check_pid_srvid(struct ctdb_context *ctdb, + TDB_DATA indata) +{ + struct ctdb_client *client; + pid_t pid; + uint64_t srvid; + int ret; + + pid = *(pid_t *)indata.dptr; + srvid = *(uint64_t *)(indata.dptr + sizeof(pid_t)); + + client = ctdb_find_client_by_pid(ctdb, pid); + if (client == NULL) { + return -1; + } + + ret = srvid_exists(ctdb->srv, srvid, client); + if (ret != 0) { + return -1; + } + + return 0; +} + int ctdb_control_getnodesfile(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata) { struct ctdb_node_map_old *node_map = NULL; -- 2.13.5 From 8ed056923b0a6fdb6468009ed5b2e870283000d9 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Thu, 21 Sep 2017 15:52:14 +1000 Subject: [PATCH 06/16] ctdb-client: Add client code for control CHECK_PID_SRVID BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit c6a35200f45b04e2e6f867743213f2d95eabef4f) --- ctdb/client/client_control_sync.c | 29 +++++++++++++++++++++++++++++ ctdb/client/client_sync.h | 5 +++++ 2 files changed, 34 insertions(+) diff --git a/ctdb/client/client_control_sync.c b/ctdb/client/client_control_sync.c index 43a941d79db..6b64c75458c 100644 --- a/ctdb/client/client_control_sync.c +++ b/ctdb/client/client_control_sync.c @@ -2758,3 +2758,32 @@ int ctdb_ctrl_db_attach_replicated(TALLOC_CTX *mem_ctx, return 0; } + +int ctdb_ctrl_check_pid_srvid(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct ctdb_client_context *client, + int destnode, struct timeval timeout, + struct ctdb_pid_srvid *pid_srvid, int *status) +{ + struct ctdb_req_control request; + struct ctdb_reply_control *reply; + int ret; + + ctdb_req_control_check_pid_srvid(&request, pid_srvid); + ret = ctdb_client_control(mem_ctx, ev, client, destnode, timeout, + &request, &reply); + if (ret != 0) { + DEBUG(DEBUG_ERR, + ("Control CHECK_PID_SRVID failed to node %u, ret=%d\n", + destnode, ret)); + return ret; + } + + ret = ctdb_reply_control_check_pid_srvid(reply, status); + if (ret != 0) { + DEBUG(DEBUG_ERR, + ("Control CHECK_PID_SRVID failed, ret=%d\n", ret)); + return ret; + } + + return 0; +} diff --git a/ctdb/client/client_sync.h b/ctdb/client/client_sync.h index a4b5c49ab0b..c0a7b2589b6 100644 --- a/ctdb/client/client_sync.h +++ b/ctdb/client/client_sync.h @@ -494,6 +494,11 @@ int ctdb_ctrl_db_attach_replicated(TALLOC_CTX *mem_ctx, int destnode, struct timeval timeout, const char *db_name, uint32_t *db_id); +int ctdb_ctrl_check_pid_srvid(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct ctdb_client_context *client, + int destnode, struct timeval timeout, + struct ctdb_pid_srvid *pid_srvid, int *status); + /* from client/client_message_sync.c */ int ctdb_message_recd_update_ip(TALLOC_CTX *mem_ctx, struct tevent_context *ev, -- 2.13.5 From b67a3462389dc476c04a054593c3d2a4d63ef583 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 16:29:01 +1000 Subject: [PATCH 07/16] ctdb-tool: Update process-exists command to pass optional srvid BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit 1c472dffd4d412806c2cb7202a8a5f37aac53b0f) --- ctdb/doc/ctdb.1.xml | 8 ++++++-- ctdb/tools/ctdb.c | 32 ++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/ctdb/doc/ctdb.1.xml b/ctdb/doc/ctdb.1.xml index 3aceb7369ac..471d8255bce 100644 --- a/ctdb/doc/ctdb.1.xml +++ b/ctdb/doc/ctdb.1.xml @@ -1681,9 +1681,13 @@ RUNNING - process-exists <parameter>PID</parameter> + process-exists <parameter>PID</parameter> <parameter>[SRVID]</parameter> - This command checks if a specific process exists on the CTDB host. This is mainly used by Samba to check if remote instances of samba are still running or not. + This command checks if a specific process exists on the CTDB + host. This is mainly used by Samba to check if remote instances + of samba are still running or not. When the optional SRVID + argument is specified, the command check if a specific process + exists on the CTDB host and has registered for specified SRVID. diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index 98f63e8b2a0..944f37033d8 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -1864,23 +1864,43 @@ static int control_process_exists(TALLOC_CTX *mem_ctx, int argc, const char **argv) { pid_t pid; + uint64_t srvid = 0; int ret, status; - if (argc != 1) { + if (argc != 1 && argc != 2) { usage("process-exists"); } pid = atoi(argv[0]); - ret = ctdb_ctrl_process_exists(mem_ctx, ctdb->ev, ctdb->client, + if (argc == 2) { + srvid = strtoull(argv[1], NULL, 0); + } + + if (srvid == 0) { + ret = ctdb_ctrl_process_exists(mem_ctx, ctdb->ev, ctdb->client, ctdb->cmd_pnn, TIMEOUT(), pid, &status); + } else { + struct ctdb_pid_srvid pid_srvid; + + pid_srvid.pid = pid; + pid_srvid.srvid = srvid; + + ret = ctdb_ctrl_check_pid_srvid(mem_ctx, ctdb->ev, + ctdb->client, ctdb->cmd_pnn, + TIMEOUT(), &pid_srvid, + &status); + } + if (ret != 0) { return ret; } - if (status == 0) { - printf("PID %u exists\n", pid); + if (srvid == 0) { + printf("PID %d %s\n", pid, + (status == 0 ? "exists" : "does not exist")); } else { - printf("PID %u does not exist\n", pid); + printf("PID %d with SRVID 0x%"PRIx64" %s\n", pid, srvid, + (status == 0 ? "exists" : "does not exist")); } return status; } @@ -6000,7 +6020,7 @@ static const struct ctdb_cmd { { "setifacelink", control_setifacelink, false, true, "set interface link status", " up|down" }, { "process-exists", control_process_exists, false, true, - "check if a process exists on a node", "" }, + "check if a process exists on a node", " []" }, { "getdbmap", control_getdbmap, false, true, "show attached databases", NULL }, { "getdbstatus", control_getdbstatus, false, true, -- 2.13.5 From 925f0bff5b956cd6d4abe2f07f7cb801747ff5a6 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 16:59:16 +1000 Subject: [PATCH 08/16] ctdb-tests: Reimplement message handlers using srvid abstraction BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 This is required for CHECK_PID_SRVID control implementation. Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit c480cc0152f3afc8ea81e2bc72c31deed1e0ca71) --- ctdb/tests/src/fake_ctdbd.c | 50 +++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/ctdb/tests/src/fake_ctdbd.c b/ctdb/tests/src/fake_ctdbd.c index c79c28da0a2..a9dadc2d8a1 100644 --- a/ctdb/tests/src/fake_ctdbd.c +++ b/ctdb/tests/src/fake_ctdbd.c @@ -39,6 +39,7 @@ #include "common/system.h" #include "common/logging.h" #include "common/tunable.h" +#include "common/srvid.h" #include "ipalloc_read_known_ips.h" @@ -94,12 +95,6 @@ struct database_map { struct database *db; }; -struct srvid_register_state { - struct srvid_register_state *prev, *next; - struct ctdbd_context *ctdb; - uint64_t srvid; -}; - struct fake_control_failure { struct fake_control_failure *prev, *next; enum ctdb_controls opcode; @@ -120,7 +115,7 @@ struct ctdbd_context { struct interface_map *iface_map; struct vnn_map *vnn_map; struct database_map *db_map; - struct srvid_register_state *rstate; + struct srvid_context *srv; int num_clients; struct timeval start_time; struct timeval recovery_start_time; @@ -898,6 +893,7 @@ static struct ctdbd_context *ctdbd_setup(TALLOC_CTX *mem_ctx) struct ctdbd_context *ctdb; char line[1024]; bool status; + int ret; ctdb = talloc_zero(mem_ctx, struct ctdbd_context); if (ctdb == NULL) { @@ -924,6 +920,11 @@ static struct ctdbd_context *ctdbd_setup(TALLOC_CTX *mem_ctx) goto fail; } + ret = srvid_init(ctdb, &ctdb->srv); + if (ret != 0) { + goto fail; + } + while (fgets(line, sizeof(line), stdin) != NULL) { char *t; @@ -1592,10 +1593,9 @@ fail: } -static int srvid_register_state_destructor(struct srvid_register_state *rstate) +static void srvid_handler(uint64_t srvid, TDB_DATA data, void *private_data) { - DLIST_REMOVE(rstate->ctdb->rstate, rstate); - return 0; + printf("Received a message for SRVID 0x%"PRIx64"\n", srvid); } static void control_register_srvid(TALLOC_CTX *mem_ctx, @@ -1607,24 +1607,19 @@ static void control_register_srvid(TALLOC_CTX *mem_ctx, req, struct client_state); struct ctdbd_context *ctdb = state->ctdb; struct ctdb_reply_control reply; - struct srvid_register_state *rstate; + int ret; reply.rdata.opcode = request->opcode; - rstate = talloc_zero(ctdb, struct srvid_register_state); - if (rstate == NULL) { + ret = srvid_register(ctdb->srv, state, request->srvid, + srvid_handler, state); + if (ret != 0) { reply.status = -1; reply.errmsg = "Memory error"; goto fail; } - rstate->ctdb = ctdb; - rstate->srvid = request->srvid; - talloc_set_destructor(rstate, srvid_register_state_destructor); - - DLIST_ADD_END(ctdb->rstate, rstate); - - DEBUG(DEBUG_INFO, ("Register srvid 0x%"PRIx64"\n", rstate->srvid)); + DEBUG(DEBUG_INFO, ("Register srvid 0x%"PRIx64"\n", request->srvid)); reply.status = 0; reply.errmsg = NULL; @@ -1642,24 +1637,18 @@ static void control_deregister_srvid(TALLOC_CTX *mem_ctx, req, struct client_state); struct ctdbd_context *ctdb = state->ctdb; struct ctdb_reply_control reply; - struct srvid_register_state *rstate = NULL; + int ret; reply.rdata.opcode = request->opcode; - for (rstate = ctdb->rstate; rstate != NULL; rstate = rstate->next) { - if (rstate->srvid == request->srvid) { - break; - } - } - - if (rstate == NULL) { + ret = srvid_deregister(ctdb->srv, request->srvid, state); + if (ret != 0) { reply.status = -1; reply.errmsg = "srvid not registered"; goto fail; } - DEBUG(DEBUG_INFO, ("Deregister srvid 0x%"PRIx64"\n", rstate->srvid)); - talloc_free(rstate); + DEBUG(DEBUG_INFO, ("Deregister srvid 0x%"PRIx64"\n", request->srvid)); reply.status = 0; reply.errmsg = NULL; @@ -1668,7 +1657,6 @@ static void control_deregister_srvid(TALLOC_CTX *mem_ctx, return; fail: - TALLOC_FREE(rstate); client_send_control(req, header, &reply); } -- 2.13.5 From 1364751c5d7eef34dd30cfcd0273b4b6b817d07c Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 17:04:44 +1000 Subject: [PATCH 09/16] ctdb-tests: Implement control CHECK_PID_SRVID in fake daemon BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit 7d034fe1399ecb7305c91e16e114a63c67f5a983) --- ctdb/tests/src/fake_ctdbd.c | 47 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/ctdb/tests/src/fake_ctdbd.c b/ctdb/tests/src/fake_ctdbd.c index a9dadc2d8a1..850a5920a1a 100644 --- a/ctdb/tests/src/fake_ctdbd.c +++ b/ctdb/tests/src/fake_ctdbd.c @@ -1653,9 +1653,6 @@ static void control_deregister_srvid(TALLOC_CTX *mem_ctx, reply.status = 0; reply.errmsg = NULL; - client_send_control(req, header, &reply); - return; - fail: client_send_control(req, header, &reply); } @@ -2842,6 +2839,46 @@ fail: client_send_control(req, header, &reply); } +static void control_check_pid_srvid(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct ctdb_req_header *header, + struct ctdb_req_control *request) +{ + struct client_state *state = tevent_req_data( + req, struct client_state); + struct ctdbd_context *ctdb = state->ctdb; + struct client_state *cstate; + struct ctdb_reply_control reply; + int ret; + + reply.rdata.opcode = request->opcode; + + cstate = client_find(ctdb, request->rdata.data.pid_srvid->pid); + if (cstate == NULL) { + reply.status = -1; + reply.errmsg = "No client for PID"; + } else { + ret = srvid_exists(ctdb->srv, + request->rdata.data.pid_srvid->srvid, + cstate); + if (ret != 0) { + reply.status = -1; + reply.errmsg = "No client for PID and SRVID"; + } else { + ret = kill(cstate->pid, 0); + if (ret != 0) { + reply.status = ret; + reply.errmsg = strerror(errno); + } else { + reply.status = 0; + reply.errmsg = NULL; + } + } + } + + client_send_control(req, header, &reply); +} + static bool fake_control_failure(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ctdb_req_header *header, @@ -3441,6 +3478,10 @@ static void client_process_control(struct tevent_req *req, control_get_nodes_file(mem_ctx, req, &header, &request); break; + case CTDB_CONTROL_CHECK_PID_SRVID: + control_check_pid_srvid(mem_ctx, req, &header, &request); + break; + default: if (! (request.flags & CTDB_CTRL_FLAG_NOREPLY)) { control_error(mem_ctx, req, &header, &request); -- 2.13.5 From aeb4e0b7c11eeb218eed0b9c2f26a7d418384e7b Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 30 Aug 2017 16:35:49 +1000 Subject: [PATCH 10/16] ctdb-tests: Add tests for PID with srvid BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke Autobuild-User(master): Martin Schwenke Autobuild-Date(master): Thu Sep 21 12:56:30 CEST 2017 on sn-devel-144 (cherry picked from commit 503bc3997800cfb2fd9f7f092ef896c355b844cd) --- ctdb/tests/simple/07_ctdb_process_exists.sh | 20 +++++++++++++++++++- ctdb/tests/tool/ctdb.process-exists.002.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100755 ctdb/tests/tool/ctdb.process-exists.002.sh diff --git a/ctdb/tests/simple/07_ctdb_process_exists.sh b/ctdb/tests/simple/07_ctdb_process_exists.sh index f24e93a47ad..b3b8e513741 100755 --- a/ctdb/tests/simple/07_ctdb_process_exists.sh +++ b/ctdb/tests/simple/07_ctdb_process_exists.sh @@ -36,11 +36,12 @@ set -e cluster_is_healthy test_node=1 +srvid=0xAE00000012345678 # Execute a ctdb client on $test_node that will last for 60 seconds. # It should still be there when we check. try_command_on_node -v $test_node \ - "$CTDB_TEST_WRAPPER exec dummy_client >/dev/null 2>&1 & echo \$!" + "$CTDB_TEST_WRAPPER exec dummy_client -S ${srvid} >/dev/null 2>&1 & echo \$!" client_pid="$out" cleanup () @@ -65,6 +66,23 @@ else testfailures=1 fi +echo "Checking for PID $client_pid with SRVID $srvid on node $test_node" +status=0 +try_command_on_node $test_node \ + "$CTDB process-exists ${client_pid} ${srvid}" || status=$? +echo "$out" + +if [ $status -eq 0 ] ; then + echo "OK" +else + echo "BAD" + testfailures=1 +fi + +echo "Checking for PID $client_pid with SRVID $client_pid on node $test_node" +try_command_on_node -v $test_node \ + "! $CTDB process-exists ${client_pid} ${client_pid}" + # Now just echo the PID of the ctdb daemon on test node. # This is not a ctdb client and process-exists should return error. try_command_on_node $test_node "ctdb getpid" diff --git a/ctdb/tests/tool/ctdb.process-exists.002.sh b/ctdb/tests/tool/ctdb.process-exists.002.sh new file mode 100755 index 00000000000..fe3dfd4d59f --- /dev/null +++ b/ctdb/tests/tool/ctdb.process-exists.002.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "ctdbd process on node 0" + +setup_ctdbd < Date: Fri, 22 Sep 2017 13:52:09 +1000 Subject: [PATCH 11/16] ctdb-daemon: Check all connections from a process in CHECK_PID_SRVID control BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Volker Lendecke (cherry picked from commit e342f1f078fa50904216e6e45fb9b6e40043eb98) --- ctdb/server/ctdb_daemon.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c index a81f8c2d7a2..de38542083b 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -1816,7 +1816,7 @@ int32_t ctdb_control_process_exists(struct ctdb_context *ctdb, pid_t pid) int32_t ctdb_control_check_pid_srvid(struct ctdb_context *ctdb, TDB_DATA indata) { - struct ctdb_client *client; + struct ctdb_client_pid_list *client_pid; pid_t pid; uint64_t srvid; int ret; @@ -1824,17 +1824,19 @@ int32_t ctdb_control_check_pid_srvid(struct ctdb_context *ctdb, pid = *(pid_t *)indata.dptr; srvid = *(uint64_t *)(indata.dptr + sizeof(pid_t)); - client = ctdb_find_client_by_pid(ctdb, pid); - if (client == NULL) { - return -1; - } - - ret = srvid_exists(ctdb->srv, srvid, client); - if (ret != 0) { - return -1; + for (client_pid = ctdb->client_pids; + client_pid != NULL; + client_pid = client_pid->next) { + if (client_pid->pid == pid) { + ret = srvid_exists(ctdb->srv, srvid, + client_pid->client); + if (ret == 0) { + return 0; + } + } } - return 0; + return -1; } int ctdb_control_getnodesfile(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA indata, TDB_DATA *outdata) -- 2.13.5 From b32d7a555249ad0480729d93e120cd28a49355ea Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Fri, 22 Sep 2017 14:04:50 +1000 Subject: [PATCH 12/16] ctdb-tests: Check all connections from a process in CHECK_PID_SRVID control BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Volker Lendecke (cherry picked from commit 6ed2ed7e2dc55e2508f31f32e53db5dab1fce2a8) --- ctdb/tests/src/fake_ctdbd.c | 49 +++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/ctdb/tests/src/fake_ctdbd.c b/ctdb/tests/src/fake_ctdbd.c index 850a5920a1a..1c1205b581c 100644 --- a/ctdb/tests/src/fake_ctdbd.c +++ b/ctdb/tests/src/fake_ctdbd.c @@ -2847,35 +2847,46 @@ static void control_check_pid_srvid(TALLOC_CTX *mem_ctx, struct client_state *state = tevent_req_data( req, struct client_state); struct ctdbd_context *ctdb = state->ctdb; + struct ctdb_client *client; struct client_state *cstate; struct ctdb_reply_control reply; + bool pid_found, srvid_found; int ret; reply.rdata.opcode = request->opcode; - cstate = client_find(ctdb, request->rdata.data.pid_srvid->pid); - if (cstate == NULL) { - reply.status = -1; - reply.errmsg = "No client for PID"; - } else { - ret = srvid_exists(ctdb->srv, - request->rdata.data.pid_srvid->srvid, - cstate); - if (ret != 0) { - reply.status = -1; - reply.errmsg = "No client for PID and SRVID"; - } else { - ret = kill(cstate->pid, 0); - if (ret != 0) { - reply.status = ret; - reply.errmsg = strerror(errno); - } else { - reply.status = 0; - reply.errmsg = NULL; + pid_found = false; + srvid_found = false; + + for (client=ctdb->client_list; client != NULL; client=client->next) { + if (client->pid == request->rdata.data.pid_srvid->pid) { + pid_found = true; + cstate = (struct client_state *)client->state; + ret = srvid_exists(ctdb->srv, + request->rdata.data.pid_srvid->srvid, + cstate); + if (ret == 0) { + srvid_found = true; + ret = kill(cstate->pid, 0); + if (ret != 0) { + reply.status = ret; + reply.errmsg = strerror(errno); + } else { + reply.status = 0; + reply.errmsg = NULL; + } } } } + if (! pid_found) { + reply.status = -1; + reply.errmsg = "No client for PID"; + } else if (! srvid_found) { + reply.status = -1; + reply.errmsg = "No client for PID and SRVID"; + } + client_send_control(req, header, &reply); } -- 2.13.5 From ce9b32fcbe7cede6711c480fe941ddc13a827e4b Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Fri, 22 Sep 2017 14:14:00 +1000 Subject: [PATCH 13/16] ctdb-tests: Add support for multiple ctdb connections in dummy_client BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Volker Lendecke (cherry picked from commit 90f7e06c2553a13779dd24739aeefea96f55ba3e) --- ctdb/tests/src/dummy_client.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/ctdb/tests/src/dummy_client.c b/ctdb/tests/src/dummy_client.c index 6af41f3b1f9..6f30512ee65 100644 --- a/ctdb/tests/src/dummy_client.c +++ b/ctdb/tests/src/dummy_client.c @@ -31,6 +31,7 @@ static struct { const char *sockpath; const char *debuglevel; + int num_connections; int timelimit; const char *srvidstr; } options; @@ -41,6 +42,8 @@ static struct poptOption cmdline_options[] = { "Unix domain socket path", "filename" }, { "debug", 'd', POPT_ARG_STRING, &options.debuglevel, 0, "debug level", "ERR|WARNING|NOTICE|INFO|DEBUG" } , + { "nconn", 'n', POPT_ARG_INT, &options.num_connections, 0, + "number of connections", "" }, { "timelimit", 't', POPT_ARG_INT, &options.timelimit, 0, "time limit", "seconds" }, { "srvid", 'S', POPT_ARG_STRING, &options.srvidstr, 0, @@ -59,16 +62,18 @@ int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; struct tevent_context *ev; - struct ctdb_client_context *client; + struct ctdb_client_context **client; + struct ctdb_client_context *last_client; const char *ctdb_socket; poptContext pc; - int opt, ret; + int opt, ret, i; int log_level; bool status, done; /* Set default options */ options.sockpath = CTDB_SOCKET; options.debuglevel = "ERR"; + options.num_connections = 1; options.timelimit = 60; options.srvidstr = NULL; @@ -112,19 +117,32 @@ int main(int argc, const char *argv[]) setup_logging("dummy_client", DEBUG_STDERR); DEBUGLEVEL = log_level; - ret = ctdb_client_init(mem_ctx, ev, options.sockpath, &client); - if (ret != 0) { - D_ERR("Failed to initialize client, ret=%d\n", ret); + client = talloc_array(mem_ctx, struct ctdb_client_context *, + options.num_connections); + if (client == NULL) { + fprintf(stderr, "Memory allocation error\n"); exit(1); } + for (i=0; i Date: Fri, 22 Sep 2017 14:17:59 +1000 Subject: [PATCH 14/16] ctdb-tests: Add tests for client with multiple connections BUG: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Amitay Isaacs Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Fri Sep 22 20:58:46 CEST 2017 on sn-devel-144 (cherry picked from commit 4df3dcdda692ef65b7d95c4b5623905982b4bd2b) --- ctdb/tests/simple/07_ctdb_process_exists.sh | 2 +- ctdb/tests/tool/ctdb.process-exists.003.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100755 ctdb/tests/tool/ctdb.process-exists.003.sh diff --git a/ctdb/tests/simple/07_ctdb_process_exists.sh b/ctdb/tests/simple/07_ctdb_process_exists.sh index b3b8e513741..8ccfc69baa9 100755 --- a/ctdb/tests/simple/07_ctdb_process_exists.sh +++ b/ctdb/tests/simple/07_ctdb_process_exists.sh @@ -41,7 +41,7 @@ srvid=0xAE00000012345678 # Execute a ctdb client on $test_node that will last for 60 seconds. # It should still be there when we check. try_command_on_node -v $test_node \ - "$CTDB_TEST_WRAPPER exec dummy_client -S ${srvid} >/dev/null 2>&1 & echo \$!" + "$CTDB_TEST_WRAPPER exec dummy_client -n 10 -S ${srvid} >/dev/null 2>&1 & echo \$!" client_pid="$out" cleanup () diff --git a/ctdb/tests/tool/ctdb.process-exists.003.sh b/ctdb/tests/tool/ctdb.process-exists.003.sh new file mode 100755 index 00000000000..bb1ef9ae940 --- /dev/null +++ b/ctdb/tests/tool/ctdb.process-exists.003.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "ctdbd process with multiple connections on node 0" + +setup_ctdbd < Date: Tue, 29 Aug 2017 13:26:20 +0200 Subject: [PATCH 15/16] lib: Add "unique_id" to ctdbd_process_exists Bug: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Volker Lendecke Reviewed-by: Amitay Isaacs (cherry picked from commit f059585fe61e33ce2dd518464829c183de874d8a) --- source3/include/ctdbd_conn.h | 2 +- source3/lib/ctdb_dummy.c | 3 ++- source3/lib/ctdbd_conn.c | 3 ++- source3/lib/serverid.c | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h index 38477d313de..8d94fb33eaa 100644 --- a/source3/include/ctdbd_conn.h +++ b/source3/include/ctdbd_conn.h @@ -49,7 +49,7 @@ int ctdbd_messaging_send_iov(struct ctdbd_connection *conn, const struct iovec *iov, int iovlen); bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, - pid_t pid); + pid_t pid, uint64_t unique_id); char *ctdbd_dbpath(struct ctdbd_connection *conn, TALLOC_CTX *mem_ctx, uint32_t db_id); diff --git a/source3/lib/ctdb_dummy.c b/source3/lib/ctdb_dummy.c index 2ed7b102a62..3baf718ec5f 100644 --- a/source3/lib/ctdb_dummy.c +++ b/source3/lib/ctdb_dummy.c @@ -59,7 +59,8 @@ int ctdbd_register_ips(struct ctdbd_connection *conn, return ENOSYS; } -bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, pid_t pid) +bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, + pid_t pid, uint64_t unique_id) { return false; } diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index b81feca65ba..bc35bb22442 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -775,7 +775,8 @@ static int ctdbd_control(struct ctdbd_connection *conn, /* * see if a remote process exists */ -bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, pid_t pid) +bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, + pid_t pid, uint64_t unique_id) { int32_t cstatus = 0; int ret; diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c index fb32526fa6b..17eecaed1ba 100644 --- a/source3/lib/serverid.c +++ b/source3/lib/serverid.c @@ -198,8 +198,8 @@ bool serverid_exists(const struct server_id *id) } if (lp_clustering()) { - return ctdbd_process_exists(messaging_ctdbd_connection(), - id->vnn, id->pid); + return ctdbd_process_exists(messaging_ctdb_connection(), + id->vnn, id->pid, id->unique_id); } return false; -- 2.13.5 From 087bad3547fd155831db9809cc62b8065bacb7a5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Aug 2017 13:31:07 +0200 Subject: [PATCH 16/16] lib: Use CTDB_CONTROL_CHECK_PID_SRVID Also check the unique ID for remote server ids, just like we do for local server ids Bug: https://bugzilla.samba.org/show_bug.cgi?id=13042 Signed-off-by: Volker Lendecke Reviewed-by: Amitay Isaacs Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Tue Sep 26 13:47:31 CEST 2017 on sn-devel-144 (cherry picked from commit 61de349673809b17e680496b616bc432bf0823b0) --- source3/lib/ctdbd_conn.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index bc35bb22442..6a6f803dbd8 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -778,12 +778,27 @@ static int ctdbd_control(struct ctdbd_connection *conn, bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32_t vnn, pid_t pid, uint64_t unique_id) { + uint8_t buf[sizeof(pid)+sizeof(unique_id)]; int32_t cstatus = 0; int ret; - ret = ctdbd_control(conn, vnn, CTDB_CONTROL_PROCESS_EXISTS, 0, 0, - (TDB_DATA) { .dptr = (uint8_t *)&pid, - .dsize = sizeof(pid) }, + if (unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) { + ret = ctdbd_control(conn, vnn, CTDB_CONTROL_PROCESS_EXISTS, + 0, 0, + (TDB_DATA) { .dptr = (uint8_t *)&pid, + .dsize = sizeof(pid) }, + NULL, NULL, &cstatus); + if (ret != 0) { + return false; + } + return (cstatus == 0); + } + + memcpy(buf, &pid, sizeof(pid)); + memcpy(buf+sizeof(pid), &unique_id, sizeof(unique_id)); + + ret = ctdbd_control(conn, vnn, CTDB_CONTROL_CHECK_PID_SRVID, 0, 0, + (TDB_DATA) { .dptr = buf, .dsize = sizeof(buf) }, NULL, NULL, &cstatus); if (ret != 0) { return false; -- 2.13.5