]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:cluster_level_db: add cluster_level_db_nodes_foreach()
authorStefan Metzmacher <metze@samba.org>
Fri, 31 Jul 2026 07:50:16 +0000 (09:50 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 4 Aug 2026 09:51:32 +0000 (09:51 +0000)
This allows the caller to get information about the supported
ranges of all (non-deleted) nodes together with information
about the node.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/lib/cluster_level_db.c
source3/lib/cluster_level_db.h

index 6ceee2a0feab598cead617864bfabd3a667a750e..18169bbcbfb2984a6ee3c36087b93e945338cfbd 100644 (file)
@@ -25,6 +25,7 @@
 #include "ctdbd_conn.h"
 #include "cluster_support.h"
 #include "cluster_level_db.h"
+#include "ctdb/protocol/protocol.h"
 
 /*
  * Note msg_ctx is optional, passing NULL means
@@ -758,3 +759,94 @@ NTSTATUS cluster_level_db_check_or_update(struct ctdbd_connection *ctdb_conn,
        TALLOC_FREE(frame);
        return NT_STATUS_OK;
 }
+
+struct cluster_level_db_nodes_foreach_state {
+       struct db_context *db;
+       cluster_level_db_nodes_foreach_cb_t cb;
+       void *cb_private;
+       NTSTATUS error;
+};
+
+static int cluster_level_db_nodes_foreach_ctdbd_cb(
+                               uint32_t total_nodes_count,
+                               const struct ctdb_node_and_flags *nf,
+                               void *private_data)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct cluster_level_db_nodes_foreach_state *state =
+               (struct cluster_level_db_nodes_foreach_state *)private_data;
+       struct cluster_level_ranges *n_ranges = NULL;
+       struct cluster_level_ranges zero_ranges = { .num_ranges = 0, };
+       struct cluster_level_db_nodes_foreach_node node = {
+               .nf = nf,
+       };
+       NTSTATUS status;
+
+       status = cluster_level_db_fetch_ranges(state->db,
+                                              nf->pnn,
+                                              frame,
+                                              &node.update_time,
+                                              &node.update_ctdbd.start_time,
+                                              &node.update_ctdbd.pid,
+                                              &n_ranges);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+               /* no ranges stored yet */
+               n_ranges = &zero_ranges;
+               node.update_ctdbd.pid = -1;
+       } else if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               state->error = status;
+               return -1;
+       }
+
+       node.supported_ranges = n_ranges;
+       status = state->cb(total_nodes_count,
+                          &node,
+                          state->cb_private);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               state->error = status;
+               return -1;
+       }
+       TALLOC_FREE(frame);
+       return 0;
+}
+
+NTSTATUS cluster_level_db_nodes_foreach(struct ctdbd_connection *ctdb_conn,
+                                       cluster_level_db_nodes_foreach_cb_t cb,
+                                       void *private_data)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct cluster_level_db_nodes_foreach_state state = {
+               .cb = cb,
+               .cb_private = private_data,
+       };
+       int ret;
+
+       /*
+        * We only need temporary read only access,
+        * so we pass msg_ctx=NULL ...
+        */
+       state.db = cluster_level_db_open(frame,
+                                        ctdb_conn,
+                                        NULL);  /* msg_ctx */
+       if (state.db == NULL) {
+               DBG_ERR("cluster_level_db_open() failed\n");
+               TALLOC_FREE(frame);
+               return NT_STATUS_INTERNAL_DB_ERROR;
+       }
+
+       ret = ctdbd_nodes_foreach(ctdb_conn,
+                                 cluster_level_db_nodes_foreach_ctdbd_cb,
+                                 &state);
+       if (ret != 0) {
+               if (NT_STATUS_IS_OK(state.error)) {
+                       state.error = NT_STATUS_INTERNAL_ERROR;
+               }
+               TALLOC_FREE(frame);
+               return state.error;
+       }
+
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
+}
index cf33d7c26de354f3facc8ca7f7f2f0a13618cda8..423eb8edd9e416d4e10b44c4a5284aefc3a66378 100644 (file)
@@ -21,6 +21,7 @@
 #define CLUSTER_LEVEL_DB_H
 
 struct ctdbd_connection;
+struct ctdb_node_and_flags;
 struct messaging_context;
 
 NTSTATUS cluster_level_db_check(struct ctdbd_connection *ctdb_conn);
@@ -28,4 +29,23 @@ NTSTATUS cluster_level_db_check(struct ctdbd_connection *ctdb_conn);
 NTSTATUS cluster_level_db_check_or_update(struct ctdbd_connection *ctdb_conn,
                                          struct messaging_context *msg_ctx);
 
+struct cluster_level_db_nodes_foreach_node {
+       const struct ctdb_node_and_flags *nf;
+       struct timeval update_time;
+       struct {
+               struct timeval start_time;
+               pid_t pid;
+       } update_ctdbd;
+       const struct cluster_level_ranges *supported_ranges;
+};
+
+typedef NTSTATUS (*cluster_level_db_nodes_foreach_cb_t)(
+               uint32_t total_nodes_count,
+               const struct cluster_level_db_nodes_foreach_node *node,
+               void *private_data);
+
+NTSTATUS cluster_level_db_nodes_foreach(struct ctdbd_connection *ctdb_conn,
+                                       cluster_level_db_nodes_foreach_cb_t cb,
+                                       void *private_data);
+
 #endif /* CLUSTER_LEVEL_DB_H */