#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
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;
+}
#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);
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 */