ctdb-daemon: Support per-node robust mutex feature
[obnox/samba/samba-obnox.git] / ctdb / client / ctdb_client.c
index 885dbfdfb4656fd57f77695eb36ad6bc8e4bb9ab..df57302de0481839406b178c51ca2b354d91810d 100644 (file)
@@ -29,8 +29,6 @@
 #include "../include/ctdb_private.h"
 #include "lib/util/dlinklist.h"
 
-pid_t ctdbd_pid;
-
 /*
   allocate a packet for use in client<->daemon communication
  */
@@ -709,6 +707,21 @@ again:
                goto again;
        }
 
+       /* if this is a request for read/write and we have delegations
+          we have to revoke all delegations first
+       */
+       if ((h->header.dmaster == ctdb_db->ctdb->pnn) &&
+           (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
+               ctdb_ltdb_unlock(ctdb_db, key);
+               ret = ctdb_client_force_migration(ctdb_db, key);
+               if (ret != 0) {
+                       DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
+                       talloc_free(h);
+                       return NULL;
+               }
+               goto again;
+       }
+
        DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
        return h;
 }
@@ -1913,6 +1926,12 @@ int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32
                tdb_flags = TDB_INCOMPATIBLE_HASH;
        }
 
+#ifdef TDB_MUTEX_LOCKING
+       if (!persistent && ctdb->tunable.mutex_enabled == 1) {
+               tdb_flags |= TDB_MUTEX_LOCKING;
+       }
+#endif
+
        ret = ctdb_control(ctdb, destnode, tdb_flags,
                           persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH, 
                           0, data, 
@@ -2060,6 +2079,12 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
                tdb_flags |= TDB_INCOMPATIBLE_HASH;
        }
 
+#ifdef TDB_MUTEX_LOCKING
+       if (!persistent && ctdb->tunable.mutex_enabled == 1) {
+               tdb_flags |= TDB_MUTEX_LOCKING;
+       }
+#endif
+
        /* tell ctdb daemon to attach */
        ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags, 
                           persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
@@ -2086,7 +2111,8 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
        }
        tdb_flags |= TDB_DISALLOW_NESTING;
 
-       ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
+       ctdb_db->ltdb = tdb_wrap_open(ctdb_db, ctdb_db->db_path, 0, tdb_flags,
+                                     O_RDWR, 0);
        if (ctdb_db->ltdb == NULL) {
                ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
                talloc_free(ctdb_db);
@@ -2105,6 +2131,25 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
        return ctdb_db;
 }
 
+/*
+ * detach from a specific database - client call
+ */
+int ctdb_detach(struct ctdb_context *ctdb, uint32_t db_id)
+{
+       int ret;
+       int32_t status;
+       TDB_DATA data;
+
+       data.dsize = sizeof(db_id);
+       data.dptr = (uint8_t *)&db_id;
+
+       ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_DB_DETACH,
+                          0, data, NULL, NULL, &status, NULL, NULL);
+       if (ret != 0 || status != 0) {
+               return -1;
+       }
+       return 0;
+}
 
 /*
   setup a call for a database