ctdb: Rename ctdb socket variable from CTDB_PATH to CTDB_SOCKET
[obnox/samba/samba-obnox.git] / ctdb / client / ctdb_client.c
index 885dbfdfb4656fd57f77695eb36ad6bc8e4bb9ab..424937ad8ca84e34dad455ee5205fd018eca62e6 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 #include "includes.h"
-#include "db_wrap.h"
+#include "lib/tdb_wrap/tdb_wrap.h"
 #include "tdb.h"
 #include "lib/util/dlinklist.h"
 #include "system/network.h"
@@ -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
@@ -3330,7 +3375,7 @@ struct ctdb_context *ctdb_init(struct event_context *ev)
        ctdb->lastid = INT_MAX-200;
        CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
 
-       ret = ctdb_set_socketname(ctdb, CTDB_PATH);
+       ret = ctdb_set_socketname(ctdb, CTDB_SOCKET);
        if (ret != 0) {
                DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
                talloc_free(ctdb);
@@ -3753,7 +3798,10 @@ static struct server_id server_id_get(struct ctdb_context *ctdb, uint32_t reqid)
        return id;
 }
 
-static bool server_id_equal(struct server_id *id1, struct server_id *id2)
+/* This is basically a copy from Samba's server_id.*.  However, a
+ * dependency chain stops us from using Samba's version, so use a
+ * renamed copy until a better solution is found. */
+static bool ctdb_server_id_equal(struct server_id *id1, struct server_id *id2)
 {
        if (id1->pid != id2->pid) {
                return false;
@@ -3891,7 +3939,7 @@ again:
 
        i = 0;
        while (i < locks->num) {
-               if (server_id_equal(&locks->lock[i].id, &id)) {
+               if (ctdb_server_id_equal(&locks->lock[i].id, &id)) {
                        /* Internal error */
                        talloc_free(h);
                        return false;
@@ -3979,7 +4027,7 @@ static bool g_lock_unlock(TALLOC_CTX *mem_ctx,
        id = server_id_get(ctdb_db->ctdb, reqid);
 
        for (i=0; i<locks->num; i++) {
-               if (server_id_equal(&locks->lock[i].id, &id)) {
+               if (ctdb_server_id_equal(&locks->lock[i].id, &id)) {
                        if (i < locks->num-1) {
                                locks->lock[i] = locks->lock[locks->num-1];
                        }