diff --git a/SOURCES/bz1445889-IPaddr2-IPv6-add-preferred_lft-parameter.patch b/SOURCES/bz1445889-IPaddr2-IPv6-add-preferred_lft-parameter.patch new file mode 100644 index 0000000..a59a371 --- /dev/null +++ b/SOURCES/bz1445889-IPaddr2-IPv6-add-preferred_lft-parameter.patch @@ -0,0 +1,81 @@ +From 2918ab999cbcbe6bc04061dd070e5b0dd8465346 Mon Sep 17 00:00:00 2001 +From: Damien Ciabrini +Date: Wed, 26 Apr 2017 17:51:52 +0200 +Subject: [PATCH] IPaddr2: add option for specifying IPv6's preferred_lft + +This change allows setting the preferred_lft option when creating an +IPv6 address. This can be used to ensure that the created IP address +will not be used as a source address for routing. +--- + heartbeat/IPaddr2 | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/heartbeat/IPaddr2 b/heartbeat/IPaddr2 +index 27b7208..2d2ba2c 100755 +--- a/heartbeat/IPaddr2 ++++ b/heartbeat/IPaddr2 +@@ -56,6 +56,7 @@ + # OCF_RESKEY_arp_count + # OCF_RESKEY_arp_bg + # OCF_RESKEY_arp_mac ++# OCF_RESKEY_preferred_lft + # + # OCF_RESKEY_CRM_meta_clone + # OCF_RESKEY_CRM_meta_clone_max +@@ -80,6 +81,7 @@ OCF_RESKEY_arp_count_refresh_default=0 + OCF_RESKEY_arp_count_default=5 + OCF_RESKEY_arp_bg_default=true + OCF_RESKEY_arp_mac_default="ffffffffffff" ++OCF_RESKEY_preferred_lft_default="forever" + + : ${OCF_RESKEY_lvs_support=${OCF_RESKEY_lvs_support_default}} + : ${OCF_RESKEY_lvs_ipv6_addrlabel=${OCF_RESKEY_lvs_ipv6_addrlabel_default}} +@@ -92,6 +94,7 @@ + : ${OCF_RESKEY_arp_count=${OCF_RESKEY_arp_count_default} + : ${OCF_RESKEY_arp_bg=${OCF_RESKEY_arp_bg_default}} + : ${OCF_RESKEY_arp_mac=${OCF_RESKEY_arp_mac_default}} ++: ${OCF_RESKEY_preferred_lft=${OCF_RESKEY_preferred_lft_default}} + ####################################################################### + + SENDARP=$HA_BIN/send_arp +@@ -350,6 +353,17 @@ Whether or not to run arping for IPv4 collision detection check. + + + ++ ++ ++For IPv6, set the preferred lifetime of the IP address. ++This can be used to ensure that the created IP address will not ++be used as a source address for routing. ++Expects a value as specified in section 5.5.4 of RFC 4862. ++ ++IPv6 preferred lifetime ++ ++ ++ + + + +@@ -590,6 +604,10 @@ add_interface () { + cmd="$cmd label $label" + msg="${msg} (with label $label)" + fi ++ if [ "$FAMILY" = "inet6" ] ;then ++ cmd="$cmd preferred_lft $OCF_RESKEY_preferred_lft" ++ msg="${msg} (with preferred_lft $OCF_RESKEY_preferred_lft)" ++ fi + + ocf_log info "$msg" + ocf_run $cmd || return $OCF_ERR_GENERIC +@@ -1076,6 +1094,11 @@ ip_validate() { + exit $OCF_ERR_CONFIGURED + fi + ++ if [ -z "$OCF_RESKEY_preferred_lft" ]; then ++ ocf_exit_reason "Empty value is invalid for OCF_RESKEY_preferred_lft" ++ exit $OCF_ERR_CONFIGURED ++ fi ++ + if [ -n "$IP_CIP" ]; then + + local valid=1 diff --git a/SOURCES/bz1451414-1-galera-fix-bootstrap-when-cluster-has-no-data.patch b/SOURCES/bz1451414-1-galera-fix-bootstrap-when-cluster-has-no-data.patch new file mode 100644 index 0000000..98e98bf --- /dev/null +++ b/SOURCES/bz1451414-1-galera-fix-bootstrap-when-cluster-has-no-data.patch @@ -0,0 +1,140 @@ +From aa486941a7d980ded7a30e404a9d91620b19c47a Mon Sep 17 00:00:00 2001 +From: Damien Ciabrini +Date: Mon, 19 Dec 2016 14:13:21 +0100 +Subject: [PATCH] galera: allow names in wsrep_cluster_address to differ from + pacemaker nodes' names + +Add a new option cluster_host_map to the galera resource agent in case +names to be used in wsrep_cluster_address need to differ from names +used for the pacemaker nodes. (e.g. when galera names map to IP +from a specific network interface) +--- + heartbeat/galera | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 65 insertions(+), 6 deletions(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index fe2aa8a..45693ac 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -208,13 +208,30 @@ The galera cluster address. This takes the form of: + gcomm://node,node,node + + Only nodes present in this node list will be allowed to start a galera instance. +-It is expected that the galera node names listed in this address match valid +-pacemaker node names. ++The galera node names listed in this address are expected to match valid ++pacemaker node names. If both names need to differ, you must provide a ++mapping in option cluster_host_map. + + Galera cluster address + + + ++ ++ ++A mapping of pacemaker node names to galera node names. ++ ++To be used when both pacemaker and galera names need to differ, ++(e.g. when galera names map to IP from a specific network interface) ++This takes the form of: ++pcmk1:node.1.galera;pcmk2:node.2.galera;pcmk3:node.3.galera ++ ++where the galera resource started on node pcmk1 would be named ++node.1.galera in the wsrep_cluster_address ++ ++Pacemaker to Galera name mapping ++ ++ ++ + + + Cluster check user. +@@ -454,6 +471,27 @@ greater_than_equal_long() + echo | awk -v n1="$1" -v n2="$2" '{if (n1>=n2) printf ("true"); else printf ("false");}' | grep -q "true" + } + ++galera_to_pcmk_name() ++{ ++ local galera=$1 ++ if [ -z "$OCF_RESKEY_cluster_host_map" ]; then ++ echo $galera ++ else ++ echo "$OCF_RESKEY_cluster_host_map" | tr ';' '\n' | tr -d ' ' | sed 's/:/ /' | awk -F' ' '$2=="'"$galera"'" {print $1;exit}' ++ fi ++} ++ ++pcmk_to_galera_name() ++{ ++ local pcmk=$1 ++ if [ -z "$OCF_RESKEY_cluster_host_map" ]; then ++ echo $pcmk ++ else ++ echo "$OCF_RESKEY_cluster_host_map" | tr ';' '\n' | tr -d ' ' | sed 's/:/ /' | awk -F' ' '$1=="'"$pcmk"'" {print $2;exit}' ++ fi ++} ++ ++ + detect_first_master() + { + local best_commit=0 +@@ -465,6 +503,14 @@ detect_first_master() + + # avoid selecting a recovered node as bootstrap if possible + for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do ++ local pcmk_node=$(galera_to_pcmk_name $node) ++ if [ -z "$pcmk_node" ]; then ++ ocf_log error "Could not determine pacemaker node from galera name <${node}>." ++ return ++ else ++ node=$pcmk_node ++ fi ++ + if is_no_grastate $node; then + nodes_recovered="$nodes_recovered $node" + else +@@ -783,10 +829,17 @@ galera_demote() + galera_start() + { + local rc ++ local galera_node ++ ++ galera_node=$(pcmk_to_galera_name $NODENAME) ++ if [ -z "$galera_node" ]; then ++ ocf_exit_reason "Could not determine galera name from pacemaker node <${NODENAME}>." ++ return $OCF_ERR_CONFIGURED ++ fi + +- echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME ++ echo $OCF_RESKEY_wsrep_cluster_address | grep -q -F $galera_node + if [ $? -ne 0 ]; then +- ocf_exit_reason "local node <${NODENAME}> must be a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>to start this galera instance" ++ ocf_exit_reason "local node <${NODENAME}> (galera node <${galera_node}>) must be a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}> to start this galera instance" + return $OCF_ERR_CONFIGURED + fi + +@@ -818,6 +871,7 @@ galera_start() + galera_monitor() + { + local rc ++ local galera_node + local status_loglevel="err" + + # Set loglevel to info during probe +@@ -857,10 +911,15 @@ galera_monitor() + fi + + # if we make it here, mysql is running. Check cluster status now. ++ galera_node=$(pcmk_to_galera_name $NODENAME) ++ if [ -z "$galera_node" ]; then ++ ocf_exit_reason "Could not determine galera name from pacemaker node <${NODENAME}>." ++ return $OCF_ERR_CONFIGURED ++ fi + +- echo $OCF_RESKEY_wsrep_cluster_address | grep -q $NODENAME ++ echo $OCF_RESKEY_wsrep_cluster_address | grep -q -F $galera_node + if [ $? -ne 0 ]; then +- ocf_exit_reason "local node <${NODENAME}> is started, but is not a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>" ++ ocf_exit_reason "local node <${NODENAME}> (galera node <${galera_node}>) is started, but is not a member of the wsrep_cluster_address <${OCF_RESKEY_wsrep_cluster_address}>" + return $OCF_ERR_GENERIC + fi + diff --git a/SOURCES/bz1451414-2-galera-fix-bootstrap-when-cluster-has-no-data.patch b/SOURCES/bz1451414-2-galera-fix-bootstrap-when-cluster-has-no-data.patch new file mode 100644 index 0000000..b72c06d --- /dev/null +++ b/SOURCES/bz1451414-2-galera-fix-bootstrap-when-cluster-has-no-data.patch @@ -0,0 +1,50 @@ +From a05eb8673bd1d5d3d41f2ed39df2650b19681d08 Mon Sep 17 00:00:00 2001 +From: Damien Ciabrini +Date: Fri, 3 Mar 2017 15:31:30 +0100 +Subject: [PATCH] galera: fix the first bootstrap when cluster has no data + +The resource agent selects the first node to go into Master state +based on the biggest commit version found on each node. If case no +data were written yet into the galera cluster, the current node is +selected as a "fallback" node to bootstrap the cluster. + +The way the "fallback" node is selected is wrong because every node +takes a different decision, and this ultimately yields to 3 +single-node galera clusters being started. To fix that, let the +"fallback" node be the last one in the wsrep_cluster_address, so that +the selection algorithm yields coherent results across nodes. +--- + heartbeat/galera | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index decbaa2..475a8ba 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -451,14 +451,24 @@ pcmk_to_galera_name() + detect_first_master() + { + local best_commit=0 +- local best_node="$NODENAME" + local last_commit=0 + local missing_nodes=0 + local nodes="" + local nodes_recovered="" ++ local all_nodes ++ local best_node_gcomm ++ local best_node ++ ++ all_nodes=$(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' ') ++ best_node_gcomm=$(echo "$all_nodes" | sed 's/^.* \(.*\)$/\1/') ++ best_node=$(galera_to_pcmk_name $best_node_gcomm) ++ if [ -z "$best_node" ]; then ++ ocf_log error "Could not determine initial best node from galera name <${best_node_gcomm}>." ++ return ++ fi + + # avoid selecting a recovered node as bootstrap if possible +- for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do ++ for node in $all_nodes; do + local pcmk_node=$(galera_to_pcmk_name $node) + if [ -z "$pcmk_node" ]; then + ocf_log error "Could not determine pacemaker node from galera name <${node}>." diff --git a/SOURCES/bz1451414-3-galera-fix-bootstrap-when-cluster-has-no-data.patch b/SOURCES/bz1451414-3-galera-fix-bootstrap-when-cluster-has-no-data.patch new file mode 100644 index 0000000..2a9f52b --- /dev/null +++ b/SOURCES/bz1451414-3-galera-fix-bootstrap-when-cluster-has-no-data.patch @@ -0,0 +1,52 @@ +From a6b40d102e24134a3e5e99a63bd3636aebc2145a Mon Sep 17 00:00:00 2001 +From: Damien Ciabrini +Date: Thu, 13 Apr 2017 08:51:39 +0200 +Subject: [PATCH] galera: fix master target during promotion with + cluster_host_map + +When option cluster_host_map is in use, it is assumed that galera node +names map to pacemaker node names _because_ those galera names are not +part of the pacemaker cluster in the first place. + +This is not always the case (e.g. when using pacemaker bundles), so +fix accordingly. +--- + heartbeat/galera | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/heartbeat/galera b/heartbeat/galera +index 475a8ba..32c4222 100755 +--- a/heartbeat/galera ++++ b/heartbeat/galera +@@ -415,6 +415,13 @@ promote_everyone() + { + + for node in $(echo "$OCF_RESKEY_wsrep_cluster_address" | sed 's/gcomm:\/\///g' | tr -d ' ' | tr -s ',' ' '); do ++ local pcmk_node=$(galera_to_pcmk_name $node) ++ if [ -z "$pcmk_node" ]; then ++ ocf_log err "Could not determine pacemaker node from galera name <${node}>." ++ return ++ else ++ node=$pcmk_node ++ fi + + set_master_score $node + done +@@ -463,7 +470,7 @@ detect_first_master() + best_node_gcomm=$(echo "$all_nodes" | sed 's/^.* \(.*\)$/\1/') + best_node=$(galera_to_pcmk_name $best_node_gcomm) + if [ -z "$best_node" ]; then +- ocf_log error "Could not determine initial best node from galera name <${best_node_gcomm}>." ++ ocf_log err "Could not determine initial best node from galera name <${best_node_gcomm}>." + return + fi + +@@ -471,7 +478,7 @@ detect_first_master() + for node in $all_nodes; do + local pcmk_node=$(galera_to_pcmk_name $node) + if [ -z "$pcmk_node" ]; then +- ocf_log error "Could not determine pacemaker node from galera name <${node}>." ++ ocf_log err "Could not determine pacemaker node from galera name <${node}>." + return + else + node=$pcmk_node diff --git a/SPECS/resource-agents.spec b/SPECS/resource-agents.spec index 9ffbeae..039cba3 100644 --- a/SPECS/resource-agents.spec +++ b/SPECS/resource-agents.spec @@ -32,7 +32,7 @@ Name: resource-agents Summary: Open Source HA Reusable Cluster Resource Scripts Version: 3.9.5 -Release: 82%{?dist}.9 +Release: 82%{?dist}.11 License: GPLv2+, LGPLv2+ and ASL 2.0 URL: https://github.com/ClusterLabs/resource-agents %if 0%{?fedora} || 0%{?centos_version} || 0%{?rhel} @@ -177,6 +177,10 @@ Patch132: bz1402511-rabbitmq-cluster-reset-mnesia-before-join.patch Patch133: bz1423424-1-update-saphana-saphanatopology.patch Patch134: bz1423424-2-update-saphana-saphanatopology.patch Patch135: bz1437122-rabbitmq-cluster-pacemaker-remote.patch +Patch136: bz1445889-IPaddr2-IPv6-add-preferred_lft-parameter.patch +Patch137: bz1451414-1-galera-fix-bootstrap-when-cluster-has-no-data.patch +Patch138: bz1451414-2-galera-fix-bootstrap-when-cluster-has-no-data.patch +Patch139: bz1451414-3-galera-fix-bootstrap-when-cluster-has-no-data.patch Obsoletes: heartbeat-resources <= %{version} Provides: heartbeat-resources = %{version} @@ -423,6 +427,10 @@ exit 1 %patch133 -p1 %patch134 -p1 %patch135 -p1 +%patch136 -p1 -F1 +%patch137 -p1 +%patch138 -p1 +%patch139 -p1 %build if [ ! -f configure ]; then @@ -677,6 +685,16 @@ ccs_update_schema > /dev/null 2>&1 ||: %endif %changelog +* Tue May 16 2017 Oyvind Albrigtsen - 3.9.5-82.11 +- galera: fix bootstrap when cluster has no data + + Resolves: rhbz#1451414 + +* Wed Apr 26 2017 Oyvind Albrigtsen - 3.9.5-82.10 +- IPaddr2: add "preferred_lft" parameter for IPv6 + + Resolves: rhbz#1445889 + * Tue Apr 4 2017 Oyvind Albrigtsen - 3.9.5-82.9 - rabbitmq-cluster: allow to run on Pacemaker remote nodes