summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2019-07-30 14:17:11 +1000
committerAmitay Isaacs <amitay@samba.org>2019-10-24 04:06:43 +0000
commit41a41d5f3e2b8e16e25221e14939dc5962997ac7 (patch)
treeb1b3749d810e78879c7f1ce78769d52ca3c3678a
parentd462d64cdf001fd5d1cbf2a109df62e087ad0c49 (diff)
downloadsamba-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.h5
-rw-r--r--ctdb/server/ctdb_control.c9
-rw-r--r--ctdb/server/ctdb_vacuum.c89
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) {