|
|
646f31 |
From a716a8ddd3df615009bcff3bd96dd9ae64cb5f68 Mon Sep 17 00:00:00 2001
|
|
|
646f31 |
From: Klaus Wenninger <klaus.wenninger@aon.at>
|
|
|
646f31 |
Date: Tue, 19 Mar 2019 21:36:15 +0100
|
|
|
646f31 |
Subject: [PATCH] Fix: sbd-pacemaker: make handling of cib-connection loss more
|
|
|
646f31 |
robust
|
|
|
646f31 |
|
|
|
646f31 |
Exit pcmk-servant on graceful pacemaker shutdown and go back
|
|
|
646f31 |
to state before pacemaker was detected initially.
|
|
|
646f31 |
Purge all cib-traces otherwise and try to reconnect within timeout.
|
|
|
646f31 |
---
|
|
|
646f31 |
src/sbd-inquisitor.c | 24 ++++++++++++++++++++----
|
|
|
646f31 |
src/sbd-md.c | 30 +++++++++++++++---------------
|
|
|
646f31 |
src/sbd-pacemaker.c | 38 +++++++++++++++++++++++++++++---------
|
|
|
646f31 |
src/sbd.h | 11 +++++++----
|
|
|
646f31 |
4 files changed, 71 insertions(+), 32 deletions(-)
|
|
|
646f31 |
|
|
|
646f31 |
diff --git a/src/sbd-inquisitor.c b/src/sbd-inquisitor.c
|
|
|
646f31 |
index 9be6c99..77c6e4f 100644
|
|
|
646f31 |
--- a/src/sbd-inquisitor.c
|
|
|
646f31 |
+++ b/src/sbd-inquisitor.c
|
|
|
646f31 |
@@ -490,19 +490,19 @@ void inquisitor_child(void)
|
|
|
646f31 |
if (sbd_is_disk(s)) {
|
|
|
646f31 |
if (WIFEXITED(status)) {
|
|
|
646f31 |
switch(WEXITSTATUS(status)) {
|
|
|
646f31 |
- case EXIT_MD_IO_FAIL:
|
|
|
646f31 |
+ case EXIT_MD_SERVANT_IO_FAIL:
|
|
|
646f31 |
DBGLOG(LOG_INFO, "Servant for %s requests to be disowned",
|
|
|
646f31 |
s->devname);
|
|
|
646f31 |
break;
|
|
|
646f31 |
- case EXIT_MD_REQUEST_RESET:
|
|
|
646f31 |
+ case EXIT_MD_SERVANT_REQUEST_RESET:
|
|
|
646f31 |
cl_log(LOG_WARNING, "%s requested a reset", s->devname);
|
|
|
646f31 |
do_reset();
|
|
|
646f31 |
break;
|
|
|
646f31 |
- case EXIT_MD_REQUEST_SHUTOFF:
|
|
|
646f31 |
+ case EXIT_MD_SERVANT_REQUEST_SHUTOFF:
|
|
|
646f31 |
cl_log(LOG_WARNING, "%s requested a shutoff", s->devname);
|
|
|
646f31 |
do_off();
|
|
|
646f31 |
break;
|
|
|
646f31 |
- case EXIT_MD_REQUEST_CRASHDUMP:
|
|
|
646f31 |
+ case EXIT_MD_SERVANT_REQUEST_CRASHDUMP:
|
|
|
646f31 |
cl_log(LOG_WARNING, "%s requested a crashdump", s->devname);
|
|
|
646f31 |
do_crashdump();
|
|
|
646f31 |
break;
|
|
|
646f31 |
@@ -510,6 +510,22 @@ void inquisitor_child(void)
|
|
|
646f31 |
break;
|
|
|
646f31 |
}
|
|
|
646f31 |
}
|
|
|
646f31 |
+ } else if (sbd_is_pcmk(s)) {
|
|
|
646f31 |
+ if (WIFEXITED(status)) {
|
|
|
646f31 |
+ switch(WEXITSTATUS(status)) {
|
|
|
646f31 |
+ case EXIT_PCMK_SERVANT_GRACEFUL_SHUTDOWN:
|
|
|
646f31 |
+ DBGLOG(LOG_INFO, "PCMK-Servant has exited gracefully");
|
|
|
646f31 |
+ /* revert to state prior to pacemaker-detection */
|
|
|
646f31 |
+ s->restarts = 0;
|
|
|
646f31 |
+ s->restart_blocked = 0;
|
|
|
646f31 |
+ cluster_appeared = 0;
|
|
|
646f31 |
+ s->outdated = 1;
|
|
|
646f31 |
+ s->t_last.tv_sec = 0;
|
|
|
646f31 |
+ break;
|
|
|
646f31 |
+ default:
|
|
|
646f31 |
+ break;
|
|
|
646f31 |
+ }
|
|
|
646f31 |
+ }
|
|
|
646f31 |
}
|
|
|
646f31 |
cleanup_servant_by_pid(pid);
|
|
|
646f31 |
}
|
|
|
646f31 |
diff --git a/src/sbd-md.c b/src/sbd-md.c
|
|
|
646f31 |
index ba2c34d..c51d381 100644
|
|
|
646f31 |
--- a/src/sbd-md.c
|
|
|
646f31 |
+++ b/src/sbd-md.c
|
|
|
646f31 |
@@ -1061,19 +1061,19 @@ int servant_md(const char *diskname, int mode, const void* argp)
|
|
|
646f31 |
|
|
|
646f31 |
st = open_device(diskname, LOG_WARNING);
|
|
|
646f31 |
if (!st) {
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
s_header = header_get(st);
|
|
|
646f31 |
if (!s_header) {
|
|
|
646f31 |
cl_log(LOG_ERR, "Not a valid header on %s", diskname);
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
if (servant_check_timeout_inconsistent(s_header) < 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "Timeouts on %s do not match first device",
|
|
|
646f31 |
diskname);
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
if (s_header->minor_version > 0) {
|
|
|
646f31 |
@@ -1086,14 +1086,14 @@ int servant_md(const char *diskname, int mode, const void* argp)
|
|
|
646f31 |
cl_log(LOG_ERR,
|
|
|
646f31 |
"No slot allocated, and automatic allocation failed for disk %s.",
|
|
|
646f31 |
diskname);
|
|
|
646f31 |
- rc = EXIT_MD_IO_FAIL;
|
|
|
646f31 |
+ rc = EXIT_MD_SERVANT_IO_FAIL;
|
|
|
646f31 |
goto out;
|
|
|
646f31 |
}
|
|
|
646f31 |
s_node = sector_alloc();
|
|
|
646f31 |
if (slot_read(st, mbox, s_node) < 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "Unable to read node entry on %s",
|
|
|
646f31 |
diskname);
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
cl_log(LOG_NOTICE, "Monitoring slot %d on disk %s", mbox, diskname);
|
|
|
646f31 |
@@ -1109,7 +1109,7 @@ int servant_md(const char *diskname, int mode, const void* argp)
|
|
|
646f31 |
if (mode > 0) {
|
|
|
646f31 |
if (mbox_read(st, mbox, s_mbox) < 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "mbox read failed during start-up in servant.");
|
|
|
646f31 |
- rc = EXIT_MD_IO_FAIL;
|
|
|
646f31 |
+ rc = EXIT_MD_SERVANT_IO_FAIL;
|
|
|
646f31 |
goto out;
|
|
|
646f31 |
}
|
|
|
646f31 |
if (s_mbox->cmd != SBD_MSG_EXIT &&
|
|
|
646f31 |
@@ -1125,7 +1125,7 @@ int servant_md(const char *diskname, int mode, const void* argp)
|
|
|
646f31 |
DBGLOG(LOG_INFO, "First servant start - zeroing inbox");
|
|
|
646f31 |
memset(s_mbox, 0, sizeof(*s_mbox));
|
|
|
646f31 |
if (mbox_write(st, mbox, s_mbox) < 0) {
|
|
|
646f31 |
- rc = EXIT_MD_IO_FAIL;
|
|
|
646f31 |
+ rc = EXIT_MD_SERVANT_IO_FAIL;
|
|
|
646f31 |
goto out;
|
|
|
646f31 |
}
|
|
|
646f31 |
}
|
|
|
646f31 |
@@ -1154,28 +1154,28 @@ int servant_md(const char *diskname, int mode, const void* argp)
|
|
|
646f31 |
s_header_retry = header_get(st);
|
|
|
646f31 |
if (!s_header_retry) {
|
|
|
646f31 |
cl_log(LOG_ERR, "No longer found a valid header on %s", diskname);
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
if (memcmp(s_header, s_header_retry, sizeof(*s_header)) != 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "Header on %s changed since start-up!", diskname);
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
free(s_header_retry);
|
|
|
646f31 |
|
|
|
646f31 |
s_node_retry = sector_alloc();
|
|
|
646f31 |
if (slot_read(st, mbox, s_node_retry) < 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "slot read failed in servant.");
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
if (memcmp(s_node, s_node_retry, sizeof(*s_node)) != 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "Node entry on %s changed since start-up!", diskname);
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
free(s_node_retry);
|
|
|
646f31 |
|
|
|
646f31 |
if (mbox_read(st, mbox, s_mbox) < 0) {
|
|
|
646f31 |
cl_log(LOG_ERR, "mbox read failed in servant.");
|
|
|
646f31 |
- exit(EXIT_MD_IO_FAIL);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_IO_FAIL);
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
if (s_mbox->cmd > 0) {
|
|
|
646f31 |
@@ -1190,14 +1190,14 @@ int servant_md(const char *diskname, int mode, const void* argp)
|
|
|
646f31 |
sigqueue(ppid, SIG_TEST, signal_value);
|
|
|
646f31 |
break;
|
|
|
646f31 |
case SBD_MSG_RESET:
|
|
|
646f31 |
- exit(EXIT_MD_REQUEST_RESET);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_REQUEST_RESET);
|
|
|
646f31 |
case SBD_MSG_OFF:
|
|
|
646f31 |
- exit(EXIT_MD_REQUEST_SHUTOFF);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_REQUEST_SHUTOFF);
|
|
|
646f31 |
case SBD_MSG_EXIT:
|
|
|
646f31 |
sigqueue(ppid, SIG_EXITREQ, signal_value);
|
|
|
646f31 |
break;
|
|
|
646f31 |
case SBD_MSG_CRASHDUMP:
|
|
|
646f31 |
- exit(EXIT_MD_REQUEST_CRASHDUMP);
|
|
|
646f31 |
+ exit(EXIT_MD_SERVANT_REQUEST_CRASHDUMP);
|
|
|
646f31 |
default:
|
|
|
646f31 |
/* FIXME:
|
|
|
646f31 |
An "unknown" message might result
|
|
|
646f31 |
diff --git a/src/sbd-pacemaker.c b/src/sbd-pacemaker.c
|
|
|
646f31 |
index aac355a..c69fc55 100644
|
|
|
646f31 |
--- a/src/sbd-pacemaker.c
|
|
|
646f31 |
+++ b/src/sbd-pacemaker.c
|
|
|
646f31 |
@@ -103,6 +103,9 @@ static pe_working_set_t *data_set = NULL;
|
|
|
646f31 |
|
|
|
646f31 |
static long last_refresh = 0;
|
|
|
646f31 |
|
|
|
646f31 |
+static int pcmk_clean_shutdown = 0;
|
|
|
646f31 |
+static int pcmk_shutdown = 0;
|
|
|
646f31 |
+
|
|
|
646f31 |
static gboolean
|
|
|
646f31 |
mon_timer_reconnect(gpointer data)
|
|
|
646f31 |
{
|
|
|
646f31 |
@@ -128,10 +131,26 @@ mon_cib_connection_destroy(gpointer user_data)
|
|
|
646f31 |
{
|
|
|
646f31 |
if (cib) {
|
|
|
646f31 |
cib->cmds->signoff(cib);
|
|
|
646f31 |
+ /* retrigger as last one might have been skipped */
|
|
|
646f31 |
+ mon_refresh_state(NULL);
|
|
|
646f31 |
+ if (pcmk_clean_shutdown) {
|
|
|
646f31 |
+ /* assume a graceful pacemaker-shutdown */
|
|
|
646f31 |
+ clean_up(EXIT_PCMK_SERVANT_GRACEFUL_SHUTDOWN);
|
|
|
646f31 |
+ }
|
|
|
646f31 |
+ /* getting here we aren't sure about the pacemaker-state
|
|
|
646f31 |
+ so try to use the timeout to reconnect and get
|
|
|
646f31 |
+ everything sorted out again
|
|
|
646f31 |
+ */
|
|
|
646f31 |
+ pcmk_shutdown = 0;
|
|
|
646f31 |
set_servant_health(pcmk_health_transient, LOG_WARNING, "Disconnected from CIB");
|
|
|
646f31 |
timer_id_reconnect = g_timeout_add(reconnect_msec, mon_timer_reconnect, NULL);
|
|
|
646f31 |
}
|
|
|
646f31 |
cib_connected = 0;
|
|
|
646f31 |
+ /* no sense in looking into outdated cib, trying to apply patch, ... */
|
|
|
646f31 |
+ if (current_cib) {
|
|
|
646f31 |
+ free_xml(current_cib);
|
|
|
646f31 |
+ current_cib = NULL;
|
|
|
646f31 |
+ }
|
|
|
646f31 |
return;
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
@@ -171,7 +190,7 @@ static gboolean
|
|
|
646f31 |
mon_timer_notify(gpointer data)
|
|
|
646f31 |
{
|
|
|
646f31 |
static int counter = 0;
|
|
|
646f31 |
- int counter_max = timeout_watchdog / timeout_loop;
|
|
|
646f31 |
+ int counter_max = timeout_watchdog / timeout_loop / 2;
|
|
|
646f31 |
|
|
|
646f31 |
if (timer_id_notify > 0) {
|
|
|
646f31 |
g_source_remove(timer_id_notify);
|
|
|
646f31 |
@@ -280,11 +299,6 @@ compute_status(pe_working_set_t * data_set)
|
|
|
646f31 |
} else if (node->details->pending) {
|
|
|
646f31 |
set_servant_health(pcmk_health_pending, LOG_WARNING, "Node state: pending");
|
|
|
646f31 |
|
|
|
646f31 |
-#if 0
|
|
|
646f31 |
- } else if (node->details->shutdown) {
|
|
|
646f31 |
- set_servant_health(pcmk_health_shutdown, LOG_WARNING, "Node state: shutting down");
|
|
|
646f31 |
-#endif
|
|
|
646f31 |
-
|
|
|
646f31 |
} else if (data_set->flags & pe_flag_have_quorum) {
|
|
|
646f31 |
set_servant_health(pcmk_health_online, LOG_INFO, "Node state: online");
|
|
|
646f31 |
ever_had_quorum = TRUE;
|
|
|
646f31 |
@@ -315,6 +329,12 @@ compute_status(pe_working_set_t * data_set)
|
|
|
646f31 |
}
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
+ if (node->details->shutdown) {
|
|
|
646f31 |
+ pcmk_shutdown = 1;
|
|
|
646f31 |
+ }
|
|
|
646f31 |
+ if (pcmk_shutdown && !(node->details->running_rsc)) {
|
|
|
646f31 |
+ pcmk_clean_shutdown = 1;
|
|
|
646f31 |
+ }
|
|
|
646f31 |
notify_parent();
|
|
|
646f31 |
return;
|
|
|
646f31 |
}
|
|
|
646f31 |
@@ -339,7 +359,7 @@ crm_diff_update(const char *event, xmlNode * msg)
|
|
|
646f31 |
static mainloop_timer_t *refresh_timer = NULL;
|
|
|
646f31 |
|
|
|
646f31 |
if(refresh_timer == NULL) {
|
|
|
646f31 |
- refresh_timer = mainloop_timer_add("refresh", 2000, FALSE, mon_trigger_refresh, NULL);
|
|
|
646f31 |
+ refresh_timer = mainloop_timer_add("refresh", reconnect_msec, FALSE, mon_trigger_refresh, NULL);
|
|
|
646f31 |
refresh_trigger = mainloop_add_trigger(G_PRIORITY_LOW, mon_refresh_state, refresh_timer);
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
@@ -369,9 +389,9 @@ crm_diff_update(const char *event, xmlNode * msg)
|
|
|
646f31 |
}
|
|
|
646f31 |
|
|
|
646f31 |
/* Refresh
|
|
|
646f31 |
- * - immediately if the last update was more than 5s ago
|
|
|
646f31 |
+ * - immediately if the last update was more than 1s ago
|
|
|
646f31 |
* - every 10 updates
|
|
|
646f31 |
- * - at most 2s after the last update
|
|
|
646f31 |
+ * - at most 1s after the last update
|
|
|
646f31 |
*/
|
|
|
646f31 |
if (updates > 10 || (now - last_refresh) > (reconnect_msec / 1000)) {
|
|
|
646f31 |
mon_refresh_state(refresh_timer);
|
|
|
646f31 |
diff --git a/src/sbd.h b/src/sbd.h
|
|
|
646f31 |
index 6fe07f9..3b05a11 100644
|
|
|
646f31 |
--- a/src/sbd.h
|
|
|
646f31 |
+++ b/src/sbd.h
|
|
|
646f31 |
@@ -54,10 +54,13 @@
|
|
|
646f31 |
/* FIXME: should add dynamic check of SIG_XX >= SIGRTMAX */
|
|
|
646f31 |
|
|
|
646f31 |
/* exit status for disk-servant */
|
|
|
646f31 |
-#define EXIT_MD_IO_FAIL 20
|
|
|
646f31 |
-#define EXIT_MD_REQUEST_RESET 21
|
|
|
646f31 |
-#define EXIT_MD_REQUEST_SHUTOFF 22
|
|
|
646f31 |
-#define EXIT_MD_REQUEST_CRASHDUMP 23
|
|
|
646f31 |
+#define EXIT_MD_SERVANT_IO_FAIL 20
|
|
|
646f31 |
+#define EXIT_MD_SERVANT_REQUEST_RESET 21
|
|
|
646f31 |
+#define EXIT_MD_SERVANT_REQUEST_SHUTOFF 22
|
|
|
646f31 |
+#define EXIT_MD_SERVANT_REQUEST_CRASHDUMP 23
|
|
|
646f31 |
+
|
|
|
646f31 |
+/* exit status for pcmk-servant */
|
|
|
646f31 |
+#define EXIT_PCMK_SERVANT_GRACEFUL_SHUTDOWN 30
|
|
|
646f31 |
|
|
|
646f31 |
#define HOG_CHAR 0xff
|
|
|
646f31 |
#define SECTOR_NAME_MAX 63
|
|
|
646f31 |
--
|
|
|
646f31 |
1.8.3.1
|
|
|
646f31 |
|