From fc0c33878bdbf27cb0c8527e8d91700e546d6850 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 067777a79f3..043149eedd9 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -629,6 +629,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 d92f707b25d..c41fc7d53ee 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 15f914a2bee2b928aeb9a148fa5a5adff71c8aaa 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