summaryrefslogtreecommitdiffstats
path: root/ctdb
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-11-29 12:39:37 +0100
committerStefan Metzmacher <metze@samba.org>2009-12-16 08:03:56 +0100
commitb74918b465a91bbe437e5cbc077115a24e20265b (patch)
tree0850b2860ebac4d90af8310f1da3958326ed360e /ctdb
parent7f05a423e215e706c279c9734cc8d353ecd5a42a (diff)
downloadsamba-b74918b465a91bbe437e5cbc077115a24e20265b.tar.gz
samba-b74918b465a91bbe437e5cbc077115a24e20265b.tar.xz
samba-b74918b465a91bbe437e5cbc077115a24e20265b.zip
server: open /var/ctdb/state/persistent_health.tdb.X on startup
This node internal tdb will store the HEALTH state of persistent tdbs. metze (This used to be ctdb commit cbda4666be88c11a810a192a70667b57f773ace1)
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/include/ctdb_private.h1
-rw-r--r--ctdb/server/ctdb_ltdb_server.c121
2 files changed, 117 insertions, 5 deletions
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index b99f12e1f1..5f63c8f97b 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -406,6 +406,7 @@ struct ctdb_context {
const char *db_directory;
const char *db_directory_persistent;
const char *db_directory_state;
+ struct tdb_wrap *db_persistent_health;
const char *transport;
char *recovery_lock_file;
int recovery_lock_fd;
diff --git a/ctdb/server/ctdb_ltdb_server.c b/ctdb/server/ctdb_ltdb_server.c
index 162a694b83..9a4044e0ca 100644
--- a/ctdb/server/ctdb_ltdb_server.c
+++ b/ctdb/server/ctdb_ltdb_server.c
@@ -28,6 +28,8 @@
#include "lib/util/dlinklist.h"
#include <ctype.h>
+#define PERSISTENT_HEALTH_TDB "persistent_health.tdb"
+
/*
this is the dummy null procedure that all databases support
*/
@@ -193,7 +195,8 @@ static void ctdb_check_db_empty(struct ctdb_db_context *ctdb_db)
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)
+static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
+ bool persistent, const char *unhealthy_reason)
{
struct ctdb_db_context *ctdb_db, *tmp_db;
int ret;
@@ -327,7 +330,7 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
return 0;
}
- if (ctdb_local_attach(ctdb, db_name, persistent) != 0) {
+ if (ctdb_local_attach(ctdb, db_name, persistent, NULL) != 0) {
return -1;
}
@@ -358,7 +361,8 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
/*
attach to all existing persistent databases
*/
-static int ctdb_attach_persistent(struct ctdb_context *ctdb)
+static int ctdb_attach_persistent(struct ctdb_context *ctdb,
+ const char *unhealthy_reason)
{
DIR *d;
struct dirent *de;
@@ -399,12 +403,13 @@ static int ctdb_attach_persistent(struct ctdb_context *ctdb)
}
p[4] = 0;
- if (ctdb_local_attach(ctdb, s, true) != 0) {
+ if (ctdb_local_attach(ctdb, s, true, unhealthy_reason) != 0) {
DEBUG(DEBUG_ERR,("Failed to attach to persistent database '%s'\n", de->d_name));
closedir(d);
talloc_free(s);
return -1;
}
+
DEBUG(DEBUG_INFO,("Attached to persistent database %s\n", s));
talloc_free(s);
@@ -416,6 +421,9 @@ static int ctdb_attach_persistent(struct ctdb_context *ctdb)
int ctdb_attach_databases(struct ctdb_context *ctdb)
{
int ret;
+ char *persistent_health_path = NULL;
+ char *unhealthy_reason = NULL;
+ bool first_try = true;
if (ctdb->db_directory == NULL) {
ctdb->db_directory = VARDIR "/ctdb";
@@ -451,7 +459,110 @@ int ctdb_attach_databases(struct ctdb_context *ctdb)
return -1;
}
- ret = ctdb_attach_persistent(ctdb);
+ persistent_health_path = talloc_asprintf(ctdb, "%s/%s.%u",
+ ctdb->db_directory_state,
+ PERSISTENT_HEALTH_TDB,
+ ctdb->pnn);
+ if (persistent_health_path == NULL) {
+ DEBUG(DEBUG_CRIT,(__location__ " talloc_asprintf() failed\n"));
+ return -1;
+ }
+
+again:
+
+ ctdb->db_persistent_health = tdb_wrap_open(ctdb, persistent_health_path,
+ 0, TDB_DISALLOW_NESTING,
+ O_CREAT | O_RDWR, 0600);
+ if (ctdb->db_persistent_health == NULL) {
+ struct tdb_wrap *tdb;
+
+ if (!first_try) {
+ DEBUG(DEBUG_CRIT,("Failed to open tdb '%s': %d - %s\n",
+ persistent_health_path,
+ errno,
+ strerror(errno)));
+ talloc_free(persistent_health_path);
+ talloc_free(unhealthy_reason);
+ return -1;
+ }
+ first_try = false;
+
+ unhealthy_reason = talloc_asprintf(ctdb, "WARNING - '%s' %s - %s",
+ persistent_health_path,
+ "was cleared after a failure",
+ "manual verification needed");
+ if (unhealthy_reason == NULL) {
+ DEBUG(DEBUG_CRIT,(__location__ " talloc_asprintf() failed\n"));
+ talloc_free(persistent_health_path);
+ return -1;
+ }
+
+ DEBUG(DEBUG_CRIT,("Failed to open tdb '%s' - retrying after CLEAR_IF_FIRST\n",
+ persistent_health_path));
+ tdb = tdb_wrap_open(ctdb, persistent_health_path,
+ 0, TDB_CLEAR_IF_FIRST | TDB_DISALLOW_NESTING,
+ O_CREAT | O_RDWR, 0600);
+ if (tdb) {
+ DEBUG(DEBUG_CRIT,("Failed to open tdb '%s' - with CLEAR_IF_FIRST: %d - %s\n",
+ persistent_health_path,
+ errno,
+ strerror(errno)));
+ talloc_free(persistent_health_path);
+ talloc_free(unhealthy_reason);
+ return -1;
+ }
+
+ talloc_free(tdb);
+ goto again;
+ }
+ ret = tdb_check(ctdb->db_persistent_health->tdb, NULL, NULL);
+ if (ret != 0) {
+ struct tdb_wrap *tdb;
+
+ talloc_free(ctdb->db_persistent_health);
+ ctdb->db_persistent_health = NULL;
+
+ if (!first_try) {
+ DEBUG(DEBUG_CRIT,("tdb_check('%s') failed\n",
+ persistent_health_path));
+ talloc_free(persistent_health_path);
+ talloc_free(unhealthy_reason);
+ return -1;
+ }
+ first_try = false;
+
+ unhealthy_reason = talloc_asprintf(ctdb, "WARNING - '%s' %s - %s",
+ persistent_health_path,
+ "was cleared after a failure",
+ "manual verification needed");
+ if (unhealthy_reason == NULL) {
+ DEBUG(DEBUG_CRIT,(__location__ " talloc_asprintf() failed\n"));
+ talloc_free(persistent_health_path);
+ return -1;
+ }
+
+ DEBUG(DEBUG_CRIT,("tdb_check('%s') failed - retrying after CLEAR_IF_FIRST\n",
+ persistent_health_path));
+ tdb = tdb_wrap_open(ctdb, persistent_health_path,
+ 0, TDB_CLEAR_IF_FIRST | TDB_DISALLOW_NESTING,
+ O_CREAT | O_RDWR, 0600);
+ if (tdb) {
+ DEBUG(DEBUG_CRIT,("Failed to open tdb '%s' - with CLEAR_IF_FIRST: %d - %s\n",
+ persistent_health_path,
+ errno,
+ strerror(errno)));
+ talloc_free(persistent_health_path);
+ talloc_free(unhealthy_reason);
+ return -1;
+ }
+
+ talloc_free(tdb);
+ goto again;
+ }
+ talloc_free(persistent_health_path);
+
+ ret = ctdb_attach_persistent(ctdb, unhealthy_reason);
+ talloc_free(unhealthy_reason);
if (ret != 0) {
return ret;
}