summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2013-04-11 13:18:36 +1000
committerMichael Adam <obnox@samba.org>2013-04-17 12:30:59 +0200
commit9e0f8fa09cc788b1efffce7598bee012178d90d4 (patch)
tree393bcad2d09ac04ecf9aa298f25e076edbe9d79e
parent43860e4ba01db28b4be9624c7b6f1ca7a11e5a46 (diff)
downloadsamba-9e0f8fa09cc788b1efffce7598bee012178d90d4.tar.gz
samba-9e0f8fa09cc788b1efffce7598bee012178d90d4.tar.xz
samba-9e0f8fa09cc788b1efffce7598bee012178d90d4.zip
traverse: Add CTDB_CONTROL_TRAVERSE_ALL_EXT to support withemptyrecords
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Michael Adam <obnox@samba.org> (This used to be ctdb commit e691df43d20871468142c8fb83f7c7303c4ec307)
-rw-r--r--ctdb/include/ctdb_private.h1
-rw-r--r--ctdb/include/ctdb_protocol.h1
-rw-r--r--ctdb/server/ctdb_control.c3
-rw-r--r--ctdb/server/ctdb_traverse.c58
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