*/
#include "includes.h"
-#include "lib/events/events.h"
+#include "lib/tevent/tevent.h"
#include "lib/tdb/include/tdb.h"
#include "system/network.h"
#include "system/filesys.h"
/* now the contended path */
h = ctdb_lockwait(ctdb_db, key, lock_fetch_callback, state);
if (h == NULL) {
- tdb_chainunlock(tdb, key);
return -1;
}
if (ret == 0) {
ret = ctdb_ltdb_fetch(ctdb_db, key, header, hdr, data);
if (ret != 0) {
- ctdb_ltdb_unlock(ctdb_db, key);
+ int uret;
+ uret = ctdb_ltdb_unlock(ctdb_db, key);
+ if (uret != 0) {
+ DEBUG(DEBUG_ERR,(__location__ " ctdb_ltdb_unlock() failed with error %d\n", uret));
+ }
}
}
return ret;
return 0 on success, -1 on failure
*/
static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
- bool persistent, const char *unhealthy_reason)
+ bool persistent, const char *unhealthy_reason,
+ bool jenkinshash)
{
struct ctdb_db_context *ctdb_db, *tmp_db;
int ret;
db_name, ctdb->pnn);
tdb_flags = persistent? TDB_DEFAULT : TDB_CLEAR_IF_FIRST | TDB_NOSYNC;
- if (!ctdb->do_setsched) {
+ if (ctdb->valgrinding) {
tdb_flags |= TDB_NOMMAP;
}
tdb_flags |= TDB_DISALLOW_NESTING;
+ if (jenkinshash) {
+ tdb_flags |= TDB_INCOMPATIBLE_HASH;
+ }
again:
ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path,
*/
int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
TDB_DATA *outdata, uint64_t tdb_flags,
- bool persistent)
+ bool persistent, uint32_t client_id)
{
const char *db_name = (const char *)indata.dptr;
struct ctdb_db_context *db;
- struct ctdb_node *node = ctdb->nodes[ctdb->pnn];
+ struct ctdb_node *node;
+
+ /* dont allow any local clients to attach while we are in recovery mode
+ * except for the recovery daemon.
+ * allow all attach from the network since these are always from remote
+ * recovery daemons.
+ */
+ if (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE && client_id != 0) {
+ struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
+
+ if (client != NULL && client->pid != ctdb->recoverd_pid) {
+ DEBUG(DEBUG_ERR,("DB Attach to database %s refused for client with pid:%d since node is in recovery mode.\n", db_name, client->pid));
+ return -1;
+ }
+ }
+
+ node = ctdb->nodes[ctdb->pnn];
/* the client can optionally pass additional tdb flags, but we
only allow a subset of those on the database in ctdb. Note
that tdb_flags is passed in via the (otherwise unused)
srvid to the attach control */
- tdb_flags &= TDB_NOSYNC;
+ tdb_flags &= (TDB_NOSYNC|TDB_INCOMPATIBLE_HASH);
/* If the node is inactive it is not part of the cluster
and we should not allow clients to attach to any
return 0;
}
- if (ctdb_local_attach(ctdb, db_name, persistent, NULL) != 0) {
+ if (ctdb_local_attach(ctdb, db_name, persistent, NULL, (tdb_flags&TDB_INCOMPATIBLE_HASH)?true:false) != 0) {
return -1;
}
outdata->dptr = (uint8_t *)&db->db_id;
outdata->dsize = sizeof(db->db_id);
+ /* Try to ensure it's locked in mem */
+ ctdb_lockdown_memory(ctdb);
+
/* tell all the other nodes about this database */
- ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_ALL, 0,
+ ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_ALL, tdb_flags,
persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:
CTDB_CONTROL_DB_ATTACH,
0, CTDB_CTRL_FLAG_NOREPLY,
}
p[4] = 0;
- if (ctdb_local_attach(ctdb, s, true, unhealthy_reason) != 0) {
+ if (ctdb_local_attach(ctdb, s, true, unhealthy_reason, 0) != 0) {
DEBUG(DEBUG_ERR,("Failed to attach to persistent database '%s'\n", de->d_name));
closedir(d);
talloc_free(s);