*/
#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"
#include "../include/ctdb_private.h"
#include "lib/util/dlinklist.h"
-pid_t ctdbd_pid;
-
/*
allocate a packet for use in client<->daemon communication
*/
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;
}
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,
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,
}
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);
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
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);
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;
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;
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];
}