diff options
author | Martin Schwenke <martin@meltin.net> | 2019-07-30 14:17:11 +1000 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2020-03-30 10:08:24 +0000 |
commit | 9c3b0d389ce9828e6681e3bf52804ed34df5b25c (patch) | |
tree | 19bb5a369815620ce8dca22f9525070135ef77a9 /ctdb | |
parent | b87b08a540f20a42f9425e18a82f82cb8d9329bd (diff) | |
download | samba-9c3b0d389ce9828e6681e3bf52804ed34df5b25c.tar.gz |
ctdb-daemon: Implement DB_VACUUM control
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
(cherry picked from commit 41a41d5f3e2b8e16e25221e14939dc5962997ac7)
Diffstat (limited to 'ctdb')
-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 19b8bb98d8f..d3e70b5e2fa 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 910751d59e0..2cc6aa53ecb 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" @@ -1554,6 +1556,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) { |