summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2020-02-24 10:26:34 +1100
committerKarolin Seeger <kseeger@samba.org>2020-03-30 08:06:12 +0000
commit63db9658e1e71146ff6f06619b26d2ad3c7ebfbb (patch)
tree8f53f5d719d68ce02d2769ef91a63650ce3c25b5
parent7131081967600ad8fa332e4004b8d93859a35008 (diff)
downloadsamba-63db9658e1e71146ff6f06619b26d2ad3c7ebfbb.tar.gz
ctdb-recovery: Fetch database name from all nodes where it is attached
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14294 Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com> (cherry picked from commit e6e63f8fb8194634135bf34cda18f6cc8ff69a7c)
-rw-r--r--ctdb/server/ctdb_recovery_helper.c80
1 files changed, 67 insertions, 13 deletions
diff --git a/ctdb/server/ctdb_recovery_helper.c b/ctdb/server/ctdb_recovery_helper.c
index 2b77542245a..0fbafe45fb6 100644
--- a/ctdb/server/ctdb_recovery_helper.c
+++ b/ctdb/server/ctdb_recovery_helper.c
@@ -1656,7 +1656,7 @@ static bool collect_all_db_recv(struct tevent_req *req, int *perr)
/**
* For each database do the following:
- * - Get DB name
+ * - Get DB name from all nodes
* - Get DB path
* - Freeze database on all nodes
* - Start transaction on all nodes
@@ -1719,8 +1719,13 @@ static struct tevent_req *recover_db_send(TALLOC_CTX *mem_ctx,
state->transdb.tid = generation;
ctdb_req_control_get_dbname(&request, db->db_id);
- subreq = ctdb_client_control_send(state, ev, client, state->destnode,
- TIMEOUT(), &request);
+ subreq = ctdb_client_control_multi_send(state,
+ ev,
+ client,
+ state->db->pnn_list,
+ state->db->num_nodes,
+ TIMEOUT(),
+ &request);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
@@ -1735,26 +1740,75 @@ static void recover_db_name_done(struct tevent_req *subreq)
subreq, struct tevent_req);
struct recover_db_state *state = tevent_req_data(
req, struct recover_db_state);
- struct ctdb_reply_control *reply;
+ struct ctdb_reply_control **reply;
struct ctdb_req_control request;
+ int *err_list;
+ unsigned int i;
int ret;
bool status;
- status = ctdb_client_control_recv(subreq, &ret, state, &reply);
+ status = ctdb_client_control_multi_recv(subreq,
+ &ret,
+ state,
+ &err_list,
+ &reply);
TALLOC_FREE(subreq);
if (! status) {
- D_ERR("control GET_DBNAME failed for db=0x%x, ret=%d\n",
- state->db->db_id, ret);
+ int ret2;
+ uint32_t pnn;
+
+ ret2 = ctdb_client_control_multi_error(state->db->pnn_list,
+ state->db->num_nodes,
+ err_list,
+ &pnn);
+ if (ret2 != 0) {
+ D_ERR("control GET_DBNAME failed on node %u,"
+ " ret=%d\n",
+ pnn,
+ ret2);
+ } else {
+ D_ERR("control GET_DBNAME failed, ret=%d\n",
+ ret);
+ }
tevent_req_error(req, ret);
return;
}
- ret = ctdb_reply_control_get_dbname(reply, state, &state->db_name);
- if (ret != 0) {
- D_ERR("control GET_DBNAME failed for db=0x%x, ret=%d\n",
- state->db->db_id, ret);
- tevent_req_error(req, EPROTO);
- return;
+ for (i = 0; i < state->db->num_nodes; i++) {
+ const char *db_name;
+ uint32_t pnn;
+
+ pnn = state->nlist->pnn_list[i];
+
+ ret = ctdb_reply_control_get_dbname(reply[i],
+ state,
+ &db_name);
+ if (ret != 0) {
+ D_ERR("control GET_DBNAME failed on node %u "
+ "for db=0x%x, ret=%d\n",
+ pnn,
+ state->db->db_id,
+ ret);
+ tevent_req_error(req, EPROTO);
+ return;
+ }
+
+ if (state->db_name == NULL) {
+ state->db_name = db_name;
+ continue;
+ }
+
+ if (strcmp(state->db_name, db_name) != 0) {
+ D_ERR("Incompatible database name for 0x%"PRIx32" "
+ "(%s != %s) on node %"PRIu32"\n",
+ state->db->db_id,
+ db_name,
+ state->db_name,
+ pnn);
+ node_list_ban_credits(state->nlist, pnn);
+ tevent_req_error(req, ret);
+ return;
+ }
}
talloc_free(reply);