diff options
-rw-r--r-- | ctdb/include/ctdb_private.h | 1 | ||||
-rw-r--r-- | ctdb/include/ctdb_protocol.h | 1 | ||||
-rw-r--r-- | ctdb/server/ctdb_control.c | 3 | ||||
-rw-r--r-- | ctdb/server/ctdb_traverse.c | 58 |
4 files changed, 63 insertions, 0 deletions
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 7e46603bea..ecdf2577e9 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -1015,6 +1015,7 @@ int32_t ctdb_control_traverse_start_ext(struct ctdb_context *ctdb, int32_t ctdb_control_traverse_start(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata, uint32_t srcnode, uint32_t client_id); int32_t ctdb_control_traverse_all(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata); +int32_t ctdb_control_traverse_all_ext(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata); int32_t ctdb_control_traverse_data(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata); int32_t ctdb_control_traverse_kill(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata, uint32_t srcnode); diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h index cc3ea3f9ed..9302c7bc31 100644 --- a/ctdb/include/ctdb_protocol.h +++ b/ctdb/include/ctdb_protocol.h @@ -402,6 +402,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0, CTDB_CONTROL_GET_DB_STATISTICS = 132, CTDB_CONTROL_SET_DB_STICKY = 133, CTDB_CONTROL_RELOAD_PUBLIC_IPS = 134, + CTDB_CONTROL_TRAVERSE_ALL_EXT = 135, }; /* diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c index 9708acd8cf..b567865ca9 100644 --- a/ctdb/server/ctdb_control.c +++ b/ctdb/server/ctdb_control.c @@ -264,6 +264,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, case CTDB_CONTROL_TRAVERSE_ALL: return ctdb_control_traverse_all(ctdb, indata, outdata); + case CTDB_CONTROL_TRAVERSE_ALL_EXT: + return ctdb_control_traverse_all_ext(ctdb, indata, outdata); + case CTDB_CONTROL_TRAVERSE_DATA: return ctdb_control_traverse_data(ctdb, indata, outdata); diff --git a/ctdb/server/ctdb_traverse.c b/ctdb/server/ctdb_traverse.c index df0afb0bee..e869f0c417 100644 --- a/ctdb/server/ctdb_traverse.c +++ b/ctdb/server/ctdb_traverse.c @@ -232,6 +232,14 @@ struct ctdb_traverse_all { uint32_t pnn; uint32_t client_reqid; uint64_t srvid; +}; + +struct ctdb_traverse_all_ext { + uint32_t db_id; + uint32_t reqid; + uint32_t pnn; + uint32_t client_reqid; + uint64_t srvid; bool withemptyrecords; }; @@ -381,6 +389,56 @@ static void traverse_all_callback(void *p, TDB_DATA key, TDB_DATA data) } /* + * extended version to take the "withemptyrecords" parameter" + */ +int32_t ctdb_control_traverse_all_ext(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata) +{ + struct ctdb_traverse_all_ext *c = (struct ctdb_traverse_all_ext *)data.dptr; + struct traverse_all_state *state; + struct ctdb_db_context *ctdb_db; + + if (data.dsize != sizeof(struct ctdb_traverse_all_ext)) { + DEBUG(DEBUG_ERR,(__location__ " Invalid size in ctdb_control_traverse_all_ext\n")); + return -1; + } + + ctdb_db = find_ctdb_db(ctdb, c->db_id); + if (ctdb_db == NULL) { + return -1; + } + + if (ctdb_db->unhealthy_reason) { + if (ctdb->tunable.allow_unhealthy_db_read == 0) { + DEBUG(DEBUG_ERR,("db(%s) unhealty in ctdb_control_traverse_all: %s\n", + ctdb_db->db_name, ctdb_db->unhealthy_reason)); + return -1; + } + DEBUG(DEBUG_WARNING,("warn: db(%s) unhealty in ctdb_control_traverse_all: %s\n", + ctdb_db->db_name, ctdb_db->unhealthy_reason)); + } + + state = talloc(ctdb_db, struct traverse_all_state); + if (state == NULL) { + return -1; + } + + state->reqid = c->reqid; + state->srcnode = c->pnn; + state->ctdb = ctdb; + state->client_reqid = c->client_reqid; + state->srvid = c->srvid; + state->withemptyrecords = c->withemptyrecords; + + state->h = ctdb_traverse_local(ctdb_db, traverse_all_callback, state); + if (state->h == NULL) { + talloc_free(state); + return -1; + } + + return 0; +} + +/* called when a CTDB_CONTROL_TRAVERSE_ALL control comes in. We then setup a traverse of our local ltdb, sending the records as CTDB_CONTROL_TRAVERSE_DATA records back to the originator |