diff options
author | Martin Schwenke <martin@meltin.net> | 2019-07-30 14:17:11 +1000 |
---|---|---|
committer | Amitay Isaacs <amitay@samba.org> | 2019-10-24 04:06:43 +0000 |
commit | 41a41d5f3e2b8e16e25221e14939dc5962997ac7 (patch) | |
tree | b1b3749d810e78879c7f1ce78769d52ca3c3678a | |
parent | d462d64cdf001fd5d1cbf2a109df62e087ad0c49 (diff) | |
download | samba-41a41d5f3e2b8e16e25221e14939dc5962997ac7.tar.gz |
ctdb-daemon: Implement DB_VACUUM control
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
-rw-r--r-- | ctdb/include/ctdb_private.h | 5 | ||||
-rw-r--r-- | ctdb/server/ctdb_control.c | 9 | ||||
-rw-r--r-- | ctdb/server/ctdb_vacuum.c | 89 |
3 files changed, 103 insertions, 0 deletions
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index b42b32a3967..4f36c9a44a5 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -986,6 +986,11 @@ int32_t ctdb_control_uptime(struct ctdb_context *ctdb, TDB_DATA *outdata); /* from ctdb_vacuum.c */ +int32_t ctdb_control_db_vacuum(struct ctdb_context *ctdb, + struct ctdb_req_control_old *c, + TDB_DATA indata, + bool *async_reply); + void ctdb_stop_vacuuming(struct ctdb_context *ctdb); int ctdb_vacuum_init(struct ctdb_db_context *ctdb_db); diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c index 0174f303f14..d162268a178 100644 --- a/ctdb/server/ctdb_control.c +++ b/ctdb/server/ctdb_control.c @@ -33,6 +33,8 @@ #include "ctdb_private.h" #include "ctdb_client.h" +#include "protocol/protocol_private.h" + #include "common/reqid.h" #include "common/common.h" #include "common/logging.h" @@ -732,6 +734,13 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb, case CTDB_CONTROL_VACUUM_FETCH: return ctdb_control_vacuum_fetch(ctdb, indata); + case CTDB_CONTROL_DB_VACUUM: { + struct ctdb_db_vacuum db_vacuum; + + CHECK_CONTROL_DATA_SIZE(ctdb_db_vacuum_len(&db_vacuum)); + return ctdb_control_db_vacuum(ctdb, c, indata, async_reply); + } + default: DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode)); return -1; diff --git a/ctdb/server/ctdb_vacuum.c b/ctdb/server/ctdb_vacuum.c index 8df362be233..5351a3c5175 100644 --- a/ctdb/server/ctdb_vacuum.c +++ b/ctdb/server/ctdb_vacuum.c @@ -37,6 +37,8 @@ #include "ctdb_private.h" #include "ctdb_client.h" +#include "protocol/protocol_private.h" + #include "common/rb_tree.h" #include "common/common.h" #include "common/logging.h" @@ -1555,6 +1557,93 @@ static void ctdb_vacuum_event(struct tevent_context *ev, } +struct vacuum_control_state { + struct ctdb_vacuum_child_context *child_ctx; + struct ctdb_req_control_old *c; + struct ctdb_context *ctdb; +}; + +static int vacuum_control_state_destructor(struct vacuum_control_state *state) +{ + struct ctdb_vacuum_child_context *child_ctx = state->child_ctx; + int32_t status; + + status = (child_ctx->status == VACUUM_OK ? 0 : -1); + ctdb_request_control_reply(state->ctdb, state->c, NULL, status, NULL); + + return 0; +} + +int32_t ctdb_control_db_vacuum(struct ctdb_context *ctdb, + struct ctdb_req_control_old *c, + TDB_DATA indata, + bool *async_reply) +{ + struct ctdb_db_context *ctdb_db; + struct ctdb_vacuum_child_context *child_ctx = NULL; + struct ctdb_db_vacuum *db_vacuum; + struct vacuum_control_state *state; + size_t np; + int ret; + + ret = ctdb_db_vacuum_pull(indata.dptr, + indata.dsize, + ctdb, + &db_vacuum, + &np); + if (ret != 0) { + DBG_ERR("Invalid data\n"); + return -1; + } + + ctdb_db = find_ctdb_db(ctdb, db_vacuum->db_id); + if (ctdb_db == NULL) { + DBG_ERR("Unknown db id 0x%08x\n", db_vacuum->db_id); + talloc_free(db_vacuum); + return -1; + } + + state = talloc(ctdb, struct vacuum_control_state); + if (state == NULL) { + DBG_ERR("Memory allocation error\n"); + return -1; + } + + ret = vacuum_db_child(ctdb_db, + ctdb_db, + false, + db_vacuum->full_vacuum_run, + &child_ctx); + + talloc_free(db_vacuum); + + if (ret == 0) { + (void) talloc_steal(child_ctx, state); + + state->child_ctx = child_ctx; + state->c = talloc_steal(state, c); + state->ctdb = ctdb; + + talloc_set_destructor(state, vacuum_control_state_destructor); + + *async_reply = true; + return 0; + } + + talloc_free(state); + + switch (ret) { + case EBUSY: + DBG_WARNING("Vacuuming collision\n"); + break; + + default: + DBG_ERR("Temporary vacuuming failure, ret=%d\n", ret); + } + + return -1; +} + void ctdb_stop_vacuuming(struct ctdb_context *ctdb) { if (ctdb->vacuumer != NULL) { |