From c66c4ded58b06580c88dd2017f9ea8ec13928098 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Tue, 7 Jun 2016 16:58:55 -0500 Subject: [PATCH 01/14] Build: rename sample alert scripts and install them in datadir --- configure.ac | 1 + extra/Makefile.am | 2 +- extra/alerts/Makefile.am | 22 +++++++++++++++++++ ...k_alert_sample.sh => alert_file.sh.sample} | 0 ...mk_smtp_helper.sh => alert_smtp.sh.sample} | 0 ...mk_snmp_helper.sh => alert_snmp.sh.sample} | 0 pacemaker.spec.in | 3 +++ 7 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 extra/alerts/Makefile.am rename extra/alerts/{pcmk_alert_sample.sh => alert_file.sh.sample} (100%) mode change 100755 => 100644 rename extra/alerts/{pcmk_smtp_helper.sh => alert_smtp.sh.sample} (100%) mode change 100755 => 100644 rename extra/alerts/{pcmk_snmp_helper.sh => alert_snmp.sh.sample} (100%) mode change 100755 => 100644 diff --git a/configure.ac b/configure.ac index 1ad807859e9..01853b3cb0d 100644 --- a/configure.ac +++ b/configure.ac @@ -1965,6 +1965,7 @@ lrmd/Makefile \ lrmd/pacemaker_remote.service \ lrmd/pacemaker_remote \ extra/Makefile \ + extra/alerts/Makefile \ extra/resources/Makefile \ extra/logrotate/Makefile \ extra/logrotate/pacemaker \ diff --git a/extra/Makefile.am b/extra/Makefile.am index 40e6cada809..d742ae2cff6 100644 --- a/extra/Makefile.am +++ b/extra/Makefile.am @@ -18,7 +18,7 @@ MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = resources logrotate +SUBDIRS = alerts resources logrotate mibdir = $(datadir)/snmp/mibs mib_DATA = PCMK-MIB.txt diff --git a/extra/alerts/Makefile.am b/extra/alerts/Makefile.am new file mode 100644 index 00000000000..2cd3bd6d91e --- /dev/null +++ b/extra/alerts/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright (C) 2016 Ken Gaillot +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +MAINTAINERCLEANFILES = Makefile.in + +samplesdir = $(datadir)/$(PACKAGE)/alerts/ +samples_DATA = alert_file.sh.sample alert_smtp.sh.sample alert_snmp.sh.sample diff --git a/extra/alerts/pcmk_alert_sample.sh b/extra/alerts/alert_file.sh.sample old mode 100755 new mode 100644 similarity index 100% rename from extra/alerts/pcmk_alert_sample.sh rename to extra/alerts/alert_file.sh.sample diff --git a/extra/alerts/pcmk_smtp_helper.sh b/extra/alerts/alert_smtp.sh.sample old mode 100755 new mode 100644 similarity index 100% rename from extra/alerts/pcmk_smtp_helper.sh rename to extra/alerts/alert_smtp.sh.sample diff --git a/extra/alerts/pcmk_snmp_helper.sh b/extra/alerts/alert_snmp.sh.sample old mode 100755 new mode 100644 similarity index 100% rename from extra/alerts/pcmk_snmp_helper.sh rename to extra/alerts/alert_snmp.sh.sample diff --git a/pacemaker.spec.in b/pacemaker.spec.in index 0378e289013..60245147558 100644 --- a/pacemaker.spec.in +++ b/pacemaker.spec.in @@ -490,6 +490,8 @@ exit 0 %doc %{_mandir}/man8/pacemakerd.* %doc %{_mandir}/man8/stonith_admin.* +%doc %{_datadir}/pacemaker/alerts + %license COPYING %doc AUTHORS %doc ChangeLog @@ -543,6 +545,7 @@ exit 0 %{_sbindir}/crm_simulate %{_sbindir}/crm_report %{_sbindir}/crm_ticket +%exclude %{_datadir}/pacemaker/alerts %exclude %{_datadir}/pacemaker/tests %{_datadir}/pacemaker %{_datadir}/snmp/mibs/PCMK-MIB.txt From de1d2d4caccc0f84d10fe5e74c4c06d4d5d18855 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Tue, 7 Jun 2016 17:54:45 -0500 Subject: [PATCH 02/14] Low: extra: update sample alert scripts for new names and general cleanup --- extra/alerts/alert_file.sh.sample | 26 +++++++++++--------------- extra/alerts/alert_smtp.sh.sample | 31 ++++++++++++++++--------------- extra/alerts/alert_snmp.sh.sample | 29 ++++++----------------------- 3 files changed, 33 insertions(+), 53 deletions(-) diff --git a/extra/alerts/alert_file.sh.sample b/extra/alerts/alert_file.sh.sample index 5bfe383689e..a6a4913c78f 100644 --- a/extra/alerts/alert_file.sh.sample +++ b/extra/alerts/alert_file.sh.sample @@ -17,19 +17,12 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## -# This sample script assumes that only users who already have root access can -# edit the CIB. Otherwise, a malicious user can create damage anywhere in the -# filesystem where user hacluster has access - as well as writing to special -# files. -# If that is not the case in your environment, you should edit this script to -# validate the log-destination. -# # Sample configuration (cib fragment in xml notation) # ================================ # # -# -# +# +# # # # @@ -41,12 +34,15 @@ # if [ -z $CRM_alert_version ]; then - echo "Pacemaker version 1.1.15 is required" >> ${CRM_alert_recipient} + echo "Pacemaker version 1.1.15 or later is required" >> "${CRM_alert_recipient}" exit 0 fi debug_exec_order_default="false" +# Pacemaker passes instance attributes to alert agents as environment variables. +# It is completely up to the agent what instance attributes to support. +# Here, we define an instance attribute "debug_exec_order". : ${debug_exec_order=${debug_exec_order_default}} if [ "${debug_exec_order}" = "true" ] @@ -62,7 +58,7 @@ fi case $CRM_alert_kind in node) - echo "${tstamp}Node '${CRM_alert_node}' is now '${CRM_alert_desc}'" >> ${CRM_alert_recipient} + echo "${tstamp}Node '${CRM_alert_node}' is now '${CRM_alert_desc}'" >> "${CRM_alert_recipient}" ;; fencing) # Other keys: @@ -71,7 +67,7 @@ case $CRM_alert_kind in # CRM_alert_task # CRM_alert_rc # - echo "${tstamp}Fencing ${CRM_alert_desc}" >> ${CRM_alert_recipient} + echo "${tstamp}Fencing ${CRM_alert_desc}" >> "${CRM_alert_recipient}" ;; resource) # Other keys: @@ -95,12 +91,12 @@ case $CRM_alert_kind in case ${CRM_alert_desc} in Cancelled) ;; *) - echo "${tstamp}Resource operation '${CRM_alert_task}${CRM_alert_interval}' for '${CRM_alert_rsc}' on '${CRM_alert_node}': ${CRM_alert_desc}${CRM_alert_target_rc}" >> ${CRM_alert_recipient} + echo "${tstamp}Resource operation '${CRM_alert_task}${CRM_alert_interval}' for '${CRM_alert_rsc}' on '${CRM_alert_node}': ${CRM_alert_desc}${CRM_alert_target_rc}" >> "${CRM_alert_recipient}" ;; esac ;; *) - echo "${tstamp}Unhandled $CRM_alert_kind alert" >> ${CRM_alert_recipient} - env | grep CRM_alert >> ${CRM_alert_recipient} + echo "${tstamp}Unhandled $CRM_alert_kind alert" >> "${CRM_alert_recipient}" + env | grep CRM_alert >> "${CRM_alert_recipient}" ;; esac diff --git a/extra/alerts/alert_smtp.sh.sample b/extra/alerts/alert_smtp.sh.sample index 81bbc5f76bd..e677271f690 100644 --- a/extra/alerts/alert_smtp.sh.sample +++ b/extra/alerts/alert_smtp.sh.sample @@ -22,13 +22,13 @@ # ================================ # # -# -# +# +# # # # # -# +# # # # @@ -56,10 +56,8 @@ if [ ! -z "${email_recipient##*@*}" ]; then fi if [ -z ${CRM_alert_version} ]; then - email_subject="Pacemaker version 1.1.15 is required for smtp-helper" - + email_subject="Pacemaker version 1.1.15 or later is required for alerts" else - case ${CRM_alert_kind} in node) email_subject="${CRM_alert_timestamp} ${cluster_name}: Node '${CRM_alert_node}' is now '${CRM_alert_desc}'" @@ -92,11 +90,15 @@ else ;; esac +fi - if [ ! -z "${email_subject}" ]; then - case $email_client in - sendmail) - sendmail -t -r ${email_sender} <<__EOF__ +if [ ! -z "${email_subject}" ]; then + case $email_client in + # This sample script supports only sendmail for sending the email. + # Support for additional senders can easily be added by adding + # new cases here. + sendmail) + sendmail -t -r "${email_sender}" <<__EOF__ From: ${email_sender} To: ${email_recipient} Return-Path: ${email_sender} @@ -104,9 +106,8 @@ Subject: ${email_subject} ${email_body} __EOF__ - ;; - *) - ;; - esac - fi + ;; + *) + ;; + esac fi diff --git a/extra/alerts/alert_snmp.sh.sample b/extra/alerts/alert_snmp.sh.sample index 8f8de7bc43b..6f16e0e7c44 100644 --- a/extra/alerts/alert_snmp.sh.sample +++ b/extra/alerts/alert_snmp.sh.sample @@ -20,18 +20,17 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # ############################################################################## -# This sample script assumes that only users who already have root access can -# edit the CIB. Otherwise, a malicious user could run commands as hacluster by -# inserting shell code into the trap_options variable. If that is not the case -# in your environment, you should edit this script to remove or validate -# trap_options. +# This sample script assumes that only users who already have +# hacluster-equivalent access to the cluster nodes can edit the CIB. Otherwise, +# a malicious user could run commands as hacluster by inserting shell code into +# the trap_options or timestamp-format parameters. # # Sample configuration (cib fragment in xml notation) # ================================ # # -# -# +# +# # # # @@ -42,22 +41,6 @@ # # # ================================ -# ================================ -# -# -# -# -# -# -# -# -# -# -# -# -# -# -# ================================ if [ -z "$CRM_alert_version" ]; then echo "Pacemaker version 1.1.15 or later is required" From 9cdae519e38955e564ae201c3218f234dad8469c Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Tue, 7 Jun 2016 18:03:27 -0500 Subject: [PATCH 03/14] Doc: Pacemaker Explained: update alerts chapter for new sample script names --- doc/Pacemaker_Explained/en-US/Ch-Alerts.txt | 29 ++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/doc/Pacemaker_Explained/en-US/Ch-Alerts.txt b/doc/Pacemaker_Explained/en-US/Ch-Alerts.txt index 499b6498d7f..2e89293f41b 100644 --- a/doc/Pacemaker_Explained/en-US/Ch-Alerts.txt +++ b/doc/Pacemaker_Explained/en-US/Ch-Alerts.txt @@ -162,14 +162,11 @@ instance attributes are completely up to the particular agent. == Using the Sample Alert Agents == -Several sample alert agents are provided in the -https://github.com/ClusterLabs/pacemaker/tree/master/extra/alerts[+extra/alerts+] -directory of the pacemaker source tree. If you installed Pacemaker via a -package, these might be available somewhere on your system, such as -+/usr/share/pacemaker+. - -While these sample scripts may be used directly as alert agents, -they are provided mainly as templates to be edited to suit your purposes. +Pacemaker provides several sample alert agents, installed in ++/usr/share/pacemaker/alerts+ by default. + +While these sample scripts may be copied and used as-is, they are provided +mainly as templates to be edited to suit your purposes. See their source code for the full set of instance attributes they support. .Sending cluster events as SNMP traps @@ -178,8 +175,8 @@ See their source code for the full set of instance attributes they support. ----- - - + + @@ -199,8 +196,8 @@ See their source code for the full set of instance attributes they support. ----- - - + + @@ -307,6 +304,14 @@ Special concerns when writing alert agents: recommended to configure +sudo+ to allow the agent to run the necessary commands as another user with the appropriate privileges. +* As always, take care to validate and sanitize user-configured parameters, + such as CRM_alert_timestamp (whose content is specified by the + user-configured timestamp-format), CRM_alert_recipient, and all instance + attributes. Mostly this is needed simply to protect against configuration + errors, but if some user can modify the CIB without having hacluster-level + access to the cluster nodes, it is a potential security concern as well, to + avoid the possibility of code injection. + [NOTE] ===== The alerts interface is designed to be backward compatible with the external From 4693a15f9f1c2ece9b6af463b99c8900f86b078e Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Wed, 8 Jun 2016 18:30:59 -0500 Subject: [PATCH 04/14] Test: cts: avoid kill usage error if DummySD stop called when already stopped --- cts/CIB.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cts/CIB.py b/cts/CIB.py index b723cf0b2c6..06c72d01ea4 100644 --- a/cts/CIB.py +++ b/cts/CIB.py @@ -414,8 +414,7 @@ def add_resources(self): [Service] Type=notify ExecStart=/usr/bin/python -c 'import time, systemd.daemon; time.sleep(10); systemd.daemon.notify("READY=1"); time.sleep(86400)' -ExecStop=/bin/sleep 10 -ExecStop=/bin/kill -s KILL \$MAINPID +ExecStop=/bin/sh -c 'sleep 10; [ -n "\$MAINPID" ] && kill -s KILL \$MAINPID' """ os.system("cat <<-END >/tmp/DummySD.service\n%s\nEND" % (dummy_service_file)) From cd143722f77a835225a718c4ac92b21a4622aaff Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 11:27:56 -0500 Subject: [PATCH 05/14] Refactor: pengine: reduce code duplication when unpacking location constraints Certain error conditions were checked by both unpack_location() and unpack_location_tags(). Now, it's done only in the latter (which the former calls and checks). This also simplifies the code to make it more readable. --- pengine/constraints.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/pengine/constraints.c b/pengine/constraints.c index 6390b21e884..a39b8b2ffeb 100644 --- a/pengine/constraints.c +++ b/pengine/constraints.c @@ -791,7 +791,6 @@ unpack_location_tags(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_ xmlNode *new_xml = NULL; xmlNode *rsc_set_lh = NULL; - gboolean any_sets = FALSE; *expanded_xml = NULL; @@ -846,13 +845,11 @@ unpack_location_tags(xmlNode * xml_obj, xmlNode ** expanded_xml, pe_working_set_ crm_xml_add(rsc_set_lh, "role", state_lh); xml_remove_prop(new_xml, XML_RULE_ATTR_ROLE); } - any_sets = TRUE; - } - - if (any_sets) { crm_log_xml_trace(new_xml, "Expanded rsc_location..."); *expanded_xml = new_xml; + } else { + /* No sets */ free_xml(new_xml); } @@ -897,27 +894,13 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set) xmlNode *orig_xml = NULL; xmlNode *expanded_xml = NULL; - const char *id = crm_element_value(xml_obj, XML_ATTR_ID); - - gboolean rc = TRUE; - - if (xml_obj == NULL) { - crm_config_err("No rsc_location constraint object to process."); + if (unpack_location_tags(xml_obj, &expanded_xml, data_set) == FALSE) { return FALSE; } - if (id == NULL) { - crm_config_err("%s constraint must have an id", crm_element_name(xml_obj)); - return FALSE; - } - - rc = unpack_location_tags(xml_obj, &expanded_xml, data_set); if (expanded_xml) { orig_xml = xml_obj; xml_obj = expanded_xml; - - } else if (rc == FALSE) { - return FALSE; } for (set = __xml_first_child(xml_obj); set != NULL; set = __xml_next_element(set)) { From 7e4a8a575efc59eacccfdd3dc8c1b76a2a0e37c3 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 11:52:43 -0500 Subject: [PATCH 06/14] Fix: pengine: avoid memory leak when invalid constraint involves set --- pengine/constraints.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pengine/constraints.c b/pengine/constraints.c index a39b8b2ffeb..dd7d8432b82 100644 --- a/pengine/constraints.c +++ b/pengine/constraints.c @@ -908,6 +908,9 @@ unpack_location(xmlNode * xml_obj, pe_working_set_t * data_set) any_sets = TRUE; set = expand_idref(set, data_set->input); if (unpack_location_set(xml_obj, set, data_set) == FALSE) { + if (expanded_xml) { + free_xml(expanded_xml); + } return FALSE; } } From 03743bd258b7f7eac4b56cccb2c90d418a956fc6 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 13:57:11 -0500 Subject: [PATCH 07/14] Fix: pengine: better error handling when unpacking sets in location constraints --- pengine/constraints.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pengine/constraints.c b/pengine/constraints.c index dd7d8432b82..0f5055b5efc 100644 --- a/pengine/constraints.c +++ b/pengine/constraints.c @@ -861,20 +861,24 @@ unpack_location_set(xmlNode * location, xmlNode * set, pe_working_set_t * data_s { xmlNode *xml_rsc = NULL; resource_t *resource = NULL; - const char *set_id = ID(set); - const char *role = crm_element_value(set, "role"); - const char *local_score = crm_element_value(set, XML_RULE_ATTR_SCORE); + const char *set_id; + const char *role; + const char *local_score; if (set == NULL) { crm_config_err("No resource_set object to process."); return FALSE; } + set_id = ID(set); if (set_id == NULL) { crm_config_err("resource_set must have an id"); return FALSE; } + role = crm_element_value(set, "role"); + local_score = crm_element_value(set, XML_RULE_ATTR_SCORE); + for (xml_rsc = __xml_first_child(set); xml_rsc != NULL; xml_rsc = __xml_next_element(xml_rsc)) { if (crm_str_eq((const char *)xml_rsc->name, XML_TAG_RESOURCE_REF, TRUE)) { EXPAND_CONSTRAINT_IDREF(set_id, resource, ID(xml_rsc)); From 41dd34090e02ac22a5266e47217467ffc2545bb6 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 13:58:24 -0500 Subject: [PATCH 08/14] Fix: pengine: avoid use-after-free with location constraint + sets + templates Previously, rsc2node_new() assumed id would be persistent, but when a location constraint involves a resource set referencing a template, unpack_location() will use a copy of the XML and free it afterward. Now, it makes a copy of id, and pe_free_rsc_to_node() will free that copy when appropriate. --- pengine/pengine.h | 2 +- pengine/utils.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pengine/pengine.h b/pengine/pengine.h index 671cfe3dae6..5500819dc63 100644 --- a/pengine/pengine.h +++ b/pengine/pengine.h @@ -82,7 +82,7 @@ enum rsc_discover_e { }; struct rsc_to_node_s { - const char *id; + char *id; resource_t *rsc_lh; enum rsc_role_e role_filter; diff --git a/pengine/utils.c b/pengine/utils.c index 7671e04a2dd..d84559b67af 100644 --- a/pengine/utils.c +++ b/pengine/utils.c @@ -51,6 +51,7 @@ pe_free_rsc_to_node(GListPtr constraints) iterator = iterator->next; g_list_free_full(cons->node_list_rh, free); + free(cons->id); free(cons); } if (constraints != NULL) { @@ -75,7 +76,7 @@ rsc2node_new(const char *id, resource_t * rsc, new_con = calloc(1, sizeof(rsc_to_node_t)); if (new_con != NULL) { - new_con->id = id; + new_con->id = strdup(id); new_con->rsc_lh = rsc; new_con->node_list_rh = NULL; new_con->role_filter = RSC_ROLE_UNKNOWN; From 2270ae36c9e01c9bcf18b205742787a8e06ab031 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 14:40:33 -0500 Subject: [PATCH 09/14] Fix: tools: avoid memory leak when crm_mon unpacks constraints --- tools/crm_mon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/crm_mon.c b/tools/crm_mon.c index d69aac8fc58..5646903fac1 100644 --- a/tools/crm_mon.c +++ b/tools/crm_mon.c @@ -48,6 +48,8 @@ #include <../pengine/pengine.h> #include +extern void cleanup_alloc_calculations(pe_working_set_t * data_set); + void clean_up(int rc); void crm_diff_update(const char *event, xmlNode * msg); gboolean mon_refresh_display(gpointer user_data); @@ -4036,7 +4038,7 @@ mon_refresh_display(gpointer user_data) break; } - cleanup_calculations(&data_set); + cleanup_alloc_calculations(&data_set); return TRUE; } From ad00c8a541737517b4ac3ab730a9a9006abe2952 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 14:59:05 -0500 Subject: [PATCH 10/14] Low: extra: improve determination of successful monitors in SNMP alert script --- extra/alerts/alert_snmp.sh.sample | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extra/alerts/alert_snmp.sh.sample b/extra/alerts/alert_snmp.sh.sample index 6f16e0e7c44..788e3c12970 100644 --- a/extra/alerts/alert_snmp.sh.sample +++ b/extra/alerts/alert_snmp.sh.sample @@ -120,10 +120,10 @@ case "$CRM_alert_kind" in case "${CRM_alert_desc}" in Cancelled) ;; *) - if [ "${trap_monitor_success}" = "false" ]; then - if [[ ${CRM_alert_rc} -eq 0 && "${CRM_alert_task}" == "monitor" ]]; then - exit; - fi + if [ "${trap_monitor_success}" = "false" ] \ + && [ "${CRM_alert_rc}" = "${CRM_alert_target_rc}" ] \ + && [ "${CRM_alert_task}" = "monitor" ]; then + exit fi "${trap_binary}" -v "${trap_version}" ${trap_options} \ From c2684cc893f8511dbe89c0c1ca9f7382779d4592 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 16:01:34 -0500 Subject: [PATCH 11/14] Build: use new %CONFIGDIR% variable wherever appropriate --- cts/HBDummy.in | 13 --------- cts/LSBDummy.in | 13 --------- doc/Pacemaker_Remote/en-US/Ch-Options.txt | 6 +++-- lrmd/pacemaker_remote.in | 32 +++++++++++------------ mcp/pacemaker.combined.upstart.in | 32 ++++++++++------------- mcp/pacemaker.in | 30 ++++++++++----------- mcp/pacemaker.upstart.in | 32 ++++++++++------------- tools/crm_mon.service.in | 2 +- tools/crm_mon.upstart.in | 28 +++++++++----------- 9 files changed, 74 insertions(+), 114 deletions(-) diff --git a/cts/HBDummy.in b/cts/HBDummy.in index 4960dd25721..f1cba94dc04 100755 --- a/cts/HBDummy.in +++ b/cts/HBDummy.in @@ -48,19 +48,6 @@ failure() echo -ne "[FAILED]\r" } -# rpm based distros -if [ -d @sysconfdir@/sysconfig ]; then - [ -f @INITDIR@/functions ] && . @INITDIR@/functions - [ -f @sysconfdir@/sysconfig/pacemaker ] && . @sysconfdir@/sysconfig/pacemaker - [ -z "$LOCK_FILE" ] && LOCK_FILE="@localstatedir@/lock/subsys/pacemaker" -fi - -# deb based distros -if [ -d @sysconfdir@/default ]; then - [ -f @sysconfdir@/default/pacemaker ] && . @sysconfdir@/default/pacemaker - [ -z "$LOCK_FILE" ] && LOCK_FILE="@localstatedir@/lock/pacemaker" -fi - dummy_usage() { cat < /dev/null 2>&1; then success @@ -93,8 +91,8 @@ start() sleep 5 if status $prog > /dev/null 2>&1; then - touch $LOCK_FILE - pidof $prog > @localstatedir@/run/$prog.pid + touch "$LOCK_FILE" + pidof $prog > "@localstatedir@/run/$prog.pid" success else failure @@ -119,8 +117,8 @@ stop() done fi - rm -f $LOCK_FILE - rm -f @localstatedir@/run/$prog.pid + rm -f "$LOCK_FILE" + rm -f "@localstatedir@/run/$prog.pid" success echo } diff --git a/mcp/pacemaker.combined.upstart.in b/mcp/pacemaker.combined.upstart.in index a4749139ec7..6f0e39ae824 100644 --- a/mcp/pacemaker.combined.upstart.in +++ b/mcp/pacemaker.combined.upstart.in @@ -10,14 +10,12 @@ kill timeout 3600 respawn env prog=pacemakerd -env rpm_sysconf=@sysconfdir@/sysconfig/pacemaker -env rpm_lockfile=@localstatedir@/lock/subsys/pacemaker -env deb_sysconf=@sysconfdir@/default/pacemaker -env deb_lockfile=@localstatedir@/lock/pacemaker +env sysconf=@CONFIGDIR@/crm_mon +env rpm_lockdir=@localstatedir@/lock/subsys +env deb_lockdir=@localstatedir@/lock script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -f "$sysconf" ] && . "$sysconf" exec $prog end script @@ -39,21 +37,19 @@ pre-start script end script post-start script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf - [ -z "$LOCK_FILE" -a -d @sysconfdir@/sysconfig ] && LOCK_FILE="$rpm_lockfile" - [ -z "$LOCK_FILE" -a -d @sysconfdir@/default ] && LOCK_FILE="$deb_lockfile" - touch $LOCK_FILE - pidof $prog > @localstatedir@/run/$prog.pid + [ -f "$sysconf" ] && . "$sysconf" + [ -z "$LOCK_FILE" -a -d "$rpm_lockdir" ] && LOCK_FILE="$rpm_lockdir/pacemaker" + [ -z "$LOCK_FILE" -a -d "$deb_lockdir" ] && LOCK_FILE="$deb_lockdir/pacemaker" + touch "$LOCK_FILE" + pidof $prog > "@localstatedir@/run/$prog.pid" end script post-stop script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf - [ -z "$LOCK_FILE" -a -d @sysconfdir@/sysconfig ] && LOCK_FILE="$rpm_lockfile" - [ -z "$LOCK_FILE" -a -d @sysconfdir@/default ] && LOCK_FILE="$deb_lockfile" - rm -f $LOCK_FILE - rm -f @localstatedir@/run/$prog.pid + [ -f "$sysconf" ] && . "$sysconf" + [ -z "$LOCK_FILE" -a -d "$rpm_lockdir" ] && LOCK_FILE="$rpm_lockdir/pacemaker" + [ -z "$LOCK_FILE" -a -d "$deb_lockdir" ] && LOCK_FILE="$deb_lockdir/pacemaker" + rm -f "$LOCK_FILE" + rm -f "@localstatedir@/run/$prog.pid" # if you use watchdog of corosync, uncomment the line below. #pidof corosync || false diff --git a/mcp/pacemaker.in b/mcp/pacemaker.in index e6d5462b989..c67732213b9 100644 --- a/mcp/pacemaker.in +++ b/mcp/pacemaker.in @@ -68,25 +68,23 @@ status() return $rtrn } -# rpm based distros -if [ -d @sysconfdir@/sysconfig ]; then +if [ -d @CONFIGDIR@ ]; then [ -f @INITDIR@/functions ] && . @INITDIR@/functions set -a - [ -f @sysconfdir@/sysconfig/pacemaker ] && . @sysconfdir@/sysconfig/pacemaker + [ -f @CONFIGDIR@/pacemaker ] && . @CONFIGDIR@/pacemaker set +a - [ -z "$LOCK_FILE" ] && LOCK_FILE="@localstatedir@/lock/subsys/pacemaker" fi -# deb based distros -if [ -d @sysconfdir@/default ]; then -set -a - [ -f @sysconfdir@/default/pacemaker ] && . @sysconfdir@/default/pacemaker -set +a - [ -z "$LOCK_FILE" ] && LOCK_FILE="@localstatedir@/lock/pacemaker" +LOCK_DIR="." +if [ -d "@localstatedir@/lock/subsys" ]; then + LOCK_DIR="@localstatedir@/lock/subsys" +elif [ -d "@localstatedir@/lock" ]; then + LOCK_DIR="@localstatedir@/lock" fi +[ -z "$LOCK_FILE" ] && LOCK_FILE="$LOCK_DIR/pacemaker" # Unless specified otherwise, assume cman is in use if cluster.conf exists -if [ x = "x$PCMK_STACK" -a -f @sysconfdir@/cluster/cluster.conf ]; then +if [ x = "x$PCMK_STACK" -a -f "@sysconfdir@/cluster/cluster.conf" ]; then PCMK_STACK=cman fi @@ -98,7 +96,7 @@ start() # to avoid to clean it up on every boot. # they also assume that init scripts will create # required subdirectories for proper operations - mkdir -p @localstatedir@/run + mkdir -p "@localstatedir@/run" if status $prog > /dev/null 2>&1; then success @@ -109,8 +107,8 @@ start() sleep 5 if status $prog > /dev/null 2>&1; then - touch $LOCK_FILE - pidof $prog > @localstatedir@/run/$prog.pid + touch "$LOCK_FILE" + pidof $prog > "@localstatedir@/run/$prog.pid" success else failure @@ -228,8 +226,8 @@ stop() echo -n "$desc is already stopped" fi - rm -f $LOCK_FILE - rm -f @localstatedir@/run/$prog.pid + rm -f "$LOCK_FILE" + rm -f "@localstatedir@/run/$prog.pid" killall -q -9 'crmd stonithd attrd cib lrmd pacemakerd' success echo diff --git a/mcp/pacemaker.upstart.in b/mcp/pacemaker.upstart.in index 7c977dc6e23..9ac3fd664d5 100644 --- a/mcp/pacemaker.upstart.in +++ b/mcp/pacemaker.upstart.in @@ -7,31 +7,27 @@ kill timeout 3600 respawn env prog=pacemakerd -env rpm_sysconf=@sysconfdir@/sysconfig/pacemaker -env rpm_lockfile=@localstatedir@/lock/subsys/pacemaker -env deb_sysconf=@sysconfdir@/default/pacemaker -env deb_lockfile=@localstatedir@/lock/pacemaker +env sysconf=@CONFIGDIR@/crm_mon +env rpm_lockdir=@localstatedir@/lock/subsys +env deb_lockdir=@localstatedir@/lock script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -f "$sysconf" ] && . "$sysconf" exec $prog end script post-start script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf - [ -z "$LOCK_FILE" -a -d @sysconfdir@/sysconfig ] && LOCK_FILE="$rpm_lockfile" - [ -z "$LOCK_FILE" -a -d @sysconfdir@/default ] && LOCK_FILE="$deb_lockfile" - touch $LOCK_FILE - pidof $prog > @localstatedir@/run/$prog.pid + [ -f "$sysconf" ] && . "$sysconf" + [ -z "$LOCK_FILE" -a -d "$rpm_lockdir" ] && LOCK_FILE="$rpm_lockdir/pacemaker" + [ -z "$LOCK_FILE" -a -d "$deb_lockdir" ] && LOCK_FILE="$deb_lockdir/pacemaker" + touch "$LOCK_FILE" + pidof $prog > "@localstatedir@/run/$prog.pid" end script post-stop script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf - [ -z "$LOCK_FILE" -a -d @sysconfdir@/sysconfig ] && LOCK_FILE="$rpm_lockfile" - [ -z "$LOCK_FILE" -a -d @sysconfdir@/default ] && LOCK_FILE="$deb_lockfile" - rm -f $LOCK_FILE - rm -f @localstatedir@/run/$prog.pid + [ -f "$sysconf" ] && . "$sysconf" + [ -z "$LOCK_FILE" -a -d "$rpm_lockdir" ] && LOCK_FILE="$rpm_lockdir/pacemaker" + [ -z "$LOCK_FILE" -a -d "$deb_lockdir" ] && LOCK_FILE="$deb_lockdir/pacemaker" + rm -f "$LOCK_FILE" + rm -f "@localstatedir@/run/$prog.pid" end script diff --git a/tools/crm_mon.service.in b/tools/crm_mon.service.in index 24021198d9b..1199f5fe069 100644 --- a/tools/crm_mon.service.in +++ b/tools/crm_mon.service.in @@ -4,7 +4,7 @@ Documentation=man:crm_mon [Service] Type=forking -EnvironmentFile=-@sysconfdir@/sysconfig/crm_mon +EnvironmentFile=-@CONFIGDIR@/crm_mon ExecStart=@sbindir@/crm_mon $OPTIONS Restart=always diff --git a/tools/crm_mon.upstart.in b/tools/crm_mon.upstart.in index ef0fe7a7f22..eb4c956c64e 100644 --- a/tools/crm_mon.upstart.in +++ b/tools/crm_mon.upstart.in @@ -9,31 +9,27 @@ respawn limit 10 3600 expect fork env prog=crm_mon -env rpm_sysconf=@sysconfdir@/sysconfig/crm_mon -env rpm_lockfile=@localstatedir@/lock/subsys/crm_mon -env deb_sysconf=@sysconfdir@/default/crm_mon -env deb_lockfile=@localstatedir@/lock/crm_mon +env sysconf=@CONFIGDIR@/crm_mon +env rpm_lockdir=@localstatedir@/lock/subsys +env deb_lockdir=@localstatedir@/lock script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf + [ -f "$sysconf" ] && . "$sysconf" exec $prog $OPTIONS end script post-start script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf - [ -z "$LOCK_FILE" -a -d @sysconfdir@/sysconfig ] && LOCK_FILE="$rpm_lockfile" - [ -z "$LOCK_FILE" -a -d @sysconfdir@/default ] && LOCK_FILE="$deb_lockfile" - touch $LOCK_FILE + [ -f "$sysconf" ] && . "$sysconf" + [ -z "$LOCK_FILE" -a -d "$rpm_lockdir" ] && LOCK_FILE="$rpm_lockdir/$prog" + [ -z "$LOCK_FILE" -a -d "$deb_lockdir" ] && LOCK_FILE="$deb_lockdir/$prog" + touch "$LOCK_FILE" end script post-stop script - [ -f "$rpm_sysconf" ] && . $rpm_sysconf - [ -f "$deb_sysconf" ] && . $deb_sysconf - [ -z "$LOCK_FILE" -a -d @sysconfdir@/sysconfig ] && LOCK_FILE="$rpm_lockfile" - [ -z "$LOCK_FILE" -a -d @sysconfdir@/default ] && LOCK_FILE="$deb_lockfile" - rm -f $LOCK_FILE + [ -f "$sysconf" ] && . "$sysconf" + [ -z "$LOCK_FILE" -a -d "$rpm_lockdir" ] && LOCK_FILE="$rpm_lockdir/$prog" + [ -z "$LOCK_FILE" -a -d "$deb_lockdir" ] && LOCK_FILE="$deb_lockdir/$prog" + rm -f "$LOCK_FILE" end script From 27d58a580adb434ad3ef4571f090ce0d6be5b327 Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 17:00:41 -0500 Subject: [PATCH 12/14] Fix: liblrmd: avoid memory leak when closing or deleting lrmd connections 6424a64 introduced a peer version to the private lrmd structure but never freed it --- lib/lrmd/lrmd_client.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/lrmd/lrmd_client.c b/lib/lrmd/lrmd_client.c index 151df40fc78..255537424d3 100644 --- a/lib/lrmd/lrmd_client.c +++ b/lib/lrmd/lrmd_client.c @@ -1412,6 +1412,9 @@ lrmd_api_disconnect(lrmd_t * lrmd) free(native->token); native->token = NULL; + + free(native->peer_version); + native->peer_version = NULL; return 0; } @@ -2217,6 +2220,8 @@ lrmd_api_delete(lrmd_t * lrmd) #endif free(native->remote_nodename); free(native->remote); + free(native->token); + free(native->peer_version); } free(lrmd->private); From e4c435394fb22702d1347b968af75f48965b824c Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Thu, 9 Jun 2016 17:18:37 -0500 Subject: [PATCH 13/14] Fix: crmd: avoid memory leak when sending fencing alert --- crmd/notify.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crmd/notify.c b/crmd/notify.c index 67654433ab6..64d1b5bed9c 100644 --- a/crmd/notify.c +++ b/crmd/notify.c @@ -756,6 +756,7 @@ crmd_notify_fencing_op(stonith_event_t * e) set_alert_key_int(CRM_notify_rc, e->result); send_notifications("fencing"); + free(desc); } void From a82de2e8ee4ffb62bfcfc1c6c8b104db92a50f6a Mon Sep 17 00:00:00 2001 From: Ken Gaillot Date: Fri, 10 Jun 2016 09:11:08 -0500 Subject: [PATCH 14/14] Fix: crmd: use proper resource agent name when caching metadata This also improves logging when retrieving metadata. --- crmd/lrm.c | 19 ++++++++----------- lib/lrmd/lrmd_client.c | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/crmd/lrm.c b/crmd/lrm.c index 3d271fcb51a..8ae3e180d21 100644 --- a/crmd/lrm.c +++ b/crmd/lrm.c @@ -499,7 +499,7 @@ get_rsc_metadata(const char *type, const char *rclass, const char *provider, boo return NULL; } - snprintf(key, len, "%s::%s:%s", type, rclass, provider); + snprintf(key, len, "%s::%s:%s", rclass, provider, type); if(force == FALSE) { metadata = g_hash_table_lookup(metadata_hash, key); if (metadata) { @@ -509,21 +509,18 @@ get_rsc_metadata(const char *type, const char *rclass, const char *provider, boo if(metadata == NULL) { rc = lrm_state_get_metadata(lrm_state, rclass, provider, type, &metadata, 0); - crm_trace("Retrieved live metadata for %s: %s (%d)", key, pcmk_strerror(rc), rc); if(rc == pcmk_ok) { + crm_trace("Retrieved live metadata for %s", key); CRM_LOG_ASSERT(metadata != NULL); g_hash_table_insert(metadata_hash, key, metadata); key = NULL; } else { - CRM_LOG_ASSERT(metadata == NULL); - metadata = NULL; + crm_trace("No metadata found for %s: %s" CRM_XS " rc=%d", + key, pcmk_strerror(rc), rc); + CRM_CHECK(metadata == NULL, metadata = NULL); } } - if (metadata == NULL) { - crm_warn("No metadata found for %s: %s (%d)", key, pcmk_strerror(rc), rc); - } - free(key); return metadata; } @@ -751,17 +748,17 @@ build_operation_update(xmlNode * parent, lrmd_rsc_info_t * rsc, lrmd_event_data_ m_string = get_rsc_metadata(rsc->type, rsc->class, rsc->provider, safe_str_eq(op->op_type, RSC_START)); if(m_string == NULL) { - crm_err("No metadata for %s::%s:%s", rsc->provider, rsc->class, rsc->type); + crm_err("No metadata for %s::%s:%s", rsc->class, rsc->provider, rsc->type); return TRUE; } metadata = string2xml(m_string); if(metadata == NULL) { - crm_err("Metadata for %s::%s:%s is not valid XML", rsc->provider, rsc->class, rsc->type); + crm_err("Metadata for %s::%s:%s is not valid XML", rsc->class, rsc->provider, rsc->type); return TRUE; } - crm_trace("Including additional digests for %s::%s:%s", rsc->provider, rsc->class, rsc->type); + crm_trace("Including additional digests for %s::%s:%s", rsc->class, rsc->provider, rsc->type); append_restart_list(op, metadata, xml_op, caller_version); append_secure_list(op, metadata, xml_op, caller_version); diff --git a/lib/lrmd/lrmd_client.c b/lib/lrmd/lrmd_client.c index 255537424d3..3208d8e4362 100644 --- a/lib/lrmd/lrmd_client.c +++ b/lib/lrmd/lrmd_client.c @@ -1921,15 +1921,15 @@ heartbeat_get_metadata(const char *type, char **output) static int generic_get_metadata(const char *standard, const char *provider, const char *type, char **output) { - svc_action_t *action = resources_action_create(type, - standard, - provider, - type, - "meta-data", - 0, - 30000, - NULL, - 0); + svc_action_t *action; + + action = resources_action_create(type, standard, provider, type, + "meta-data", 0, 30000, NULL, 0); + if (action == NULL) { + crm_err("Unable to retrieve meta-data for %s:%s:%s", standard, provider, type); + services_action_free(action); + return -EINVAL; + } if (!(services_action_sync(action))) { crm_err("Failed to retrieve meta-data for %s:%s:%s", standard, provider, type); @@ -1938,7 +1938,7 @@ generic_get_metadata(const char *standard, const char *provider, const char *typ } if (!action->stdout_data) { - crm_err("Failed to retrieve meta-data for %s:%s:%s", standard, provider, type); + crm_err("Failed to receive meta-data for %s:%s:%s", standard, provider, type); services_action_free(action); return -EIO; }