From acf080817b538968d6e7cbcd5a037399c9a66c28 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 12 Oct 2023 17:11:42 +0200 Subject: [PATCH] ctdbd_conn: Add deregister_from_ctdbd() This is to remove a callback during rundown of smbds. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523 Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Volker Lendecke Signed-off-by: Stefan Metzmacher Reviewed-by: Martin Schwenke (cherry picked from commit 75aa6693940201a928b46f6880b43820c0e1c555) --- source3/include/ctdbd_conn.h | 10 +++++++ source3/lib/ctdb_dummy.c | 13 +++++++++ source3/lib/ctdbd_conn.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h index 74db96e89e7..3fa94871029 100644 --- a/source3/include/ctdbd_conn.h +++ b/source3/include/ctdbd_conn.h @@ -116,6 +116,16 @@ int register_with_ctdbd(struct ctdbd_connection *conn, uint64_t srvid, const uint8_t *msg, size_t msglen, void *private_data), void *private_data); +void deregister_from_ctdbd(struct ctdbd_connection *conn, + uint64_t srvid, + int (*cb)(struct tevent_context *ev, + uint32_t src_vnn, + uint32_t dst_vnn, + uint64_t dst_srvid, + const uint8_t *msg, + size_t msglen, + void *private_data), + void *private_data); int ctdbd_probe(const char *sockname, int timeout); struct ctdb_req_header; diff --git a/source3/lib/ctdb_dummy.c b/source3/lib/ctdb_dummy.c index 294d178966b..f21037e0c30 100644 --- a/source3/lib/ctdb_dummy.c +++ b/source3/lib/ctdb_dummy.c @@ -49,6 +49,19 @@ int register_with_ctdbd(struct ctdbd_connection *conn, uint64_t srvid, return ENOSYS; } +void deregister_from_ctdbd(struct ctdbd_connection *conn, + uint64_t srvid, + int (*cb)(struct tevent_context *ev, + uint32_t src_vnn, + uint32_t dst_vnn, + uint64_t dst_srvid, + const uint8_t *msg, + size_t msglen, + void *private_data), + void *private_data) +{ +} + int ctdbd_register_ips(struct ctdbd_connection *conn, const struct sockaddr_storage *_server, const struct sockaddr_storage *_client, diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index a11c31d7f63..41239f702b9 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -172,6 +172,73 @@ int register_with_ctdbd(struct ctdbd_connection *conn, uint64_t srvid, return 0; } +void deregister_from_ctdbd(struct ctdbd_connection *conn, + uint64_t srvid, + int (*cb)(struct tevent_context *ev, + uint32_t src_vnn, + uint32_t dst_vnn, + uint64_t dst_srvid, + const uint8_t *msg, + size_t msglen, + void *private_data), + void *private_data) +{ + struct ctdbd_srvid_cb *cbs = conn->callbacks; + size_t i, num_callbacks = talloc_array_length(cbs); + bool need_deregister = false; + bool keep_registration = false; + + if (num_callbacks == 0) { + return; + } + + for (i = 0; i < num_callbacks;) { + struct ctdbd_srvid_cb *c = &cbs[i]; + + if (c->srvid != srvid) { + i++; + continue; + } + + if ((c->cb == cb) && (c->private_data == private_data)) { + need_deregister = true; + ARRAY_DEL_ELEMENT(cbs, i, num_callbacks); + num_callbacks--; + continue; + } + + keep_registration = true; + i++; + } + + conn->callbacks = talloc_realloc(conn, + cbs, + struct ctdbd_srvid_cb, + num_callbacks); + + if (keep_registration) { + need_deregister = false; + } + + if (need_deregister) { + int ret; + int32_t cstatus; + + ret = ctdbd_control_local(conn, CTDB_CONTROL_DEREGISTER_SRVID, + srvid, 0, tdb_null, NULL, NULL, + &cstatus); + if (ret != 0) { + /* + * If CTDB_CONTROL_DEREGISTER_SRVID fails we may still + * get messages later, but we don't have a callback + * anymore, we just ignore these. + */ + } + } + + return; +} + static int ctdbd_msg_call_back(struct tevent_context *ev, struct ctdbd_connection *conn, struct ctdb_req_message_old *msg) -- 2.11.4.GIT