From 6ddb87f6a364bd5c3be651d0ede0ec1c8f48666c Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Thu, 18 Oct 2018 14:33:24 -0500
Subject: [PATCH] Low: attrd: handle shutdown more cleanly

Once shutdown has started, avoid wasting time on such things as updating the
alert configuration, responding to most peer messages, starting a new election,
or writing out attributes after a CIB replace.

This doesn't really matter much since shutdown is self-contained at the moment.
There were plans to change that, but they wound up being unnecessary. These
changes still seem worthwhile, though.
---
 attrd/attrd_common_alerts.c    |  2 +-
 attrd/commands.c  |  8 ++++++++
 attrd/attrd_elections.c |  9 +++++++--
 attrd/attrd_utils.c     | 25 +++++++++++++++++++++----
 attrd/pacemaker-attrd.c |  6 +++++-
 5 files changed, 42 insertions(+), 8 deletions(-)

Index: pacemaker-1.1.16+20170320.77ea74d/attrd/commands.c
===================================================================
--- pacemaker-1.1.16+20170320.77ea74d.orig/attrd/commands.c
+++ pacemaker-1.1.16+20170320.77ea74d/attrd/commands.c
@@ -317,7 +317,10 @@ attrd_client_update(xmlNode *xml)
         }
     }
 
-    if ((peer_writer == NULL) && (election_state(writer) != election_in_progress)) {
+    if ((peer_writer == NULL)
+        && (election_state(writer) != election_in_progress)
+        && !attrd_shutting_down()) {
+
         crm_info("Starting an election to determine the writer");
         election_vote(writer);
     }
@@ -605,7 +608,10 @@ attrd_peer_message(crm_node_t *peer, xml
         enum election_result rc = 0;
 
         crm_xml_add(xml, F_CRM_HOST_FROM, peer->uname);
-        rc = election_count_vote(writer, xml, TRUE);
+
+        // Don't become writer if we're shutting down
+        rc = election_count_vote(writer, xml, !attrd_shutting_down());
+
         switch(rc) {
             case election_start:
                 free(peer_writer);
@@ -651,6 +657,14 @@ attrd_peer_message(crm_node_t *peer, xml
         }
     }
 
+    if (attrd_shutting_down()) {
+        /* If we're shutting down, we want to continue responding to election
+         * ops as long as we're a cluster member (because our vote may be
+         * needed). Ignore all other messages.
+         */
+        return;
+    }
+
     crm_element_value_int(xml, F_ATTRD_WRITER, &peer_state);
     if(election_state(writer) == election_won
        && peer_state == election_won
Index: pacemaker-1.1.16+20170320.77ea74d/attrd/attrd_common.c
===================================================================
--- pacemaker-1.1.16+20170320.77ea74d.orig/attrd/attrd_common.c
+++ pacemaker-1.1.16+20170320.77ea74d/attrd/attrd_common.c
@@ -8,6 +8,7 @@
 #include <crm_internal.h>
 
 #include <stdio.h>
+#include <stdbool.h>
 #include <errno.h>
 #include <glib.h>
 #include <regex.h>
@@ -19,7 +20,9 @@
 
 #include <attrd_common.h>
 
-static gboolean shutting_down = FALSE;
+// volatile because attrd_shutdown() can be called for a signal
+static volatile bool shutting_down = FALSE;
+
 static GMainLoop *mloop = NULL;
 
 /*!
@@ -43,11 +46,25 @@ attrd_shutting_down()
 void
 attrd_shutdown(int nsig)
 {
+    // Tell various functions not to do anthing
     shutting_down = TRUE;
-    if ((mloop != NULL) && g_main_is_running(mloop)) {
-        g_main_quit(mloop);
-    } else {
+
+    // Don't respond to signals while shutting down
+    mainloop_destroy_signal(SIGTERM);
+    mainloop_destroy_signal(SIGCHLD);
+    mainloop_destroy_signal(SIGPIPE);
+    mainloop_destroy_signal(SIGUSR1);
+    mainloop_destroy_signal(SIGUSR2);
+    mainloop_destroy_signal(SIGTRAP);
+
+    if ((mloop == NULL) || !g_main_loop_is_running(mloop)) {
+        /* If there's no main loop active, just exit. This should be possible
+         * only if we get SIGTERM in brief windows at start-up and shutdown.
+         */
         crm_exit(pcmk_ok);
+    } else {
+        g_main_loop_quit(mloop);
+        g_main_loop_unref(mloop);
     }
 }
 
Index: pacemaker-1.1.16+20170320.77ea74d/attrd/main.c
===================================================================
--- pacemaker-1.1.16+20170320.77ea74d.orig/attrd/main.c
+++ pacemaker-1.1.16+20170320.77ea74d/attrd/main.c
@@ -94,8 +94,12 @@ attrd_cpg_destroy(gpointer unused)
 static void
 attrd_cib_replaced_cb(const char *event, xmlNode * msg)
 {
-    crm_notice("Updating all attributes after %s event", event);
+    if (attrd_shutting_down()) {
+        return;
+    }
+
     if(election_state(writer) == election_won) {
+        crm_notice("Updating all attributes after %s event", event);
         write_attributes(TRUE, FALSE);
     }
 }
