*/
#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;
}
+
+/*
+ mark a database - as healthy
+ */
+int32_t ctdb_control_db_set_healthy(struct ctdb_context *ctdb, TDB_DATA indata)
+{
+ uint32_t db_id = *(uint32_t *)indata.dptr;
+ struct ctdb_db_context *ctdb_db;
+ int ret;
+ bool may_recover = false;
+
+ ctdb_db = find_ctdb_db(ctdb, db_id);
+ if (!ctdb_db) {
+ DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%x\n", db_id));
+ return -1;
+ }
+
+ if (ctdb_db->unhealthy_reason) {
+ may_recover = true;
+ }
+
+ ret = ctdb_update_persistent_health(ctdb, ctdb_db, NULL, 1);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,(__location__
+ " ctdb_update_persistent_health(%s) failed\n",
+ ctdb_db->db_name));
+ return -1;
+ }
+
+ if (may_recover && !ctdb->done_startup) {
+ DEBUG(DEBUG_ERR, (__location__ " db %s become healthy - force recovery for startup\n",
+ ctdb_db->db_name));
+ ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
+ }
+
+ return 0;
+}
+
+int32_t ctdb_control_db_get_health(struct ctdb_context *ctdb,
+ TDB_DATA indata,
+ TDB_DATA *outdata)
+{
+ uint32_t db_id = *(uint32_t *)indata.dptr;
+ struct ctdb_db_context *ctdb_db;
+ int ret;
+
+ ctdb_db = find_ctdb_db(ctdb, db_id);
+ if (!ctdb_db) {
+ DEBUG(DEBUG_ERR,(__location__ " Unknown db 0x%x\n", db_id));
+ return -1;
+ }
+
+ ret = ctdb_load_persistent_health(ctdb, ctdb_db);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,(__location__
+ " ctdb_load_persistent_health(%s) failed\n",
+ ctdb_db->db_name));
+ return -1;
+ }
+
+ *outdata = tdb_null;
+ if (ctdb_db->unhealthy_reason) {
+ outdata->dptr = (uint8_t *)ctdb_db->unhealthy_reason;
+ outdata->dsize = strlen(ctdb_db->unhealthy_reason)+1;
+ }
+
+ return 0;
+}
+
/*
attach to a database, handling both persistent and non-persistent databases
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,
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);