ctdbd_conn: Add deregister_from_ctdbd()
authorVolker Lendecke <vl@samba.org>
Thu, 12 Oct 2023 15:11:42 +0000 (17:11 +0200)
committerJule Anger <janger@samba.org>
Sat, 16 Dec 2023 14:29:10 +0000 (14:29 +0000)
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 <metze@samba.org>

Signed-off-by: Volker Lendecke <vl@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Martin Schwenke <martin@meltin.net>
(cherry picked from commit 75aa6693940201a928b46f6880b43820c0e1c555)

source3/include/ctdbd_conn.h
source3/lib/ctdb_dummy.c
source3/lib/ctdbd_conn.c

index 74db96e89e7d750bddea66ff0059e4c0b0d063c4..3fa948710298460ca0c8f79bcea082a1f060263e 100644 (file)
@@ -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;
index 294d178966b2ba92713f47b66d623f3ec0b7e750..f21037e0c3093ef6a93000ed637151ec0ba1b14f 100644 (file)
@@ -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,
index a11c31d7f6333e13a8b00bd81a41595ff3234730..41239f702b9daf11778dba3a6a3e504de637334e 100644 (file)
@@ -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)