]> git.samba.org - sahlberg/ctdb.git/commitdiff
Port Volkers deadlock avoidance patch to HEAD.
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 13 Oct 2009 21:17:49 +0000 (08:17 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 13 Oct 2009 21:17:49 +0000 (08:17 +1100)
This patch ensures that we lock all non-notify related databases first and
then the notify databases to avoiud a deadlock where samba needs to lock records on two databases at once (and notify being the second database).

Newer versions of samba would instead use the set-db-prio control to set this explicitely on a database per database basis instead of relying on  hardcoded database names. This patch will be reverted in the future when all updated versions of samba has been pushed out.

server/ctdb_freeze.c
server/ctdb_recover.c

index da7272fddaa277914095b59d66abe916c0dbd92c..a2b765b8dfe9d0f95164bcf2044b1e88f78cf01b 100644 (file)
 static int ctdb_lock_all_databases(struct ctdb_context *ctdb, uint32_t priority)
 {
        struct ctdb_db_context *ctdb_db;
+       /* REMOVE later */
+       /* This double loop is for backward compatibility and deadlock
+          avoidance for old samba versions that not yet support
+          the set prio call.
+          This code shall be removed later
+       */
        for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
                if (ctdb_db->priority != priority) {
                        continue;
                }
+               if (strstr(ctdb_db->db_name, "notify") != NULL) {
+                       continue;
+               }
+               DEBUG(DEBUG_INFO,("locking database 0x%08x priority:%u %s\n", ctdb_db->db_id, ctdb_db->priority, ctdb_db->db_name));
+               if (tdb_lockall(ctdb_db->ltdb->tdb) != 0) {
+                       return -1;
+               }
+       }
+       for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
+               if (ctdb_db->priority != priority) {
+                       continue;
+               }
+               if (strstr(ctdb_db->db_name, "notify") == NULL) {
+                       continue;
+               }
                DEBUG(DEBUG_INFO,("locking database 0x%08x priority:%u %s\n", ctdb_db->db_id, ctdb_db->priority, ctdb_db->db_name));
                if (tdb_lockall(ctdb_db->ltdb->tdb) != 0) {
                        return -1;
index 40544f14eba661c5e1f64a60c7d474370a6e3bfb..21dc28d05d23804dd20427c2bc63f891bc688afa 100644 (file)
@@ -44,10 +44,30 @@ static int ctdb_lock_all_databases_mark(struct ctdb_context *ctdb, uint32_t prio
                DEBUG(DEBUG_ERR,("Attempt to mark all databases locked when not frozen\n"));
                return -1;
        }
+       /* The dual loop is a woraround for older versions of samba
+          that does not yet support the set-db-priority/lock order
+          call. So that we get basic deadlock avoiidance also for
+          these old versions of samba.
+          This code will be removed in the future.
+       */
        for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
                if (ctdb_db->priority != priority) {
                        continue;
                }
+               if (strstr(ctdb_db->db_name, "notify") != NULL) {
+                       continue;
+               }
+               if (tdb_lockall_mark(ctdb_db->ltdb->tdb) != 0) {
+                       return -1;
+               }
+       }
+       for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
+               if (ctdb_db->priority != priority) {
+                       continue;
+               }
+               if (strstr(ctdb_db->db_name, "notify") == NULL) {
+                       continue;
+               }
                if (tdb_lockall_mark(ctdb_db->ltdb->tdb) != 0) {
                        return -1;
                }