pacemaker/rhbz1611631.patch

231 lines
9.4 KiB
Diff
Raw Normal View History

From 1f05f5e22361f9c47aa5f23b0b1889b6eb09351a Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 8 Aug 2018 15:26:26 -0500
Subject: [PATCH 1/2] Fix: pacemaker-based: inform originator of CIB upgrade
failure
"cibadmin --upgrade" sends an upgrade request to its local CIB manager,
which forwards the request to the DC. If the DC successfully upgrades the CIB,
it broadcasts a message causing all peers to perform the upgrade, which also
results in local clients such as cibadmin being notified.
However, if the upgrade is either not necessary or fails, the DC would simply
ignore the request, and local clients would time out waiting for a reply that
would never come. Now, the DC will send the error result to the originating
peer, which will notify its clients.
---
daemons/based/based_callbacks.c | 17 ++++++++++----
daemons/based/based_messages.c | 40 ++++++++++++++++++++++++++++++---
include/crm/cib/internal.h | 19 +++++-----------
3 files changed, 55 insertions(+), 21 deletions(-)
diff --git a/daemons/based/based_callbacks.c b/daemons/based/based_callbacks.c
index 11bcbef26..ba308c86f 100644
--- a/daemons/based/based_callbacks.c
+++ b/daemons/based/based_callbacks.c
@@ -701,10 +701,18 @@ parse_peer_options_v2(int call_type, xmlNode * request,
* limit on how far newer nodes will go
*/
const char *max = crm_element_value(request, F_CIB_SCHEMA_MAX);
+ const char *upgrade_rc = crm_element_value(request, F_CIB_UPGRADE_RC);
- crm_trace("Parsing %s operation%s for %s with max=%s",
- op, is_reply?" reply":"", cib_is_master?"master":"slave", max);
- if(max == NULL && cib_is_master) {
+ crm_trace("Parsing %s operation%s for %s with max=%s and upgrade_rc=%s",
+ op, (is_reply? " reply" : ""),
+ (cib_is_master? "master" : "slave"),
+ (max? max : "none"), (upgrade_rc? upgrade_rc : "none"));
+
+ if (upgrade_rc != NULL) {
+ // Our upgrade request was rejected by DC, notify clients of result
+ crm_xml_add(request, F_CIB_RC, upgrade_rc);
+
+ } else if ((max == NULL) && cib_is_master) {
/* We are the DC, check if this upgrade is allowed */
goto skip_is_reply;
@@ -713,7 +721,8 @@ parse_peer_options_v2(int call_type, xmlNode * request,
goto skip_is_reply;
} else {
- return FALSE; /* Ignore */
+ // Ignore broadcast client requests when we're not DC
+ return FALSE;
}
} else if (crm_is_true(update)) {
diff --git a/daemons/based/based_messages.c b/daemons/based/based_messages.c
index 9d733dc92..4f513e358 100644
--- a/daemons/based/based_messages.c
+++ b/daemons/based/based_messages.c
@@ -211,6 +211,11 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml
*answer = NULL;
if(crm_element_value(req, F_CIB_SCHEMA_MAX)) {
+ /* The originator of an upgrade request sends it to the DC, without
+ * F_CIB_SCHEMA_MAX. If an upgrade is needed, the DC re-broadcasts the
+ * request with F_CIB_SCHEMA_MAX, and each node performs the upgrade
+ * (and notifies its local clients) here.
+ */
return cib_process_upgrade(
op, options, section, req, input, existing_cib, result_cib, answer);
@@ -220,6 +225,9 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml
xmlNode *scratch = copy_xml(existing_cib);
const char *host = crm_element_value(req, F_ORIG);
const char *value = crm_element_value(existing_cib, XML_ATTR_VALIDATION);
+ const char *client_id = crm_element_value(req, F_CIB_CLIENTID);
+ const char *call_opts = crm_element_value(req, F_CIB_CALLOPTS);
+ const char *call_id = crm_element_value(req, F_CIB_CALLID);
crm_trace("Processing \"%s\" event", op);
if (value != NULL) {
@@ -237,9 +245,9 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml
crm_xml_add(up, F_CIB_OPERATION, CIB_OP_UPGRADE);
crm_xml_add(up, F_CIB_SCHEMA_MAX, get_schema_name(new_version));
crm_xml_add(up, F_CIB_DELEGATED, host);
- crm_xml_add(up, F_CIB_CLIENTID, crm_element_value(req, F_CIB_CLIENTID));
- crm_xml_add(up, F_CIB_CALLOPTS, crm_element_value(req, F_CIB_CALLOPTS));
- crm_xml_add(up, F_CIB_CALLID, crm_element_value(req, F_CIB_CALLID));
+ crm_xml_add(up, F_CIB_CLIENTID, client_id);
+ crm_xml_add(up, F_CIB_CALLOPTS, call_opts);
+ crm_xml_add(up, F_CIB_CALLID, call_id);
if (cib_legacy_mode() && cib_is_master) {
rc = cib_process_upgrade(
@@ -255,6 +263,32 @@ cib_process_upgrade_server(const char *op, int options, const char *section, xml
rc = -pcmk_err_schema_unchanged;
}
+ if (rc != pcmk_ok) {
+ // Notify originating peer so it can notify its local clients
+ crm_node_t *origin = crm_find_peer(0, host);
+
+ crm_info("Rejecting upgrade request from %s: %s "
+ CRM_XS " rc=%d peer=%s", host, pcmk_strerror(rc), rc,
+ (origin? origin->uname : "lost"));
+
+ if (origin) {
+ xmlNode *up = create_xml_node(NULL, __FUNCTION__);
+
+ crm_xml_add(up, F_TYPE, "cib");
+ crm_xml_add(up, F_CIB_OPERATION, CIB_OP_UPGRADE);
+ crm_xml_add(up, F_CIB_DELEGATED, host);
+ crm_xml_add(up, F_CIB_ISREPLY, host);
+ crm_xml_add(up, F_CIB_CLIENTID, client_id);
+ crm_xml_add(up, F_CIB_CALLOPTS, call_opts);
+ crm_xml_add(up, F_CIB_CALLID, call_id);
+ crm_xml_add_int(up, F_CIB_UPGRADE_RC, rc);
+ if (send_cluster_message(origin, crm_msg_cib, up, TRUE)
+ == FALSE) {
+ crm_warn("Could not send CIB upgrade result to %s", host);
+ }
+ free_xml(up);
+ }
+ }
free_xml(scratch);
}
return rc;
diff --git a/include/crm/cib/internal.h b/include/crm/cib/internal.h
index c3eb00f9f..5497fe9d3 100644
--- a/include/crm/cib/internal.h
+++ b/include/crm/cib/internal.h
@@ -1,20 +1,10 @@
/*
- * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * This source code is licensed under the GNU Lesser General Public License
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
+
#ifndef CIB_INTERNAL__H
# define CIB_INTERNAL__H
# include <crm/cib.h>
@@ -46,6 +36,7 @@
# define F_CIB_SECTION "cib_section"
# define F_CIB_HOST "cib_host"
# define F_CIB_RC "cib_rc"
+# define F_CIB_UPGRADE_RC "cib_upgrade_rc"
# define F_CIB_DELEGATED "cib_delegated_from"
# define F_CIB_OBJID "cib_object"
# define F_CIB_OBJTYPE "cib_object_type"
--
2.18.0.rc2
From 8576f3a2058fd7191b9823d6ab83012b55a6b958 Mon Sep 17 00:00:00 2001
From: Ken Gaillot <kgaillot@redhat.com>
Date: Wed, 8 Aug 2018 16:02:05 -0500
Subject: [PATCH 2/2] Low: tools: already latest schema is not failure for
cibadmin --upgrade
a2950209 handled sync results only (cibadmin -s)
---
tools/cibadmin.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/tools/cibadmin.c b/tools/cibadmin.c
index 410eea930..96caf3483 100644
--- a/tools/cibadmin.c
+++ b/tools/cibadmin.c
@@ -155,6 +155,17 @@ print_xml_output(xmlNode * xml)
}
}
+// Upgrade requested but already at latest schema
+static void
+report_schema_unchanged()
+{
+ const char *err = pcmk_strerror(pcmk_err_schema_unchanged);
+
+ crm_info("Upgrade unnecessary: %s\n", err);
+ printf("Upgrade unnecessary: %s\n", err);
+ exit_code = CRM_EX_OK;
+}
+
int
main(int argc, char **argv)
{
@@ -425,10 +436,7 @@ main(int argc, char **argv)
} else if ((rc == -pcmk_err_schema_unchanged)
&& crm_str_eq(cib_action, CIB_OP_UPGRADE, TRUE)) {
-
- // Already at latest schema
- crm_info("Upgrade unnecessary: %s\n", pcmk_strerror(rc));
- printf("Upgrade unnecessary: %s\n", pcmk_strerror(rc));
+ report_schema_unchanged();
} else if (rc < 0) {
crm_err("Call failed: %s", pcmk_strerror(rc));
@@ -513,7 +521,10 @@ cibadmin_op_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void
{
exit_code = crm_errno2exit(rc);
- if (rc != 0) {
+ if (rc == -pcmk_err_schema_unchanged) {
+ report_schema_unchanged();
+
+ } else if (rc != pcmk_ok) {
crm_warn("Call %s failed (%d): %s", cib_action, rc, pcmk_strerror(rc));
fprintf(stderr, "Call %s failed (%d): %s\n", cib_action, rc, pcmk_strerror(rc));
print_xml_output(output);
--
2.18.0.rc2