diff options
author | Stefan Metzmacher <metze@samba.org> | 2009-11-29 12:39:37 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-12-16 08:03:56 +0100 |
commit | b74918b465a91bbe437e5cbc077115a24e20265b (patch) | |
tree | 0850b2860ebac4d90af8310f1da3958326ed360e /ctdb | |
parent | 7f05a423e215e706c279c9734cc8d353ecd5a42a (diff) | |
download | samba-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.h | 1 | ||||
-rw-r--r-- | ctdb/server/ctdb_ltdb_server.c | 121 |
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; } |