From 4ae0994af9c84e4d0634cbfbb9256c2c70a8d267 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Thu, 7 Sep 2017 17:18:18 +1000 Subject: [PATCH 1/2] ctdb-daemon: Add a function to check if db access is allowed BUG: https://bugzilla.samba.org/show_bug.cgi?id=13021 Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit 5d2f2677de65a0fd6683bb759d80ebced604fa6b) --- ctdb/include/ctdb_private.h | 1 + ctdb/server/ctdb_freeze.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index d81ed56d763..491dd78eda8 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -626,6 +626,7 @@ int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata); bool ctdb_db_frozen(struct ctdb_db_context *ctdb_db); bool ctdb_db_all_frozen(struct ctdb_context *ctdb); +bool ctdb_db_allow_access(struct ctdb_db_context *ctdb_db); /* from server/ctdb_keepalive.c */ diff --git a/ctdb/server/ctdb_freeze.c b/ctdb/server/ctdb_freeze.c index 2666013744b..e2b12c79f1f 100644 --- a/ctdb/server/ctdb_freeze.c +++ b/ctdb/server/ctdb_freeze.c @@ -874,3 +874,21 @@ bool ctdb_db_all_frozen(struct ctdb_context *ctdb) } return true; } + +bool ctdb_db_allow_access(struct ctdb_db_context *ctdb_db) +{ + if (ctdb_db->freeze_mode == CTDB_FREEZE_NONE) { + /* If database is not frozen, then allow access. */ + return true; + } else if (ctdb_db->freeze_transaction_started) { + /* If database is frozen, allow access only if the + * transaction is started. This is required during + * recovery. + * + * If a node is inactive, then transaction is not started. + */ + return true; + } + + return false; +} -- 2.13.5 From c043229e2b552f22bab69b9a94cefb01b482b97b Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Thu, 7 Sep 2017 17:21:03 +1000 Subject: [PATCH 2/2] ctdb-daemon: GET_DB_SEQNUM should read database conditionally BUG: https://bugzilla.samba.org/show_bug.cgi?id=13021 Once the recovery starts and databases are frozen, then all the record access is postponed till the recovery is complete except reading the database sequence number. Database access for reading sequence number is done via a control which does not check if the databases are frozen or not. If the database is frozen and if the freeze transaction is not started (this can happen when a node is inactive, or during recovery when the database is frozen but the transaction has not yet started), then trying to read sequence number will cause ctdb daemon to deadlock. Before reading the sequence number, check if the database access is allowed. Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke (cherry picked from commit f57d379446c551bca5906247c622e857c77089b0) --- ctdb/server/ctdb_persistent.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ctdb/server/ctdb_persistent.c b/ctdb/server/ctdb_persistent.c index 1811ae8fa66..fc286552747 100644 --- a/ctdb/server/ctdb_persistent.c +++ b/ctdb/server/ctdb_persistent.c @@ -344,6 +344,11 @@ static int32_t ctdb_get_db_seqnum(struct ctdb_context *ctdb, goto done; } + if (! ctdb_db_allow_access(ctdb_db)) { + ret = -1; + goto done; + } + key.dptr = (uint8_t *)discard_const(keyname); key.dsize = strlen(keyname) + 1; -- 2.13.5