[pve-devel] [PATCH corosync-pve 1/2] cherry-pick 3.0.2 as patches

Fabian Grünbichler f.gruenbichler at proxmox.com
Wed Jun 19 14:36:52 CEST 2019


and rebase/drop patches as appropriate

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
 .../0001-cherry-pick-3.0.2-as-patches.patch   | 5541 +++++++++++++++++
 ...don-t-install-default-corosync.conf.patch} |   14 +-
 ...pt.patch => 0003-remove-init-script.patch} |    0
 ...-cfgtool-Improve-link-status-display.patch |  240 -
 ...art-corosync.service-if-conf-exists.patch} |   16 +-
 ....patch => 0006-CPG-callback-merging.patch} |  175 +-
 ...-Revert-init-Enable-StopWhenUnneeded.patch |   63 -
 patches/0007-add-crypto-patches.patch         |  404 --
 patches/0007-bump-version-to-3.0.2.patch      |   57 +
 patches/series                                |   13 +-
 10 files changed, 5620 insertions(+), 903 deletions(-)
 create mode 100644 patches/0001-cherry-pick-3.0.2-as-patches.patch
 rename patches/{0001-don-t-install-default-corosync.conf.patch => 0002-don-t-install-default-corosync.conf.patch} (88%)
 rename patches/{0002-remove-init-script.patch => 0003-remove-init-script.patch} (100%)
 delete mode 100644 patches/0005-cfgtool-Improve-link-status-display.patch
 rename patches/{0003-only-start-corosync.service-if-conf-exists.patch => 0005-only-start-corosync.service-if-conf-exists.patch} (86%)
 rename patches/{0008-CPG-callback-merging.patch => 0006-CPG-callback-merging.patch} (77%)
 delete mode 100644 patches/0006-Revert-init-Enable-StopWhenUnneeded.patch
 delete mode 100644 patches/0007-add-crypto-patches.patch
 create mode 100644 patches/0007-bump-version-to-3.0.2.patch

diff --git a/patches/0001-cherry-pick-3.0.2-as-patches.patch b/patches/0001-cherry-pick-3.0.2-as-patches.patch
new file mode 100644
index 0000000..b604997
--- /dev/null
+++ b/patches/0001-cherry-pick-3.0.2-as-patches.patch
@@ -0,0 +1,5541 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
+Date: Wed, 22 May 2019 12:26:43 +0200
+Subject: [PATCH] cherry-pick 3.0.2 as patches
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
+---
+ ...vateTmp-in-the-systemd-service-files.patch |    4 +-
+ .../Revert-init-Enable-StopWhenUnneeded.patch |   31 +
+ ...-AWK-variable-provided-by-configure.patch} |    8 +-
+ ...-SED-variable-provided-by-configure.patch} |   10 +-
+ .../cfgtool-Fix-link-status-display.patch     |   65 +
+ .../cfgtool-Improve-link-status-display.patch |  134 ++
+ .../configure-Do-not-autodetect-nozzle.patch  |  114 ++
+ .../configure-Fix-GDB_CFLAGS-typo.patch       |   27 +
+ ...e.ac-AC_PROG_SED-is-already-present.patch} |    8 +-
+ .../coroparse-Fix-compiler-warning.patch      |   24 +
+ .../corosync-cfgtool-Fix-i-matching.patch     |  115 ++
+ .../patches/corosync.conf.5-fix-grammar.patch |    8 +-
+ .../corosync.conf.5-typography-fixes.patch    |    8 +-
+ .../cpg-Add-CPG_REASON_UNDEFINED.patch        |  152 +++
+ ...rypto-re-introduce-secauth-parameter.patch |   62 +
+ debian/patches/doc-Update-INSTALL-file.patch  |  124 ++
+ .../keygen-Reflect-change-in-knet.patch       |  100 ++
+ ...ple-of-errors-when-adding-a-new-link.patch |   82 ++
+ ...ix-initialising-of-knet-access-lists.patch |   70 +
+ .../patches/knet-Use-block_unlisted_ips.patch |   67 +
+ ...ow-corosync-to-use-knet-access-lists.patch |   93 ++
+ ...im-man-page-into-distributed-tarball.patch |   40 +
+ ...ahnce-block_unlisted_ips-description.patch |   33 +
+ .../man-Enhance-corosync.conf-mp-a-bit.patch  |   37 +
+ ...Enhance-token_retransmit-description.patch |   28 +
+ ...le-Add-support-for-libnozzle-devices.patch |  707 ++++++++++
+ .../quorumtool-Fix-exit-status-codes.patch    |  237 ++++
+ ...et-totem.keyfile-and-totem.key-to-RO.patch |   44 +
+ ...port-for-user-flags-configure-option.patch |   43 +
+ ...-Ensure-nodeid-is-specified-for-IPv6.patch |   48 +
+ ...g-Fix-minimum-limit-for-hold-timeout.patch |   67 +
+ .../totemconfig-Remove-support-for-3des.patch |  138 ++
+ ...fig-fix-autogen-mcastaddr-for-ipv6-4.patch |   51 +
+ ...ig-ipaddr_equal-check-just-addr-part.patch |   86 ++
+ .../totemconfig-ipaddr_equal-use-switch.patch |   44 +
+ .../totemip-Use-res-in-totemip_sa_equal.patch |   32 +
+ ...mknet-Ignore-icmap_get_string-result.patch |   32 +
+ ...tialize-return-value-in-setup_nozzle.patch |   39 +
+ ...-create_nozzle_device-simplify-check.patch |   34 +
+ .../totemknet-macaddr_str-is-always-set.patch |   27 +
+ .../totemsrp-Word-spelling-mistake.patch      |   24 +
+ .../udpu-Drop-packets-from-unlisted-IPs.patch |  254 ++++
+ .../vqsim-Check-length-of-copied-optarg.patch |   37 +
+ ...sim-Check-length-of-received-message.patch |   42 +
+ ...sim-Check-result-of-icmap_set_uint32.patch |   31 +
+ debian/patches/vqsim-Check-write-result.patch |   33 +
+ ...sim-Do-not-access-unitialized-argv-0.patch |   24 +
+ debian/patches/vqsim-Enhance-vqsim.patch      | 1155 +++++++++++++++++
+ .../vqsim-Fix-vqsim-for-corosync-3.0.patch    |  102 ++
+ .../vqsim-Free-allocated-newvq-on-error.patch |   23 +
+ debian/patches/vqsim-Make-vqsim-compile.patch |  131 ++
+ .../vqsim-Remove-unused-total_nodes.patch     |   62 +
+ debian/patches/series                         |   57 +-
+ 53 files changed, 5034 insertions(+), 14 deletions(-)
+ create mode 100644 debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
+ rename debian/patches/{Use-the-AWK-variable-provided-by-configure.patch => build-Use-the-AWK-variable-provided-by-configure.patch} (78%)
+ rename debian/patches/{Use-the-SED-variable-provided-by-configure.patch => build-Use-the-SED-variable-provided-by-configure.patch} (94%)
+ create mode 100644 debian/patches/cfgtool-Fix-link-status-display.patch
+ create mode 100644 debian/patches/cfgtool-Improve-link-status-display.patch
+ create mode 100644 debian/patches/configure-Do-not-autodetect-nozzle.patch
+ create mode 100644 debian/patches/configure-Fix-GDB_CFLAGS-typo.patch
+ rename debian/patches/{AC_PROG_SED-is-already-present.patch => configure.ac-AC_PROG_SED-is-already-present.patch} (62%)
+ create mode 100644 debian/patches/coroparse-Fix-compiler-warning.patch
+ create mode 100644 debian/patches/corosync-cfgtool-Fix-i-matching.patch
+ create mode 100644 debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
+ create mode 100644 debian/patches/crypto-re-introduce-secauth-parameter.patch
+ create mode 100644 debian/patches/doc-Update-INSTALL-file.patch
+ create mode 100644 debian/patches/keygen-Reflect-change-in-knet.patch
+ create mode 100644 debian/patches/knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
+ create mode 100644 debian/patches/knet-Fix-initialising-of-knet-access-lists.patch
+ create mode 100644 debian/patches/knet-Use-block_unlisted_ips.patch
+ create mode 100644 debian/patches/knet-allow-corosync-to-use-knet-access-lists.patch
+ create mode 100644 debian/patches/man-Add-vqsim-man-page-into-distributed-tarball.patch
+ create mode 100644 debian/patches/man-Enahnce-block_unlisted_ips-description.patch
+ create mode 100644 debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch
+ create mode 100644 debian/patches/man-Enhance-token_retransmit-description.patch
+ create mode 100644 debian/patches/nozzle-Add-support-for-libnozzle-devices.patch
+ create mode 100644 debian/patches/quorumtool-Fix-exit-status-codes.patch
+ create mode 100644 debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
+ create mode 100644 debian/patches/spec-Add-support-for-user-flags-configure-option.patch
+ create mode 100644 debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
+ create mode 100644 debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch
+ create mode 100644 debian/patches/totemconfig-Remove-support-for-3des.patch
+ create mode 100644 debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
+ create mode 100644 debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch
+ create mode 100644 debian/patches/totemconfig-ipaddr_equal-use-switch.patch
+ create mode 100644 debian/patches/totemip-Use-res-in-totemip_sa_equal.patch
+ create mode 100644 debian/patches/totemknet-Ignore-icmap_get_string-result.patch
+ create mode 100644 debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch
+ create mode 100644 debian/patches/totemknet-create_nozzle_device-simplify-check.patch
+ create mode 100644 debian/patches/totemknet-macaddr_str-is-always-set.patch
+ create mode 100644 debian/patches/totemsrp-Word-spelling-mistake.patch
+ create mode 100644 debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch
+ create mode 100644 debian/patches/vqsim-Check-length-of-copied-optarg.patch
+ create mode 100644 debian/patches/vqsim-Check-length-of-received-message.patch
+ create mode 100644 debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch
+ create mode 100644 debian/patches/vqsim-Check-write-result.patch
+ create mode 100644 debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch
+ create mode 100644 debian/patches/vqsim-Enhance-vqsim.patch
+ create mode 100644 debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch
+ create mode 100644 debian/patches/vqsim-Free-allocated-newvq-on-error.patch
+ create mode 100644 debian/patches/vqsim-Make-vqsim-compile.patch
+ create mode 100644 debian/patches/vqsim-Remove-unused-total_nodes.patch
+
+diff --git a/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch b/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch
+index 45d24d3d..b4644516 100644
+--- a/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch
++++ b/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch
+@@ -20,10 +20,10 @@ index 410a683..9247cbc 100644
+  [Install]
+  WantedBy=multi-user.target
+ diff --git a/init/corosync.service.in b/init/corosync.service.in
+-index bf757d8..dc99a4a 100644
++index 654e41f..0c74306 100644
+ --- a/init/corosync.service.in
+ +++ b/init/corosync.service.in
+-@@ -29,6 +29,7 @@ StandardError=null
++@@ -28,6 +28,7 @@ StandardError=null
+  #RestartSec=70
+  #  rewrite according to environment.
+  #ExecStartPre=/sbin/modprobe softdog
+diff --git a/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch b/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
+new file mode 100644
+index 00000000..29fb842d
+--- /dev/null
++++ b/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
+@@ -0,0 +1,31 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Thu, 4 Apr 2019 11:40:19 +0200
++Subject: Revert "init: Enable StopWhenUnneeded"
++
++This reverts commit 03d9321bc80887d4578744c26c05d61e2d9d4278.
++
++Reverted because when corosync service is not enabled and corosync
++is executed by "systemctl start corosync" it is then immediately
++shutdown because of "Unit not needed anymore. Stopping.".
++
++This is really not expected behavior.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 527e30a8d050c077d8adff2a5aa77d9b683a8f28)
++---
++ init/corosync.service.in | 1 -
++ 1 file changed, 1 deletion(-)
++
++diff --git a/init/corosync.service.in b/init/corosync.service.in
++index bf757d8..654e41f 100644
++--- a/init/corosync.service.in
+++++ b/init/corosync.service.in
++@@ -4,7 +4,6 @@ Documentation=man:corosync man:corosync.conf man:corosync_overview
++ ConditionKernelCommandLine=!nocluster
++ Requires=network-online.target
++ After=network-online.target
++-StopWhenUnneeded=yes
++ 
++ [Service]
++ EnvironmentFile=- at INITCONFIGDIR@/corosync
+diff --git a/debian/patches/Use-the-AWK-variable-provided-by-configure.patch b/debian/patches/build-Use-the-AWK-variable-provided-by-configure.patch
+similarity index 78%
+rename from debian/patches/Use-the-AWK-variable-provided-by-configure.patch
+rename to debian/patches/build-Use-the-AWK-variable-provided-by-configure.patch
+index 85511c66..61407483 100644
+--- a/debian/patches/Use-the-AWK-variable-provided-by-configure.patch
++++ b/debian/patches/build-Use-the-AWK-variable-provided-by-configure.patch
+@@ -1,7 +1,13 @@
+ From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi at debian.org>
+ Date: Tue, 29 Jan 2019 15:25:18 +0100
+-Subject: Use the AWK variable provided by configure
++Subject: build: Use the AWK variable provided by configure
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
+ 
++Signed-off-by: Ferenc Wágner <wferi at debian.org>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit b09b96fe6ff5a77e637efb692ed37b6c80f40ba3)
+ ---
+  man/Makefile.am | 4 ++--
+  1 file changed, 2 insertions(+), 2 deletions(-)
+diff --git a/debian/patches/Use-the-SED-variable-provided-by-configure.patch b/debian/patches/build-Use-the-SED-variable-provided-by-configure.patch
+similarity index 94%
+rename from debian/patches/Use-the-SED-variable-provided-by-configure.patch
+rename to debian/patches/build-Use-the-SED-variable-provided-by-configure.patch
+index 672d4817..1c2941c5 100644
+--- a/debian/patches/Use-the-SED-variable-provided-by-configure.patch
++++ b/debian/patches/build-Use-the-SED-variable-provided-by-configure.patch
+@@ -1,7 +1,13 @@
+ From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi at debian.org>
+ Date: Tue, 29 Jan 2019 15:24:19 +0100
+-Subject: Use the SED variable provided by configure
++Subject: build: Use the SED variable provided by configure
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
+ 
++Signed-off-by: Ferenc Wágner <wferi at debian.org>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 6a476017b998e02bc4c1b88e78f86bc11f16ae7f)
+ ---
+  Makefile.am                |  8 ++++----
+  conf/logrotate/Makefile.am | 10 +++++-----
+@@ -141,7 +147,7 @@ index 131d675..1994a3c 100644
+  
+  LINT_FILES1:=$(filter-out sa_error.c, $(wildcard *.c))
+ diff --git a/tools/Makefile.am b/tools/Makefile.am
+-index 14520c2..7a9ab04 100644
++index 8825498..0793884 100644
+ --- a/tools/Makefile.am
+ +++ b/tools/Makefile.am
+ @@ -49,12 +49,12 @@ EXTRA_DIST		= corosync-xmlproc.sh \
+diff --git a/debian/patches/cfgtool-Fix-link-status-display.patch b/debian/patches/cfgtool-Fix-link-status-display.patch
+new file mode 100644
+index 00000000..b441458b
+--- /dev/null
++++ b/debian/patches/cfgtool-Fix-link-status-display.patch
+@@ -0,0 +1,65 @@
++From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
++Date: Wed, 29 May 2019 14:57:09 +0200
++Subject: cfgtool: Fix link status display
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
++
++instead of the nodeid, this displayed arbitrary values (usually '1')
++from other cmap keys under nodelist.node.XX.
++
++sscanf returns the number of conversions even on mismatch, e.g. it also
++returns 1 for
++
++nodelist.node.2.quorum_votes
++nodelist.node.2.ring0_addr
++nodelist.node.2.name
++...
++
++instead of just
++
++nodelist.node.2.nodeid
++
++which leads to the value of (at least) quorum_votes being stored in
++nodeid_list in addition to the actual nodeid.
++
++storing the returned int in a cs_error_t enum also potentially masks
++errors, so just compare the result with the expectation directly.
++
++Fixes: c0d14485c3ebdeb2332f7c48acd155163e5b7fc1
++
++Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit ef2569d323c68633a63dc15e59805ec491b69348)
++---
++ tools/corosync-cfgtool.c | 10 +++++++---
++ 1 file changed, 7 insertions(+), 3 deletions(-)
++
++diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
++index a43ee1e..f51b9d4 100644
++--- a/tools/corosync-cfgtool.c
+++++ b/tools/corosync-cfgtool.c
++@@ -100,7 +100,7 @@ linkstatusget_do (char *interface_name, int brief)
++ 	unsigned int i;
++ 	cmap_iter_handle_t iter;
++ 	unsigned int nodeid;
++-	unsigned int node_pos;
+++	int nodeid_match_guard;
++ 	cmap_value_types_t type;
++ 	size_t value_len;
++ 	int rc = 0;
++@@ -128,8 +128,12 @@ linkstatusget_do (char *interface_name, int brief)
++ 	}
++ 
++ 	while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
++-		result = sscanf(iter_key, "nodelist.node.%u.nodeid", &node_pos);
++-		if (result != 1) {
+++		nodeid_match_guard = 0;
+++		if (sscanf(iter_key, "nodelist.node.%*u.nodeid%n", &nodeid_match_guard) != 0) {
+++			continue;
+++		}
+++		/* check for exact match */
+++		if (nodeid_match_guard != strlen(iter_key)) {
++ 			continue;
++ 		}
++ 		if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
+diff --git a/debian/patches/cfgtool-Improve-link-status-display.patch b/debian/patches/cfgtool-Improve-link-status-display.patch
+new file mode 100644
+index 00000000..e05732bf
+--- /dev/null
++++ b/debian/patches/cfgtool-Improve-link-status-display.patch
+@@ -0,0 +1,134 @@
++From: Christine Caulfield <ccaulfie at redhat.com>
++Date: Tue, 22 Jan 2019 10:06:29 +0000
++Subject: cfgtool: Improve link status display
++
++Now show the nodeids properly, rather than node indexes which were
++annoying and unhelpful.
++
++Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit c0d14485c3ebdeb2332f7c48acd155163e5b7fc1)
++---
++ tools/Makefile.am        |  2 +-
++ tools/corosync-cfgtool.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
++ 2 files changed, 55 insertions(+), 3 deletions(-)
++
++diff --git a/tools/Makefile.am b/tools/Makefile.am
++index 14520c2..8825498 100644
++--- a/tools/Makefile.am
+++++ b/tools/Makefile.am
++@@ -58,7 +58,7 @@ corosync-blackbox: corosync-blackbox.sh
++ 
++ corosync_cmapctl_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcmap.la
++ 
++-corosync_cfgtool_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la
+++corosync_cfgtool_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcmap.la
++ 
++ corosync_cpgtool_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la \
++ 			  $(top_builddir)/lib/libcpg.la
++diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
++index c138085..ed29694 100644
++--- a/tools/corosync-cfgtool.c
+++++ b/tools/corosync-cfgtool.c
++@@ -50,6 +50,7 @@
++ #include <corosync/corotypes.h>
++ #include <corosync/totem/totem.h>
++ #include <corosync/cfg.h>
+++#include <corosync/cmap.h>
++ 
++ #define cs_repeat(result, max, code)				\
++ 	do {							\
++@@ -75,16 +76,33 @@ enum user_action {
++ 	ACTION_KILL_NODE,
++ };
++ 
+++static int node_compare(const void *aptr, const void *bptr)
+++{
+++	uint32_t a,b;
+++
+++	a = *(uint32_t *)aptr;
+++	b = *(uint32_t *)bptr;
+++
+++	return a > b;
+++}
+++
++ static int
++ linkstatusget_do (char *interface_name, int brief)
++ {
++ 	cs_error_t result;
++ 	corosync_cfg_handle_t handle;
+++	cmap_handle_t cmap_handle;
++ 	unsigned int interface_count;
++ 	char **interface_names;
++ 	char **interface_status;
+++	uint32_t nodeid_list[KNET_MAX_HOST];
+++	char iter_key[CMAP_KEYNAME_MAXLEN];
++ 	unsigned int i;
+++	cmap_iter_handle_t iter;
++ 	unsigned int nodeid;
+++	unsigned int node_pos;
+++	cmap_value_types_t type;
+++	size_t value_len;
++ 	int rc = 0;
++ 	int len, s = 0, t;
++ 
++@@ -95,6 +113,37 @@ linkstatusget_do (char *interface_name, int brief)
++ 		exit (1);
++ 	}
++ 
+++	result = cmap_initialize (&cmap_handle);
+++	if (result != CS_OK) {
+++		printf ("Could not initialize corosync cmap API error %d\n", result);
+++		exit (1);
+++	}
+++	/* Get a list of nodes. We do it this way rather than using votequorum as cfgtool
+++	 * needs to be independent of quorum type
+++	 */
+++	result = cmap_iter_init(cmap_handle, "nodelist.node.", &iter);
+++	if (result != CS_OK) {
+++		printf ("Could not get nodelist from cmap. error %d\n", result);
+++		exit (1);
+++	}
+++
+++	while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
+++		result = sscanf(iter_key, "nodelist.node.%u.nodeid", &node_pos);
+++		if (result != 1) {
+++			continue;
+++		}
+++		if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
+++			nodeid_list[s++] = nodeid;
+++		}
+++	}
+++
+++	/* totemknet returns nodes in nodeid order - even though it doesn't tell us
+++	   what the nodeid is. So sort our node list and we can then look up
+++	   knet node pos to get an actual nodeid.
+++	   Yep, I really should have totally rewritten the cfg interface for this.
+++	*/
+++	qsort(nodeid_list, s, sizeof(uint32_t), node_compare);
+++
++ 	result = corosync_cfg_local_get(handle, &nodeid);
++ 	if (result != CS_OK) {
++ 		printf ("Could not get the local node id, the error is: %d\n", result);
++@@ -134,9 +183,11 @@ linkstatusget_do (char *interface_name, int brief)
++ 					(!strstr(interface_status[i], "FAULTY"))) {
++ 					len = strlen(interface_status[i]);
++ 					printf ("\tstatus:\n");
++-					while(s < len) {
+++					while (s < len) {
+++						nodeid = nodeid_list[s];
++ 						t = interface_status[i][s] - '0';
++-						printf("\t\tnode %d:\t", s++);
+++						s++;
+++						printf("\t\tnodeid %2d:\t", nodeid);
++ 						printf("link enabled:%d\t", t&1? 1 : 0);
++ 						printf("link connected:%d\n", t&2? 1: 0);
++ 					}
++@@ -157,6 +208,7 @@ linkstatusget_do (char *interface_name, int brief)
++ 		free(interface_names);
++ 	}
++ 
+++	(void)cmap_finalize (cmap_handle);
++ 	(void)corosync_cfg_finalize (handle);
++ 	return rc;
++ }
+diff --git a/debian/patches/configure-Do-not-autodetect-nozzle.patch b/debian/patches/configure-Do-not-autodetect-nozzle.patch
+new file mode 100644
+index 00000000..6d66e433
+--- /dev/null
++++ b/debian/patches/configure-Do-not-autodetect-nozzle.patch
+@@ -0,0 +1,114 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 26 Feb 2019 11:04:16 +0100
++Subject: configure: Do not autodetect nozzle
++
++Nozzle is part of kronosnet but it is independent library. Enabling it
++when detected without ability to turn it off is not in line with
++other libraries.
++
++Solution is to use same method as for other libraries - add
++--enable-nozzle to configure script and add support for this option into
++spec file.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 83dc407f550a5b67f134dc41da6282f7b80d0ba2)
++---
++ configure.ac     | 21 ++++++++++++++-------
++ corosync.spec.in |  7 +++++++
++ 2 files changed, 21 insertions(+), 7 deletions(-)
++
++diff --git a/configure.ac b/configure.ac
++index 95cdb35..14c0e17 100644
++--- a/configure.ac
+++++ b/configure.ac
++@@ -174,7 +174,6 @@ LIBS="$SAVE_LIBS"
++ AC_CHECK_LIB([pthread], [pthread_create])
++ AC_CHECK_LIB([socket], [socket])
++ PKG_CHECK_MODULES([knet],[libknet])
++-PKG_CHECK_MODULES([nozzle],[libnozzle], [AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [Have libnozzle])], [have_nozzle="no"])
++ AC_CHECK_LIB([nsl], [t_open])
++ AC_CHECK_LIB([rt], [sched_getscheduler])
++ AC_CHECK_LIB([z], [crc32],
++@@ -395,21 +394,20 @@ AC_ARG_ENABLE([xmlconf],
++ AM_CONDITIONAL(INSTALL_XMLCONF, test x$enable_xmlconf = xyes)
++ 
++ AC_ARG_ENABLE([vqsim],
++-	[  --enable-vqsim               : Quorum simulator support ],,
+++	[  --enable-vqsim                  : Quorum simulator support ],,
++ 	[ enable_vqsim="no" ])
++ AM_CONDITIONAL(BUILD_VQSIM, test x$enable_vqsim = xyes)
++ 
+++AC_ARG_ENABLE([nozzle],
+++	[  --enable-nozzle                 : Support for nozzle ],,
+++	[ enable_nozzle="no" ])
+++
++ # *FLAGS handling goes here
++ 
++ ENV_CFLAGS="$CFLAGS"
++ ENV_CPPFLAGS="$CPPFLAGS"
++ ENV_LDFLAGS="$LDFLAGS"
++ 
++-# Add nozzle to Package features if enabled
++-if test "x$have_nozzle" != xno; then
++-	PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
++-fi
++-
++ # debug build stuff
++ if test "x${enable_debug}" = xyes; then
++ 	AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
++@@ -426,6 +424,7 @@ else
++ 	GDB_FLAGS="-g"
++ fi
++ 
+++
++ # Look for dbus-1
++ if test "x${enable_dbus}" = xyes; then
++ 	PKG_CHECK_MODULES([DBUS],[dbus-1])
++@@ -474,6 +473,14 @@ if test "x${enable_vqsim}" = xyes; then
++ fi
++ AM_CONDITIONAL(VQSIM_READLINE, [test "x${ac_cv_header_readline_readline_h}" = xyes])
++ 
+++# Look for nozzle
+++if test "x${enable_nozzle}" = xyes; then
+++	PKG_CHECK_MODULES([nozzle],[libnozzle])
+++	AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [have nozzle])
+++	PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
+++	WITH_LIST="$WITH_LIST --with nozzle"
+++fi
+++
++ do_snmp=0
++ if test "x${enable_snmp}" = xyes; then
++ 	AC_PATH_PROGS([SNMPCONFIG], [net-snmp-config])
++diff --git a/corosync.spec.in b/corosync.spec.in
++index bf5bfc2..07c004c 100644
++--- a/corosync.spec.in
+++++ b/corosync.spec.in
++@@ -11,6 +11,7 @@
++ %bcond_with dbus
++ %bcond_with systemd
++ %bcond_with xmlconf
+++%bcond_with nozzle
++ %bcond_with runautogen
++ 
++ %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
++@@ -55,6 +56,9 @@ BuildRequires: dbus-1-devel
++ BuildRequires: dbus-devel
++ %endif
++ %endif
+++%if %{with nozzle}
+++BuildRequires: libnozzle1-devel
+++%endif
++ %if %{with systemd}
++ %{?systemd_requires}
++ BuildRequires: systemd
++@@ -93,6 +97,9 @@ Requires: libxslt
++ %endif
++ %if %{with xmlconf}
++ 	--enable-xmlconf \
+++%endif
+++%if %{with nozzle}
+++	--enable-nozzle \
++ %endif
++ 	--with-initddir=%{_initrddir} \
++ 	--with-systemddir=%{_unitdir} \
+diff --git a/debian/patches/configure-Fix-GDB_CFLAGS-typo.patch b/debian/patches/configure-Fix-GDB_CFLAGS-typo.patch
+new file mode 100644
+index 00000000..8c1340d6
+--- /dev/null
++++ b/debian/patches/configure-Fix-GDB_CFLAGS-typo.patch
+@@ -0,0 +1,27 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Mon, 10 Jun 2019 10:56:10 +0200
++Subject: configure: Fix GDB_CFLAGS typo
++
++GDB_FLAGS (without C) is the correct name of variable
++to print in the summary.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 45d19a2d90bc2e926974e5668f85c17b37688637)
++---
++ configure.ac | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/configure.ac b/configure.ac
++index 82479f9..22b7898 100644
++--- a/configure.ac
+++++ b/configure.ac
++@@ -746,7 +746,7 @@ AC_MSG_RESULT([$PACKAGE build info:])
++ AC_MSG_RESULT([  Library SONAME           = ${SONAME}])
++ LIB_MSG_RESULT(m4_shift(local_soname_list))dnl
++ AC_MSG_RESULT([  Default optimization     = ${OPT_CFLAGS}])
++-AC_MSG_RESULT([  Default debug options    = ${GDB_CFLAGS}])
+++AC_MSG_RESULT([  Default debug options    = ${GDB_FLAGS}])
++ AC_MSG_RESULT([  Extra compiler warnings  = ${EXTRA_WARNING}])
++ AC_MSG_RESULT([  Env. defined CFLAG       = ${ENV_CFLAGS}])
++ AC_MSG_RESULT([  Env. defined CPPFLAGS    = ${ENV_CPPFLAGS}])
+diff --git a/debian/patches/AC_PROG_SED-is-already-present.patch b/debian/patches/configure.ac-AC_PROG_SED-is-already-present.patch
+similarity index 62%
+rename from debian/patches/AC_PROG_SED-is-already-present.patch
+rename to debian/patches/configure.ac-AC_PROG_SED-is-already-present.patch
+index 7547a7e7..fa970bcf 100644
+--- a/debian/patches/AC_PROG_SED-is-already-present.patch
++++ b/debian/patches/configure.ac-AC_PROG_SED-is-already-present.patch
+@@ -1,7 +1,13 @@
+ From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi at debian.org>
+ Date: Tue, 29 Jan 2019 15:15:27 +0100
+-Subject: AC_PROG_SED is already present
++Subject: configure.ac: AC_PROG_SED is already present
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
+ 
++Signed-off-by: Ferenc Wágner <wferi at debian.org>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit b9cc5be3a2ee7acd45486c821785cddffba3a48e)
+ ---
+  configure.ac | 1 -
+  1 file changed, 1 deletion(-)
+diff --git a/debian/patches/coroparse-Fix-compiler-warning.patch b/debian/patches/coroparse-Fix-compiler-warning.patch
+new file mode 100644
+index 00000000..418a4625
+--- /dev/null
++++ b/debian/patches/coroparse-Fix-compiler-warning.patch
+@@ -0,0 +1,24 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 26 Feb 2019 13:28:08 +0100
++Subject: coroparse: Fix compiler warning
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 7c825173deae33645d4c24d091a86162ac5ba28e)
++---
++ exec/coroparse.c | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/exec/coroparse.c b/exec/coroparse.c
++index bee0a8c..08f8f14 100644
++--- a/exec/coroparse.c
+++++ b/exec/coroparse.c
++@@ -596,7 +596,7 @@ static int main_config_parser_cb(const char *path,
++ 	 * Key_name is used in atoi_error/icmap_set_error, but many of icmap_set*
++ 	 * are using path, so initialize key_name to valid value
++ 	 */
++-	strncpy(key_name, path, sizeof(key_name));
+++	strncpy(key_name, path, sizeof(key_name) - 1);
++ 
++ 	switch (type) {
++ 	case PARSER_CB_START:
+diff --git a/debian/patches/corosync-cfgtool-Fix-i-matching.patch b/debian/patches/corosync-cfgtool-Fix-i-matching.patch
+new file mode 100644
+index 00000000..bb8cb73d
+--- /dev/null
++++ b/debian/patches/corosync-cfgtool-Fix-i-matching.patch
+@@ -0,0 +1,115 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Wed, 13 Feb 2019 12:54:55 +0100
++Subject: corosync-cfgtool: Fix -i matching
++
++Previously it was required to use link id together with IP address (ex.
++"0 127.0.0.1") as a -i parameter.
++
++This was reported as not very user friendly. Solution is to split
++returned interface name and try match link id and ip address
++separately.
++
++Also fix typo in description of parameter -s.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 4f9e46e7a820986c81a528cae0e0f44a6f17db3c)
++---
++ tools/corosync-cfgtool.c | 42 +++++++++++++++++++++++-------------------
++ man/corosync-cfgtool.8   |  6 +++---
++ 2 files changed, 26 insertions(+), 22 deletions(-)
++
++diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
++index ed29694..a43ee1e 100644
++--- a/tools/corosync-cfgtool.c
+++++ b/tools/corosync-cfgtool.c
++@@ -1,5 +1,5 @@
++ /*
++- * Copyright (c) 2006-2017 Red Hat, Inc.
+++ * Copyright (c) 2006-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -160,25 +160,29 @@ linkstatusget_do (char *interface_name, int brief)
++ 		printf ("Could not get the link status, the error is: %d\n", result);
++ 	} else {
++ 		for (i = 0; i < interface_count; i++) {
+++			char *cur_iface_name_space = strchr(interface_names[i], ' ');
+++			int show_current_iface;
+++
++ 			s = 0;
++-			if ( (interface_name &&
++-			      interface_names[i][0] != '\0' &&
++-			      (interface_name[0]=='\0' ||
++-				strcasecmp (interface_name, interface_names[i]) == 0)) ||
++-				!interface_name ) {
++-
++-				/*
++-				 * Interface_name is "<linkid> <IP address>"
++-				 * separate them out
++-				 */
++-				char *space = strchr(interface_names[i], ' ');
++-				if (!space) {
++-					continue;
++-				}
++-				*space = '\0';
+++			/*
+++			 * Interface_name is "<linkid> <IP address>"
+++			 * separate them out
+++			 */
+++			if (!cur_iface_name_space) {
+++				continue;
+++			}
+++			*cur_iface_name_space = '\0';
+++
+++			show_current_iface = 1;
+++			if (interface_name != NULL && interface_name[0] != '\0' &&
+++			    strcmp(interface_name, interface_names[i]) != 0 &&
+++			    strcmp(interface_name, cur_iface_name_space + 1) != 0) {
+++				show_current_iface = 0;
+++			}
++ 
+++			if (show_current_iface) {
++ 				printf ("LINK ID %s\n", interface_names[i]);
++-				printf ("\taddr\t= %s\n", space+1);
+++				printf ("\taddr\t= %s\n", cur_iface_name_space + 1);
++ 				if((!brief) && (strcmp(interface_status[i], "OK") != 0) &&
++ 					(!strstr(interface_status[i], "FAULTY"))) {
++ 					len = strlen(interface_status[i]);
++@@ -361,8 +365,8 @@ static void usage_do (void)
++ 	printf ("corosync-cfgtool [[-i <interface ip>] [-b] -s] [-R] [-L] [-k nodeid] [-a nodeid] [-h] [-H]\n\n");
++ 	printf ("A tool for displaying and configuring active parameters within corosync.\n");
++ 	printf ("options:\n");
++-	printf ("\t-i\tFinds only information about the specified interface IP address when used with -s..\n");
++-	printf ("\t-s\tDisplays the status of the current links on this node(UDP/UDPU), while extended status for KNET.\n");
+++	printf ("\t-i\tFinds only information about the specified interface IP address or link id when used with -s..\n");
+++	printf ("\t-s\tDisplays the status of the current links on this node(UDP/UDPU), with extended status for KNET.\n");
++ 	printf ("\t-b\tDisplays the brief status of the current links on this node when used with -s.(KNET only)\n");
++ 	printf ("\t-R\tTell all instances of corosync in this cluster to reload corosync.conf.\n");
++ 	printf ("\t-L\tTell corosync to reopen all logging files.\n");
++diff --git a/man/corosync-cfgtool.8 b/man/corosync-cfgtool.8
++index 9ac3da9..07e63b4 100644
++--- a/man/corosync-cfgtool.8
+++++ b/man/corosync-cfgtool.8
++@@ -31,7 +31,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH "COROSYNC-CFGTOOL" "8" "2018-10-15" "" ""
+++.TH "COROSYNC-CFGTOOL" "8" "2019-02-13" "" ""
++ .SH "NAME"
++ corosync-cfgtool \- An administrative tool for corosync.
++ .SH "SYNOPSIS"
++@@ -42,10 +42,10 @@ A tool for displaying and configuring active parameters within corosync.
++ .SH "OPTIONS"
++ .TP
++ .B -i
++-Finds only information about the specified interface IP address with -s.
+++Finds only information about the specified interface IP address or link id with -s.
++ .TP 
++ .B -s
++-Displays the status of the current links on this node for UDP/UDPU, while extended status
+++Displays the status of the current links on this node for UDP/UDPU, with extended status
++ for KNET. If any interfaces are faulty, 1 is returned by the binary. If all interfaces are
++ active 0 is returned to the shell.
++ After each link, the nodes on that link are displayed in order with their status,
+diff --git a/debian/patches/corosync.conf.5-fix-grammar.patch b/debian/patches/corosync.conf.5-fix-grammar.patch
+index e28efba4..c0331169 100644
+--- a/debian/patches/corosync.conf.5-fix-grammar.patch
++++ b/debian/patches/corosync.conf.5-fix-grammar.patch
+@@ -1,13 +1,19 @@
+ From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi at debian.org>
+ Date: Sat, 22 Dec 2018 18:56:01 +0100
+ Subject: corosync.conf.5: fix grammar
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
+ 
++Signed-off-by: Ferenc Wágner <wferi at debian.org>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 059c22a1545371175d38d7e7171ec6c3db64a99e)
+ ---
+  man/corosync.conf.5 | 2 +-
+  1 file changed, 1 insertion(+), 1 deletion(-)
+ 
+ diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
+-index 0e752bc..433a9b2 100644
++index 0b2ee03..a72650b 100644
+ --- a/man/corosync.conf.5
+ +++ b/man/corosync.conf.5
+ @@ -322,7 +322,7 @@ otherwise use first IPv4 address).
+diff --git a/debian/patches/corosync.conf.5-typography-fixes.patch b/debian/patches/corosync.conf.5-typography-fixes.patch
+index ebfb7f07..4e901a1e 100644
+--- a/debian/patches/corosync.conf.5-typography-fixes.patch
++++ b/debian/patches/corosync.conf.5-typography-fixes.patch
+@@ -1,13 +1,19 @@
+ From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi at debian.org>
+ Date: Sat, 22 Dec 2018 18:58:27 +0100
+ Subject: corosync.conf.5: typography fixes
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
+ 
++Signed-off-by: Ferenc Wágner <wferi at debian.org>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 4d0e764310b318a35da984cc125ef99010502172)
+ ---
+  man/corosync.conf.5 | 6 +++++-
+  1 file changed, 5 insertions(+), 1 deletion(-)
+ 
+ diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
+-index 433a9b2..dd6f3ba 100644
++index a72650b..aa928bc 100644
+ --- a/man/corosync.conf.5
+ +++ b/man/corosync.conf.5
+ @@ -320,7 +320,11 @@ otherwise use first IPv6 address) and
+diff --git a/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
+new file mode 100644
+index 00000000..a69b53ac
+--- /dev/null
++++ b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
+@@ -0,0 +1,152 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 16 Apr 2019 12:52:31 +0200
++Subject: cpg: Add CPG_REASON_UNDEFINED
++
++Previously the reason field for the member_list items
++in cpg_totem_confchg_fn was unset what may be little confusing.
++
++Solution is to add a special value CPG_REASON_UNDEFINED and use it for
++the member_list items.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 41f9e966bb1cfa70d0f6ec1ce46d9c845845b599)
++---
++ include/corosync/cpg.h        |  3 ++-
++ man/cpg_initialize.3.in       | 18 ++++++++++--------
++ man/cpg_model_initialize.3.in | 18 ++++++++++--------
++ exec/cpg.c                    |  3 ++-
++ 4 files changed, 24 insertions(+), 18 deletions(-)
++
++diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h
++index 5ebd478..600bbf7 100644
++--- a/include/corosync/cpg.h
+++++ b/include/corosync/cpg.h
++@@ -1,5 +1,5 @@
++ /*
++- * Copyright (c) 2006-2011 Red Hat, Inc.
+++ * Copyright (c) 2006-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -80,6 +80,7 @@ typedef enum {
++  * @brief The cpg_reason_t enum
++  */
++ typedef enum {
+++	CPG_REASON_UNDEFINED = 0,
++ 	CPG_REASON_JOIN = 1,
++ 	CPG_REASON_LEAVE = 2,
++ 	CPG_REASON_NODEDOWN = 3,
++diff --git a/man/cpg_initialize.3.in b/man/cpg_initialize.3.in
++index bdecc1e..38c7de5 100644
++--- a/man/cpg_initialize.3.in
+++++ b/man/cpg_initialize.3.in
++@@ -1,5 +1,5 @@
++ .\"/*
++-.\" * Copyright (c) 2006-2009 Red Hat, Inc.
+++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
++ .\" *
++ .\" * All rights reserved.
++ .\" *
++@@ -31,7 +31,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH CPG_INITIALIZE 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+++.TH CPG_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
++ .SH NAME
++ cpg_initialize \- Create a new connection to the CPG service
++ .SH SYNOPSIS
++@@ -132,18 +132,20 @@ struct cpg_address {
++ .IP
++ .PP
++ where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
++-or sent the message, and reason is an integer code indicating why the node joined/left the group.
+++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
+++set for the member_list items).
++ .PP
++ .IP
++ .RS
++ .ne 18
++ .nf
++ .PP
++-CPG_REASON_JOIN     - the process joined a group using cpg_join().
++-CPG_REASON_LEAVE    - the process left a group using cpg_leave()
++-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
++-CPG_REASON_NODEUP   - the process joined a group because it was already a member of a group on a node that has just joined the cluster
++-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
+++CPG_REASON_JOIN      - the process joined a group using cpg_join().
+++CPG_REASON_LEAVE     - the process left a group using cpg_leave()
+++CPG_REASON_NODEDOWN  - the process left a group because the node left the cluster.
+++CPG_REASON_NODEUP    - the process joined a group because it was already a member of a group on a node that has just joined the cluster
+++CPG_REASON_PROCDOWN  - the process left a group without calling cpg_leave()
+++CPG_REASON_UNDEFINED - a special value used for the member_list items
++ .ta
++ .fi
++ .RE
++diff --git a/man/cpg_model_initialize.3.in b/man/cpg_model_initialize.3.in
++index e06325d..17ca16a 100644
++--- a/man/cpg_model_initialize.3.in
+++++ b/man/cpg_model_initialize.3.in
++@@ -1,5 +1,5 @@
++ .\"/*
++-.\" * Copyright (c) 2010 Red Hat, Inc.
+++.\" * Copyright (c) 2010-2019 Red Hat, Inc.
++ .\" *
++ .\" * All rights reserved.
++ .\" *
++@@ -32,7 +32,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH CPG_MODEL_INITIALIZE 3 2010-04-07 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+++.TH CPG_MODEL_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
++ .SH NAME
++ cpg_model_initialize \- Create a new connection to the CPG service
++ .SH SYNOPSIS
++@@ -166,18 +166,20 @@ struct cpg_address {
++ .IP
++ .PP
++ where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
++-or sent the message, and reason is an integer code indicating why the node joined/left the group.
+++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
+++set for the member_list items).
++ .PP
++ .IP
++ .RS
++ .ne 18
++ .nf
++ .PP
++-CPG_REASON_JOIN     - the process joined a group using cpg_join().
++-CPG_REASON_LEAVE    - the process left a group using cpg_leave()
++-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
++-CPG_REASON_NODEUP   - the process joined a group because it was already a member of a group on a node that has just joined the cluster
++-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
+++CPG_REASON_JOIN      - the process joined a group using cpg_join().
+++CPG_REASON_LEAVE     - the process left a group using cpg_leave()
+++CPG_REASON_NODEDOWN  - the process left a group because the node left the cluster.
+++CPG_REASON_NODEUP    - the process joined a group because it was already a member of a group on a node that has just joined the cluster
+++CPG_REASON_PROCDOWN  - the process left a group without calling cpg_leave()
+++CPG_REASON_UNDEFINED - a special value used for the member_list items
++ .ta
++ .fi
++ .RE
++diff --git a/exec/cpg.c b/exec/cpg.c
++index b7ac579..e39ca34 100644
++--- a/exec/cpg.c
+++++ b/exec/cpg.c
++@@ -1,5 +1,5 @@
++ /*
++- * Copyright (c) 2006-2015 Red Hat, Inc.
+++ * Copyright (c) 2006-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -712,6 +712,7 @@ static int notify_lib_joinlist(
++ 			if (!founded) {
++ 				retgi->nodeid = pi->nodeid;
++ 				retgi->pid = pi->pid;
+++				retgi->reason = CPG_REASON_UNDEFINED;
++ 				retgi++;
++ 			}
++ 		}
+diff --git a/debian/patches/crypto-re-introduce-secauth-parameter.patch b/debian/patches/crypto-re-introduce-secauth-parameter.patch
+new file mode 100644
+index 00000000..84e009e2
+--- /dev/null
++++ b/debian/patches/crypto-re-introduce-secauth-parameter.patch
+@@ -0,0 +1,62 @@
++From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
++Date: Wed, 10 Apr 2019 09:43:33 +0200
++Subject: crypto: re-introduce secauth parameter
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
++
++with the following semantics:
++- default off
++- implies crypto_hash SHA256 and crypto_cipher AES256
++- crypto_* have higher precedence
++- only applicable for knet, like crypto_*
++
++this should make upgrading from Corosync 2.x less painful for users that
++have an explicit secauth=on in their configuration.
++
++Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit b97ca8e9f026aaaf2fe9cf697d89803004587f60)
++---
++ exec/totemconfig.c  | 8 ++++++++
++ man/corosync.conf.5 | 8 ++++++++
++ 2 files changed, 16 insertions(+)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 4f69fd5..1954f76 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -450,6 +450,14 @@ static int totem_get_crypto(struct totem_config *totem_config, const char **erro
++ 		tmp_model = "nss";
++ 	}
++ 
+++	if (icmap_get_string("totem.secauth", &str) == CS_OK) {
+++		if (strcmp(str, "on") == 0) {
+++			tmp_cipher = "aes256";
+++			tmp_hash = "sha256";
+++		}
+++		free(str);
+++	}
+++
++ 	if (icmap_get_string("totem.crypto_cipher", &str) == CS_OK) {
++ 		if (strcmp(str, "none") == 0) {
++ 			tmp_cipher = "none";
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 887a52b..e2fd9ed 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -227,6 +227,14 @@ transmission is only supported for the knet transport.
++ 
++ The default is none.
++ 
+++.TP
+++secauth
+++This implies crypto_cipher=aes256 and crypto_hash=sha256, unless those options
+++are explicitly set. Encrypted transmission is only supported for the knet
+++transport.
+++
+++The default is off.
+++
++ .TP
++ keyfile
++ This specifies the fully qualified path to the shared key used to
+diff --git a/debian/patches/doc-Update-INSTALL-file.patch b/debian/patches/doc-Update-INSTALL-file.patch
+new file mode 100644
+index 00000000..0404de43
+--- /dev/null
++++ b/debian/patches/doc-Update-INSTALL-file.patch
+@@ -0,0 +1,124 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Wed, 16 Jan 2019 14:39:42 +0100
++Subject: doc: Update INSTALL file
++
++- Add LibQB and Knet links
++- Remove old (pre udpu) config file example
++- Change corosync.conf man page to contain useful information about
++token timeout
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Fabio M. Di Nitto <fdinitto at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit ce29717491160dec3104245af1fa98910e1e6951)
++---
++ INSTALL             | 58 ++++++++---------------------------------------------
++ man/corosync.conf.5 |  5 ++++-
++ 2 files changed, 12 insertions(+), 51 deletions(-)
++
++diff --git a/INSTALL b/INSTALL
++index 85655ca..bfe684d 100644
++--- a/INSTALL
+++++ b/INSTALL
++@@ -43,7 +43,8 @@ balance:~/corosync# make install
++ * A notice about dependencies *
++ -------------------------------
++ We have strived very hard to avoid dependencies as much as possible, but there
++-are two required libraries: LibQB and KNET.
+++are two required libraries: LibQB (https://github.com/ClusterLabs/libqb)
+++and KNET (https://kronosnet.org/).
++ 
++ Optional dependencies are support for DBUS, SNMP and libstatgrab.
++ 
++@@ -102,54 +103,11 @@ And you should get traps
++ ------------------------
++ * Configuring Corosync *
++ ------------------------
++-The corosync executive will automatically determine cluster membership by
++-communicating on a specified multicast address and port.
++-
++-The directory conf contains the file corosync.conf.example
++-
++-# Please read the corosync.conf.5 manual page
++-totem {
++-	version: 2
++-	secauth: off
++-	threads: 0
++-	interface {
++-		ringnumber: 0
++-		bindnetaddr: 192.168.1.1
++-		mcastaddr: 226.94.1.1
++-		mcastport: 5405
++-	}
++-}
++-
++-logging {
++-	fileline: off
++-	to_stderr: yes
++-	to_file: yes
++-	to_syslog: yes
++-	logfile: /tmp/corosync.log
++-	debug: off
++-	timestamp: on
++-}
++-
++-The totem section contains three values.  All three values must be set
++-or the corosync executive wll exit with an error.
++-
++-bindnetaddr specifies the address which the corosync Executive should bind to.
++-This address should always end in zero.  If the local interface taffic
++-should routed over is 192.168.5.92, set bindnetaddr to 192.168.5.0.
++-
++-mcastaddr is a multicast address.  The default should work but you may have
++-a different network configuration.  Avoid 224.x.x.x because this is a "config"
++-multicast address.
++-
++-mcastport specifies the UDP port number.  It is possible to use the same
++-multicast address on a network with the corosync services configured for
++-different UDP ports.
++-
++-The timeout section contains seven values.  This section is not normally used,
++-but rather used to override the program defaults for the purposes of fine
++-tuning for a given networking/processor combination or for debugging purposes.
++-Be careful to use the same timeout values on each of the nodes in the cluster
++-or unpredictable results may occur.
+++The configuration directory (usually /etc/corosync) contains an example
+++configuration file (corosync.conf.example). Please copy it as corosync.conf
+++and edit it as needed. At the very minimum, the nodelist section will have to be changed
+++to list all cluster nodes. For more information about the configuration file
+++please read the corosync.conf.5 manual page.
++ 
++ Generate a private key
++ ----------------------
++@@ -161,7 +119,7 @@ First generate the key on one of the nodes:
++ 
++ balance# corosync-keygen
++ Corosync Authentication key generator.
++-Gathering 1024 bits for key from /dev/random.
+++Gathering 8192 bits for key from /dev/random.
++ Writing corosync key to /etc/corosync/authkey.
++ 
++ After this is complete, a private key will be in the file /etc/corosync/authkey.
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 0e752bc..0b2ee03 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -32,7 +32,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH COROSYNC_CONF 5 2019-01-10 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+++.TH COROSYNC_CONF 5 2019-01-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
++ .SH NAME
++ corosync.conf - corosync executive configuration file
++ 
++@@ -347,6 +347,9 @@ For real token timeout used by totem it's possible to read cmap value of
++ .B runtime.config.totem.token
++ key.
++ 
+++Be careful to use the same timeout values on each of the nodes in the cluster
+++or unpredictable results may occur.
+++
++ The default is 1000 milliseconds.
++ 
++ .TP
+diff --git a/debian/patches/keygen-Reflect-change-in-knet.patch b/debian/patches/keygen-Reflect-change-in-knet.patch
+new file mode 100644
+index 00000000..068f481f
+--- /dev/null
++++ b/debian/patches/keygen-Reflect-change-in-knet.patch
+@@ -0,0 +1,100 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 9 Apr 2019 17:09:34 +0200
++Subject: keygen: Reflect change in knet
++
++Knet commit 1cb36f0cffd4559971826ca4774a88c5b05882fb reduced minimal
++key length to 1024-bit. Keygen should keep compatibility with already
++released 3.0.[0-1] so default key length should be 2048 bits. It's
++possible to use -s argument to generate shorter key - keygen respects
++minimum/maximum as defined by knet.
++
++Also fix man page to reflect this change.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit c260bce45b1f5b4a82c74513c4b3302d32daf179)
++---
++ tools/corosync-keygen.c |  4 ++--
++ man/corosync-keygen.8   | 21 +++++++++------------
++ 2 files changed, 11 insertions(+), 14 deletions(-)
++
++diff --git a/tools/corosync-keygen.c b/tools/corosync-keygen.c
++index 40e4d6e..243661a 100644
++--- a/tools/corosync-keygen.c
+++++ b/tools/corosync-keygen.c
++@@ -1,6 +1,6 @@
++ /*
++  * Copyright (c) 2004 MontaVista Software, Inc.
++- * Copyright (c) 2005-2017 Red Hat, Inc.
+++ * Copyright (c) 2005-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -52,7 +52,7 @@
++ 
++ #define DEFAULT_KEYFILE COROSYSCONFDIR "/authkey"
++ 
++-#define DEFAULT_KEYFILE_LEN		TOTEM_PRIVATE_KEY_LEN_MIN
+++#define DEFAULT_KEYFILE_LEN		256
++ 
++ #define DEFAULT_RANDOM_DEV		"/dev/urandom"
++ 
++diff --git a/man/corosync-keygen.8 b/man/corosync-keygen.8
++index 0839621..8767ddc 100644
++--- a/man/corosync-keygen.8
+++++ b/man/corosync-keygen.8
++@@ -1,5 +1,5 @@
++ .\"/*
++-.\" * Copyright (C) 2010-2017 Red Hat, Inc.
+++.\" * Copyright (C) 2010-2019 Red Hat, Inc.
++ .\" *
++ .\" * All rights reserved.
++ .\" *
++@@ -31,7 +31,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH COROSYNC-KEYGEN 8 2017-07-03
+++.TH COROSYNC-KEYGEN 8 2019-04-09
++ .SH NAME
++ corosync-keygen \- Generate an authentication key for Corosync.
++ .SH SYNOPSIS
++@@ -69,7 +69,7 @@ Random number source file. Default is /dev/urandom. As an example /dev/random ma
++ used when really superb randomness is needed.
++ .TP
++ .B -s size
++-Size of the generated key in bytes. Default is 1024 bytes. Allowed range is <1024, 4096>.
+++Size of the generated key in bytes. Default is 256 bytes. Allowed range is <128, 4096>.
++ .TP
++ .TP
++ .B -l
++@@ -84,7 +84,7 @@ Generate the key.
++ .nf
++ # corosync-keygen
++ Corosync Cluster Engine Authentication key generator.
++-Gathering 8192 bits for key from /dev/urandom.
+++Gathering 2048 bits for key from /dev/urandom.
++ Writing corosync key to /etc/corosync/authkey
++ .fi
++ 
++@@ -101,15 +101,12 @@ Writing corosync key to /tmp/authkey.
++ Generate superb key using /dev/random
++ .nf
++ # corosync-keygen -r /dev/random
++-Corosync Cluster Engine Authentication key generator.
++-Gathering 8192 bits for key from /dev/random.
+++Gathering 2048 bits for key from /dev/random.
++ Press keys on your keyboard to generate entropy.
++-Press keys on your keyboard to generate entropy (7928 bits still needed).
++-Press keys on your keyboard to generate entropy (7880 bits still needed).
++- ...
++-Press keys on your keyboard to generate entropy (104 bits still needed).
++-Press keys on your keyboard to generate entropy (56 bits still needed).
++-Press keys on your keyboard to generate entropy (8 bits still needed).
+++Press keys on your keyboard to generate entropy (1128 bits still needed).
+++Press keys on your keyboard to generate entropy (504 bits still needed).
+++Press keys on your keyboard to generate entropy (128 bits still needed).
+++Press keys on your keyboard to generate entropy (32 bits still needed).
++ Writing corosync key to /etc/corosync/authkey.
++ .fi
++ 
+diff --git a/debian/patches/knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch b/debian/patches/knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
+new file mode 100644
+index 00000000..1b3fd495
+--- /dev/null
++++ b/debian/patches/knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
+@@ -0,0 +1,82 @@
++From: Christine Caulfield <ccaulfie at redhat.com>
++Date: Thu, 2 May 2019 14:22:47 +0100
++Subject: knet: Fix a couple of errors when adding a new link
++
++When adding a new link for the first time you will often see:
++1) knet_link_set_ping_timers for nodeid 1, link 1 failed: Invalid
++argument (22)
++2) New config has different knet transport for link 1. Internal value
++was NOT changed. To reconfigure an interface it must be deleted and
++recreated. A working interface needs to be available to corosync at all
++times
++
++1) is caused by setting the ping timers twice, once in
++totemknet_member_add() and once in totemknet_refresh_config().
++The first time we don't know the value
++so it's zero and thus display an error. For this we simply check
++for the zero and skip the knet API call. It's not ideal, but
++totemconfig needs a lot of reconfiguring itself before we can
++make this more sane.
++
++2) was caused by simply comparing an unconfigured link with
++a configured one, so OF COURSE, they are going to be different!
++
++Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 01ce5a96ef9dea2d517d84abec7aecc6af99e7aa)
++---
++ exec/totemconfig.c |  3 ++-
++ exec/totemknet.c   | 26 +++++++++++++++-----------
++ 2 files changed, 17 insertions(+), 12 deletions(-)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 3b4dbae..091eedc 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -1152,7 +1152,8 @@ static void check_things_have_not_changed(struct totem_config *totem_config)
++ 	int changed = 0;
++ 
++ 	for (i = 0; i<INTERFACE_MAX; i++) {
++-		if (totem_config->interfaces[i].configured) {
+++		if (totem_config->interfaces[i].configured &&
+++		    totem_config->orig_interfaces[i].configured) {
++ 			if (totem_config->interfaces[i].knet_transport !=
++ 			    totem_config->orig_interfaces[i].knet_transport) {
++ 				log_printf(LOGSYS_LEVEL_ERROR,
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 77cb65a..2c3f47f 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -1306,17 +1306,21 @@ int totemknet_member_add (
++ 		KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_priority for nodeid %d, link %d failed", member->nodeid, link_no);
++ 	}
++ 
++-	err = knet_link_set_ping_timers(instance->knet_handle, member->nodeid, link_no,
++-				  instance->totem_config->interfaces[link_no].knet_ping_interval,
++-				  instance->totem_config->interfaces[link_no].knet_ping_timeout,
++-				  instance->totem_config->interfaces[link_no].knet_ping_precision);
++-	if (err) {
++-		KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_ping_timers for nodeid %d, link %d failed", member->nodeid, link_no);
++-	}
++-	err = knet_link_set_pong_count(instance->knet_handle, member->nodeid, link_no,
++-				       instance->totem_config->interfaces[link_no].knet_pong_count);
++-	if (err) {
++-		KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_pong_count for nodeid %d, link %d failed", member->nodeid, link_no);
+++	/* ping timeouts maybe 0 here for a newly added interface so we leave this till later, it will
+++	   get done in totemknet_refresh_config */
+++	if (instance->totem_config->interfaces[link_no].knet_ping_interval != 0) {
+++		err = knet_link_set_ping_timers(instance->knet_handle, member->nodeid, link_no,
+++						instance->totem_config->interfaces[link_no].knet_ping_interval,
+++						instance->totem_config->interfaces[link_no].knet_ping_timeout,
+++						instance->totem_config->interfaces[link_no].knet_ping_precision);
+++		if (err) {
+++			KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_ping_timers for nodeid %d, link %d failed", member->nodeid, link_no);
+++		}
+++		err = knet_link_set_pong_count(instance->knet_handle, member->nodeid, link_no,
+++					       instance->totem_config->interfaces[link_no].knet_pong_count);
+++		if (err) {
+++			KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_pong_count for nodeid %d, link %d failed", member->nodeid, link_no);
+++		}
++ 	}
++ 
++ 	err = knet_link_set_enable(instance->knet_handle, member->nodeid, link_no, 1);
+diff --git a/debian/patches/knet-Fix-initialising-of-knet-access-lists.patch b/debian/patches/knet-Fix-initialising-of-knet-access-lists.patch
+new file mode 100644
+index 00000000..b50865ec
+--- /dev/null
++++ b/debian/patches/knet-Fix-initialising-of-knet-access-lists.patch
+@@ -0,0 +1,70 @@
++From: Christine Caulfield <ccaulfie at redhat.com>
++Date: Tue, 19 Mar 2019 10:47:58 +0000
++Subject: knet: Fix initialising of knet access lists.
++
++It needs to be done at both reload and initialize time.
++Also disable access lists if the config key is removed.
++
++Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 482df5d67b6b9fe021a1252537c4c499a66de0f8)
++---
++ exec/totemknet.c | 31 ++++++++++++++++++++++---------
++ 1 file changed, 22 insertions(+), 9 deletions(-)
++
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 7984b55..884eefe 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -737,6 +737,24 @@ static void timer_function_netif_check_timeout (
++ 	}
++ }
++ 
+++static void knet_set_access_list_config(struct totemknet_instance *instance)
+++{
+++#ifdef HAVE_KNET_ACCESS_LIST
+++	uint32_t value = 0; /* disable by default */
+++	cs_error_t err;
+++
+++	if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
+++		knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
+++        }
+++
+++	err = knet_handle_enable_access_lists(instance->knet_handle, value);
+++	if (err) {
+++	        KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
+++	}
+++#endif
+++}
+++
+++
++ /* NOTE: this relies on the fact that totem_reload_notify() is called first */
++ static void totemknet_refresh_config(
++ 	int32_t event,
++@@ -764,15 +782,7 @@ static void totemknet_refresh_config(
++ 		return;
++ 	}
++ 
++-#ifdef HAVE_KNET_ACCESS_LIST
++-	if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
++-		knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
++-		err = knet_handle_enable_access_lists(instance->knet_handle, value);
++-		if (err) {
++-			KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
++-		}
++-	}
++-#endif
+++	knet_set_access_list_config(instance);
++ 
++ 	if (icmap_get_uint32("totem.knet_pmtud_interval", &value) == CS_OK) {
++ 
++@@ -944,6 +954,9 @@ int totemknet_initialize (
++ 		KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_CRIT, "knet_handle_new failed");
++ 		goto exit_error;
++ 	}
+++
+++	knet_set_access_list_config(instance);
+++
++ 	res = knet_handle_pmtud_setfreq(instance->knet_handle, instance->totem_config->knet_pmtud_interval);
++ 	if (res) {
++ 		KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_pmtud_setfreq failed");
+diff --git a/debian/patches/knet-Use-block_unlisted_ips.patch b/debian/patches/knet-Use-block_unlisted_ips.patch
+new file mode 100644
+index 00000000..c3ff3092
+--- /dev/null
++++ b/debian/patches/knet-Use-block_unlisted_ips.patch
+@@ -0,0 +1,67 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Fri, 24 May 2019 09:33:13 +0200
++Subject: knet: Use block_unlisted_ips
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 9bba026bcd99bfc27c24e749262210513bd43ccc)
++---
++ exec/coroparse.c    | 3 ---
++ exec/totemknet.c    | 7 +++----
++ man/corosync.conf.5 | 7 +------
++ 3 files changed, 4 insertions(+), 13 deletions(-)
++
++diff --git a/exec/coroparse.c b/exec/coroparse.c
++index 87bbceb..0acb4c2 100644
++--- a/exec/coroparse.c
+++++ b/exec/coroparse.c
++@@ -708,9 +708,6 @@ static int main_config_parser_cb(const char *path,
++ 			    (strcmp(path, "totem.miss_count_const") == 0) ||
++ 			    (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
++ 			    (strcmp(path, "totem.knet_compression_threshold") == 0) ||
++-#ifdef HAVE_KNET_ACCESS_LIST
++-			    (strcmp(path, "totem.knet_enable_access_lists") == 0) ||
++-#endif
++ 			    (strcmp(path, "totem.netmtu") == 0)) {
++ 				val_type = ICMAP_VALUETYPE_UINT32;
++ 				if (safe_atoq(value, &val, val_type) != 0) {
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 884eefe..2af69b3 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -740,12 +740,11 @@ static void timer_function_netif_check_timeout (
++ static void knet_set_access_list_config(struct totemknet_instance *instance)
++ {
++ #ifdef HAVE_KNET_ACCESS_LIST
++-	uint32_t value = 0; /* disable by default */
+++	uint32_t value;
++ 	cs_error_t err;
++ 
++-	if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
++-		knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
++-        }
+++	value = instance->totem_config->block_unlisted_ips;
+++	knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
++ 
++ 	err = knet_handle_enable_access_lists(instance->knet_handle, value);
++ 	if (err) {
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 953c830..0e1ef88 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -566,14 +566,9 @@ knet_pmtud_interval
++ How often the knet PMTUd runs to look for network MTU changes.
++ Value in seconds, default: 30
++ 
++-.TP
++-knet_enable_access_lists
++-Allow knet to drop packets from IP addresses that are not known to corosync.
++-Value is 0 (off) and 1 (on). Default: 0.
++-
++ .TP
++ block_unlisted_ips
++-Allow UDPU to drop packets from IP addresses that are not known
+++Allow UDPU and KNET to drop packets from IP addresses that are not known
++ (nodes which don't exist in the nodelist) to corosync.
++ Value is yes or no.
++ 
+diff --git a/debian/patches/knet-allow-corosync-to-use-knet-access-lists.patch b/debian/patches/knet-allow-corosync-to-use-knet-access-lists.patch
+new file mode 100644
+index 00000000..f5cb424d
+--- /dev/null
++++ b/debian/patches/knet-allow-corosync-to-use-knet-access-lists.patch
+@@ -0,0 +1,93 @@
++From: "Fabio M. Di Nitto" <fdinitto at redhat.com>
++Date: Sun, 10 Mar 2019 08:23:38 +0100
++Subject: knet: allow corosync to use knet access lists
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
++
++currently knet acl are only available on master
++but they might be backported
++to stable1 as they don´t break onwire protocol.
++
++Signed-off-by: Fabio M. Di Nitto <fdinitto at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 5c9a2b1c0676aa7581b31b5cfb6ae2d969abd1b2)
++---
++ configure.ac        |  9 +++++++++
++ exec/coroparse.c    |  3 +++
++ exec/totemknet.c    | 10 ++++++++++
++ man/corosync.conf.5 |  5 +++++
++ 4 files changed, 27 insertions(+)
++
++diff --git a/configure.ac b/configure.ac
++index a27ba95..82479f9 100644
++--- a/configure.ac
+++++ b/configure.ac
++@@ -180,6 +180,15 @@ AC_CHECK_LIB([z], [crc32],
++     AM_CONDITIONAL([HAVE_CRC32], true),
++     AM_CONDITIONAL([HAVE_CRC32], false))
++ 
+++# this hack is necessary to check for symbols on out of tree builds
+++# but it is as horrible as it gets and in theory users should be
+++# invoking ./configure with proper LIBRARY_PATH set.
+++OLDLIBS="$LIBS"
+++LIBS="$knet_LIBS $LIBS"
+++AC_CHECK_LIB([knet],[knet_handle_enable_access_lists],
+++	     [AC_DEFINE_UNQUOTED([HAVE_KNET_ACCESS_LIST], 1, [have knet access list])])
+++LIBS="$OLDLIBS"
+++
++ # Checks for library functions.
++ AC_FUNC_ALLOCA
++ AC_FUNC_CLOSEDIR_VOID
++diff --git a/exec/coroparse.c b/exec/coroparse.c
++index 0acb4c2..87bbceb 100644
++--- a/exec/coroparse.c
+++++ b/exec/coroparse.c
++@@ -708,6 +708,9 @@ static int main_config_parser_cb(const char *path,
++ 			    (strcmp(path, "totem.miss_count_const") == 0) ||
++ 			    (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
++ 			    (strcmp(path, "totem.knet_compression_threshold") == 0) ||
+++#ifdef HAVE_KNET_ACCESS_LIST
+++			    (strcmp(path, "totem.knet_enable_access_lists") == 0) ||
+++#endif
++ 			    (strcmp(path, "totem.netmtu") == 0)) {
++ 				val_type = ICMAP_VALUETYPE_UINT32;
++ 				if (safe_atoq(value, &val, val_type) != 0) {
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 2c3f47f..7984b55 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -764,6 +764,16 @@ static void totemknet_refresh_config(
++ 		return;
++ 	}
++ 
+++#ifdef HAVE_KNET_ACCESS_LIST
+++	if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
+++		knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
+++		err = knet_handle_enable_access_lists(instance->knet_handle, value);
+++		if (err) {
+++			KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
+++		}
+++	}
+++#endif
+++
++ 	if (icmap_get_uint32("totem.knet_pmtud_interval", &value) == CS_OK) {
++ 
++ 		instance->totem_config->knet_pmtud_interval = value;
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 5fef28a..674179d 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -566,6 +566,11 @@ knet_pmtud_interval
++ How often the knet PMTUd runs to look for network MTU changes.
++ Value in seconds, default: 30
++ 
+++.TP
+++knet_enable_access_lists
+++Allow knet to drop packets from IP addresses that are not known to corosync.
+++Value is 0 (off) and 1 (on). Default: 0.
+++
++ .PP
++ Within the
++ .B logging
+diff --git a/debian/patches/man-Add-vqsim-man-page-into-distributed-tarball.patch b/debian/patches/man-Add-vqsim-man-page-into-distributed-tarball.patch
+new file mode 100644
+index 00000000..c13e4f97
+--- /dev/null
++++ b/debian/patches/man-Add-vqsim-man-page-into-distributed-tarball.patch
+@@ -0,0 +1,40 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Mon, 10 Jun 2019 08:04:50 +0200
++Subject: man: Add vqsim man page into distributed tarball
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 8ced7e545dde485ac57886e8713330ec82eaa35c)
++---
++ man/Makefile.am | 5 ++++-
++ 1 file changed, 4 insertions(+), 1 deletion(-)
++
++diff --git a/man/Makefile.am b/man/Makefile.am
++index 8e4eda3..2ef5dcd 100644
++--- a/man/Makefile.am
+++++ b/man/Makefile.am
++@@ -37,6 +37,8 @@ MAINTAINERCLEANFILES	= Makefile.in
++ xml_man			= corosync-xmlproc.8 \
++ 			  corosync.xml.5
++ 
+++corosync_vqsim_man	= corosync-vqsim.8
+++
++ INDEX_HTML		= index.html
++ 
++ autogen_man		= cpg_context_get.3 \
++@@ -116,6 +118,7 @@ autogen_common		= ipc_common.sh.errors
++ 
++ EXTRA_DIST		= $(INDEX_HTML) \
++ 			  $(xml_man) \
+++			  $(corosync_vqsim_man) \
++ 			  $(autogen_man:%=%.in) \
++ 			  $(autogen_common)
++ 
++@@ -140,7 +143,7 @@ dist_man_MANS 		= corosync.conf.5 \
++ 			  cmap_keys.8
++ 
++ if BUILD_VQSIM
++-dist_man_MANS		+= corosync-vqsim.8
+++dist_man_MANS		+= $(corosync_vqsim_man)
++ endif
++ 
++ if INSTALL_XMLCONF
+diff --git a/debian/patches/man-Enahnce-block_unlisted_ips-description.patch b/debian/patches/man-Enahnce-block_unlisted_ips-description.patch
+new file mode 100644
+index 00000000..effd8231
+--- /dev/null
++++ b/debian/patches/man-Enahnce-block_unlisted_ips-description.patch
+@@ -0,0 +1,33 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Fri, 31 May 2019 09:34:33 +0200
++Subject: man: Enahnce block_unlisted_ips description
++
++Thanks Christine Caulfield <ccaulfie at redhat.com> for
++Englishify and refining the description.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit d775f1425d6ebbfa25c7ba43c0fc69902507a8d6)
++---
++ man/corosync.conf.5 | 8 ++++++++
++ 1 file changed, 8 insertions(+)
++
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index ba1397f..3b77733 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -572,6 +572,14 @@ Allow UDPU and KNET to drop packets from IP addresses that are not known
++ (nodes which don't exist in the nodelist) to corosync.
++ Value is yes or no.
++ 
+++This feature is mainly to protect against the joining of nodes
+++with outdated configurations after a cluster split.
+++Another use case is to allow the atomic merge of two independent clusters.
+++
+++Changing the default value is not recommended, the overhead is tiny and
+++an existing cluster may fail if corosync is started on an unlisted node
+++with an old configuration.
+++
++ The default value is yes.
++ 
++ .PP
+diff --git a/debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch b/debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch
+new file mode 100644
+index 00000000..33098378
+--- /dev/null
++++ b/debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch
+@@ -0,0 +1,37 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 28 May 2019 10:08:37 +0200
++Subject: man: Enhance corosync.conf mp a bit
++
++Fix issues found by Ulrich Windl <Ulrich.Windl at rz.uni-regensburg.de>
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 183d5da5eb3d74043464dbc5d6e92f8b38a2e9cb)
++---
++ man/corosync.conf.5 | 6 +++---
++ 1 file changed, 3 insertions(+), 3 deletions(-)
++
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 0e1ef88..ba1397f 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -191,7 +191,7 @@ version
++ This specifies the version of the configuration file.  Currently the only
++ valid version for this directive is 2.
++ 
++-.PP
+++.TP
++ clear_node_high_bit
++ This configuration option is optional and is only relevant when no nodeid is
++ specified.  Some corosync clients require a signed 32 bit nodeid that is greater
++@@ -432,8 +432,8 @@ The default is 180 milliseconds.
++ .TP
++ token_retransmits_before_loss_const
++ This value identifies how many token retransmits should be attempted before
++-forming a new configuration.  If this value is set, retransmit and hold will
++-be automatically calculated from retransmits_before_loss and token.
+++forming a new configuration. It is also used for token_retransmit
+++and hold calculations.
++ 
++ The default is 4 retransmissions.
++ 
+diff --git a/debian/patches/man-Enhance-token_retransmit-description.patch b/debian/patches/man-Enhance-token_retransmit-description.patch
+new file mode 100644
+index 00000000..9b9f3def
+--- /dev/null
++++ b/debian/patches/man-Enhance-token_retransmit-description.patch
+@@ -0,0 +1,28 @@
++From: yuan ren <yren at suse.com>
++Date: Thu, 16 May 2019 18:31:44 +0800
++Subject: man: Enhance token_retransmit description
++
++Signed-off-by: yuan ren <yren at suse.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 3e8b525e3289e19c773e18c7fce9812393356ddc)
++---
++ man/corosync.conf.5 | 6 +++++-
++ 1 file changed, 5 insertions(+), 1 deletion(-)
++
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index e2fd9ed..5fef28a 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -394,7 +394,11 @@ the token is retransmitted.  This will be automatically calculated if token
++ is modified.  It is not recommended to alter this value without guidance from
++ the corosync community.
++ 
++-The default is 238 milliseconds.
+++The minimum is 30 milliseconds. If not set and error occur, make sure
+++token / (token_retransmits_before_loss_const + 0.2) is more than 30.
+++
+++The default is 238 milliseconds for two nodes cluster. Three or more nodes reference
+++.B token_coefficient.
++ 
++ .TP
++ knet_compression_model
+diff --git a/debian/patches/nozzle-Add-support-for-libnozzle-devices.patch b/debian/patches/nozzle-Add-support-for-libnozzle-devices.patch
+new file mode 100644
+index 00000000..47f9bda6
+--- /dev/null
++++ b/debian/patches/nozzle-Add-support-for-libnozzle-devices.patch
+@@ -0,0 +1,707 @@
++From: Christine Caulfield <ccaulfie at redhat.com>
++Date: Tue, 15 Jan 2019 15:18:18 +0000
++Subject: nozzle: Add support for libnozzle devices
++
++A nozzle device is a pseudo ethernet device that routes network
++traffic through a channel on the corosync knet network (NOT cpg or any
++corosync internal service) to other nodes in the cluster. It allows
++applications to take advantage of knet features such as multipathing,
++automatic failover, link switching etc.
++
++Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit eab55e7384c33f16d3d9b2c9c9d0878ddd234e38)
++---
++ configure.ac        |   6 +
++ exec/Makefile.am    |   4 +-
++ exec/cfg.c          |   1 +
++ exec/totemknet.c    | 413 +++++++++++++++++++++++++++++++++++++++++++++++++++-
++ man/corosync.conf.5 |  68 +++++++--
++ 5 files changed, 476 insertions(+), 16 deletions(-)
++
++diff --git a/configure.ac b/configure.ac
++index c85edf8..95cdb35 100644
++--- a/configure.ac
+++++ b/configure.ac
++@@ -174,6 +174,7 @@ LIBS="$SAVE_LIBS"
++ AC_CHECK_LIB([pthread], [pthread_create])
++ AC_CHECK_LIB([socket], [socket])
++ PKG_CHECK_MODULES([knet],[libknet])
+++PKG_CHECK_MODULES([nozzle],[libnozzle], [AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [Have libnozzle])], [have_nozzle="no"])
++ AC_CHECK_LIB([nsl], [t_open])
++ AC_CHECK_LIB([rt], [sched_getscheduler])
++ AC_CHECK_LIB([z], [crc32],
++@@ -404,6 +405,11 @@ ENV_CFLAGS="$CFLAGS"
++ ENV_CPPFLAGS="$CPPFLAGS"
++ ENV_LDFLAGS="$LDFLAGS"
++ 
+++# Add nozzle to Package features if enabled
+++if test "x$have_nozzle" != xno; then
+++	PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
+++fi
+++
++ # debug build stuff
++ if test "x${enable_debug}" = xyes; then
++ 	AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
++diff --git a/exec/Makefile.am b/exec/Makefile.am
++index 4602663..1c31f8c 100644
++--- a/exec/Makefile.am
+++++ b/exec/Makefile.am
++@@ -59,10 +59,10 @@ endif
++ 
++ corosync_CPPFLAGS	= -DLOGCONFIG_USE_ICMAP=1
++ 
++-corosync_CFLAGS         = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS)
+++corosync_CFLAGS         = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS) $(nozzle_CFLAGS)
++ 
++ corosync_LDADD		= ../common_lib/libcorosync_common.la \
++-			  $(LIBQB_LIBS) $(statgrab_LIBS) $(libsystemd_LIBS) $(knet_LIBS)
+++			  $(LIBQB_LIBS) $(statgrab_LIBS) $(libsystemd_LIBS) $(knet_LIBS) $(nozzle_LIBS)
++ 
++ corosync_DEPENDENCIES	= ../common_lib/libcorosync_common.la
++ 
++diff --git a/exec/cfg.c b/exec/cfg.c
++index dec7dbf..c02f739 100644
++--- a/exec/cfg.c
+++++ b/exec/cfg.c
++@@ -701,6 +701,7 @@ static void message_handler_req_exec_cfg_reload_config (
++ 	remove_deleted_entries(temp_map, "nodelist.");
++ 	remove_deleted_entries(temp_map, "quorum.");
++ 	remove_deleted_entries(temp_map, "uidgid.config.");
+++	remove_deleted_entries(temp_map, "nozzle.");
++ 
++ 	/* Remove entries that cannot be changed */
++ 	remove_ro_entries(temp_map);
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 1098bdb..77cb65a 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -1,6 +1,5 @@
++-
++ /*
++- * Copyright (c) 2016-2018 Red Hat, Inc.
+++ * Copyright (c) 2016-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -45,6 +44,7 @@
++ #include <sys/ioctl.h>
++ #include <sys/param.h>
++ #include <netinet/in.h>
+++#include <net/ethernet.h>
++ #include <arpa/inet.h>
++ #include <unistd.h>
++ #include <fcntl.h>
++@@ -60,6 +60,10 @@
++ 
++ #include <qb/qbdefs.h>
++ #include <qb/qbloop.h>
+++#ifdef HAVE_LIBNOZZLE
+++#include <libgen.h>
+++#include <libnozzle.h>
+++#endif
++ 
++ #include <corosync/sq.h>
++ #include <corosync/swab.h>
++@@ -68,6 +72,7 @@
++ #include <corosync/totem/totemip.h>
++ #include "totemknet.h"
++ 
+++#include "main.h"
++ #include "util.h"
++ 
++ #include <libknet.h>
++@@ -77,6 +82,10 @@
++ #define MSG_NOSIGNAL 0
++ #endif
++ 
+++#ifdef HAVE_LIBNOZZLE
+++static int setup_nozzle(void *knet_context);
+++#endif
+++
++ /* Should match that used by cfg */
++ #define CFG_INTERFACE_STATUS_MAX_LEN 512
++ 
++@@ -162,6 +171,13 @@ struct totemknet_instance {
++ 
++ 	int logpipes[2];
++ 	int knet_fd;
+++#ifdef HAVE_LIBNOZZLE
+++	char *nozzle_name;
+++	char *nozzle_ipaddr;
+++	char *nozzle_prefix;
+++	char *nozzle_macaddr;
+++	nozzle_t nozzle_handle;
+++#endif
++ };
++ 
++ /* Awkward. But needed to get stats from knet */
++@@ -217,6 +233,46 @@ do {												\
++ 	} while(0)
++ 
++ 
+++#ifdef HAVE_LIBNOZZLE
+++static inline int is_ether_addr_multicast(const uint8_t *addr)
+++{
+++	return (addr[0] & 0x01);
+++}
+++static inline int is_ether_addr_zero(const uint8_t *addr)
+++{
+++	return (!addr[0] && !addr[1] && !addr[2] && !addr[3] && !addr[4] && !addr[5]);
+++}
+++
+++static int ether_host_filter_fn(void *private_data,
+++				const unsigned char *outdata,
+++				ssize_t outdata_len,
+++				uint8_t tx_rx,
+++				knet_node_id_t this_host_id,
+++				knet_node_id_t src_host_id,
+++				int8_t *channel,
+++				knet_node_id_t *dst_host_ids,
+++				size_t *dst_host_ids_entries)
+++{
+++	struct ether_header *eth_h = (struct ether_header *)outdata;
+++	uint8_t *dst_mac = (uint8_t *)eth_h->ether_dhost;
+++	uint16_t dst_host_id;
+++
+++	if (is_ether_addr_zero(dst_mac))
+++		return -1;
+++
+++	if (is_ether_addr_multicast(dst_mac)) {
+++		return 1;
+++	}
+++
+++	memmove(&dst_host_id, &dst_mac[4], 2);
+++
+++	dst_host_ids[0] = ntohs(dst_host_id);
+++	*dst_host_ids_entries = 1;
+++
+++	return 0;
+++}
+++#endif
+++
++ static int dst_host_filter_callback_fn(void *private_data,
++ 				       const unsigned char *outdata,
++ 				       ssize_t outdata_len,
++@@ -230,7 +286,17 @@ static int dst_host_filter_callback_fn(void *private_data,
++ 	struct totem_message_header *header = (struct totem_message_header *)outdata;
++ 	int res;
++ 
++-	*channel = 0;
+++#ifdef HAVE_LIBNOZZLE
+++	if (*channel != 0) {
+++		return ether_host_filter_fn(private_data,
+++					    outdata, outdata_len,
+++					    tx_rx,
+++					    this_host_id, src_host_id,
+++					    channel,
+++					    dst_host_ids,
+++					    dst_host_ids_entries);
+++	}
+++#endif
++ 	if (header->target_nodeid) {
++ 		dst_host_ids[0] = header->target_nodeid;
++ 		*dst_host_ids_entries = 1;
++@@ -1334,6 +1400,11 @@ int totemknet_reconfigure (
++ 			KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_handle_compress failed");
++ 		}
++ 	}
+++
+++#ifdef HAVE_LIBNOZZLE
+++	/* Set up nozzle device(s) */
+++	setup_nozzle(instance);
+++#endif
++ 	return (res);
++ }
++ 
++@@ -1454,3 +1525,339 @@ static void log_flush_messages (void *knet_context)
++ 		}
++ 	}
++ }
+++
+++
+++#ifdef HAVE_LIBNOZZLE
+++#define NOZZLE_NAME    "nozzle.name"
+++#define NOZZLE_IPADDR  "nozzle.ipaddr"
+++#define NOZZLE_PREFIX  "nozzle.ipprefix"
+++#define NOZZLE_MACADDR "nozzle.macaddr"
+++
+++#define NOZZLE_CHANNEL 1
+++
+++
+++static char *get_nozzle_script_dir(void *knet_context)
+++{
+++	struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+++	char filename[PATH_MAX + FILENAME_MAX + 1];
+++	static char updown_dirname[PATH_MAX + FILENAME_MAX + 1];
+++	int res;
+++	const char *dirname_res;
+++
+++	/*
+++	 * Build script directory based on corosync.conf file location
+++	 */
+++	res = snprintf(filename, sizeof(filename), "%s",
+++	    corosync_get_config_file());
+++	if (res >= sizeof(filename)) {
+++		knet_log_printf (LOGSYS_LEVEL_DEBUG, "nozzle up/down path too long");
+++		return NULL;
+++	}
+++
+++	dirname_res = dirname(filename);
+++
+++	res = snprintf(updown_dirname, sizeof(updown_dirname), "%s/%s",
+++	    dirname_res, "updown.d");
+++	if (res >= sizeof(updown_dirname)) {
+++		knet_log_printf (LOGSYS_LEVEL_DEBUG, "nozzle up/down path too long");
+++		return NULL;
+++	}
+++	return updown_dirname;
+++}
+++
+++/*
+++ * Deliberately doesn't return the status as caller doesn't care.
+++ * The result will be logged though
+++ */
+++static void run_nozzle_script(struct totemknet_instance *instance, int type, const char *typename)
+++{
+++	int res;
+++	char *exec_string;
+++
+++	res = nozzle_run_updown(instance->nozzle_handle, type, &exec_string);
+++	if (res == -1 && errno != ENOENT) {
+++		knet_log_printf (LOGSYS_LEVEL_INFO, "exec nozzle %s script failed: %s", typename, strerror(errno));
+++	} else if (res == -2) {
+++		knet_log_printf (LOGSYS_LEVEL_INFO, "nozzle %s script failed", typename);
+++		knet_log_printf (LOGSYS_LEVEL_INFO, "%s", exec_string);
+++	}
+++}
+++
+++/*
+++ * Reparse IP address to add in our node ID
+++ * IPv6 addresses must end in '::'
+++ * IPv4 addresses must just be valid
+++ * '/xx' lengths are optional for IPv6, mandatory for IPv4
+++ *
+++ * Returns the modified IP address as a string to pass into libnozzle
+++ */
+++static int reparse_nozzle_ip_address(struct totemknet_instance *instance,
+++				     const char *input_addr,
+++				     const char *prefix, int nodeid,
+++				     char *output_addr, size_t output_len)
+++{
+++	char *coloncolon;
+++	int bits;
+++	int max_prefix = 64;
+++	uint32_t nodeid_mask;
+++	uint32_t addr_mask;
+++	uint32_t masked_nodeid;
+++	struct in_addr *addr;
+++	struct totem_ip_address totemip;
+++
+++	coloncolon = strstr(input_addr, "::");
+++	if (!coloncolon) {
+++		max_prefix = 30;
+++	}
+++
+++	bits = atoi(prefix);
+++	if (bits < 8 || bits > max_prefix) {
+++		knet_log_printf(LOGSYS_LEVEL_ERROR, "nozzle IP address prefix must be >= 8 and <= %d (got %d)", max_prefix, bits);
+++		return -1;
+++	}
+++
+++	/* IPv6 is easy */
+++	if (coloncolon) {
+++		memcpy(output_addr, input_addr, coloncolon-input_addr);
+++		sprintf(output_addr + (coloncolon-input_addr), "::%x", nodeid);
+++		return 0;
+++	}
+++
+++	/* For IPv4 we need to parse the address into binary, mask off the required bits,
+++	 * add in the masked_nodeid and 'print' it out again
+++	 */
+++	nodeid_mask = UINT32_MAX & ((1<<(32 - bits)) - 1);
+++	addr_mask   = UINT32_MAX ^ nodeid_mask;
+++	masked_nodeid = nodeid & nodeid_mask;
+++
+++	if (totemip_parse(&totemip, input_addr, AF_INET)) {
+++		knet_log_printf(LOGSYS_LEVEL_ERROR, "Failed to parse IPv4 nozzle IP address");
+++		return -1;
+++	}
+++	addr = (struct in_addr *)&totemip.addr;
+++	addr->s_addr &= htonl(addr_mask);
+++	addr->s_addr |= htonl(masked_nodeid);
+++
+++	inet_ntop(AF_INET, addr, output_addr, output_len);
+++	return 0;
+++}
+++
+++static int create_nozzle_device(void *knet_context, const char *name,
+++				const char *ipaddr, const char *prefix,
+++				const char *macaddr)
+++{
+++	struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+++	char device_name[IFNAMSIZ+1];
+++	size_t size = IFNAMSIZ;
+++	int8_t channel = NOZZLE_CHANNEL;
+++	nozzle_t nozzle_dev;
+++	int nozzle_fd;
+++	int res;
+++	char *updown_dir;
+++	char parsed_ipaddr[INET6_ADDRSTRLEN];
+++	char mac[19];
+++
+++	memset(device_name, 0, size);
+++	memset(&mac, 0, sizeof(mac));
+++	strncpy(device_name, name, size);
+++
+++	updown_dir = get_nozzle_script_dir(knet_context);
+++	knet_log_printf (LOGSYS_LEVEL_INFO, "nozzle script dir is %s", updown_dir);
+++
+++	nozzle_dev = nozzle_open(device_name, size, updown_dir);
+++	if (!nozzle_dev) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to init nozzle device %s: %s", device_name, strerror(errno));
+++		return -1;
+++	}
+++	instance->nozzle_handle = nozzle_dev;
+++
+++	if (nozzle_set_mac(nozzle_dev, macaddr) < 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle MAC to %s: %s", mac, strerror(errno));
+++		goto out_clean;
+++	}
+++
+++	if (reparse_nozzle_ip_address(instance, ipaddr, prefix, instance->our_nodeid, parsed_ipaddr, sizeof(parsed_ipaddr))) {
+++		/* Prints its own errors */
+++		goto out_clean;
+++	}
+++	knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle IP address is %s / %d", parsed_ipaddr, atoi(prefix));
+++	if (ipaddr) {
+++		if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
+++			knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
+++			goto out_clean;
+++		}
+++	}
+++
+++	nozzle_fd = nozzle_get_fd(nozzle_dev);
+++	knet_log_printf (LOGSYS_LEVEL_INFO, "Opened '%s' on fd %d", device_name, nozzle_fd);
+++
+++	res = knet_handle_add_datafd(instance->knet_handle, &nozzle_fd, &channel);
+++	if (res != 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add nozzle FD to knet: %s", strerror(errno));
+++		goto out_clean;
+++	}
+++
+++	run_nozzle_script(instance, NOZZLE_PREUP, "pre-up");
+++
+++	res = nozzle_set_up(nozzle_dev);
+++	if (res != 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to set nozzle interface UP: %s", strerror(errno));
+++		goto out_clean;
+++	}
+++	run_nozzle_script(instance, NOZZLE_UP, "up");
+++
+++	return 0;
+++
+++out_clean:
+++	nozzle_close(nozzle_dev);
+++	return -1;
+++}
+++
+++static int remove_nozzle_device(void *knet_context)
+++{
+++	struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+++	int res;
+++	int datafd;
+++
+++	res = knet_handle_get_datafd(instance->knet_handle, NOZZLE_CHANNEL, &datafd);
+++	if (res != 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't find datafd for channel %d: %s", NOZZLE_CHANNEL, strerror(errno));
+++		return -1;
+++	}
+++
+++	res = knet_handle_remove_datafd(instance->knet_handle, datafd);
+++	if (res != 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't remove datafd for nozzle channel %d: %s", NOZZLE_CHANNEL, strerror(errno));
+++		return -1;
+++	}
+++
+++	run_nozzle_script(instance, NOZZLE_DOWN, "pre-down");
+++	res = nozzle_set_down(instance->nozzle_handle);
+++	if (res != 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't set nozzle device down: %s", strerror(errno));
+++		return -1;
+++	}
+++	run_nozzle_script(instance, NOZZLE_POSTDOWN, "post-down");
+++
+++	res = nozzle_close(instance->nozzle_handle);
+++	if (res != 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't close nozzle device: %s", strerror(errno));
+++		return -1;
+++	}
+++	knet_log_printf (LOGSYS_LEVEL_INFO, "Removed nozzle device");
+++	return 0;
+++}
+++
+++static void free_nozzle(struct totemknet_instance *instance)
+++{
+++	free(instance->nozzle_name);
+++	free(instance->nozzle_ipaddr);
+++	free(instance->nozzle_prefix);
+++	free(instance->nozzle_macaddr);
+++
+++	instance->nozzle_name =	instance->nozzle_ipaddr = instance->nozzle_prefix =
+++		instance->nozzle_macaddr = NULL;
+++}
+++
+++static int setup_nozzle(void *knet_context)
+++{
+++	struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
+++	char *ipaddr_str = NULL;
+++	char *name_str = NULL;
+++	char *prefix_str = NULL;
+++	char *macaddr_str = NULL;
+++	char mac[32];
+++	int name_res;
+++	int macaddr_res;
+++	int res;
+++
+++	icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
+++	icmap_get_string(NOZZLE_PREFIX, &prefix_str);
+++	macaddr_res = icmap_get_string(NOZZLE_MACADDR, &macaddr_str);
+++	name_res = icmap_get_string(NOZZLE_NAME, &name_str);
+++
+++	/* Is is being removed? */
+++	if (name_res == CS_ERR_NOT_EXIST && instance->nozzle_handle) {
+++		remove_nozzle_device(instance);
+++		free_nozzle(instance);
+++		goto out_free;
+++	}
+++
+++	if (!name_str) {
+++		/* no nozzle */
+++		goto out_free;
+++	}
+++
+++	if (!ipaddr_str) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "No IP address supplied for Nozzle device");
+++		goto out_free;
+++	}
+++
+++	if (!prefix_str) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "No prefix supplied for Nozzle IP address");
+++		goto out_free;
+++	}
+++
+++	if (macaddr_str && strlen(macaddr_str) != 17) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "macaddr for nozzle device is not in the correct format '%s'", macaddr_str);
+++		goto out_free;
+++	}
+++	if (!macaddr_str) {
+++		macaddr_str = (char*)"54:54:01:00:00:00";
+++	}
+++
+++	if (instance->nozzle_name &&
+++	    (strcmp(name_str, instance->nozzle_name) == 0) &&
+++	    (strcmp(ipaddr_str, instance->nozzle_ipaddr) == 0) &&
+++	    (strcmp(prefix_str, instance->nozzle_prefix) == 0) &&
+++	    ((macaddr_str == NULL && instance->nozzle_macaddr == NULL) ||
+++	     strcmp(macaddr_str, instance->nozzle_macaddr) == 0)) {
+++		/* Nothing has changed */
+++		knet_log_printf (LOGSYS_LEVEL_DEBUG, "Nozzle device info not changed");
+++		goto out_free;
+++	}
+++
+++	/* Add nodeid into MAC address */
+++	memcpy(mac, macaddr_str, 12);
+++	snprintf(mac+12, sizeof(mac) - 13, "%02x:%02x",
+++		 instance->our_nodeid >> 8,
+++		 instance->our_nodeid & 0xFF);
+++	knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle MAC address is %s", mac);
+++
+++	if (name_res == CS_OK && name_str) {
+++		/* Reconfigure */
+++		if (instance->nozzle_name) {
+++			remove_nozzle_device(instance);
+++			free_nozzle(instance);
+++		}
+++
+++		res = create_nozzle_device(knet_context, name_str, ipaddr_str, prefix_str,
+++					   mac);
+++
+++		instance->nozzle_name = strdup(name_str);
+++		instance->nozzle_ipaddr = strdup(ipaddr_str);
+++		instance->nozzle_prefix = strdup(prefix_str);
+++		instance->nozzle_macaddr = strdup(macaddr_str);
+++		if (!instance->nozzle_name || !instance->nozzle_ipaddr ||
+++		    !instance->nozzle_prefix) {
+++			knet_log_printf (LOGSYS_LEVEL_ERROR, "strdup failed in nozzle allocation");
+++			/*
+++			 * This 'free' will cause a complete reconfigure of the device next time we reload
+++			 * but will also let the the current device keep working until then.
+++			 * remove_nozzle() only needs the, statically-allocated, nozzle_handle
+++			 */
+++			free_nozzle(instance);
+++		}
+++	}
+++
+++out_free:
+++	free(name_str);
+++	free(ipaddr_str);
+++	free(prefix_str);
+++	if (macaddr_res == CS_OK) {
+++		free(macaddr_str);
+++	}
+++
+++	return res;
+++}
+++#endif // HAVE_LIBNOZZLE
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index aa928bc..52eb7b1 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -63,9 +63,12 @@ This top level directive contains configuration options related to system.
++ .TP
++ resources { }
++ This top level directive contains configuration options for resources.
+++.TP
+++nozzle { }
+++This top level directive contains configuration options for a libnozzle device.
++ 
++ .PP
++-The 
+++The
++ .B interface sub-directive of totem is optional for UDP and knet transports.
++ 
++ For knet, multiple interface subsections define parameters for each knet link on the
++@@ -78,7 +81,7 @@ is used to define cluster nodes.
++ linknumber
++ This specifies the link number for the interface.  When using the knet
++ protocol, each interface should specify separate link numbers to uniquely
++-identify to the membership protocol which interface to use for which link. 
+++identify to the membership protocol which interface to use for which link.
++ The linknumber must start at 0. For UDP the only supported linknumber is 0.
++ 
++ .TP
++@@ -88,7 +91,7 @@ mode. (see link_mode below)
++ 
++ .TP
++ knet_ping_interval
++-This specifies the interval between knet link pings. 
+++This specifies the interval between knet link pings.
++ knet_ping_interval and knet_ping_timeout
++ are a pair, if one is specified the other should be too, otherwise one will be calculated from
++ the token timeout and one will be taken from the config file.
++@@ -96,7 +99,7 @@ the token timeout and one will be taken from the config file.
++ 
++ .TP
++ knet_ping_timeout
++-If no ping is received within this time, the knet link is declared dead. 
+++If no ping is received within this time, the knet link is declared dead.
++ knet_ping_interval and knet_ping_timeout
++ are a pair, if one is specified the other should be too, otherwise one will be calculated from
++ the token timeout and one will be taken from the config file.
++@@ -120,7 +123,7 @@ bindnetaddr (udp only)
++ This specifies the network address the corosync executive should bind
++ to when using udp.
++ 
++-bindnetaddr (udp only) 
+++bindnetaddr (udp only)
++ should be an IP address configured on the system, or a network
++ address.
++ 
++@@ -160,9 +163,9 @@ mcastport (udp only)
++ This specifies the UDP port number.  It is possible to use the same multicast
++ address on a network with the corosync services configured for different
++ UDP ports.
++-Please note corosync uses two UDP ports mcastport (for mcast receives) and 
+++Please note corosync uses two UDP ports mcastport (for mcast receives) and
++ mcastport - 1 (for mcast sends).
++-If you have multiple clusters on the same network using the same mcastaddr 
+++If you have multiple clusters on the same network using the same mcastaddr
++ please configure the mcastports with a gap.
++ 
++ .TP
++@@ -243,14 +246,14 @@ link_mode
++ This specifies the Kronosnet mode, which may be passive, active, or
++ rr (round-robin).
++ .B passive:
++-the active link with the lowest priority will be used. If one or more 
+++the active link with the lowest priority will be used. If one or more
++ links share the same priority the one with the lowest link ID will
++ be used.
++ .B active:
++ All active links will be used simultaneously to send traffic.
++ link priority is ignored.
++ .B rr:
++-Round-Robin policy. Each packet will be sent to the next active link in 
+++Round-Robin policy. Each packet will be sent to the next active link in
++ order.
++ 
++ If only one interface directive is specified, passive is automatically chosen.
++@@ -284,7 +287,7 @@ The default is 1500.
++ 
++ .TP
++ transport
++-This directive controls the transport mechanism used.  
+++This directive controls the transport mechanism used.
++ The default is knet.  The transport type can also be set to udpu or udp.
++ Only knet allows crypto or multiple interfaces per node.
++ 
++@@ -604,7 +607,7 @@ and
++ The default is syslog and stderr.
++ 
++ Please note, if you are using to_logfile and want to rotate the file, use logrotate(8)
++-with the option 
+++with the option
++ .B
++ copytruncate.
++ eg.
++@@ -797,6 +800,49 @@ potentially breaking down membership.  IPMI watchdogs are particularly
++ notorious in this regard: read about kipmid_max_busy_us in IPMI.txt in
++ the Linux kernel documentation.
++ 
+++
+++.PP
+++Within the
+++.B nozzle
+++directive it is possible to specify options for a libnozzle device. This is a pseudo
+++ethernet device that routes network traffic through a channel on the corosync knet network
+++(NOT cpg or any corosync internal service) to other nodes in the cluster. This allows
+++applications to take advantage of knet features such as multipathing, automatic failover,
+++link switching etc. Note that libnozzle is not a reliable transport, but you can tunnel TCP
+++through it for reliable communications.
+++.br
+++libnozzle also supports optional interface up/down scripts that are kept under a
+++/etc/corosync/updown.d/ directory. See the knet documentation for more information.
+++.br
+++Only one nozzle device is allowed.
+++.br
+++The nozzle stanza takes several options:
+++.TP
+++name
+++The name of the network device to be created. On Linux this may be any name at all, other
+++platforms have restrictions on the name.
+++.TP
+++ipaddr
+++The IP address (IPv6 or IPv4) of the interface. The bottom part of this address will be replaced
+++by the local node's nodeid in conjunction with ipprefix. so, eg
+++ipaddr: 192.168.1.0
+++ipprefix: 24
+++will make nodeids 1,2,5 use IP addresses 192.168.1.1, 192.168.1.2 & 192.168.1.5.
+++If a prefix length of 16 is used then the bottom two bytes will be filled in with nodeid numbers.
+++IPv6 addresses must end in '::', the nodeid will be added after the two colons to make the
+++local IP address.
+++Only one IP address is currently supported in the corosync.conf file. Additional IP addresses
+++can be added in the ifup script if necessary.
+++.TP
+++ipprefix
+++specifies the IP address prefix for the nozzle device (see above)
+++.TP
+++macaddr
+++Specifies the MAC address prefix for the nozzle device. As for the IP address, the bottom part
+++of the MAC address will be filled in with the node id. In this case no prefix applies, the bottom
+++two bytes of the MAC address will always be overwritten with the node id. So specifying
+++macaddr: 54:54:12:24:12:12 on nodeid 1 will result in it having a MAC address of 54:54:12:24:00:01
+++
++ .SH "TO ADD A NEW NODE TO THE CLUSTER"
++ For example to add a node with address 10.24.38.108 with nodeid 3. The node has the name NEW
++ (in DNS or /etc/hosts) and is not currently running corosync. The current corosync.conf nodelist
+diff --git a/debian/patches/quorumtool-Fix-exit-status-codes.patch b/debian/patches/quorumtool-Fix-exit-status-codes.patch
+new file mode 100644
+index 00000000..e001d123
+--- /dev/null
++++ b/debian/patches/quorumtool-Fix-exit-status-codes.patch
+@@ -0,0 +1,237 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Thu, 14 Feb 2019 16:05:59 +0100
++Subject: quorumtool: Fix exit status codes
++
++1. Use EXIT_SUCCESS and EXIT_FAILURE when possible
++2. For -s option return EXIT_SUCCESS when no problem appeared and node
++   is quorate, EXIT_FAILURE if problem appeared and exit code 2
++   (EXIT_NOT_QUORATE) when no problem appeared but node is not quorate.
++3. Document exit codes in the man page
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit db38e3958c4f88d5d06e8f7c83d6d90334d9fbd2)
++---
++ tools/corosync-quorumtool.c | 53 ++++++++++++++++++++++++++-------------------
++ man/corosync-quorumtool.8   | 17 ++++++++++++++-
++ 2 files changed, 47 insertions(+), 23 deletions(-)
++
++diff --git a/tools/corosync-quorumtool.c b/tools/corosync-quorumtool.c
++index 8f128e0..4819951 100644
++--- a/tools/corosync-quorumtool.c
+++++ b/tools/corosync-quorumtool.c
++@@ -1,5 +1,5 @@
++ /*
++- * Copyright (c) 2009-2014 Red Hat, Inc.
+++ * Copyright (c) 2009-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -75,6 +75,8 @@ typedef enum {
++ 	SORT_NODENAME
++ } sorttype_t;
++ 
+++#define EXIT_NOT_QUORATE	2
+++
++ /*
++  * global vars
++  */
++@@ -238,7 +240,7 @@ static int set_votes(uint32_t nodeid, int votes)
++ 			votes, nodeid, cs_strerror(err));
++ 	}
++ 
++-	return err==CS_OK?0:err;
+++	return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
++ }
++ 
++ static int set_expected(int expected_votes)
++@@ -249,7 +251,7 @@ static int set_expected(int expected_votes)
++ 		fprintf(stderr, "Unable to set expected votes: %s\n", cs_strerror(err));
++ 	}
++ 
++-	return err==CS_OK?0:err;
+++	return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
++ }
++ 
++ /*
++@@ -642,9 +644,9 @@ static int display_quorum_data(int is_quorate,
++ }
++ 
++ /*
++- * return  1 if quorate
++- *         0 if not quorate
++- *        -1 on error
+++ * return EXIT_SUCCESS if quorate
+++ *        EXIT_NOT_QUORATE if not quorate
+++ *        EXIT_FAILURE on error
++  */
++ static int show_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
++ {
++@@ -693,15 +695,15 @@ static int show_status(nodeid_format_t nodeid_format, name_format_t name_format,
++ 
++ quorum_err:
++ 	if (err != CS_OK) {
++-		return -1;
+++		return EXIT_FAILURE;
++ 	}
++ 
++ 	err = display_quorum_data(is_quorate, nodeid_format, name_format, sort_type, 0);
++ 	if (err != CS_OK) {
++-		return -1;
+++		return EXIT_FAILURE;
++ 	}
++ 
++-	return is_quorate;
+++	return (is_quorate ? EXIT_SUCCESS : EXIT_NOT_QUORATE);
++ }
++ 
++ static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) {
++@@ -754,7 +756,7 @@ static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_form
++ 	}
++ 
++ quorum_err:
++-	return -1;
+++	return EXIT_FAILURE;
++ }
++ 
++ static int show_nodes(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
++@@ -788,23 +790,30 @@ static int unregister_qdevice(void)
++ {
++ 	int err;
++ 	struct votequorum_info info;
+++	int result;
+++
+++	result = EXIT_FAILURE;
++ 
++ 	err = votequorum_getinfo(v_handle, our_nodeid, &info);
++ 	if (err != CS_OK) {
++ 		fprintf(stderr, "Unable to get quorum device info: %s\n", cs_strerror(err));
++-		return -1;
+++		goto err_exit;
++ 	}
++ 
++ 	if (!(info.flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED)) {
++-		return 0;
+++		result = EXIT_SUCCESS;
+++		goto err_exit;
++ 	}
++ 
++ 	err = votequorum_qdevice_unregister(v_handle, info.qdevice_name);
++ 	if (err != CS_OK) {
++ 		fprintf(stderr, "Unable to unregister quorum device: %s\n", cs_strerror(err));
++-		return -1;
+++		goto err_exit;
++ 	}
++-	return 0;
+++
+++	result = EXIT_SUCCESS;
+++err_exit:
+++	return result;
++ }
++ 
++ /*
++@@ -888,7 +897,7 @@ int main (int argc, char *argv[]) {
++ 
++ 	if (init_all()) {
++ 		close_all();
++-		exit(1);
+++		exit(EXIT_FAILURE);
++ 	}
++ 
++ 	while ( (opt = getopt(argc, argv, options)) != -1 ) {
++@@ -898,7 +907,7 @@ int main (int argc, char *argv[]) {
++ 				command_opt = CMD_UNREGISTER_QDEVICE;
++ 			} else {
++ 				fprintf(stderr, "You cannot unregister quorum device, corosync is not using votequorum\n");
++-				exit(2);
+++				exit(EXIT_FAILURE);
++ 			}
++ 			break;
++ 		case 's':
++@@ -932,14 +941,14 @@ int main (int argc, char *argv[]) {
++ 				}
++ 			} else {
++ 				fprintf(stderr, "You cannot change expected votes, corosync is not using votequorum\n");
++-				exit(2);
+++				exit(EXIT_FAILURE);
++ 			}
++ 			break;
++ 		case 'n':
++ 			l = strtol(optarg, &endptr, 0);
++ 			if ((l == 0 && endptr == optarg) || l < 0) {
++ 				fprintf(stderr, "The nodeid was not valid, try a positive number\n");
++-				exit(2);
+++				exit(EXIT_FAILURE);
++ 			}
++ 			nodeid = l;
++ 			nodeid_set = 1;
++@@ -949,14 +958,14 @@ int main (int argc, char *argv[]) {
++ 				votes = strtol(optarg, &endptr, 0);
++ 				if ((votes == 0 && endptr == optarg) || votes < 0) {
++ 					fprintf(stderr, "New votes value was not valid, try a positive number or zero\n");
++-					exit(2);
+++					exit(EXIT_FAILURE);
++ 				} else {
++ 					command_opt = CMD_SETVOTES;
++ 				}
++ 			}
++ 			else {
++ 				fprintf(stderr, "You cannot change node votes, corosync is not using votequorum\n");
++-				exit(2);
+++				exit(EXIT_FAILURE);
++ 			}
++ 			break;
++ 		case 'o':
++@@ -970,7 +979,7 @@ int main (int argc, char *argv[]) {
++ 					break;
++ 			        default:
++ 					fprintf(stderr, "Invalid ordering option. valid orders are a(address), i(node ID) or n(name)\n");
++-					exit(2);
+++					exit(EXIT_FAILURE);
++ 					break;
++ 			}
++ 			break;
++@@ -989,7 +998,7 @@ int main (int argc, char *argv[]) {
++ 	switch (command_opt) {
++ 	case CMD_UNKNOWN:
++ 		show_usage(argv[0]);
++-		ret = -1;
+++		ret = EXIT_FAILURE;
++ 		break;
++ 	case CMD_SHOWNODES:
++ 		ret = show_nodes(nodeid_format, address_format, sort_opt);
++diff --git a/man/corosync-quorumtool.8 b/man/corosync-quorumtool.8
++index 0fdfccf..24c9112 100644
++--- a/man/corosync-quorumtool.8
+++++ b/man/corosync-quorumtool.8
++@@ -31,7 +31,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH COROSYNC-QUORUMTOOL 8 2012-01-12
+++.TH COROSYNC-QUORUMTOOL 8 2019-02-14
++ .SH NAME
++ corosync-quorumtool \- Set and display quorum settings.
++ .SH SYNOPSIS
++@@ -89,6 +89,21 @@ show this help text
++ show version and exit
++ .PP
++ * Starred items only work if votequorum is the quorum provider for corosync
+++.SH EXIT STATUS
+++corosync-quorumtool may return one of several error codes if it encounters problems.
+++.TP
+++0
+++No problems occurred (quorate for
+++.B -s
+++operation).
+++.TP
+++1
+++Generic error code.
+++.TP
+++2
+++Not quorate (returned only for
+++.B -s
+++operation).
++ .SH SEE ALSO
++ .BR corosync_overview (7),
++ .BR votequorum_overview (3),
+diff --git a/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch b/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
+new file mode 100644
+index 00000000..6bd733e7
+--- /dev/null
++++ b/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
+@@ -0,0 +1,44 @@
++From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
++Date: Wed, 3 Apr 2019 21:57:30 +0200
++Subject: set totem.keyfile and totem.key to RO
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
++
++so that we get the nice log message when attempting to modify them at
++runtime, just like for totem.crypto_* and co.
++
++Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 03fba21503f1b8395519190cc537f63100e995f5)
++---
++ exec/cfg.c  | 2 ++
++ exec/main.c | 2 ++
++ 2 files changed, 4 insertions(+)
++
++diff --git a/exec/cfg.c b/exec/cfg.c
++index c02f739..f42cb60 100644
++--- a/exec/cfg.c
+++++ b/exec/cfg.c
++@@ -578,6 +578,8 @@ static void remove_ro_entries(icmap_map_t temp_map)
++ 	delete_and_notify_if_changed(temp_map, "totem.secauth");
++ 	delete_and_notify_if_changed(temp_map, "totem.crypto_hash");
++ 	delete_and_notify_if_changed(temp_map, "totem.crypto_cipher");
+++	delete_and_notify_if_changed(temp_map, "totem.keyfile");
+++	delete_and_notify_if_changed(temp_map, "totem.key");
++ 	delete_and_notify_if_changed(temp_map, "totem.version");
++ 	delete_and_notify_if_changed(temp_map, "totem.threads");
++ 	delete_and_notify_if_changed(temp_map, "totem.ip_version");
++diff --git a/exec/main.c b/exec/main.c
++index 8554036..06a519c 100644
++--- a/exec/main.c
+++++ b/exec/main.c
++@@ -1036,6 +1036,8 @@ static void set_icmap_ro_keys_flag (void)
++ 	 */
++ 	icmap_set_ro_access("totem.crypto_cipher", CS_FALSE, CS_TRUE);
++ 	icmap_set_ro_access("totem.crypto_hash", CS_FALSE, CS_TRUE);
+++	icmap_set_ro_access("totem.keyfile", CS_FALSE, CS_TRUE);
+++	icmap_set_ro_access("totem.key", CS_FALSE, CS_TRUE);
++ 	icmap_set_ro_access("totem.secauth", CS_FALSE, CS_TRUE);
++ 	icmap_set_ro_access("totem.ip_version", CS_FALSE, CS_TRUE);
++ 	icmap_set_ro_access("totem.rrp_mode", CS_FALSE, CS_TRUE);
+diff --git a/debian/patches/spec-Add-support-for-user-flags-configure-option.patch b/debian/patches/spec-Add-support-for-user-flags-configure-option.patch
+new file mode 100644
+index 00000000..d7254b82
+--- /dev/null
++++ b/debian/patches/spec-Add-support-for-user-flags-configure-option.patch
+@@ -0,0 +1,43 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Fri, 7 Jun 2019 10:20:04 +0200
++Subject: spec: Add support for user-flags configure option
++
++Passing -ggdb3 (or -g3) during compiler may result in corrupted
++debuginfo files (bug in debugedit - for Fedora filed as a
++https://bugzilla.redhat.com/show_bug.cgi?id=1708786). Until the bug is
++fixed it's possible to ether change configure to add -ggdb2/-g2 or use
++already existing --enable-user-flags option and rely on environment set
++by rpmbuild.
++
++Patch implements second option so RPM distros without broken debugedit
++are not affected.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 5cced85cd58905638c81892f79e9f457efac338e)
++---
++ corosync.spec.in | 4 ++++
++ 1 file changed, 4 insertions(+)
++
++diff --git a/corosync.spec.in b/corosync.spec.in
++index 8af686e..c06675d 100644
++--- a/corosync.spec.in
+++++ b/corosync.spec.in
++@@ -14,6 +14,7 @@
++ %bcond_with nozzle
++ %bcond_with vqsim
++ %bcond_with runautogen
+++%bcond_with userflags
++ 
++ %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
++ %global gittarver %{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}
++@@ -107,6 +108,9 @@ BuildRequires: readline-devel
++ %endif
++ %if %{with vqsim}
++ 	--enable-vqsim \
+++%endif
+++%if %{with userflags}
+++	--enable-user-flags \
++ %endif
++ 	--with-initddir=%{_initrddir} \
++ 	--with-systemddir=%{_unitdir} \
+diff --git a/debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch b/debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
+new file mode 100644
+index 00000000..27b55a98
+--- /dev/null
++++ b/debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
+@@ -0,0 +1,48 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Wed, 24 Apr 2019 14:47:47 +0200
++Subject: totemconfig: Ensure nodeid is specified for IPv6
++
++Thanks Yuan Ren <yren at suse.com> for finding this problem.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 3172a76d12d16dd6c72182e005ac0bc63e58208b)
++---
++ exec/totemconfig.c | 17 +++++++++++++++++
++ 1 file changed, 17 insertions(+)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index b206eeb..6fcd6de 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -1258,6 +1258,16 @@ static int put_nodelist_members_to_config(struct totem_config *totem_config, int
++ 				snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
++ 				if (icmap_get_string(tmp_key, &str) == CS_OK) {
++ 					nodeid = generate_nodeid(totem_config, str);
+++					if (nodeid == -1) {
+++						sprintf(error_string_response,
+++						    "An IPV6 network requires that a node ID be specified "
+++						    "for address '%s'.", node_addr_str);
+++						*error_string = error_string_response;
+++						free(str);
+++
+++						return (-1);
+++					}
+++
++ 					log_printf(LOGSYS_LEVEL_DEBUG,
++ 						   "Generated nodeid = 0x%x for %s", nodeid, str);
++ 					free(str);
++@@ -1750,6 +1760,13 @@ extern int totem_config_read (
++ 				icmap_get_string(tmp_key, &str);
++ 
++ 				totem_config->node_id = generate_nodeid(totem_config, str);
+++				if (totem_config->node_id == -1) {
+++					*error_string = "An IPV6 network requires that a node ID be specified";
+++
+++					free(str);
+++					return (-1);
+++				}
+++
++ 				totem_config->interfaces[0].member_list[local_node_pos].nodeid = totem_config->node_id;
++ 
++ 				free(str);
+diff --git a/debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch b/debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch
+new file mode 100644
+index 00000000..26b553c3
+--- /dev/null
++++ b/debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch
+@@ -0,0 +1,67 @@
++From: yuan ren <yren at suse.com>
++Date: Tue, 14 May 2019 19:33:12 +0800
++Subject: totemconfig: Fix minimum limit for hold timeout
++
++Make sure the retransmit timeout have the lowest limit
++`MINIMUM_TIMEOUT`. So, the lowest limit of hold should be
++recalculated.
++
++Also token timeout and retransmits count should
++keep a relational expression.
++
++Signed-off-by: yuan ren <yren at suse.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 2a4cd3c4af0256cc79e1ed1c7f070fd469e4cfaf)
++---
++ exec/totemconfig.c | 20 ++++++++++++++------
++ 1 file changed, 14 insertions(+), 6 deletions(-)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 091eedc..262dcac 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -74,6 +74,7 @@
++ #define FAIL_TO_RECV_CONST			2500
++ #define	SEQNO_UNCHANGED_CONST			30
++ #define MINIMUM_TIMEOUT				(int)(1000/HZ)*3
+++#define MINIMUM_TIMEOUT_HOLD			(int)(MINIMUM_TIMEOUT * 0.8 - (1000/HZ))
++ #define MAX_NETWORK_DELAY			50
++ #define WINDOW_SIZE				50
++ #define MAX_MESSAGES				17
++@@ -313,6 +314,7 @@ static int totem_volatile_config_validate (
++ 	char name_key[ICMAP_KEYNAME_MAXLEN];
++ 	char *name_str;
++ 	int i, num_configured, members;
+++	uint32_t tmp_config_value;
++ 
++ 	if (totem_config->max_network_delay < MINIMUM_TIMEOUT) {
++ 		snprintf (local_error_reason, sizeof(local_error_reason),
++@@ -336,16 +338,22 @@ static int totem_volatile_config_validate (
++ 	}
++ 
++ 	if (totem_config->token_retransmit_timeout < MINIMUM_TIMEOUT) {
++-		snprintf (local_error_reason, sizeof(local_error_reason),
++-			"The token retransmit timeout parameter (%d ms) may not be less than (%d ms).",
++-			totem_config->token_retransmit_timeout, MINIMUM_TIMEOUT);
++-		goto parse_error;
+++		if (icmap_get_uint32("totem.token_retransmit", &tmp_config_value) == CS_OK) {
+++			snprintf (local_error_reason, sizeof(local_error_reason),
+++				"The token retransmit timeout parameter (%d ms) may not be less than (%d ms).",
+++				totem_config->token_retransmit_timeout, MINIMUM_TIMEOUT);
+++			goto parse_error;
+++		} else {
+++			snprintf (local_error_reason, sizeof(local_error_reason),
+++				"Not appropriate token or token_retransmits_before_loss_const value set");
+++			goto parse_error;
+++		}
++ 	}
++ 
++-	if (totem_config->token_hold_timeout < MINIMUM_TIMEOUT) {
+++	if (totem_config->token_hold_timeout < MINIMUM_TIMEOUT_HOLD) {
++ 		snprintf (local_error_reason, sizeof(local_error_reason),
++ 			"The token hold timeout parameter (%d ms) may not be less than (%d ms).",
++-			totem_config->token_hold_timeout, MINIMUM_TIMEOUT);
+++			totem_config->token_hold_timeout, MINIMUM_TIMEOUT_HOLD);
++ 		goto parse_error;
++ 	}
++ 
+diff --git a/debian/patches/totemconfig-Remove-support-for-3des.patch b/debian/patches/totemconfig-Remove-support-for-3des.patch
+new file mode 100644
+index 00000000..63dcc729
+--- /dev/null
++++ b/debian/patches/totemconfig-Remove-support-for-3des.patch
+@@ -0,0 +1,138 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Thu, 11 Apr 2019 08:23:29 +0200
++Subject: totemconfig: Remove support for 3des
++
++Triple DES is considered as a "weak cipher" since 2016 so there is
++really no need to support it in the corosync. Thanks to bug in
++Corosync/Knet/NSS which caused 3des to not work at all,
++no matter what library was used, we can just remove support for 3des
++without braking the compatibility.
++
++Also fix coroparse so:
++- totem.crypto_type is removed (this is 1.x construct which was not used
++even in 2.x)
++- Add checking of totem.crypto_model.
++- Enumarate possible values for crypto_model, crypto_cipher and
++crypto_hash error messages
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit d05636b738e3cb1cd7a491e4ef492cd44a8bf6a9)
++---
++ exec/coroparse.c         | 21 ++++++++++-----------
++ exec/totemconfig.c       |  3 ---
++ conf/lenses/corosync.aug |  4 ++--
++ man/corosync.conf.5      |  6 +++---
++ 4 files changed, 15 insertions(+), 19 deletions(-)
++
++diff --git a/exec/coroparse.c b/exec/coroparse.c
++index 08f8f14..0acb4c2 100644
++--- a/exec/coroparse.c
+++++ b/exec/coroparse.c
++@@ -1,5 +1,5 @@
++ /*
++- * Copyright (c) 2006-2018 Red Hat, Inc.
+++ * Copyright (c) 2006-2019 Red Hat, Inc.
++  *
++  * All rights reserved.
++  *
++@@ -747,13 +747,11 @@ static int main_config_parser_cb(const char *path,
++ 					return (0);
++ 				}
++ 			}
++-			if (strcmp(path, "totem.crypto_type") == 0) {
+++			if (strcmp(path, "totem.crypto_model") == 0) {
++ 				if ((strcmp(value, "nss") != 0) &&
++-				    (strcmp(value, "aes256") != 0) &&
++-				    (strcmp(value, "aes192") != 0) &&
++-				    (strcmp(value, "aes128") != 0) &&
++-				    (strcmp(value, "3des") != 0)) {
++-					*error_string = "Invalid crypto type";
+++				    (strcmp(value, "openssl") != 0)) {
+++					*error_string = "Invalid crypto model. "
+++					    "Should be nss or openssl";
++ 
++ 					return (0);
++ 				}
++@@ -762,9 +760,9 @@ static int main_config_parser_cb(const char *path,
++ 				if ((strcmp(value, "none") != 0) &&
++ 				    (strcmp(value, "aes256") != 0) &&
++ 				    (strcmp(value, "aes192") != 0) &&
++-				    (strcmp(value, "aes128") != 0) &&
++-				    (strcmp(value, "3des") != 0)) {
++-					*error_string = "Invalid cipher type";
+++				    (strcmp(value, "aes128") != 0)) {
+++					*error_string = "Invalid cipher type. "
+++					    "Should be none, aes256, aes192 or aes128";
++ 
++ 					return (0);
++ 				}
++@@ -776,7 +774,8 @@ static int main_config_parser_cb(const char *path,
++ 				    (strcmp(value, "sha256") != 0) &&
++ 				    (strcmp(value, "sha384") != 0) &&
++ 				    (strcmp(value, "sha512") != 0)) {
++-					*error_string = "Invalid hash type";
+++					*error_string = "Invalid hash type. "
+++					    "Should be none, md5, sha1, sha256, sha384 or sha512";
++ 
++ 					return (0);
++ 				}
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index d57562a..4f69fd5 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -463,9 +463,6 @@ static int totem_get_crypto(struct totem_config *totem_config, const char **erro
++ 		if (strcmp(str, "aes128") == 0) {
++ 			tmp_cipher = "aes128";
++ 		}
++-		if (strcmp(str, "3des") == 0) {
++-			tmp_cipher = "3des";
++-		}
++ 		free(str);
++ 	}
++ 
++diff --git a/conf/lenses/corosync.aug b/conf/lenses/corosync.aug
++index 39334f1..edeb4fb 100644
++--- a/conf/lenses/corosync.aug
+++++ b/conf/lenses/corosync.aug
++@@ -51,8 +51,8 @@ let totem =
++     |kv "rrp_mode" /none|active|passive/
++     |kv "vsftype" /none|ykd/
++     |kv "secauth" /on|off/
++-    |kv "crypto_type" /nss|aes256|aes192|aes128|3des/
++-    |kv "crypto_cipher" /none|nss|aes256|aes192|aes128|3des/
+++    |kv "crypto_model" /nss|openssl/
+++    |kv "crypto_cipher" /none|nss|aes256|aes192|aes128/
++     |kv "crypto_hash" /none|md5|sha1|sha256|sha384|sha512/
++     |kv "transport" /udp|iba|udpu/
++     |kv "version" Rx.integer
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 52eb7b1..887a52b 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -1,6 +1,6 @@
++ .\"/*
++ .\" * Copyright (c) 2005 MontaVista Software, Inc.
++-.\" * Copyright (c) 2006-2018 Red Hat, Inc.
+++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
++ .\" *
++ .\" * All rights reserved.
++ .\" *
++@@ -32,7 +32,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH COROSYNC_CONF 5 2019-01-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+++.TH COROSYNC_CONF 5 2019-04-11 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
++ .SH NAME
++ corosync.conf - corosync executive configuration file
++ 
++@@ -221,7 +221,7 @@ The default is none.
++ .TP
++ crypto_cipher
++ This specifies which cipher should be used to encrypt all messages.
++-Valid values are none (no encryption), aes256, aes192, aes128 and 3des.
+++Valid values are none (no encryption), aes256, aes192 and aes128.
++ Enabling crypto_cipher, requires also enabling of crypto_hash. Encrypted
++ transmission is only supported for the knet transport.
++ 
+diff --git a/debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch b/debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
+new file mode 100644
+index 00000000..43e02d43
+--- /dev/null
++++ b/debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
+@@ -0,0 +1,51 @@
++From: yuan ren <yren at suse.com>
++Date: Sun, 28 Apr 2019 18:29:37 +0800
++Subject: totemconfig: fix autogen mcastaddr for ipv6-4
++
++When UDP is used as a transport, the error would occur
++"Multicast address family does not match bind address family"
++because there is no ipv6 in /etc/hosts specified but using the
++totem.ip_version: ipv6-4. because
++the mcastaddr generated (if not specified) only according to
++the totem.ip_version.
++
++Solution is to use bindnetaddr (configured or generated from
++nodelist) addr family.
++
++Signed-off-by: yuan ren <yren at suse.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 70cda5d55f57b99c564be5e7871d291118553a74)
++---
++ exec/totemconfig.c | 10 +++++++++-
++ 1 file changed, 9 insertions(+), 1 deletion(-)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 6fcd6de..3b4dbae 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -1370,6 +1370,7 @@ static int get_interface_params(struct totem_config *totem_config,
++ 	uint32_t u32;
++ 	char *str;
++ 	char *cluster_name = NULL;
+++	enum totem_ip_version_enum tmp_ip_version = TOTEM_IP_VERSION_4;
++ 
++ 	if (reload) {
++ 		for (i=0; i<INTERFACE_MAX; i++) {
++@@ -1460,9 +1461,16 @@ static int get_interface_params(struct totem_config *totem_config,
++ 				 * udpu doesn't need mcastaddr and validity of mcastaddr for udp is
++ 				 * checked later anyway.
++ 				 */
+++
+++				if (totem_config->interfaces[0].bindnet.family == AF_INET) {
+++					tmp_ip_version = TOTEM_IP_VERSION_4;
+++				} else if (totem_config->interfaces[0].bindnet.family == AF_INET6) {
+++					tmp_ip_version = TOTEM_IP_VERSION_6;
+++				}
+++
++ 				(void)get_cluster_mcast_addr (cluster_name,
++ 							      linknumber,
++-							      totem_config->ip_version,
+++							      tmp_ip_version,
++ 							      &totem_config->interfaces[linknumber].mcast_addr);
++ 			}
++ 
+diff --git a/debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch b/debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch
+new file mode 100644
+index 00000000..a3c47f7b
+--- /dev/null
++++ b/debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch
+@@ -0,0 +1,86 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 23 Apr 2019 12:38:04 +0200
++Subject: totemconfig: ipaddr_equal check just addr part
++
++Checking whole structure is fine for IPv4, but IPv6 contains also scope
++id, what may be problem for local address. It's possible to use a zone
++index, but because it's not required when host name is used, it
++shouldn't be needed when IPv6 address is used.
++
++Example configuration snip which fails without patch:
++
++...
++nodelist {
++  node {
++    nodeid: 1
++      ring0_addr: fe80::1234:5678:9abc:def1
++    }
++}
++...
++
++(example succeed when %eth0 is used).
++
++With patch, zone index is not needed.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit d05c1593a11c91d2f419418188ebc7a23f9cc38a)
++---
++ exec/totemconfig.c | 28 ++++++++++++++--------------
++ 1 file changed, 14 insertions(+), 14 deletions(-)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 1954f76..b206eeb 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -560,27 +560,28 @@ static int nodelist_byname(const char *find_name, int strip_domain)
++ 	return -1;
++ }
++ 
++-/* Compare two addresses */
++-static int ipaddr_equal(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2)
+++/* Compare two addresses - only address part (sin_addr/sin6_addr) is checked */
+++static int ipaddr_equal(const struct sockaddr *addr1, const struct sockaddr *addr2)
++ {
++ 	int addrlen = 0;
+++	const void *addr1p, *addr2p;
++ 
++-	if (addr1->ss_family != addr2->ss_family)
+++	if (addr1->sa_family != addr2->sa_family)
++ 		return 0;
++ 
++-	if (addr1->ss_family == AF_INET) {
++-		addrlen = sizeof(struct sockaddr_in);
+++	if (addr1->sa_family == AF_INET) {
+++		addrlen = sizeof(struct in_addr);
+++		addr1p = &((struct sockaddr_in *)addr1)->sin_addr;
+++		addr2p = &((struct sockaddr_in *)addr2)->sin_addr;
++ 	}
++-	if (addr1->ss_family == AF_INET6) {
++-		addrlen = sizeof(struct sockaddr_in6);
+++	if (addr1->sa_family == AF_INET6) {
+++		addrlen = sizeof(struct in6_addr);
+++		addr1p = &((struct sockaddr_in6 *)addr1)->sin6_addr;
+++		addr2p = &((struct sockaddr_in6 *)addr2)->sin6_addr;
++ 	}
++ 	assert(addrlen);
++ 
++-	if (memcmp(addr1, addr2, addrlen) == 0)
++-		return 1;
++-	else
++-		return 0;
++-
+++	return (memcmp(addr1p, addr2p, addrlen) == 0);
++ }
++ 
++ 
++@@ -760,8 +761,7 @@ static int find_local_node(int use_cache)
++ 		for (rp = result; rp != NULL; rp = rp->ai_next) {
++ 			for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
++ 				if (ifa->ifa_addr &&
++-				    ipaddr_equal((struct sockaddr_storage *)rp->ai_addr,
++-						 (struct sockaddr_storage *)ifa->ifa_addr)) {
+++				    ipaddr_equal(rp->ai_addr, ifa->ifa_addr)) {
++ 					freeaddrinfo(result);
++ 					found = 1;
++ 					goto out2;
+diff --git a/debian/patches/totemconfig-ipaddr_equal-use-switch.patch b/debian/patches/totemconfig-ipaddr_equal-use-switch.patch
+new file mode 100644
+index 00000000..f0cd1bbc
+--- /dev/null
++++ b/debian/patches/totemconfig-ipaddr_equal-use-switch.patch
+@@ -0,0 +1,44 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 10:24:05 +0200
++Subject: totemconfig: ipaddr_equal use switch
++
++Compiler may have problem understanding relation between addr1p and
++addrlen. Small change makes code a little more readable and compiler
++happy.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 299c9c5b7016f4f8e423162791fcf4cb3fe70529)
++---
++ exec/totemconfig.c | 11 +++++++----
++ 1 file changed, 7 insertions(+), 4 deletions(-)
++
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 0501589..ff86e23 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -630,17 +630,20 @@ static int ipaddr_equal(const struct sockaddr *addr1, const struct sockaddr *add
++ 	if (addr1->sa_family != addr2->sa_family)
++ 		return 0;
++ 
++-	if (addr1->sa_family == AF_INET) {
+++	switch (addr1->sa_family) {
+++	case AF_INET:
++ 		addrlen = sizeof(struct in_addr);
++ 		addr1p = &((struct sockaddr_in *)addr1)->sin_addr;
++ 		addr2p = &((struct sockaddr_in *)addr2)->sin_addr;
++-	}
++-	if (addr1->sa_family == AF_INET6) {
+++		break;
+++	case AF_INET6:
++ 		addrlen = sizeof(struct in6_addr);
++ 		addr1p = &((struct sockaddr_in6 *)addr1)->sin6_addr;
++ 		addr2p = &((struct sockaddr_in6 *)addr2)->sin6_addr;
+++		break;
+++	default:
+++		assert(0);
++ 	}
++-	assert(addrlen);
++ 
++ 	return (memcmp(addr1p, addr2p, addrlen) == 0);
++ }
+diff --git a/debian/patches/totemip-Use-res-in-totemip_sa_equal.patch b/debian/patches/totemip-Use-res-in-totemip_sa_equal.patch
+new file mode 100644
+index 00000000..2a691774
+--- /dev/null
++++ b/debian/patches/totemip-Use-res-in-totemip_sa_equal.patch
+@@ -0,0 +1,32 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 10:28:41 +0200
++Subject: totemip: Use res in totemip_sa_equal
++
++Setting res to -1 was not entirely following semantics of "equal"
++operation. Set it to 0 and return it when families differs makes
++compiler happy.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit d4d48d9268ea5bb43382e4ed8241cccaa9d2e99a)
++---
++ exec/totemip.c | 4 ++--
++ 1 file changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/exec/totemip.c b/exec/totemip.c
++index 4c2eafe..7accf71 100644
++--- a/exec/totemip.c
+++++ b/exec/totemip.c
++@@ -97,10 +97,10 @@ int totemip_sa_equal(const struct totem_ip_address *totem_ip,
++ {
++ 	int res;
++ 
++-	res = -1;
+++	res = 0;
++ 
++ 	if (totem_ip->family != sa->sa_family) {
++-		return 0;
+++		return (res);
++ 	}
++ 
++ 	switch (totem_ip->family) {
+diff --git a/debian/patches/totemknet-Ignore-icmap_get_string-result.patch b/debian/patches/totemknet-Ignore-icmap_get_string-result.patch
+new file mode 100644
+index 00000000..432ce704
+--- /dev/null
++++ b/debian/patches/totemknet-Ignore-icmap_get_string-result.patch
+@@ -0,0 +1,32 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 10:40:07 +0200
++Subject: totemknet: Ignore icmap_get_string result
++
++... and add comment why it is not a bug.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 9b809383e65a57b8604132d93e005d42b42c71a1)
++---
++ exec/totemknet.c | 8 ++++++--
++ 1 file changed, 6 insertions(+), 2 deletions(-)
++
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 774cb2c..8762185 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -1795,8 +1795,12 @@ static int setup_nozzle(void *knet_context)
++ 	int macaddr_res;
++ 	int res;
++ 
++-	icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
++-	icmap_get_string(NOZZLE_PREFIX, &prefix_str);
+++	/*
+++	 * Return value ignored on purpose. icmap_get_string changes
+++	 * ipaddr_str/prefix_str only on success.
+++	 */
+++	(void)icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
+++	(void)icmap_get_string(NOZZLE_PREFIX, &prefix_str);
++ 	macaddr_res = icmap_get_string(NOZZLE_MACADDR, &macaddr_str);
++ 	name_res = icmap_get_string(NOZZLE_NAME, &name_str);
++ 
+diff --git a/debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch b/debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch
+new file mode 100644
+index 00000000..e2f6bcde
+--- /dev/null
++++ b/debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch
+@@ -0,0 +1,39 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 11:00:03 +0200
++Subject: totemknet: Initialize return value in setup_nozzle
++
++Also add comment why return value is currently not used.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 0839d3af82833342b43a64fbc403227a574bd63b)
++---
++ exec/totemknet.c | 8 +++++---
++ 1 file changed, 5 insertions(+), 3 deletions(-)
++
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index eb2ed2c..e6e04d3 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -1428,8 +1428,10 @@ int totemknet_reconfigure (
++ 	}
++ 
++ #ifdef HAVE_LIBNOZZLE
++-	/* Set up nozzle device(s) */
++-	setup_nozzle(instance);
+++	/* Set up nozzle device(s). Return code is ignored, because unability
+++	 * configure nozzle is not fatal problem, errors are logged and
+++	 * there is not much else we can do */
+++	(void)setup_nozzle(instance);
++ #endif
++ 	return (res);
++ }
++@@ -1793,7 +1795,7 @@ static int setup_nozzle(void *knet_context)
++ 	char mac[32];
++ 	int name_res;
++ 	int macaddr_res;
++-	int res;
+++	int res = -1;
++ 
++ 	/*
++ 	 * Return value ignored on purpose. icmap_get_string changes
+diff --git a/debian/patches/totemknet-create_nozzle_device-simplify-check.patch b/debian/patches/totemknet-create_nozzle_device-simplify-check.patch
+new file mode 100644
+index 00000000..e3260daf
+--- /dev/null
++++ b/debian/patches/totemknet-create_nozzle_device-simplify-check.patch
+@@ -0,0 +1,34 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 10:32:40 +0200
++Subject: totemknet: create_nozzle_device simplify check
++
++ipaddr existence is checked for being not NULL by caller setup_nozzle.
++Also ipaddr was passed to reparse_nozzle_ip_address function unchecked
++so code would crash before reaching the actual check.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 9a0e7b584e3b217e0bdf1a017b5995cbce27f708)
++---
++ exec/totemknet.c | 8 +++-----
++ 1 file changed, 3 insertions(+), 5 deletions(-)
++
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 2af69b3..774cb2c 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -1707,11 +1707,9 @@ static int create_nozzle_device(void *knet_context, const char *name,
++ 		goto out_clean;
++ 	}
++ 	knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle IP address is %s / %d", parsed_ipaddr, atoi(prefix));
++-	if (ipaddr) {
++-		if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
++-			knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
++-			goto out_clean;
++-		}
+++	if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
+++		knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
+++		goto out_clean;
++ 	}
++ 
++ 	nozzle_fd = nozzle_get_fd(nozzle_dev);
+diff --git a/debian/patches/totemknet-macaddr_str-is-always-set.patch b/debian/patches/totemknet-macaddr_str-is-always-set.patch
+new file mode 100644
+index 00000000..c2574cae
+--- /dev/null
++++ b/debian/patches/totemknet-macaddr_str-is-always-set.patch
+@@ -0,0 +1,27 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 10:44:17 +0200
++Subject: totemknet: macaddr_str is always set
++
++Check for NULL was invalid, because macaddr_str is ether defined in cmap
++or set to "54:54:01:00:00:00".
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 0d82e23517e299dec877e632c9c9a4d441789be8)
++---
++ exec/totemknet.c | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/exec/totemknet.c b/exec/totemknet.c
++index 8762185..eb2ed2c 100644
++--- a/exec/totemknet.c
+++++ b/exec/totemknet.c
++@@ -1838,7 +1838,7 @@ static int setup_nozzle(void *knet_context)
++ 	    (strcmp(name_str, instance->nozzle_name) == 0) &&
++ 	    (strcmp(ipaddr_str, instance->nozzle_ipaddr) == 0) &&
++ 	    (strcmp(prefix_str, instance->nozzle_prefix) == 0) &&
++-	    ((macaddr_str == NULL && instance->nozzle_macaddr == NULL) ||
+++	    (instance->nozzle_macaddr == NULL ||
++ 	     strcmp(macaddr_str, instance->nozzle_macaddr) == 0)) {
++ 		/* Nothing has changed */
++ 		knet_log_printf (LOGSYS_LEVEL_DEBUG, "Nozzle device info not changed");
+diff --git a/debian/patches/totemsrp-Word-spelling-mistake.patch b/debian/patches/totemsrp-Word-spelling-mistake.patch
+new file mode 100644
+index 00000000..99e1ffaa
+--- /dev/null
++++ b/debian/patches/totemsrp-Word-spelling-mistake.patch
+@@ -0,0 +1,24 @@
++From: yuan ren <yren at suse.com>
++Date: Fri, 29 Mar 2019 15:43:10 +0800
++Subject: totemsrp: Word spelling mistake
++
++Signed-off-by: yuan ren <reyren179 at gmail.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit 24a72e9780f30d29e0097700b68bd2056845bc31)
++---
++ exec/totemsrp.c | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/exec/totemsrp.c b/exec/totemsrp.c
++index ab27924..a48d97b 100644
++--- a/exec/totemsrp.c
+++++ b/exec/totemsrp.c
++@@ -434,7 +434,7 @@ struct totemsrp_instance {
++ 
++ 	void (*totemsrp_log_printf) (
++ 		int level,
++-		int sybsys,
+++		int subsys,
++ 		const char *function,
++ 		const char *file,
++ 		int line,
+diff --git a/debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch b/debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch
+new file mode 100644
+index 00000000..591e4873
+--- /dev/null
++++ b/debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch
+@@ -0,0 +1,254 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Fri, 24 May 2019 08:48:01 +0200
++Subject: udpu: Drop packets from unlisted IPs
++
++This feature allows corosync to block packets received from unknown
++nodes (nodes with IP address which is not in the nodelist). This is
++mainly for situations when "forgotten" node is booted and tries to join
++cluster which already removed such node from configuration. Another use
++case is to allow atomic reconfiguration and rejoin of two separate
++clusters.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 72737d39292feb7c9253c26418e1e25ef0a7fad9)
++---
++ include/corosync/totem/totem.h   |  2 ++
++ include/corosync/totem/totemip.h |  2 ++
++ exec/totemconfig.c               | 55 +++++++++++++++++++++++++++++++++++++++-
++ exec/totemip.c                   | 27 ++++++++++++++++++++
++ exec/totemudpu.c                 | 34 +++++++++++++++++++++++++
++ man/corosync.conf.5              | 10 +++++++-
++ 6 files changed, 128 insertions(+), 2 deletions(-)
++
++diff --git a/include/corosync/totem/totem.h b/include/corosync/totem/totem.h
++index d9d8e46..00ee0ab 100644
++--- a/include/corosync/totem/totem.h
+++++ b/include/corosync/totem/totem.h
++@@ -233,6 +233,8 @@ struct totem_config {
++ 
++ 	enum totem_ip_version_enum ip_version;
++ 
+++	unsigned int block_unlisted_ips;
+++
++ 	void (*totem_memb_ring_id_create_or_load) (
++ 	    struct memb_ring_id *memb_ring_id,
++ 	    unsigned int nodeid);
++diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h
++index b8da3c9..91b2266 100644
++--- a/include/corosync/totem/totemip.h
+++++ b/include/corosync/totem/totemip.h
++@@ -86,6 +86,8 @@ struct totem_ip_if_address
++ 
++ extern int totemip_equal(const struct totem_ip_address *addr1,
++ 			 const struct totem_ip_address *addr2);
+++extern int totemip_sa_equal(const struct totem_ip_address *totem_ip,
+++			const struct sockaddr *sa);
++ extern int totemip_compare(const void *a, const void *b);
++ extern int totemip_is_mcast(struct totem_ip_address *addr);
++ extern void totemip_copy(struct totem_ip_address *addr1,
++diff --git a/exec/totemconfig.c b/exec/totemconfig.c
++index 262dcac..0501589 100644
++--- a/exec/totemconfig.c
+++++ b/exec/totemconfig.c
++@@ -79,6 +79,7 @@
++ #define WINDOW_SIZE				50
++ #define MAX_MESSAGES				17
++ #define MISS_COUNT_CONST			5
+++#define BLOCK_UNLISTED_IPS			1
++ 
++ /* These currently match the defaults in libknet.h */
++ #define KNET_PING_INTERVAL                      1000
++@@ -138,6 +139,8 @@ static void *totem_get_param_by_name(struct totem_config *totem_config, const ch
++ 		return &totem_config->knet_compression_level;
++ 	if (strcmp(param_name, "totem.knet_compression_model") == 0)
++ 		return &totem_config->knet_compression_model;
+++	if (strcmp(param_name, "totem.block_unlisted_ips") == 0)
+++		return &totem_config->block_unlisted_ips;
++ 
++ 	return NULL;
++ }
++@@ -235,6 +238,55 @@ static void totem_volatile_config_set_string_value (struct totem_config *totem_c
++ 	icmap_set_string(runtime_key_name, (char *)*config_value);
++ }
++ 
+++/*
+++ * Read string value stored in key_name from icmap, use it as a boolean (yes/no) type, convert it
+++ * to integer value (1/0) and store into totem_config.
+++ *
+++ * If key is not found or key_name == delete_key default value is used
+++ * and stored into totem_config.
+++ */
+++static void totem_volatile_config_set_boolean_value (struct totem_config *totem_config,
+++	const char *key_name, const char *deleted_key, unsigned int default_value)
+++{
+++	char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
+++	char *str;
+++	int val;
+++
+++	str = NULL;
+++	val = default_value;
+++
+++	if ((deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
+++	    (icmap_get_string(key_name, &str) != CS_OK)) {
+++		/*
+++		 * Do nothing. str is NULL (icmap_get_string ether not called or
+++		 * not changed str).
+++		 */
+++	} else {
+++		if (strcmp(str, "yes") == 0) {
+++			val = 1;
+++		} else if (strcmp(str, "no") == 0) {
+++			val = 0;
+++		}
+++		free(str);
+++	}
+++
+++	/*
+++	 * Store totem_config value to cmap runtime section
+++	 */
+++	if (strlen("runtime.config.") + strlen(key_name) >= ICMAP_KEYNAME_MAXLEN) {
+++		/*
+++		 * This shouldn't happen
+++		 */
+++		return ;
+++	}
+++
+++	strcpy(runtime_key_name, "runtime.config.");
+++	strcat(runtime_key_name, key_name);
+++
+++	*(uint32_t *)totem_get_param_by_name(totem_config, key_name) = val;
+++
+++	icmap_set_uint32(runtime_key_name, val);
+++}
++ 
++ /*
++  * Read and validate config values from cmap and store them into totem_config. If key doesn't exists,
++@@ -302,7 +354,8 @@ static void totem_volatile_config_read (struct totem_config *totem_config, const
++ 
++ 	totem_volatile_config_set_string_value(totem_config, "totem.knet_compression_model", deleted_key, "none");
++ 
++-
+++	totem_volatile_config_set_boolean_value(totem_config, "totem.block_unlisted_ips", deleted_key,
+++	    BLOCK_UNLISTED_IPS);
++ }
++ 
++ static int totem_volatile_config_validate (
++diff --git a/exec/totemip.c b/exec/totemip.c
++index 36d0a72..4c2eafe 100644
++--- a/exec/totemip.c
+++++ b/exec/totemip.c
++@@ -92,6 +92,33 @@ int totemip_equal(const struct totem_ip_address *addr1,
++ 
++ }
++ 
+++int totemip_sa_equal(const struct totem_ip_address *totem_ip,
+++	const struct sockaddr *sa)
+++{
+++	int res;
+++
+++	res = -1;
+++
+++	if (totem_ip->family != sa->sa_family) {
+++		return 0;
+++	}
+++
+++	switch (totem_ip->family) {
+++	case AF_INET:
+++		res = (memcmp(totem_ip->addr,
+++		    &((const struct sockaddr_in *)sa)->sin_addr, sizeof(struct in_addr)) == 0);
+++		break;
+++	case AF_INET6:
+++		res =  (memcmp(totem_ip->addr,
+++		    &((const struct sockaddr_in6 *)sa)->sin6_addr, sizeof(struct in6_addr)) == 0);
+++		break;
+++	default:
+++		assert(0);
+++	}
+++
+++	return (res);
+++}
+++
++ /* Copy a totem_ip_address */
++ void totemip_copy(struct totem_ip_address *addr1,
++ 		  const struct totem_ip_address *addr2)
++diff --git a/exec/totemudpu.c b/exec/totemudpu.c
++index 252962d..914a328 100644
++--- a/exec/totemudpu.c
+++++ b/exec/totemudpu.c
++@@ -444,6 +444,32 @@ int totemudpu_finalize (
++ 	return (res);
++ }
++ 
+++static struct totemudpu_member *find_member_by_sockaddr(
+++	const void *udpu_context,
+++	const struct sockaddr *sa)
+++{
+++	struct qb_list_head *list;
+++	struct totemudpu_member *member;
+++	struct totemudpu_member *res_member;
+++	const struct totemudpu_instance *instance = (const struct totemudpu_instance *)udpu_context;
+++
+++	res_member = NULL;
+++
+++	qb_list_for_each(list, &(instance->member_list)) {
+++		member = qb_list_entry (list,
+++			struct totemudpu_member,
+++			list);
+++
+++		if (totemip_sa_equal(&member->member, sa)) {
+++			res_member = member;
+++			break ;
+++		}
+++	}
+++
+++	return (res_member);
+++}
+++
+++
++ static int net_deliver_fn (
++ 	int fd,
++ 	int revents,
++@@ -513,6 +539,14 @@ static int net_deliver_fn (
++ 		return (0);
++ 	}
++ 
+++	if (instance->totem_config->block_unlisted_ips &&
+++	    find_member_by_sockaddr(instance, (const struct sockaddr *)&system_from) == NULL) {
+++		log_printf(instance->totemudpu_log_level_debug, "Packet rejected from %s",
+++		    totemip_sa_print((const struct sockaddr *)&system_from));
+++
+++		return (0);
+++	}
+++
++ 	iovec->iov_len = bytes_received;
++ 
++ 	/*
++diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
++index 674179d..953c830 100644
++--- a/man/corosync.conf.5
+++++ b/man/corosync.conf.5
++@@ -32,7 +32,7 @@
++ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ .\" * THE POSSIBILITY OF SUCH DAMAGE.
++ .\" */
++-.TH COROSYNC_CONF 5 2019-04-11 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+++.TH COROSYNC_CONF 5 2019-05-24 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
++ .SH NAME
++ corosync.conf - corosync executive configuration file
++ 
++@@ -571,6 +571,14 @@ knet_enable_access_lists
++ Allow knet to drop packets from IP addresses that are not known to corosync.
++ Value is 0 (off) and 1 (on). Default: 0.
++ 
+++.TP
+++block_unlisted_ips
+++Allow UDPU to drop packets from IP addresses that are not known
+++(nodes which don't exist in the nodelist) to corosync.
+++Value is yes or no.
+++
+++The default value is yes.
+++
++ .PP
++ Within the
++ .B logging
+diff --git a/debian/patches/vqsim-Check-length-of-copied-optarg.patch b/debian/patches/vqsim-Check-length-of-copied-optarg.patch
+new file mode 100644
+index 00000000..ef2afb67
+--- /dev/null
++++ b/debian/patches/vqsim-Check-length-of-copied-optarg.patch
+@@ -0,0 +1,37 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 15:30:00 +0200
++Subject: vqsim: Check length of copied optarg
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 0390200dd427d1d3e75bba8584dbfbb794b52b49)
++---
++ vqsim/vqmain.c | 8 ++++++--
++ 1 file changed, 6 insertions(+), 2 deletions(-)
++
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index 16f7714..25d0fad 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -759,7 +759,11 @@ int main(int argc, char **argv)
++ 	while ((ch = getopt (argc, argv, "c:o:nh")) != EOF) {
++ 		switch (ch) {
++ 		case 'c':
++-			strncpy(corosync_config_file, optarg, sizeof(corosync_config_file));
+++			if (strlen(optarg) >= sizeof(sizeof(corosync_config_file) - 1)) {
+++				fprintf(stderr, "Corosync config file path too long\n");
+++				exit(1);
+++			}
+++			strncpy(corosync_config_file, optarg, sizeof(corosync_config_file) - 1);
++ 			break;
++ 		case 'o':
++ 			output_file_name = optarg;
++@@ -777,7 +781,7 @@ int main(int argc, char **argv)
++ 		output_file = fopen(output_file_name, "w");
++ 		if (!output_file) {
++ 			fprintf(stderr, "Unable to open %s for output: %s\n", output_file_name, strerror(errno));
++-			exit(-1);
+++			exit(3);
++ 		}
++ 	}
++ 	else {
+diff --git a/debian/patches/vqsim-Check-length-of-received-message.patch b/debian/patches/vqsim-Check-length-of-received-message.patch
+new file mode 100644
+index 00000000..a4d54327
+--- /dev/null
++++ b/debian/patches/vqsim-Check-length-of-received-message.patch
+@@ -0,0 +1,42 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 14:48:41 +0200
++Subject: vqsim: Check length of received message
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 7267149e050cc8963eb38c7a31bb26c84d1f2338)
++---
++ vqsim/vqmain.c | 16 +++++++++++++---
++ 1 file changed, 13 insertions(+), 3 deletions(-)
++
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index aaba512..98729b9 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -222,13 +222,23 @@ static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
++ 		msglen = read(fd, msgbuf, sizeof(msgbuf));
++ 		if (msglen < 0) {
++ 			perror("read failed");
++-		}
++-
++-		if (msglen > 0) {
+++		} else if (msglen < sizeof(*msg)) {
+++			fprintf(stderr, "Received message is too short\n");
+++		} else {
++ 			msg = (void*)msgbuf;
++ 			switch (msg->type) {
++ 			case VQMSG_QUORUM:
++ 				qmsg = (void*)msgbuf;
+++				/*
+++				 * Check length of message.
+++				 * SOCK_SEQPACKET is used so this check is not strictly needed.
+++				 */
+++				if (msglen < sizeof(*qmsg) ||
+++				    qmsg->view_list_entries > MAX_NODES ||
+++				    msglen < sizeof(*qmsg) + sizeof(qmsg->view_list[0]) * qmsg->view_list_entries) {
+++					fprintf(stderr, "Received quorum message is too short or corrupted\n");
+++					return (0);
+++				}
++ 				save_quorum_state(vqn, qmsg);
++ 				if (!sync_cmds) {
++ 					print_quorum_state(vqn);
+diff --git a/debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch b/debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch
+new file mode 100644
+index 00000000..25690b75
+--- /dev/null
++++ b/debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch
+@@ -0,0 +1,31 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 15:26:29 +0200
++Subject: vqsim: Check result of icmap_set_uint32
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 1d8c1a4c9712517b24985941b8fac2d45eef4784)
++---
++ vqsim/vqsim_vq_engine.c | 2 ++
++ 1 file changed, 2 insertions(+)
++
++diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
++index eb35d35..b8460f3 100644
++--- a/vqsim/vqsim_vq_engine.c
+++++ b/vqsim/vqsim_vq_engine.c
++@@ -208,6 +208,7 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
++ 			if (nodeid == our_nodeid) {
++ 				found = 1;
++ 				res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
+++				assert(res == CS_OK);
++ 			}
++ 		}
++ 	}
++@@ -217,6 +218,7 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
++ 		 * first node in corosync.conf
++ 		 */
++ 		res = icmap_set_uint32("nodelist.local_node_pos", 0);
+++		assert(res == CS_OK);
++ 	}
++ }
++ 
+diff --git a/debian/patches/vqsim-Check-write-result.patch b/debian/patches/vqsim-Check-write-result.patch
+new file mode 100644
+index 00000000..303f661c
+--- /dev/null
++++ b/debian/patches/vqsim-Check-write-result.patch
+@@ -0,0 +1,33 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 14:46:34 +0200
++Subject: vqsim: Check write result
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit e953cfeb873f495cd9c59ba999be2b103363718b)
++---
++ vqsim/vqmain.c | 8 +++++++-
++ 1 file changed, 7 insertions(+), 1 deletion(-)
++
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index 0eca43c..aaba512 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -138,10 +138,16 @@ static void print_quorum_state(struct vq_node *node)
++ static void propogate_vq_message(struct vq_node *vqn, const char *msg, int len)
++ {
++ 	struct vq_node *other_vqn;
+++	ssize_t write_res;
++ 
++ 	/* Send it to everyone in that node's partition (including itself) */
++ 	TAILQ_FOREACH(other_vqn, &vqn->partition->nodelist, entries) {
++-		write(other_vqn->fd, msg, len);
+++		write_res = write(other_vqn->fd, msg, len);
+++		/*
+++		 * Read counterpart is not ready for receiving non-complete message so
+++		 * ensure all required information was send.
+++		 */
+++		assert(write_res == len);
++ 	}
++ }
++ 
+diff --git a/debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch b/debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch
+new file mode 100644
+index 00000000..04973dff
+--- /dev/null
++++ b/debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch
+@@ -0,0 +1,24 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 11:04:48 +0200
++Subject: vqsim: Do not access unitialized argv[0]
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 1af23e9c2dd3830beb2cd16277a44ae50ad483db)
++---
++ vqsim/parser.c | 2 +-
++ 1 file changed, 1 insertion(+), 1 deletion(-)
++
++diff --git a/vqsim/parser.c b/vqsim/parser.c
++index d13e678..2857184 100644
++--- a/vqsim/parser.c
+++++ b/vqsim/parser.c
++@@ -196,7 +196,7 @@ void parse_input_command(char *rl_cmd)
++ 	}
++ 
++ 	/* Ignore null commands */
++-	if (strlen(argv[0]) == 0) {
+++	if (argc < 1 || strlen(argv[0]) == 0) {
++ 		free(cmd);
++ 		resume_kb_input(0);
++ 		return;
+diff --git a/debian/patches/vqsim-Enhance-vqsim.patch b/debian/patches/vqsim-Enhance-vqsim.patch
+new file mode 100644
+index 00000000..7e95761f
+--- /dev/null
++++ b/debian/patches/vqsim-Enhance-vqsim.patch
+@@ -0,0 +1,1155 @@
++From: Christine Caulfield <ccaulfie at redhat.com>
++Date: Fri, 26 Apr 2019 10:54:32 +0100
++Subject: vqsim: Enhance vqsim
++
++1. Enable scripting of vqsim and add man page
++
++I've added a 'sleep' command to help with scripting as well as
++documentation on how to do it.
++
++2. Make 'sync' operation much more robust and useful
++
++Refactored a lot of code to make sure that in sync mode the
++prompt appears at the 'right' time. What we do is wait for all
++of the nodes in all partitions to have the same ring_id. If this
++doesn't happen then the timeout will fire as before.
++
++3. Rename binary to corosync-vqsim and add a sub-package for it
++
++Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit c3d69712c614deea688b7cfe0975976ecca60a2d)
++---
++ configure.ac            |   1 +
++ man/Makefile.am         |   4 +
++ vqsim/Makefile.am       |  22 ++--
++ vqsim/vqsim.h           |  82 +++++++++++++++
++ corosync.spec.in        |  26 +++++
++ vqsim/parser.c          | 141 ++++++++++++++++++++-----
++ vqsim/vqmain.c          | 274 +++++++++++++++++++++++++++++++++---------------
++ vqsim/vqsim_vq_engine.c |  12 ++-
++ man/corosync-vqsim.8    |  94 +++++++++++++++++
++ 9 files changed, 533 insertions(+), 123 deletions(-)
++ create mode 100644 vqsim/vqsim.h
++ create mode 100644 man/corosync-vqsim.8
++
++diff --git a/configure.ac b/configure.ac
++index 14c0e17..a27ba95 100644
++--- a/configure.ac
+++++ b/configure.ac
++@@ -470,6 +470,7 @@ if test "x${enable_vqsim}" = xyes; then
++ 			 [],
++                          AC_MSG_WARN([vqsim will lack readline support]))
++ 	PACKAGE_FEATURES="$PACKAGE_FEATURES vqsim"
+++	WITH_LIST="$WITH_LIST --with vqsim"
++ fi
++ AM_CONDITIONAL(VQSIM_READLINE, [test "x${ac_cv_header_readline_readline_h}" = xyes])
++ 
++diff --git a/man/Makefile.am b/man/Makefile.am
++index d1b7f94..8e4eda3 100644
++--- a/man/Makefile.am
+++++ b/man/Makefile.am
++@@ -139,6 +139,10 @@ dist_man_MANS 		= corosync.conf.5 \
++ 			  cmap_overview.3 \
++ 			  cmap_keys.8
++ 
+++if BUILD_VQSIM
+++dist_man_MANS		+= corosync-vqsim.8
+++endif
+++
++ if INSTALL_XMLCONF
++ dist_man_MANS		+= $(xml_man)
++ endif
++diff --git a/vqsim/Makefile.am b/vqsim/Makefile.am
++index 2a76544..9a7fbf6 100644
++--- a/vqsim/Makefile.am
+++++ b/vqsim/Makefile.am
++@@ -30,23 +30,25 @@
++ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
++ # THE POSSIBILITY OF SUCH DAMAGE.
++ 
++-MAINTAINERCLEANFILES	= Makefile.in
+++MAINTAINERCLEANFILES		= Makefile.in
++ 
++ if BUILD_VQSIM
++ 
++-noinst_PROGRAMS		= vqsim
+++noinst_HEADERS			= vqsim.h
++ 
++-vqsim_LDADD		= $(top_builddir)/common_lib/libcorosync_common.la \
++-			  ../exec/corosync-votequorum.o ../exec/corosync-icmap.o ../exec/corosync-logsys.o \
++-			  ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
++-			  ../exec/corosync-util.o \
++-			  $(LIBQB_LIBS)
+++bin_PROGRAMS			= corosync-vqsim
+++
+++corosync_vqsim_LDADD		= $(top_builddir)/common_lib/libcorosync_common.la \
+++				  ../exec/corosync-votequorum.o ../exec/corosync-icmap.o  \
+++				  ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
+++				  ../exec/corosync-util.o ../exec/corosync-logsys.o \
+++				$(LIBQB_LIBS)
++ if VQSIM_READLINE
++-vqsim_LDADD		+= -lreadline
+++corosync_vqsim_LDADD		+= -lreadline
++ endif
++ 
++-vqsim_DEPENDENCIES	= $(top_builddir)/common_lib/libcorosync_common.la
+++corosync_vqsim_DEPENDENCIES	= $(top_builddir)/common_lib/libcorosync_common.la
++ 
++-vqsim_SOURCES	        = vqmain.c parser.c vq_object.c vqsim_vq_engine.c
+++corosync_vqsim_SOURCES	        = vqmain.c parser.c vq_object.c vqsim_vq_engine.c
++ 
++ endif
++diff --git a/vqsim/vqsim.h b/vqsim/vqsim.h
++new file mode 100644
++index 0000000..0c4c973
++--- /dev/null
+++++ b/vqsim/vqsim.h
++@@ -0,0 +1,82 @@
+++
+++typedef enum {VQMSG_QUIT=1,
+++	      VQMSG_SYNC,    /* set nodelist */
+++	      VQMSG_QUORUM,  /* quorum state of this 'node' */
+++	      VQMSG_EXEC,    /* message for exec_handler */
+++	      VQMSG_QDEVICE, /* quorum device enable/disable */
+++	      VQMSG_QUORUMQUIT, /* quit if you don't have quorum */
+++} vqsim_msg_type_t;
+++
+++typedef struct vq_instance *vq_object_t;
+++
+++struct vqsim_msg_header
+++{
+++	vqsim_msg_type_t type;
+++	int from_nodeid;
+++	int param;
+++};
+++
+++/* This is the sync sent from the controller process */
+++struct vqsim_sync_msg
+++{
+++	struct vqsim_msg_header header;
+++	struct memb_ring_id ring_id;
+++	size_t view_list_entries;
+++	unsigned int view_list[];
+++};
+++
+++/* This is just info sent from each VQ instance */
+++struct vqsim_quorum_msg
+++{
+++	struct vqsim_msg_header header;
+++	int quorate;
+++	struct memb_ring_id ring_id;
+++	size_t view_list_entries;
+++	unsigned int view_list[];
+++};
+++
+++struct vqsim_exec_msg
+++{
+++	struct vqsim_msg_header header;
+++	char execmsg[];
+++};
+++
+++struct vqsim_lib_msg
+++{
+++	struct vqsim_msg_header header;
+++	char libmsg[];
+++};
+++
+++#define MAX_NODES 1024
+++#define MAX_PARTITIONS 16
+++
+++/* In vq_object.c */
+++vq_object_t vq_create_instance(qb_loop_t *poll_loop, int nodeid);
+++void vq_quit(vq_object_t instance);
+++int vq_set_nodelist(vq_object_t instance, struct memb_ring_id *ring_id, int *nodeids, int nodeids_entries);
+++int vq_get_parent_fd(vq_object_t instance);
+++int vq_set_qdevice(vq_object_t instance, struct memb_ring_id *ring_id, int onoff);
+++int vq_quit_if_inquorate(vq_object_t instance);
+++pid_t vq_get_pid(vq_object_t instance);
+++
+++/* in vqsim_vq_engine.c - effectively the constructor */
+++int fork_new_instance(int nodeid, int *vq_sock, pid_t *child_pid);
+++
+++/* In parser.c */
+++void parse_input_command(char *cmd);
+++
+++/* These are in vqmain.c */
+++int  cmd_stop_node(int nodeid);
+++void cmd_stop_all_nodes(void);
+++int  cmd_start_new_node(int nodeid, int partition);
+++void cmd_set_autofence(int onoff);
+++void cmd_set_sync(int onoff);
+++void cmd_set_assert(int onoff);
+++void cmd_move_nodes(int partition, int num_nodes, int *nodelist);
+++void cmd_join_partitions(int part1, int part2);
+++void cmd_update_all_partitions(int newring);
+++void cmd_qdevice_poll(int nodeid, int onoff);
+++void cmd_show_node_states(void);
+++void cmd_set_timeout(uint64_t seconds);
+++void cmd_start_sync_command(void);
+++void resume_kb_input(int show_state);
++diff --git a/corosync.spec.in b/corosync.spec.in
++index 07c004c..8af686e 100644
++--- a/corosync.spec.in
+++++ b/corosync.spec.in
++@@ -12,6 +12,7 @@
++ %bcond_with systemd
++ %bcond_with xmlconf
++ %bcond_with nozzle
+++%bcond_with vqsim
++ %bcond_with runautogen
++ 
++ %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
++@@ -70,6 +71,9 @@ Requires(preun): /sbin/chkconfig
++ %if %{with xmlconf}
++ Requires: libxslt
++ %endif
+++%if %{with vqsim}
+++BuildRequires: readline-devel
+++%endif
++ 
++ %prep
++ %setup -q -n %{name}-%{version}%{?gittarver}
++@@ -100,6 +104,9 @@ Requires: libxslt
++ %endif
++ %if %{with nozzle}
++ 	--enable-nozzle \
+++%endif
+++%if %{with vqsim}
+++	--enable-vqsim \
++ %endif
++ 	--with-initddir=%{_initrddir} \
++ 	--with-systemddir=%{_unitdir} \
++@@ -266,6 +273,25 @@ The Corosync Cluster Engine APIs.
++ %{_mandir}/man3/sam_*3*
++ %{_mandir}/man3/cmap_*3*
++ 
+++%if %{with vqsim}
+++%package -n corosync-vqsim
+++Summary: The Corosync Cluster Engine - Votequorum Simulator
+++Requires: corosynclib%{?_isa} = %{version}-%{release}
+++Requires: pkgconfig
+++
+++%description -n corosync-vqsim
+++A command-line simulator for the corosync votequorum subsystem.
+++It uses the same code as the corosync quorum system but forks
+++them into subprocesses to simulate nodes.
+++Nodes can be added and removed as well as partitioned (to simulate
+++network splits)
+++
+++%files -n corosync-vqsim
+++%doc LICENSE
+++%{_bindir}/corosync-vqsim
+++%{_mandir}/man8/corosync-vqsim.8*
+++%endif
+++
++ %changelog
++ * @date@ Autotools generated version <nobody at nowhere.org> - @version at -1-@numcomm at .@alphatag at .@dirty@
++ - Autotools generated version
++diff --git a/vqsim/parser.c b/vqsim/parser.c
++index 2fc1043..d13e678 100644
++--- a/vqsim/parser.c
+++++ b/vqsim/parser.c
++@@ -30,21 +30,31 @@ static void do_usage(void)
++ 	printf("           Enable quorum device in specified nodes\n");
++ 	printf("autofence  on|off\n");
++ 	printf("           automatically 'down' nodes on inquorate side on netsplit\n");
+++	printf("timeout    <n> (default 250)\n");
+++	printf("           Wait a maximum of <n> milli-seconds for the next command to complete.\n");
+++	printf("sync       on|off (default on)\n");
+++	printf("           enable/disable synchronous execution of commands (wait for completion)\n");
+++	printf("assert     on|off (default off)\n");
+++	printf("           Abort the simulation run if a timeout expires\n");
++ 	printf("show       Show current nodes status\n");
++ 	printf("exit\n\n");
++ }
++ 
++ 
++-typedef void (*cmd_routine_t)(int argc, char **argv);
+++/* Commands return 0 if they return immediately, >1 if we are waiting for replies from nodes */
+++typedef int (*cmd_routine_t)(int argc, char **argv);
++ 
++-static void run_up_cmd(int argc, char **argv);
++-static void run_down_cmd(int argc, char **argv);
++-static void run_join_cmd(int argc, char **argv);
++-static void run_move_cmd(int argc, char **argv);
++-static void run_exit_cmd(int argc, char **argv);
++-static void run_show_cmd(int argc, char **argv);
++-static void run_autofence_cmd(int argc, char **argv);
++-static void run_qdevice_cmd(int argc, char **argv);
+++static int run_up_cmd(int argc, char **argv);
+++static int run_down_cmd(int argc, char **argv);
+++static int run_join_cmd(int argc, char **argv);
+++static int run_move_cmd(int argc, char **argv);
+++static int run_exit_cmd(int argc, char **argv);
+++static int run_show_cmd(int argc, char **argv);
+++static int run_timeout_cmd(int argc, char **argv);
+++static int run_assert_cmd(int argc, char **argv);
+++static int run_autofence_cmd(int argc, char **argv);
+++static int run_qdevice_cmd(int argc, char **argv);
+++static int run_sync_cmd(int argc, char **argv);
++ 
++ static struct cmd_list_struct {
++ 	const char *cmd;
++@@ -59,6 +69,9 @@ static struct cmd_list_struct {
++ 	{ "autofence", 1, run_autofence_cmd},
++ 	{ "qdevice", 1, run_qdevice_cmd},
++ 	{ "show", 0, run_show_cmd},
+++	{ "timeout", 1, run_timeout_cmd},
+++	{ "sync", 1, run_sync_cmd},
+++	{ "assert", 1, run_assert_cmd},
++ 	{ "exit", 0, run_exit_cmd},
++ 	{ "quit", 0, run_exit_cmd},
++ 	{ "q", 0, run_exit_cmd},
++@@ -135,11 +148,16 @@ void parse_input_command(char *rl_cmd)
++ 	int last_arg_start = 0;
++ 	int last_was_space = 0;
++ 	int len;
+++	int ret = 0;
++ 	char *cmd;
++ 
++ 	/* ^D quits */
++ 	if (rl_cmd == NULL) {
++-		run_exit_cmd(0, NULL);
+++		(void)run_exit_cmd(0, NULL);
+++	}
+++	/* '#' starts a comment */
+++	if (rl_cmd[0] == '#') {
+++		return;
++ 	}
++ 
++ 	cmd = strdup(rl_cmd);
++@@ -180,7 +198,8 @@ void parse_input_command(char *rl_cmd)
++ 	/* Ignore null commands */
++ 	if (strlen(argv[0]) == 0) {
++ 		free(cmd);
++-	    return;
+++		resume_kb_input(0);
+++		return;
++ 	}
++ #ifdef HAVE_READLINE_HISTORY_H
++ 	add_history(rl_cmd);
++@@ -193,7 +212,7 @@ void parse_input_command(char *rl_cmd)
++ 			if (argc < cmd_list[i].min_args) {
++ 				break;
++ 			}
++-			cmd_list[i].cmd_runner(argc, argv);
+++			ret = cmd_list[i].cmd_runner(argc, argv);
++ 			valid_cmd = 1;
++ 		}
++ 	}
++@@ -201,64 +220,86 @@ void parse_input_command(char *rl_cmd)
++ 		do_usage();
++ 	}
++ 	free(cmd);
+++
+++	/* ret==0 means we can return immediately to command-line input */
+++	if (ret == 0) {
+++		resume_kb_input(ret);
+++	}
++ }
++ 
++ 
++ 
++-static void run_up_cmd(int argc, char **argv)
+++static int run_up_cmd(int argc, char **argv)
++ {
++ 	int partition;
++ 	int num_nodes;
++ 	int *nodelist;
++ 	int i,j;
+++	int succeeded = 0;
++ 
++ 	if (argc <= 1) {
++-		return;
+++		return 0;
++ 	}
++ 
+++	cmd_start_sync_command();
+++
++ 	for (i=1; i<argc; i++) {
++ 		if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
++ 			for (j=0; j<num_nodes; j++) {
++-				cmd_start_new_node(nodelist[j], partition);
+++				if (!cmd_start_new_node(nodelist[j], partition)) {
+++					succeeded++;
+++				}
++ 			}
++ 			free(nodelist);
++ 		}
++ 	}
+++	return succeeded;
++ }
++ 
++-static void run_down_cmd(int argc, char **argv)
+++static int run_down_cmd(int argc, char **argv)
++ {
++ 	int nodeid;
++ 	int i;
+++	int succeeded = 0;
+++
+++	cmd_start_sync_command();
++ 
++ 	for (i=1; i<argc; i++) {
++ 		nodeid = atoi(argv[1]);
++-		cmd_stop_node(nodeid);
+++		if (!cmd_stop_node(nodeid)) {
+++			succeeded++;
+++		}
++ 	}
+++	return succeeded;
++ }
++ 
++-static void run_join_cmd(int argc, char **argv)
+++static int run_join_cmd(int argc, char **argv)
++ {
++ 	int i;
++ 
++ 	if (argc < 2) {
++ 		printf("join needs at least two partition numbers\n");
++-		return;
+++		return 0;
++ 	}
++ 
+++	cmd_start_sync_command();
+++
++ 	for (i=2; i<argc; i++) {
++ 		cmd_join_partitions(atoi(argv[1]), atoi(argv[i]));
++ 	}
++ 	cmd_update_all_partitions(1);
+++	return 1;
++ }
++ 
++-static void run_move_cmd(int argc, char **argv)
+++static int run_move_cmd(int argc, char **argv)
++ {
++ 	int i;
++ 	int partition;
++ 	int num_nodes;
++ 	int *nodelist;
++ 
+++	cmd_start_sync_command();
+++
++ 	for (i=1; i<argc; i++) {
++ 		if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
++ 			cmd_move_nodes(partition, num_nodes, nodelist);
++@@ -266,9 +307,10 @@ static void run_move_cmd(int argc, char **argv)
++ 		}
++ 	}
++ 	cmd_update_all_partitions(1);
+++	return 1;
++ }
++ 
++-static void run_autofence_cmd(int argc, char **argv)
+++static int run_autofence_cmd(int argc, char **argv)
++ {
++ 	int onoff = -1;
++ 
++@@ -284,9 +326,10 @@ static void run_autofence_cmd(int argc, char **argv)
++ 	else {
++ 		cmd_set_autofence(onoff);
++ 	}
+++	return 0;
++ }
++ 
++-static void run_qdevice_cmd(int argc, char **argv)
+++static int run_qdevice_cmd(int argc, char **argv)
++ {
++ 	int i,j;
++ 	int partition;
++@@ -303,7 +346,7 @@ static void run_qdevice_cmd(int argc, char **argv)
++ 
++ 	if (onoff == -1) {
++ 		fprintf(stderr, "ERR: qdevice should be 'on' or 'off'\n");
++-		return;
+++		return 0;
++ 	}
++ 
++ 	for (i=2; i<argc; i++) {
++@@ -315,17 +358,61 @@ static void run_qdevice_cmd(int argc, char **argv)
++ 		}
++ 	}
++ 	cmd_update_all_partitions(0);
+++	return 0;
++ }
++ 
++-static void run_show_cmd(int argc, char **argv)
+++static int run_show_cmd(int argc, char **argv)
++ {
++ 	cmd_show_node_states();
+++	return 0;
++ }
++ 
++-static void run_exit_cmd(int argc, char **argv)
+++static int run_timeout_cmd(int argc, char **argv)
++ {
++-	cmd_stop_all_nodes();
++-	exit(0);
+++	cmd_set_timeout(atol(argv[1]));
+++	return 0;
+++}
+++
+++static int run_sync_cmd(int argc, char **argv)
+++{
+++	int onoff = -1;
+++
+++	if (strcasecmp(argv[1], "on") == 0) {
+++		onoff = 1;
+++	}
+++	if (strcasecmp(argv[1], "off") == 0) {
+++		onoff = 0;
+++	}
+++	if (onoff == -1) {
+++		fprintf(stderr, "ERR: sync value must be 'on' or 'off'\n");
+++	}
+++	else {
+++		cmd_set_sync(onoff);
+++	}
+++	return 0;
++ }
++ 
+++static int run_assert_cmd(int argc, char **argv)
+++{
+++	int onoff = -1;
++ 
+++	if (strcasecmp(argv[1], "on") == 0) {
+++		onoff = 1;
+++	}
+++	if (strcasecmp(argv[1], "off") == 0) {
+++		onoff = 0;
+++	}
+++	if (onoff == -1) {
+++		fprintf(stderr, "ERR: assert value must be 'on' or 'off'\n");
+++	}
+++	else {
+++		cmd_set_assert(onoff);
+++	}
+++	return 0;
+++}
+++
+++static int run_exit_cmd(int argc, char **argv)
+++{
+++	cmd_stop_all_nodes();
+++	exit(0);
+++}
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index c3a1327..0eca43c 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -25,6 +25,7 @@
++ /* Easier than including the config file with a ton of conflicting dependencies */
++ extern int coroparse_configparse (icmap_map_t config_map, const char **error_string);
++ extern int corosync_log_config_read (const char **error_string);
+++static int stdin_read_fn(int32_t fd, int32_t revents, void *data);
++ 
++ /* 'Keep the compiler happy' time */
++ const char *corosync_get_config_file(void);
++@@ -56,21 +57,22 @@ static qb_loop_t *poll_loop;
++ static int autofence;
++ static int check_for_quorum;
++ static FILE *output_file;
++-static int nosync;
+++static int sync_cmds = 1;
++ static qb_loop_timer_handle kb_timer;
++-static ssize_t wait_count;
++-static ssize_t wait_count_to_unblock;
+++static int waiting_for_sync = 0;
+++static int is_tty;
+++static int assert_on_timeout;
+++static uint64_t command_timeout = 250000000L;
++ 
++ static struct vq_node *find_by_pid(pid_t pid);
++ static void send_partition_to_nodes(struct vq_partition *partition, int newring);
++-static void start_kb_input(void);
++ static void start_kb_input_timeout(void *data);
+++static void finish_wait_timeout(void *data);
++ 
++ #ifndef HAVE_READLINE_READLINE_H
++ #define INPUT_BUF_SIZE 1024
++ static char input_buf[INPUT_BUF_SIZE];
++ static size_t input_buf_term = 0;
++-static int is_tty;
++ #endif
++ 
++ /* 'Keep the compiler happy' time */
++@@ -78,7 +80,6 @@ static char corosync_config_file[PATH_MAX + 1] = COROSYSCONFDIR "/corosync.conf"
++ 
++ const char *corosync_get_config_file(void)
++ {
++-
++ 	return (corosync_config_file);
++ }
++ 
++@@ -144,6 +145,65 @@ static void propogate_vq_message(struct vq_node *vqn, const char *msg, int len)
++ 	}
++ }
++ 
+++
+++static void cmd_show_prompt_if_needed(void)
+++{
+++	qb_loop_timer_del(poll_loop, kb_timer);
+++	if (is_tty) {
+++		printf("vqsim> ");
+++		fflush(stdout);
+++	} else {
+++		printf("#vqsim> ");
+++		fflush(stdout);
+++	}
+++
+++}
+++
+++void resume_kb_input(int show_status)
+++{
+++	/* If running synchronously, we don't display
+++	   the quorum messages as they come in. So run 'show' commamnd
+++	*/
+++	if (show_status && waiting_for_sync) {
+++		cmd_show_node_states();
+++	}
+++
+++	waiting_for_sync = 0;
+++
+++	if (qb_loop_poll_add(poll_loop,
+++			     QB_LOOP_MED,
+++			     STDIN_FILENO,
+++			     POLLIN | POLLERR,
+++			     NULL,
+++			     stdin_read_fn)) {
+++		if (errno != EEXIST) {
+++			perror("qb_loop_poll_add1 returned error");
+++		}
+++	}
+++	/* Always shows the prompt here, cos we cleared waiting_for_sync */
+++	cmd_show_prompt_if_needed();
+++}
+++
+++/* Return true (1) if all nodes in each partition have the same ring id, false(0) otherwise */
+++static int all_nodes_consistent(void)
+++{
+++	int i;
+++	struct vq_node *vqn;
+++	struct memb_ring_id last_ring_id;
+++
+++	for (i=0; i<MAX_PARTITIONS; i++) {
+++		memset(&last_ring_id, 0, sizeof(last_ring_id));
+++		TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
+++			if (last_ring_id.seq &&
+++			    last_ring_id.seq != vqn->last_ring_id.seq) {
+++				return 0;
+++			}
+++			last_ring_id.seq = vqn->last_ring_id.seq;
+++		}
+++	}
+++	return 1;
+++}
+++
++ static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
++ {
++ 	char msgbuf[8192];
++@@ -162,13 +222,18 @@ static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
++ 			msg = (void*)msgbuf;
++ 			switch (msg->type) {
++ 			case VQMSG_QUORUM:
++-				if (!nosync && --wait_count_to_unblock <= 0)
++-					qb_loop_timer_del(poll_loop, kb_timer);
++ 				qmsg = (void*)msgbuf;
++ 				save_quorum_state(vqn, qmsg);
++-				print_quorum_state(vqn);
++-				if (!nosync && wait_count_to_unblock <= 0)
++-					start_kb_input();
+++				if (!sync_cmds) {
+++					print_quorum_state(vqn);
+++				}
+++
+++				/* Have the partitions stabilised? */
+++				if (sync_cmds && waiting_for_sync &&
+++				    all_nodes_consistent()) {
+++					qb_loop_timer_del(poll_loop, kb_timer);
+++					resume_kb_input(sync_cmds);
+++				}
++ 				break;
++ 			case VQMSG_EXEC:
++ 				/* Message from votequorum, pass around the partition */
++@@ -204,7 +269,7 @@ static int read_corosync_conf(void)
++ 	logsys_format_set(NULL);
++ 	res = coroparse_configparse(icmap_get_global_map(), &error_string);
++ 	if (res == -1) {
++-		log_printf (LOGSYS_LEVEL_INFO, "Error loading corosyc.conf %s", error_string);
+++		log_printf (LOGSYS_LEVEL_INFO, "Error loading corosync.conf %s", error_string);
++ 		return -1;
++ 	}
++ 	else {
++@@ -234,8 +299,6 @@ static void remove_node(struct vq_node *node)
++ 	TAILQ_REMOVE(&part->nodelist, node, entries);
++ 	free(node);
++ 
++-	wait_count--;
++-
++ 	/* Rebuild quorum */
++ 	send_partition_to_nodes(part, 1);
++ }
++@@ -263,7 +326,7 @@ static int32_t sigchld_handler(int32_t sig, void *data)
++ 				sprintf(text, "(exit code %d)", WEXITSTATUS(status));
++ 				break;
++ 			}
++-			printf("%d:%02d Quit %s\n", vqn->partition->num, vqn->nodeid, exit_status);
+++			printf("%d:%02d: Quit %s\n", vqn->partition->num, vqn->nodeid, exit_status);
++ 
++ 			remove_node(vqn);
++ 		}
++@@ -322,20 +385,24 @@ static void init_partitions(void)
++ 	}
++ }
++ 
+++static int nodes_in_partition(int part)
+++{
+++	struct vq_node *vqn;
+++	int partnodes = 0;
+++
+++	TAILQ_FOREACH(vqn, &partitions[part].nodelist, entries) {
+++		partnodes++;
+++	}
+++	return partnodes;
+++}
+++
+++
++ static pid_t create_node(int nodeid, int partno)
++ {
++ 	struct vq_node *newvq;
++ 
++ 	newvq = malloc(sizeof(struct vq_node));
++ 	if (newvq) {
++-		if (!nosync) {
++-			/* Number of expected "quorum" vq messages is a square
++-			   of the total nodes count, so increment the node
++-			   counter and set new square of this value as
++-			   a "to observe" counter */
++-			wait_count++;
++-			wait_count_to_unblock = wait_count * wait_count;
++-		}
++ 		newvq->last_quorate = -1;  /* mark "uninitialized" */
++ 		newvq->instance = vq_create_instance(poll_loop, nodeid);
++ 		if (!newvq->instance) {
++@@ -439,29 +506,39 @@ static struct vq_node *find_by_pid(pid_t pid)
++ }
++ 
++ /* Routines called from the parser */
++-void cmd_start_new_node(int nodeid, int partition)
+++
+++
+++/*
+++ * The parser calls this before running a command where
+++ * we might have to wait for a result to come back.
+++ */
+++void cmd_start_sync_command()
+++{
+++	if (sync_cmds) {
+++		qb_loop_poll_del(poll_loop, STDIN_FILENO);
+++		qb_loop_timer_add(poll_loop,
+++				  QB_LOOP_MED,
+++				  command_timeout,
+++				  NULL,
+++				  finish_wait_timeout,
+++				  &kb_timer);
+++		waiting_for_sync = 1;
+++	}
+++}
+++
+++int cmd_start_new_node(int nodeid, int partition)
++ {
++ 	struct vq_node *node;
++ 
++ 	node = find_node(nodeid);
++ 	if (node) {
++ 		fprintf(stderr, "ERR: nodeid %d already exists in partition %d\n", nodeid, node->partition->num);
++-		return;
+++		return -1;
++ 	}
++-	qb_loop_poll_del(poll_loop, STDIN_FILENO);
++-	create_node(nodeid, partition);
++-	if (!nosync) {
++-		/* Delay kb input handling by 0.25 second when we've just
++-		   added a node; expect that the delay will be cancelled
++-		   substantially earlier once it has reported its quorum info
++-		   (the delay is in fact a failsafe input enabler here) */
++-		qb_loop_timer_add(poll_loop,
++-				  QB_LOOP_MED,
++-				  250000000,
++-				  NULL,
++-				  start_kb_input_timeout,
++-				  &kb_timer);
+++	if (create_node(nodeid, partition) == -1) {
+++		return -1;
++ 	}
+++	return 0;
++ }
++ 
++ void cmd_stop_all_nodes()
++@@ -489,20 +566,21 @@ void cmd_show_node_states()
++ 	fprintf(output_file, "#autofence: %s\n", autofence?"on":"off");
++ }
++ 
++-void cmd_stop_node(int nodeid)
+++int cmd_stop_node(int nodeid)
++ {
++ 	struct vq_node *node;
++ 
++ 	node = find_node(nodeid);
++ 	if (!node) {
++ 		fprintf(stderr, "ERR: nodeid %d is not up\n", nodeid);
++-		return;
+++		return -1;
++ 	}
++ 
++ 	/* Remove processor */
++ 	vq_quit(node->instance);
++ 
++ 	/* Node will be removed when the child process exits */
+++	return 0;
++ }
++ 
++ /* Move all nodes in 'nodelist' into partition 'partition' */
++@@ -510,6 +588,13 @@ void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
++ {
++ 	int i;
++ 	struct vq_node *node;
+++	struct vq_node *vqn;
+++	int total_nodes = num_nodes;
+++
+++	/* Work out the number of nodes affected */
+++	TAILQ_FOREACH(vqn, &partitions[partition].nodelist, entries) {
+++		total_nodes++;
+++	}
++ 
++ 	for (i=0; i<num_nodes; i++) {
++ 		node = find_node(nodelist[i]);
++@@ -532,6 +617,11 @@ void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
++ void cmd_join_partitions(int part1, int part2)
++ {
++ 	struct vq_node *vqn;
+++	int total_nodes=0;
+++
+++	/* Work out the number of nodes affected */
+++	total_nodes += nodes_in_partition(part1);
+++	total_nodes += nodes_in_partition(part2);
++ 
++ 	/* TAILQ_FOREACH is not delete safe *sigh* */
++ retry:
++@@ -551,6 +641,18 @@ void cmd_set_autofence(int onoff)
++ 	fprintf(output_file, "#autofence: %s\n", onoff?"on":"off");
++ }
++ 
+++void cmd_set_sync(int onoff)
+++{
+++	autofence = onoff;
+++	fprintf(output_file, "#sync: %s\n", onoff?"on":"off");
+++	sync_cmds = onoff;
+++}
+++
+++void cmd_set_assert(int onoff)
+++{
+++	assert_on_timeout = onoff;
+++}
+++
++ void cmd_update_all_partitions(int newring)
++ {
++ 	int i;
++@@ -571,6 +673,24 @@ void cmd_qdevice_poll(int nodeid, int onoff)
++ 	}
++ }
++ 
+++/* If we get called then a command has timed-out */
+++static void finish_wait_timeout(void *data)
+++{
+++	if (command_timeout) {
+++		fprintf(stderr, "ERR: Partition(s) not stable within timeout\n");
+++		if (assert_on_timeout) {
+++			exit(2);
+++		}
+++	}
+++
+++	resume_kb_input(sync_cmds);
+++}
+++
+++void cmd_set_timeout(uint64_t seconds)
+++{
+++	command_timeout = seconds * QB_TIME_NS_IN_MSEC;
+++}
+++
++ /* ---------------------------------- */
++ 
++ #ifndef HAVE_READLINE_READLINE_H
++@@ -598,11 +718,6 @@ static void dummy_read_char()
++ 
++ 	parse_input_command((c == EOF) ? NULL : input_buf);
++ 	input_buf_term = 0;
++-
++-	if (is_tty) {
++-		printf("vqsim> ");
++-		fflush(stdout);
++-	}
++ }
++ #endif
++ 
++@@ -617,50 +732,26 @@ static int stdin_read_fn(int32_t fd, int32_t revents, void *data)
++ 	return 0;
++ }
++ 
++-static void start_kb_input(void)
++-{
++-	wait_count_to_unblock = 0;
++-
++-#ifdef HAVE_READLINE_READLINE_H
++-	/* Readline will deal with completed lines when they arrive */
++-	rl_callback_handler_install("vqsim> ", parse_input_command);
++-#else
++-	if (is_tty) {
++-		printf("vqsim> ");
++-		fflush(stdout);
++-	}
++-#endif
++-
++-	/* Send stdin to readline */
++-	if (qb_loop_poll_add(poll_loop,
++-			     QB_LOOP_MED,
++-			     STDIN_FILENO,
++-			     POLLIN | POLLERR,
++-			     NULL,
++-			     stdin_read_fn)) {
++-		if (errno != EEXIST) {
++-			perror("qb_loop_poll_add1 returned error");
++-		}
++-	}
++-}
++ 
++ static void start_kb_input_timeout(void *data)
++ {
++-//	fprintf(stderr, "Waiting for nodes to report status timed out\n");
++-	start_kb_input();
+++	resume_kb_input(1);
++ }
++ 
++ static void usage(char *program)
++ {
++ 	printf("Usage:\n");
++ 	printf("\n");
++-	printf("%s [-f <config-file>] [-o <output-file>]\n", program);
+++	printf("%s [-c <config-file>] [-o <output-file>]\n", program);
++ 	printf("\n");
++-	printf("    -f     config file. defaults to /etc/corosync/corosync.conf\n");
+++	printf("    -c     config file. defaults to /etc/corosync/corosync.conf\n");
++ 	printf("    -o     output file. defaults to stdout\n");
++ 	printf("    -n     no synchronization (on adding a node)\n");
++ 	printf("    -h     display this help text\n");
++ 	printf("\n");
+++	printf("%s always takes input from STDIN, but cannot use a file.\n", program);
+++	printf("If you want to script it then use\n cat | %s\n", program);
+++	printf("\n");
++ }
++ 
++ int main(int argc, char **argv)
++@@ -669,16 +760,16 @@ int main(int argc, char **argv)
++ 	int ch;
++ 	char *output_file_name = NULL;
++ 
++-	while ((ch = getopt (argc, argv, "f:o:nh")) != EOF) {
+++	while ((ch = getopt (argc, argv, "c:o:nh")) != EOF) {
++ 		switch (ch) {
++-		case 'f':
+++		case 'c':
++ 			strncpy(corosync_config_file, optarg, sizeof(corosync_config_file));
++ 			break;
++ 		case 'o':
++ 			output_file_name = optarg;
++ 			break;
++ 		case 'n':
++-			nosync = 1;
+++			sync_cmds = 0;
++ 			break;
++ 		default:
++ 			usage(argv[0]);
++@@ -696,9 +787,8 @@ int main(int argc, char **argv)
++ 	else {
++ 		output_file = stdout;
++ 	}
++-#ifndef HAVE_READLINE_READLINE_H
+++
++ 	is_tty = isatty(STDIN_FILENO);
++-#endif
++ 
++ 	qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
++ 			  QB_LOG_FILTER_FUNCTION, "*", LOG_DEBUG);
++@@ -717,9 +807,26 @@ int main(int argc, char **argv)
++ 			   sigchld_handler,
++ 			   &sigchld_qb_handle);
++ 
++-	/* Create a full cluster of nodes from corosync.conf */
+++
+++#ifdef HAVE_READLINE_READLINE_H
+++	/* Readline will deal with completed lines when they arrive */
+++	/*
+++	 * For scripting add '#' to the start of the prompt so that
+++	 * parsers can ignore input lines
+++	 */
+++	rl_already_prompted = 1;
+++	if (is_tty) {
+++		rl_callback_handler_install("vqsim> ", parse_input_command);
+++	} else {
+++		rl_callback_handler_install("#vqsim> ", parse_input_command);
+++	}
+++#endif
+++
+++
+++
+++/* Create a full cluster of nodes from corosync.conf */
++ 	read_corosync_conf();
++-	if (create_nodes_from_config() && !nosync) {
+++	if (create_nodes_from_config() && sync_cmds) {
++ 		/* Delay kb input handling by 1 second when we've just
++ 		   added the nodes from corosync.conf; expect that
++ 		   the delay will be cancelled substantially earlier
++@@ -731,8 +838,9 @@ int main(int argc, char **argv)
++ 				  NULL,
++ 				  start_kb_input_timeout,
++ 				  &kb_timer);
+++		waiting_for_sync = 1;
++ 	} else {
++-		start_kb_input();
+++		resume_kb_input(0);
++ 	}
++ 
++ 	qb_loop_run(poll_loop);
++diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
++index cbe1d47..eb35d35 100644
++--- a/vqsim/vqsim_vq_engine.c
+++++ b/vqsim/vqsim_vq_engine.c
++@@ -191,6 +191,7 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
++ 	uint32_t nodeid;
++ 	const char *iter_key;
++ 	int res;
+++	int found = 0;
++ 
++ 	iter = icmap_iter_init("nodelist.node.");
++ 	while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
++@@ -205,13 +206,18 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
++ 		res = icmap_get_uint32(iter_key, &nodeid);
++ 		if (res == CS_OK) {
++ 			if (nodeid == our_nodeid) {
+++				found = 1;
++ 				res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
++-				if (res != CS_OK) {
++-					fprintf(stderr, "Failed to find node %d in corosync.conf. Quorum calculations may not be correct:\n", our_nodeid);
++-				}
++ 			}
++ 		}
++ 	}
+++	if (!found) {
+++		/* This probably indicates a dynamically-added node
+++		 * set the pos to zero and use the votes of the
+++		 * first node in corosync.conf
+++		 */
+++		res = icmap_set_uint32("nodelist.local_node_pos", 0);
+++	}
++ }
++ 
++ static int load_quorum_instance(struct corosync_api_v1 *api)
++diff --git a/man/corosync-vqsim.8 b/man/corosync-vqsim.8
++new file mode 100644
++index 0000000..26a6468
++--- /dev/null
+++++ b/man/corosync-vqsim.8
++@@ -0,0 +1,94 @@
+++.\"/*
+++.\" * Copyright (C) 2019 Red Hat, Inc.
+++.\" *
+++.\" * All rights reserved.
+++.\" *
+++.\" * Author: Christine Caulfield <ccaulfie at redhat.com>
+++.\" *
+++.\" * This software licensed under BSD license, the text of which follows:
+++.\" *
+++.\" * Redistribution and use in source and binary forms, with or without
+++.\" * modification, are permitted provided that the following conditions are met:
+++.\" *
+++.\" * - Redistributions of source code must retain the above copyright notice,
+++.\" *   this list of conditions and the following disclaimer.
+++.\" * - Redistributions in binary form must reproduce the above copyright notice,
+++.\" *   this list of conditions and the following disclaimer in the documentation
+++.\" *   and/or other materials provided with the distribution.
+++.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+++.\" *   contributors may be used to endorse or promote products derived from this
+++.\" *   software without specific prior written permission.
+++.\" *
+++.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+++.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+++.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+++.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+++.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+++.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+++.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+++.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+++.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+++.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+++.\" * THE POSSIBILITY OF SUCH DAMAGE.
+++.\" */
+++.TH COROSYNC-VQSIM 8 2019-05-10
+++.SH NAME
+++corosync-vqsim \- The votequorum simulator
+++.SH SYNOPSIS
+++.B "corosync-vqsim [\-c config_file] [\-o output file] [\-n] [\-h]"
+++.SH DESCRIPTION
+++.B corosync-vqsim
+++simulates the quorum functions of corosync in a single program. it can simulate
+++multiple nodes, network splits and a basic quorum device.
+++
+++By default vqsim will build a virtual cluster of all the nodes in the corosync.conf file,
+++each 'node' running in a forked subprocess (and thus asynchronously). It then provides a
+++command-line interface to add (up) or remove (down) nodes, and cause network splits and
+++rejoins. After each event it shows the new quorum status for all nodes.
+++
+++Nodes in vqsim are always referred to by their nodeid (the IP address is meaningless) and
+++optionally by a 'partition' which precedes the nodeid with a colon. By default all nodes
+++are in partition 0. Nodes can be moved between partitions using the split and join commands.
+++Multiple nodes can be split and joined at the same time.
+++
+++To script vqsim you must send input to it via a pipe rather than just redirecting STDIN. This
+++is because it runs asynchronously to enable the virtual 'nodes' to report status when needed.
+++(eg if you kill a subprocess using the 'kill(1)' command it gets removed from the cluster).
+++
+++By default vqsim will wait for all nodes in all partitions to reach the same
+++ring sequence number before returning a prompt,
+++there is a timeout associated with this in case of a 'node' failure and exceeding this timeout
+++can (optionally) quit the program signalling an error.
+++
+++You can disable waiting using the 'sync off' command or the -n command-line option. This can easily
+++cause unexpected behaviour so use it with care.
+++
+++The number of votes per node is read from corosync.conf. New nodes added using the 'up' command
+++will copy their number of votes from the first node in corosync.conf. This may not be what you
+++expect and I might fix it in future. As most clusters have only 1 vote per node (and this is
+++strongly recommended) then this should rarely be a problem.
+++
+++Once you have the 'vqsim> ' prompt you can type 'help' and get a list of sub-commands.
+++
+++.SH OPTIONS
+++.TP
+++.B -c
+++This specifies the fully qualified path to the corosync configuration file.
+++
+++The default is /etc/corosync/corosync.conf.
+++.TP
+++.B -o
+++Specifies the output destination. STDOUT by default.
+++.TP
+++.B -n
+++Don't pause after each command, come straight back to a prompt. Use with care!
+++
+++.TP
+++.B -h
+++Display a brief help message
+++.SH SEE ALSO
+++.BR corosync (9),
+++.BR corosync.conf (5),
+++.SH AUTHOR
+++Christine Caulfield
+++.PP
+diff --git a/debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch b/debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch
+new file mode 100644
+index 00000000..36f686c9
+--- /dev/null
++++ b/debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch
+@@ -0,0 +1,102 @@
++From: Christine Caulfield <ccaulfie at redhat.com>
++Date: Thu, 25 Apr 2019 14:38:52 +0100
++Subject: vqsim: Fix vqsim for corosync 3.0
++
++A couple of small internal changes in corosync 3.0 broke vqsim.
++1) The way the custom config file is specified (no long an env variable)
++2) votequorum now needs to know ouZ_node_pos
++
++Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
++Reviewed-by: Jan Friesse <jfriesse at redhat.com>
++(cherry picked from commit e65d7b5d9800df96dcc8b5d6216a85800113924c)
++---
++ vqsim/vqmain.c          |  8 +-------
++ vqsim/vqsim_vq_engine.c | 37 +++++++++++++++++++++++++++++++++++++
++ 2 files changed, 38 insertions(+), 7 deletions(-)
++
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index 683cc22..c3a1327 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -667,14 +667,12 @@ int main(int argc, char **argv)
++ {
++ 	qb_loop_signal_handle sigchld_qb_handle;
++ 	int ch;
++-	char *config_file_name = NULL;
++ 	char *output_file_name = NULL;
++-	char envstring[PATH_MAX];
++ 
++ 	while ((ch = getopt (argc, argv, "f:o:nh")) != EOF) {
++ 		switch (ch) {
++ 		case 'f':
++-			config_file_name = optarg;
+++			strncpy(corosync_config_file, optarg, sizeof(corosync_config_file));
++ 			break;
++ 		case 'o':
++ 			output_file_name = optarg;
++@@ -688,10 +686,6 @@ int main(int argc, char **argv)
++ 		}
++ 	}
++ 
++-	if (config_file_name) {
++-		sprintf(envstring, "COROSYNC_MAIN_CONFIG_FILE=%s", config_file_name);
++-		putenv(envstring);
++-	}
++ 	if (output_file_name) {
++ 		output_file = fopen(output_file_name, "w");
++ 		if (!output_file) {
++diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
++index 9d8b4ee..cbe1d47 100644
++--- a/vqsim/vqsim_vq_engine.c
+++++ b/vqsim/vqsim_vq_engine.c
++@@ -178,6 +178,42 @@ char *get_run_dir()
++ 	return getcwd(cwd_buffer, PATH_MAX);
++ }
++ 
+++/* This is different to the one in totemconfig.c in that we already
+++ * know the 'local' node ID, so we can just search for that.
+++ * It needs to be here rather than at main config read time as it's
+++ * (obviously) going to be different for each instance.
+++ */
+++static void set_local_node_pos(struct corosync_api_v1 *api)
+++{
+++	icmap_iter_t iter;
+++	uint32_t node_pos;
+++	char name_str[ICMAP_KEYNAME_MAXLEN];
+++	uint32_t nodeid;
+++	const char *iter_key;
+++	int res;
+++
+++	iter = icmap_iter_init("nodelist.node.");
+++	while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
+++		res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, name_str);
+++		if (res != 2) {
+++			continue;
+++		}
+++		if (strcmp(name_str, "nodeid")) {
+++			continue;
+++		}
+++
+++		res = icmap_get_uint32(iter_key, &nodeid);
+++		if (res == CS_OK) {
+++			if (nodeid == our_nodeid) {
+++				res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
+++				if (res != CS_OK) {
+++					fprintf(stderr, "Failed to find node %d in corosync.conf. Quorum calculations may not be correct:\n", our_nodeid);
+++				}
+++			}
+++		}
+++	}
+++}
+++
++ static int load_quorum_instance(struct corosync_api_v1 *api)
++ {
++ 	const char *error_string;
++@@ -417,6 +453,7 @@ int fork_new_instance(int nodeid, int *vq_sock, pid_t *childpid)
++ 		qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
++ 	}
++ 
+++	set_local_node_pos(&corosync_api);
++ 	load_quorum_instance(&corosync_api);
++ 
++ 	qb_loop_poll_add(poll_loop,
+diff --git a/debian/patches/vqsim-Free-allocated-newvq-on-error.patch b/debian/patches/vqsim-Free-allocated-newvq-on-error.patch
+new file mode 100644
+index 00000000..cfa9a763
+--- /dev/null
++++ b/debian/patches/vqsim-Free-allocated-newvq-on-error.patch
+@@ -0,0 +1,23 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 14:50:03 +0200
++Subject: vqsim: Free allocated newvq on error
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit 215d2e30b20d5167161a2d803284f2b0ecf67c29)
++---
++ vqsim/vqmain.c | 1 +
++ 1 file changed, 1 insertion(+)
++
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index 98729b9..d45a24d 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -425,6 +425,7 @@ static pid_t create_node(int nodeid, int partno)
++ 			fprintf(stderr,
++ 			        "ERR: could not create vq instance nodeid %d\n",
++ 				nodeid);
+++			free(newvq);
++ 			return (pid_t) -1;
++ 		}
++ 		newvq->partition = &partitions[partno];
+diff --git a/debian/patches/vqsim-Make-vqsim-compile.patch b/debian/patches/vqsim-Make-vqsim-compile.patch
+new file mode 100644
+index 00000000..766ab88b
+--- /dev/null
++++ b/debian/patches/vqsim-Make-vqsim-compile.patch
+@@ -0,0 +1,131 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 23 Apr 2019 16:48:30 +0200
++Subject: vqsim: Make vqsim compile
++
++Also add vqsim binary to .gitignore.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit e287a7c1efd37732d2bd3309a1d7d23a303f8640)
++---
++ vqsim/Makefile.am       |  1 +
++ vqsim/vqmain.c          | 19 ++++++++++++++++---
++ vqsim/vqsim_vq_engine.c |  5 +++--
++ vqsim/.gitignore        |  1 +
++ 4 files changed, 21 insertions(+), 5 deletions(-)
++ create mode 100644 vqsim/.gitignore
++
++diff --git a/vqsim/Makefile.am b/vqsim/Makefile.am
++index b74826b..2a76544 100644
++--- a/vqsim/Makefile.am
+++++ b/vqsim/Makefile.am
++@@ -39,6 +39,7 @@ noinst_PROGRAMS		= vqsim
++ vqsim_LDADD		= $(top_builddir)/common_lib/libcorosync_common.la \
++ 			  ../exec/corosync-votequorum.o ../exec/corosync-icmap.o ../exec/corosync-logsys.o \
++ 			  ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
+++			  ../exec/corosync-util.o \
++ 			  $(LIBQB_LIBS)
++ if VQSIM_READLINE
++ vqsim_LDADD		+= -lreadline
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index e7917d7..683cc22 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -26,6 +26,9 @@
++ extern int coroparse_configparse (icmap_map_t config_map, const char **error_string);
++ extern int corosync_log_config_read (const char **error_string);
++ 
+++/* 'Keep the compiler happy' time */
+++const char *corosync_get_config_file(void);
+++
++ /* One of these per partition */
++ struct vq_partition {
++ 	TAILQ_HEAD(, vq_node) nodelist;
++@@ -70,6 +73,15 @@ static size_t input_buf_term = 0;
++ static int is_tty;
++ #endif
++ 
+++/* 'Keep the compiler happy' time */
+++static char corosync_config_file[PATH_MAX + 1] = COROSYSCONFDIR "/corosync.conf";
+++
+++const char *corosync_get_config_file(void)
+++{
+++
+++	return (corosync_config_file);
+++}
+++
++ /* Tell all non-quorate nodes to quit */
++ static void force_fence(void)
++ {
++@@ -110,7 +122,7 @@ static void print_quorum_state(struct vq_node *node)
++ 	}
++ 
++ 	fprintf(output_file, "%d:%02d: q=%d ring=[%d/%lld] ", node->partition->num, node->nodeid, node->last_quorate,
++-		node->last_ring_id.rep.nodeid, node->last_ring_id.seq);
+++		node->last_ring_id.nodeid, node->last_ring_id.seq);
++ 	fprintf(output_file, "nodes=[");
++ 	for (i = 0; i < node->last_view_list_entries; i++) {
++ 		if (i) {
++@@ -209,6 +221,7 @@ static int read_corosync_conf(void)
++ 	        log_printf (LOGSYS_LEVEL_ERROR, "Can't initialize log thread");
++ 		return -1;
++ 	}
+++
++ 	return 0;
++ }
++ 
++@@ -287,7 +300,7 @@ static void send_partition_to_nodes(struct vq_partition *partition, int newring)
++ 	TAILQ_FOREACH(vqn, &partition->nodelist, entries) {
++ 		nodelist[nodes++] = vqn->nodeid;
++ 		if (first) {
++-			partition->ring_id.rep.nodeid = vqn->nodeid;
+++			partition->ring_id.nodeid = vqn->nodeid;
++ 			first = 0;
++ 		}
++ 	}
++@@ -303,7 +316,7 @@ static void init_partitions(void)
++ 
++ 	for (i=0; i<MAX_PARTITIONS; i++) {
++ 		TAILQ_INIT(&partitions[i].nodelist);
++-		partitions[i].ring_id.rep.nodeid = 1000+i;
+++		partitions[i].ring_id.nodeid = 1000+i;
++ 		partitions[i].ring_id.seq = 0;
++ 		partitions[i].num = i;
++ 	}
++diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
++index ee139d4..9d8b4ee 100644
++--- a/vqsim/vqsim_vq_engine.c
+++++ b/vqsim/vqsim_vq_engine.c
++@@ -44,6 +44,7 @@ static unsigned int qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
++ 
++ /* 'Keep the compiler happy' time */
++ char *get_run_dir(void);
+++
++ int api_timer_add_duration (
++         unsigned long long nanosec_duration,
++         void *data,
++@@ -262,7 +263,7 @@ static int poll_qdevice(int onoff)
++ 	int res;
++ 
++ 	pollmsg.cast_vote = onoff;
++-	pollmsg.ring_id.nodeid = current_ring_id.rep.nodeid;
+++	pollmsg.ring_id.nodeid = current_ring_id.nodeid;
++ 	pollmsg.ring_id.seq = current_ring_id.seq;
++ 	strcpy(pollmsg.name, QDEVICE_NAME);
++ 
++@@ -374,7 +375,7 @@ static void initial_sync(int nodeid)
++ 	unsigned int member_list[1] = {nodeid};
++ 	struct memb_ring_id ring_id;
++ 
++-	ring_id.rep.nodeid = our_nodeid;
+++	ring_id.nodeid = our_nodeid;
++ 	ring_id.seq = 1;
++ 
++ 	/* cluster with just us in it */
++diff --git a/vqsim/.gitignore b/vqsim/.gitignore
++new file mode 100644
++index 0000000..85d30f9
++--- /dev/null
+++++ b/vqsim/.gitignore
++@@ -0,0 +1 @@
+++vqsim
+diff --git a/debian/patches/vqsim-Remove-unused-total_nodes.patch b/debian/patches/vqsim-Remove-unused-total_nodes.patch
+new file mode 100644
+index 00000000..a50c6d58
+--- /dev/null
++++ b/debian/patches/vqsim-Remove-unused-total_nodes.patch
+@@ -0,0 +1,62 @@
++From: Jan Friesse <jfriesse at redhat.com>
++Date: Tue, 11 Jun 2019 15:11:13 +0200
++Subject: vqsim: Remove unused total_nodes
++
++... and remove unused nodes_in_partition function.
++
++Also replace TAILQ_FOREACH with goto to while cycle.
++
++Signed-off-by: Jan Friesse <jfriesse at redhat.com>
++Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
++(cherry picked from commit ef9b931b7e2585ef87198693760df39d60e9f542)
++---
++ vqsim/vqmain.c | 25 ++-----------------------
++ 1 file changed, 2 insertions(+), 23 deletions(-)
++
++diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
++index d45a24d..16f7714 100644
++--- a/vqsim/vqmain.c
+++++ b/vqsim/vqmain.c
++@@ -401,18 +401,6 @@ static void init_partitions(void)
++ 	}
++ }
++ 
++-static int nodes_in_partition(int part)
++-{
++-	struct vq_node *vqn;
++-	int partnodes = 0;
++-
++-	TAILQ_FOREACH(vqn, &partitions[part].nodelist, entries) {
++-		partnodes++;
++-	}
++-	return partnodes;
++-}
++-
++-
++ static pid_t create_node(int nodeid, int partno)
++ {
++ 	struct vq_node *newvq;
++@@ -634,21 +622,12 @@ void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
++ void cmd_join_partitions(int part1, int part2)
++ {
++ 	struct vq_node *vqn;
++-	int total_nodes=0;
++-
++-	/* Work out the number of nodes affected */
++-	total_nodes += nodes_in_partition(part1);
++-	total_nodes += nodes_in_partition(part2);
++-
++-	/* TAILQ_FOREACH is not delete safe *sigh* */
++-retry:
++-	TAILQ_FOREACH(vqn, &partitions[part2].nodelist, entries) {
++ 
+++	while (!TAILQ_EMPTY(&partitions[part2].nodelist)) {
+++		vqn = TAILQ_FIRST(&partitions[part2].nodelist);
++ 		TAILQ_REMOVE(&vqn->partition->nodelist, vqn, entries);
++ 		TAILQ_INSERT_TAIL(&partitions[part1].nodelist, vqn, entries);
++ 		vqn->partition = &partitions[part1];
++-
++-		goto retry;
++ 	}
++ }
++ 
+diff --git a/debian/patches/series b/debian/patches/series
+index 6b552ce1..ea6e04ea 100644
+--- a/debian/patches/series
++++ b/debian/patches/series
+@@ -1,8 +1,53 @@
+-Fix-various-typos-in-ChangeLog.patch
+-Enable-PrivateTmp-in-the-systemd-service-files.patch
+-Make-the-example-config-valid.patch
++doc-Update-INSTALL-file.patch
++cfgtool-Improve-link-status-display.patch
+ corosync.conf.5-fix-grammar.patch
+ corosync.conf.5-typography-fixes.patch
+-AC_PROG_SED-is-already-present.patch
+-Use-the-SED-variable-provided-by-configure.patch
+-Use-the-AWK-variable-provided-by-configure.patch
++configure.ac-AC_PROG_SED-is-already-present.patch
++build-Use-the-SED-variable-provided-by-configure.patch
++build-Use-the-AWK-variable-provided-by-configure.patch
++corosync-cfgtool-Fix-i-matching.patch
++quorumtool-Fix-exit-status-codes.patch
++nozzle-Add-support-for-libnozzle-devices.patch
++configure-Do-not-autodetect-nozzle.patch
++coroparse-Fix-compiler-warning.patch
++totemsrp-Word-spelling-mistake.patch
++Revert-init-Enable-StopWhenUnneeded.patch
++set-totem.keyfile-and-totem.key-to-RO.patch
++keygen-Reflect-change-in-knet.patch
++totemconfig-Remove-support-for-3des.patch
++crypto-re-introduce-secauth-parameter.patch
++cpg-Add-CPG_REASON_UNDEFINED.patch
++totemconfig-ipaddr_equal-check-just-addr-part.patch
++vqsim-Make-vqsim-compile.patch
++vqsim-Fix-vqsim-for-corosync-3.0.patch
++totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
++totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
++knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
++vqsim-Enhance-vqsim.patch
++totemconfig-Fix-minimum-limit-for-hold-timeout.patch
++man-Enhance-token_retransmit-description.patch
++knet-allow-corosync-to-use-knet-access-lists.patch
++knet-Fix-initialising-of-knet-access-lists.patch
++udpu-Drop-packets-from-unlisted-IPs.patch
++knet-Use-block_unlisted_ips.patch
++cfgtool-Fix-link-status-display.patch
++man-Enhance-corosync.conf-mp-a-bit.patch
++man-Enahnce-block_unlisted_ips-description.patch
++spec-Add-support-for-user-flags-configure-option.patch
++man-Add-vqsim-man-page-into-distributed-tarball.patch
++configure-Fix-GDB_CFLAGS-typo.patch
++totemconfig-ipaddr_equal-use-switch.patch
++totemip-Use-res-in-totemip_sa_equal.patch
++totemknet-create_nozzle_device-simplify-check.patch
++totemknet-Ignore-icmap_get_string-result.patch
++totemknet-macaddr_str-is-always-set.patch
++totemknet-Initialize-return-value-in-setup_nozzle.patch
++vqsim-Do-not-access-unitialized-argv-0.patch
++vqsim-Check-write-result.patch
++vqsim-Check-length-of-received-message.patch
++vqsim-Free-allocated-newvq-on-error.patch
++vqsim-Remove-unused-total_nodes.patch
++vqsim-Check-result-of-icmap_set_uint32.patch
++vqsim-Check-length-of-copied-optarg.patch
++Fix-various-typos-in-ChangeLog.patch
++Enable-PrivateTmp-in-the-systemd-service-files.patch
diff --git a/patches/0001-don-t-install-default-corosync.conf.patch b/patches/0002-don-t-install-default-corosync.conf.patch
similarity index 88%
rename from patches/0001-don-t-install-default-corosync.conf.patch
rename to patches/0002-don-t-install-default-corosync.conf.patch
index e668016..dbcf22f 100644
--- a/patches/0001-don-t-install-default-corosync.conf.patch
+++ b/patches/0002-don-t-install-default-corosync.conf.patch
@@ -10,9 +10,8 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
 ---
  .../Make-the-example-config-valid.patch       | 64 -------------------
  debian/corosync.install                       |  2 +-
- debian/patches/series                         |  1 -
  debian/rules                                  |  3 -
- 4 files changed, 1 insertion(+), 69 deletions(-)
+ 3 files changed, 1 insertion(+), 68 deletions(-)
  delete mode 100644 debian/patches/Make-the-example-config-valid.patch
 
 diff --git a/debian/patches/Make-the-example-config-valid.patch b/debian/patches/Make-the-example-config-valid.patch
@@ -98,17 +97,6 @@ index bfaca759..c5b92661 100644
  etc/corosync/uidgid.d
  usr/share/corosync/xml2conf.xsl
  var/lib/corosync
-diff --git a/debian/patches/series b/debian/patches/series
-index 6b552ce1..41866b14 100644
---- a/debian/patches/series
-+++ b/debian/patches/series
-@@ -1,6 +1,5 @@
- Fix-various-typos-in-ChangeLog.patch
- Enable-PrivateTmp-in-the-systemd-service-files.patch
--Make-the-example-config-valid.patch
- corosync.conf.5-fix-grammar.patch
- corosync.conf.5-typography-fixes.patch
- AC_PROG_SED-is-already-present.patch
 diff --git a/debian/rules b/debian/rules
 index 52ff4699..50d89e2a 100755
 --- a/debian/rules
diff --git a/patches/0002-remove-init-script.patch b/patches/0003-remove-init-script.patch
similarity index 100%
rename from patches/0002-remove-init-script.patch
rename to patches/0003-remove-init-script.patch
diff --git a/patches/0005-cfgtool-Improve-link-status-display.patch b/patches/0005-cfgtool-Improve-link-status-display.patch
deleted file mode 100644
index 8315a27..0000000
--- a/patches/0005-cfgtool-Improve-link-status-display.patch
+++ /dev/null
@@ -1,240 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
-Date: Wed, 22 May 2019 12:24:45 +0200
-Subject: [PATCH] cfgtool: Improve link status display
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-cherry-picked from upstream master
-
-Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
----
- .../cfgtool-Fix-link-status-display.patch     |  65 +++++++++
- .../cfgtool-Improve-link-status-display.patch | 134 ++++++++++++++++++
- debian/patches/series                         |   2 +
- 3 files changed, 201 insertions(+)
- create mode 100644 debian/patches/cfgtool-Fix-link-status-display.patch
- create mode 100644 debian/patches/cfgtool-Improve-link-status-display.patch
-
-diff --git a/debian/patches/cfgtool-Fix-link-status-display.patch b/debian/patches/cfgtool-Fix-link-status-display.patch
-new file mode 100644
-index 00000000..37b8508c
---- /dev/null
-+++ b/debian/patches/cfgtool-Fix-link-status-display.patch
-@@ -0,0 +1,65 @@
-+From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
-+Date: Wed, 29 May 2019 14:57:09 +0200
-+Subject: cfgtool: Fix link status display
-+MIME-Version: 1.0
-+Content-Type: text/plain; charset="utf-8"
-+Content-Transfer-Encoding: 8bit
-+
-+instead of the nodeid, this displayed arbitrary values (usually '1')
-+from other cmap keys under nodelist.node.XX.
-+
-+sscanf returns the number of conversions even on mismatch, e.g. it also
-+returns 1 for
-+
-+nodelist.node.2.quorum_votes
-+nodelist.node.2.ring0_addr
-+nodelist.node.2.name
-+...
-+
-+instead of just
-+
-+nodelist.node.2.nodeid
-+
-+which leads to the value of (at least) quorum_votes being stored in
-+nodeid_list in addition to the actual nodeid.
-+
-+storing the returned int in a cs_error_t enum also potentially masks
-+errors, so just compare the result with the expectation directly.
-+
-+Fixes: c0d14485c3ebdeb2332f7c48acd155163e5b7fc1
-+
-+Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
-+Reviewed-by: Jan Friesse <jfriesse at redhat.com>
-+(cherry picked from commit ef2569d323c68633a63dc15e59805ec491b69348)
-+---
-+ tools/corosync-cfgtool.c | 10 +++++++---
-+ 1 file changed, 7 insertions(+), 3 deletions(-)
-+
-+diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
-+index ed29694..2808961 100644
-+--- a/tools/corosync-cfgtool.c
-++++ b/tools/corosync-cfgtool.c
-+@@ -100,7 +100,7 @@ linkstatusget_do (char *interface_name, int brief)
-+ 	unsigned int i;
-+ 	cmap_iter_handle_t iter;
-+ 	unsigned int nodeid;
-+-	unsigned int node_pos;
-++	int nodeid_match_guard;
-+ 	cmap_value_types_t type;
-+ 	size_t value_len;
-+ 	int rc = 0;
-+@@ -128,8 +128,12 @@ linkstatusget_do (char *interface_name, int brief)
-+ 	}
-+ 
-+ 	while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
-+-		result = sscanf(iter_key, "nodelist.node.%u.nodeid", &node_pos);
-+-		if (result != 1) {
-++		nodeid_match_guard = 0;
-++		if (sscanf(iter_key, "nodelist.node.%*u.nodeid%n", &nodeid_match_guard) != 0) {
-++			continue;
-++		}
-++		/* check for exact match */
-++		if (nodeid_match_guard != strlen(iter_key)) {
-+ 			continue;
-+ 		}
-+ 		if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
-diff --git a/debian/patches/cfgtool-Improve-link-status-display.patch b/debian/patches/cfgtool-Improve-link-status-display.patch
-new file mode 100644
-index 00000000..93ee9937
---- /dev/null
-+++ b/debian/patches/cfgtool-Improve-link-status-display.patch
-@@ -0,0 +1,134 @@
-+From: Christine Caulfield <ccaulfie at redhat.com>
-+Date: Tue, 22 Jan 2019 10:06:29 +0000
-+Subject: cfgtool: Improve link status display
-+
-+Now show the nodeids properly, rather than node indexes which were
-+annoying and unhelpful.
-+
-+Signed-off-by: Christine Caulfield <ccaulfie at redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse at redhat.com>
-+(cherry picked from commit c0d14485c3ebdeb2332f7c48acd155163e5b7fc1)
-+---
-+ tools/Makefile.am        |  2 +-
-+ tools/corosync-cfgtool.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
-+ 2 files changed, 55 insertions(+), 3 deletions(-)
-+
-+diff --git a/tools/Makefile.am b/tools/Makefile.am
-+index 7a9ab04..0793884 100644
-+--- a/tools/Makefile.am
-++++ b/tools/Makefile.am
-+@@ -58,7 +58,7 @@ corosync-blackbox: corosync-blackbox.sh
-+ 
-+ corosync_cmapctl_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcmap.la
-+ 
-+-corosync_cfgtool_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la
-++corosync_cfgtool_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcmap.la
-+ 
-+ corosync_cpgtool_LDADD	= $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la \
-+ 			  $(top_builddir)/lib/libcpg.la
-+diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
-+index c138085..ed29694 100644
-+--- a/tools/corosync-cfgtool.c
-++++ b/tools/corosync-cfgtool.c
-+@@ -50,6 +50,7 @@
-+ #include <corosync/corotypes.h>
-+ #include <corosync/totem/totem.h>
-+ #include <corosync/cfg.h>
-++#include <corosync/cmap.h>
-+ 
-+ #define cs_repeat(result, max, code)				\
-+ 	do {							\
-+@@ -75,16 +76,33 @@ enum user_action {
-+ 	ACTION_KILL_NODE,
-+ };
-+ 
-++static int node_compare(const void *aptr, const void *bptr)
-++{
-++	uint32_t a,b;
-++
-++	a = *(uint32_t *)aptr;
-++	b = *(uint32_t *)bptr;
-++
-++	return a > b;
-++}
-++
-+ static int
-+ linkstatusget_do (char *interface_name, int brief)
-+ {
-+ 	cs_error_t result;
-+ 	corosync_cfg_handle_t handle;
-++	cmap_handle_t cmap_handle;
-+ 	unsigned int interface_count;
-+ 	char **interface_names;
-+ 	char **interface_status;
-++	uint32_t nodeid_list[KNET_MAX_HOST];
-++	char iter_key[CMAP_KEYNAME_MAXLEN];
-+ 	unsigned int i;
-++	cmap_iter_handle_t iter;
-+ 	unsigned int nodeid;
-++	unsigned int node_pos;
-++	cmap_value_types_t type;
-++	size_t value_len;
-+ 	int rc = 0;
-+ 	int len, s = 0, t;
-+ 
-+@@ -95,6 +113,37 @@ linkstatusget_do (char *interface_name, int brief)
-+ 		exit (1);
-+ 	}
-+ 
-++	result = cmap_initialize (&cmap_handle);
-++	if (result != CS_OK) {
-++		printf ("Could not initialize corosync cmap API error %d\n", result);
-++		exit (1);
-++	}
-++	/* Get a list of nodes. We do it this way rather than using votequorum as cfgtool
-++	 * needs to be independent of quorum type
-++	 */
-++	result = cmap_iter_init(cmap_handle, "nodelist.node.", &iter);
-++	if (result != CS_OK) {
-++		printf ("Could not get nodelist from cmap. error %d\n", result);
-++		exit (1);
-++	}
-++
-++	while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
-++		result = sscanf(iter_key, "nodelist.node.%u.nodeid", &node_pos);
-++		if (result != 1) {
-++			continue;
-++		}
-++		if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
-++			nodeid_list[s++] = nodeid;
-++		}
-++	}
-++
-++	/* totemknet returns nodes in nodeid order - even though it doesn't tell us
-++	   what the nodeid is. So sort our node list and we can then look up
-++	   knet node pos to get an actual nodeid.
-++	   Yep, I really should have totally rewritten the cfg interface for this.
-++	*/
-++	qsort(nodeid_list, s, sizeof(uint32_t), node_compare);
-++
-+ 	result = corosync_cfg_local_get(handle, &nodeid);
-+ 	if (result != CS_OK) {
-+ 		printf ("Could not get the local node id, the error is: %d\n", result);
-+@@ -134,9 +183,11 @@ linkstatusget_do (char *interface_name, int brief)
-+ 					(!strstr(interface_status[i], "FAULTY"))) {
-+ 					len = strlen(interface_status[i]);
-+ 					printf ("\tstatus:\n");
-+-					while(s < len) {
-++					while (s < len) {
-++						nodeid = nodeid_list[s];
-+ 						t = interface_status[i][s] - '0';
-+-						printf("\t\tnode %d:\t", s++);
-++						s++;
-++						printf("\t\tnodeid %2d:\t", nodeid);
-+ 						printf("link enabled:%d\t", t&1? 1 : 0);
-+ 						printf("link connected:%d\n", t&2? 1: 0);
-+ 					}
-+@@ -157,6 +208,7 @@ linkstatusget_do (char *interface_name, int brief)
-+ 		free(interface_names);
-+ 	}
-+ 
-++	(void)cmap_finalize (cmap_handle);
-+ 	(void)corosync_cfg_finalize (handle);
-+ 	return rc;
-+ }
-diff --git a/debian/patches/series b/debian/patches/series
-index fcba2944..83f51959 100644
---- a/debian/patches/series
-+++ b/debian/patches/series
-@@ -6,3 +6,5 @@ AC_PROG_SED-is-already-present.patch
- Use-the-SED-variable-provided-by-configure.patch
- Use-the-AWK-variable-provided-by-configure.patch
- pve__only-start-corosync.service-if-conf-exists.patch
-+cfgtool-Improve-link-status-display.patch
-+cfgtool-Fix-link-status-display.patch
diff --git a/patches/0003-only-start-corosync.service-if-conf-exists.patch b/patches/0005-only-start-corosync.service-if-conf-exists.patch
similarity index 86%
rename from patches/0003-only-start-corosync.service-if-conf-exists.patch
rename to patches/0005-only-start-corosync.service-if-conf-exists.patch
index cdc1f29..cbf850c 100644
--- a/patches/0003-only-start-corosync.service-if-conf-exists.patch
+++ b/patches/0005-only-start-corosync.service-if-conf-exists.patch
@@ -15,7 +15,7 @@ Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
 
 diff --git a/debian/patches/pve__only-start-corosync.service-if-conf-exists.patch b/debian/patches/pve__only-start-corosync.service-if-conf-exists.patch
 new file mode 100644
-index 00000000..edbc5eb0
+index 00000000..d3bd7ac5
 --- /dev/null
 +++ b/debian/patches/pve__only-start-corosync.service-if-conf-exists.patch
 @@ -0,0 +1,24 @@
@@ -32,7 +32,7 @@ index 00000000..edbc5eb0
 + 1 file changed, 1 insertion(+)
 +
 +diff --git a/init/corosync.service.in b/init/corosync.service.in
-+index dc99a4a..28046ca 100644
++index 0c74306..adf7080 100644
 +--- a/init/corosync.service.in
 ++++ b/init/corosync.service.in
 +@@ -2,6 +2,7 @@
@@ -42,13 +42,13 @@ index 00000000..edbc5eb0
 ++ConditionPathExists=/etc/corosync/corosync.conf
 + Requires=network-online.target
 + After=network-online.target
-+ StopWhenUnneeded=yes
++ 
 diff --git a/debian/patches/series b/debian/patches/series
-index 41866b14..fcba2944 100644
+index ea6e04ea..803038e4 100644
 --- a/debian/patches/series
 +++ b/debian/patches/series
-@@ -5,3 +5,4 @@ corosync.conf.5-typography-fixes.patch
- AC_PROG_SED-is-already-present.patch
- Use-the-SED-variable-provided-by-configure.patch
- Use-the-AWK-variable-provided-by-configure.patch
+@@ -51,3 +51,4 @@ vqsim-Check-result-of-icmap_set_uint32.patch
+ vqsim-Check-length-of-copied-optarg.patch
+ Fix-various-typos-in-ChangeLog.patch
+ Enable-PrivateTmp-in-the-systemd-service-files.patch
 +pve__only-start-corosync.service-if-conf-exists.patch
diff --git a/patches/0008-CPG-callback-merging.patch b/patches/0006-CPG-callback-merging.patch
similarity index 77%
rename from patches/0008-CPG-callback-merging.patch
rename to patches/0006-CPG-callback-merging.patch
index 4ed50c8..cc5b8b5 100644
--- a/patches/0008-CPG-callback-merging.patch
+++ b/patches/0006-CPG-callback-merging.patch
@@ -14,177 +14,17 @@ in network load on bigger clusters running pmxcfs.
 
 Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
 ---
- .../cpg-Add-CPG_REASON_UNDEFINED.patch        | 152 +++++++++++++
  ...more-comments-to-notify_lib_joinlist.patch | 193 +++++++++++++++++
  ...illing-of-member_list-to-subfunction.patch | 130 ++++++++++++
  ...ify_lib_joinlist-drop-conn-parameter.patch | 112 ++++++++++
  ...-confchg-event-per-group-on-joinlist.patch | 199 ++++++++++++++++++
- debian/patches/series                         |   5 +
- 6 files changed, 791 insertions(+)
- create mode 100644 debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
+ debian/patches/series                         |   4 +
+ 5 files changed, 638 insertions(+)
  create mode 100644 debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch
  create mode 100644 debian/patches/cpg-Move-filling-of-member_list-to-subfunction.patch
  create mode 100644 debian/patches/cpg-notify_lib_joinlist-drop-conn-parameter.patch
  create mode 100644 debian/patches/cpg-send-single-confchg-event-per-group-on-joinlist.patch
 
-diff --git a/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
-new file mode 100644
-index 00000000..a69b53ac
---- /dev/null
-+++ b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
-@@ -0,0 +1,152 @@
-+From: Jan Friesse <jfriesse at redhat.com>
-+Date: Tue, 16 Apr 2019 12:52:31 +0200
-+Subject: cpg: Add CPG_REASON_UNDEFINED
-+
-+Previously the reason field for the member_list items
-+in cpg_totem_confchg_fn was unset what may be little confusing.
-+
-+Solution is to add a special value CPG_REASON_UNDEFINED and use it for
-+the member_list items.
-+
-+Signed-off-by: Jan Friesse <jfriesse at redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
-+(cherry picked from commit 41f9e966bb1cfa70d0f6ec1ce46d9c845845b599)
-+---
-+ include/corosync/cpg.h        |  3 ++-
-+ man/cpg_initialize.3.in       | 18 ++++++++++--------
-+ man/cpg_model_initialize.3.in | 18 ++++++++++--------
-+ exec/cpg.c                    |  3 ++-
-+ 4 files changed, 24 insertions(+), 18 deletions(-)
-+
-+diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h
-+index 5ebd478..600bbf7 100644
-+--- a/include/corosync/cpg.h
-++++ b/include/corosync/cpg.h
-+@@ -1,5 +1,5 @@
-+ /*
-+- * Copyright (c) 2006-2011 Red Hat, Inc.
-++ * Copyright (c) 2006-2019 Red Hat, Inc.
-+  *
-+  * All rights reserved.
-+  *
-+@@ -80,6 +80,7 @@ typedef enum {
-+  * @brief The cpg_reason_t enum
-+  */
-+ typedef enum {
-++	CPG_REASON_UNDEFINED = 0,
-+ 	CPG_REASON_JOIN = 1,
-+ 	CPG_REASON_LEAVE = 2,
-+ 	CPG_REASON_NODEDOWN = 3,
-+diff --git a/man/cpg_initialize.3.in b/man/cpg_initialize.3.in
-+index bdecc1e..38c7de5 100644
-+--- a/man/cpg_initialize.3.in
-++++ b/man/cpg_initialize.3.in
-+@@ -1,5 +1,5 @@
-+ .\"/*
-+-.\" * Copyright (c) 2006-2009 Red Hat, Inc.
-++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
-+ .\" *
-+ .\" * All rights reserved.
-+ .\" *
-+@@ -31,7 +31,7 @@
-+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
-+ .\" */
-+-.TH CPG_INITIALIZE 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
-++.TH CPG_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
-+ .SH NAME
-+ cpg_initialize \- Create a new connection to the CPG service
-+ .SH SYNOPSIS
-+@@ -132,18 +132,20 @@ struct cpg_address {
-+ .IP
-+ .PP
-+ where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
-+-or sent the message, and reason is an integer code indicating why the node joined/left the group.
-++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
-++set for the member_list items).
-+ .PP
-+ .IP
-+ .RS
-+ .ne 18
-+ .nf
-+ .PP
-+-CPG_REASON_JOIN     - the process joined a group using cpg_join().
-+-CPG_REASON_LEAVE    - the process left a group using cpg_leave()
-+-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
-+-CPG_REASON_NODEUP   - the process joined a group because it was already a member of a group on a node that has just joined the cluster
-+-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
-++CPG_REASON_JOIN      - the process joined a group using cpg_join().
-++CPG_REASON_LEAVE     - the process left a group using cpg_leave()
-++CPG_REASON_NODEDOWN  - the process left a group because the node left the cluster.
-++CPG_REASON_NODEUP    - the process joined a group because it was already a member of a group on a node that has just joined the cluster
-++CPG_REASON_PROCDOWN  - the process left a group without calling cpg_leave()
-++CPG_REASON_UNDEFINED - a special value used for the member_list items
-+ .ta
-+ .fi
-+ .RE
-+diff --git a/man/cpg_model_initialize.3.in b/man/cpg_model_initialize.3.in
-+index e06325d..17ca16a 100644
-+--- a/man/cpg_model_initialize.3.in
-++++ b/man/cpg_model_initialize.3.in
-+@@ -1,5 +1,5 @@
-+ .\"/*
-+-.\" * Copyright (c) 2010 Red Hat, Inc.
-++.\" * Copyright (c) 2010-2019 Red Hat, Inc.
-+ .\" *
-+ .\" * All rights reserved.
-+ .\" *
-+@@ -32,7 +32,7 @@
-+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
-+ .\" */
-+-.TH CPG_MODEL_INITIALIZE 3 2010-04-07 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
-++.TH CPG_MODEL_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
-+ .SH NAME
-+ cpg_model_initialize \- Create a new connection to the CPG service
-+ .SH SYNOPSIS
-+@@ -166,18 +166,20 @@ struct cpg_address {
-+ .IP
-+ .PP
-+ where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
-+-or sent the message, and reason is an integer code indicating why the node joined/left the group.
-++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
-++set for the member_list items).
-+ .PP
-+ .IP
-+ .RS
-+ .ne 18
-+ .nf
-+ .PP
-+-CPG_REASON_JOIN     - the process joined a group using cpg_join().
-+-CPG_REASON_LEAVE    - the process left a group using cpg_leave()
-+-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
-+-CPG_REASON_NODEUP   - the process joined a group because it was already a member of a group on a node that has just joined the cluster
-+-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
-++CPG_REASON_JOIN      - the process joined a group using cpg_join().
-++CPG_REASON_LEAVE     - the process left a group using cpg_leave()
-++CPG_REASON_NODEDOWN  - the process left a group because the node left the cluster.
-++CPG_REASON_NODEUP    - the process joined a group because it was already a member of a group on a node that has just joined the cluster
-++CPG_REASON_PROCDOWN  - the process left a group without calling cpg_leave()
-++CPG_REASON_UNDEFINED - a special value used for the member_list items
-+ .ta
-+ .fi
-+ .RE
-+diff --git a/exec/cpg.c b/exec/cpg.c
-+index b7ac579..e39ca34 100644
-+--- a/exec/cpg.c
-++++ b/exec/cpg.c
-+@@ -1,5 +1,5 @@
-+ /*
-+- * Copyright (c) 2006-2015 Red Hat, Inc.
-++ * Copyright (c) 2006-2019 Red Hat, Inc.
-+  *
-+  * All rights reserved.
-+  *
-+@@ -712,6 +712,7 @@ static int notify_lib_joinlist(
-+ 			if (!founded) {
-+ 				retgi->nodeid = pi->nodeid;
-+ 				retgi->pid = pi->pid;
-++				retgi->reason = CPG_REASON_UNDEFINED;
-+ 				retgi++;
-+ 			}
-+ 		}
 diff --git a/debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch b/debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch
 new file mode 100644
 index 00000000..e32102fa
@@ -844,14 +684,13 @@ index 00000000..013baaa0
 + 
 + static void message_handler_req_exec_cpg_procleave (
 diff --git a/debian/patches/series b/debian/patches/series
-index 76328bab..7dbb1f50 100644
+index 803038e4..fec11c03 100644
 --- a/debian/patches/series
 +++ b/debian/patches/series
-@@ -13,3 +13,8 @@ set-totem.keyfile-and-totem.key-to-RO.patch
- keygen-Reflect-change-in-knet.patch
- totemconfig-Remove-support-for-3des.patch
- crypto-re-introduce-secauth-parameter.patch
-+cpg-Add-CPG_REASON_UNDEFINED.patch
+@@ -52,3 +52,7 @@ vqsim-Check-length-of-copied-optarg.patch
+ Fix-various-typos-in-ChangeLog.patch
+ Enable-PrivateTmp-in-the-systemd-service-files.patch
+ pve__only-start-corosync.service-if-conf-exists.patch
 +cpg-notify_lib_joinlist-drop-conn-parameter.patch
 +cpg-send-single-confchg-event-per-group-on-joinlist.patch
 +cpg-Add-more-comments-to-notify_lib_joinlist.patch
diff --git a/patches/0006-Revert-init-Enable-StopWhenUnneeded.patch b/patches/0006-Revert-init-Enable-StopWhenUnneeded.patch
deleted file mode 100644
index 6b0cfd0..0000000
--- a/patches/0006-Revert-init-Enable-StopWhenUnneeded.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
-Date: Wed, 22 May 2019 12:25:28 +0200
-Subject: [PATCH] Revert "init: Enable StopWhenUnneeded"
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-cherry-picked from upstream master
-
-Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
----
- .../Revert-init-Enable-StopWhenUnneeded.patch | 31 +++++++++++++++++++
- debian/patches/series                         |  1 +
- 2 files changed, 32 insertions(+)
- create mode 100644 debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
-
-diff --git a/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch b/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
-new file mode 100644
-index 00000000..8b7f240c
---- /dev/null
-+++ b/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
-@@ -0,0 +1,31 @@
-+From: Jan Friesse <jfriesse at redhat.com>
-+Date: Thu, 4 Apr 2019 11:40:19 +0200
-+Subject: Revert "init: Enable StopWhenUnneeded"
-+
-+This reverts commit 03d9321bc80887d4578744c26c05d61e2d9d4278.
-+
-+Reverted because when corosync service is not enabled and corosync
-+is executed by "systemctl start corosync" it is then immediately
-+shutdown because of "Unit not needed anymore. Stopping.".
-+
-+This is really not expected behavior.
-+
-+Signed-off-by: Jan Friesse <jfriesse at redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
-+(cherry picked from commit 527e30a8d050c077d8adff2a5aa77d9b683a8f28)
-+---
-+ init/corosync.service.in | 1 -
-+ 1 file changed, 1 deletion(-)
-+
-+diff --git a/init/corosync.service.in b/init/corosync.service.in
-+index 28046ca..adf7080 100644
-+--- a/init/corosync.service.in
-++++ b/init/corosync.service.in
-+@@ -5,7 +5,6 @@ ConditionKernelCommandLine=!nocluster
-+ ConditionPathExists=/etc/corosync/corosync.conf
-+ Requires=network-online.target
-+ After=network-online.target
-+-StopWhenUnneeded=yes
-+ 
-+ [Service]
-+ EnvironmentFile=- at INITCONFIGDIR@/corosync
-diff --git a/debian/patches/series b/debian/patches/series
-index 83f51959..3b4e2901 100644
---- a/debian/patches/series
-+++ b/debian/patches/series
-@@ -8,3 +8,4 @@ Use-the-AWK-variable-provided-by-configure.patch
- pve__only-start-corosync.service-if-conf-exists.patch
- cfgtool-Improve-link-status-display.patch
- cfgtool-Fix-link-status-display.patch
-+Revert-init-Enable-StopWhenUnneeded.patch
diff --git a/patches/0007-add-crypto-patches.patch b/patches/0007-add-crypto-patches.patch
deleted file mode 100644
index 34b051e..0000000
--- a/patches/0007-add-crypto-patches.patch
+++ /dev/null
@@ -1,404 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
-Date: Wed, 22 May 2019 12:26:43 +0200
-Subject: [PATCH] add crypto patches
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-cherry-picked from upstream master, to ease in-place upgrade for
-clusters running our default configuration
-
-Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
----
- ...rypto-re-introduce-secauth-parameter.patch |  62 ++++++++
- .../keygen-Reflect-change-in-knet.patch       | 100 +++++++++++++
- ...et-totem.keyfile-and-totem.key-to-RO.patch |  44 ++++++
- .../totemconfig-Remove-support-for-3des.patch | 138 ++++++++++++++++++
- debian/patches/series                         |   4 +
- 5 files changed, 348 insertions(+)
- create mode 100644 debian/patches/crypto-re-introduce-secauth-parameter.patch
- create mode 100644 debian/patches/keygen-Reflect-change-in-knet.patch
- create mode 100644 debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
- create mode 100644 debian/patches/totemconfig-Remove-support-for-3des.patch
-
-diff --git a/debian/patches/crypto-re-introduce-secauth-parameter.patch b/debian/patches/crypto-re-introduce-secauth-parameter.patch
-new file mode 100644
-index 00000000..1c5739c1
---- /dev/null
-+++ b/debian/patches/crypto-re-introduce-secauth-parameter.patch
-@@ -0,0 +1,62 @@
-+From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
-+Date: Wed, 10 Apr 2019 09:43:33 +0200
-+Subject: crypto: re-introduce secauth parameter
-+MIME-Version: 1.0
-+Content-Type: text/plain; charset="utf-8"
-+Content-Transfer-Encoding: 8bit
-+
-+with the following semantics:
-+- default off
-+- implies crypto_hash SHA256 and crypto_cipher AES256
-+- crypto_* have higher precedence
-+- only applicable for knet, like crypto_*
-+
-+this should make upgrading from Corosync 2.x less painful for users that
-+have an explicit secauth=on in their configuration.
-+
-+Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
-+Reviewed-by: Jan Friesse <jfriesse at redhat.com>
-+(cherry picked from commit b97ca8e9f026aaaf2fe9cf697d89803004587f60)
-+---
-+ exec/totemconfig.c  | 8 ++++++++
-+ man/corosync.conf.5 | 8 ++++++++
-+ 2 files changed, 16 insertions(+)
-+
-+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
-+index 4f69fd5..1954f76 100644
-+--- a/exec/totemconfig.c
-++++ b/exec/totemconfig.c
-+@@ -450,6 +450,14 @@ static int totem_get_crypto(struct totem_config *totem_config, const char **erro
-+ 		tmp_model = "nss";
-+ 	}
-+ 
-++	if (icmap_get_string("totem.secauth", &str) == CS_OK) {
-++		if (strcmp(str, "on") == 0) {
-++			tmp_cipher = "aes256";
-++			tmp_hash = "sha256";
-++		}
-++		free(str);
-++	}
-++
-+ 	if (icmap_get_string("totem.crypto_cipher", &str) == CS_OK) {
-+ 		if (strcmp(str, "none") == 0) {
-+ 			tmp_cipher = "none";
-+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
-+index 216dfc5..b294e11 100644
-+--- a/man/corosync.conf.5
-++++ b/man/corosync.conf.5
-+@@ -224,6 +224,14 @@ transmission is only supported for the knet transport.
-+ 
-+ The default is none.
-+ 
-++.TP
-++secauth
-++This implies crypto_cipher=aes256 and crypto_hash=sha256, unless those options
-++are explicitly set. Encrypted transmission is only supported for the knet
-++transport.
-++
-++The default is off.
-++
-+ .TP
-+ keyfile
-+ This specifies the fully qualified path to the shared key used to
-diff --git a/debian/patches/keygen-Reflect-change-in-knet.patch b/debian/patches/keygen-Reflect-change-in-knet.patch
-new file mode 100644
-index 00000000..068f481f
---- /dev/null
-+++ b/debian/patches/keygen-Reflect-change-in-knet.patch
-@@ -0,0 +1,100 @@
-+From: Jan Friesse <jfriesse at redhat.com>
-+Date: Tue, 9 Apr 2019 17:09:34 +0200
-+Subject: keygen: Reflect change in knet
-+
-+Knet commit 1cb36f0cffd4559971826ca4774a88c5b05882fb reduced minimal
-+key length to 1024-bit. Keygen should keep compatibility with already
-+released 3.0.[0-1] so default key length should be 2048 bits. It's
-+possible to use -s argument to generate shorter key - keygen respects
-+minimum/maximum as defined by knet.
-+
-+Also fix man page to reflect this change.
-+
-+Signed-off-by: Jan Friesse <jfriesse at redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
-+(cherry picked from commit c260bce45b1f5b4a82c74513c4b3302d32daf179)
-+---
-+ tools/corosync-keygen.c |  4 ++--
-+ man/corosync-keygen.8   | 21 +++++++++------------
-+ 2 files changed, 11 insertions(+), 14 deletions(-)
-+
-+diff --git a/tools/corosync-keygen.c b/tools/corosync-keygen.c
-+index 40e4d6e..243661a 100644
-+--- a/tools/corosync-keygen.c
-++++ b/tools/corosync-keygen.c
-+@@ -1,6 +1,6 @@
-+ /*
-+  * Copyright (c) 2004 MontaVista Software, Inc.
-+- * Copyright (c) 2005-2017 Red Hat, Inc.
-++ * Copyright (c) 2005-2019 Red Hat, Inc.
-+  *
-+  * All rights reserved.
-+  *
-+@@ -52,7 +52,7 @@
-+ 
-+ #define DEFAULT_KEYFILE COROSYSCONFDIR "/authkey"
-+ 
-+-#define DEFAULT_KEYFILE_LEN		TOTEM_PRIVATE_KEY_LEN_MIN
-++#define DEFAULT_KEYFILE_LEN		256
-+ 
-+ #define DEFAULT_RANDOM_DEV		"/dev/urandom"
-+ 
-+diff --git a/man/corosync-keygen.8 b/man/corosync-keygen.8
-+index 0839621..8767ddc 100644
-+--- a/man/corosync-keygen.8
-++++ b/man/corosync-keygen.8
-+@@ -1,5 +1,5 @@
-+ .\"/*
-+-.\" * Copyright (C) 2010-2017 Red Hat, Inc.
-++.\" * Copyright (C) 2010-2019 Red Hat, Inc.
-+ .\" *
-+ .\" * All rights reserved.
-+ .\" *
-+@@ -31,7 +31,7 @@
-+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
-+ .\" */
-+-.TH COROSYNC-KEYGEN 8 2017-07-03
-++.TH COROSYNC-KEYGEN 8 2019-04-09
-+ .SH NAME
-+ corosync-keygen \- Generate an authentication key for Corosync.
-+ .SH SYNOPSIS
-+@@ -69,7 +69,7 @@ Random number source file. Default is /dev/urandom. As an example /dev/random ma
-+ used when really superb randomness is needed.
-+ .TP
-+ .B -s size
-+-Size of the generated key in bytes. Default is 1024 bytes. Allowed range is <1024, 4096>.
-++Size of the generated key in bytes. Default is 256 bytes. Allowed range is <128, 4096>.
-+ .TP
-+ .TP
-+ .B -l
-+@@ -84,7 +84,7 @@ Generate the key.
-+ .nf
-+ # corosync-keygen
-+ Corosync Cluster Engine Authentication key generator.
-+-Gathering 8192 bits for key from /dev/urandom.
-++Gathering 2048 bits for key from /dev/urandom.
-+ Writing corosync key to /etc/corosync/authkey
-+ .fi
-+ 
-+@@ -101,15 +101,12 @@ Writing corosync key to /tmp/authkey.
-+ Generate superb key using /dev/random
-+ .nf
-+ # corosync-keygen -r /dev/random
-+-Corosync Cluster Engine Authentication key generator.
-+-Gathering 8192 bits for key from /dev/random.
-++Gathering 2048 bits for key from /dev/random.
-+ Press keys on your keyboard to generate entropy.
-+-Press keys on your keyboard to generate entropy (7928 bits still needed).
-+-Press keys on your keyboard to generate entropy (7880 bits still needed).
-+- ...
-+-Press keys on your keyboard to generate entropy (104 bits still needed).
-+-Press keys on your keyboard to generate entropy (56 bits still needed).
-+-Press keys on your keyboard to generate entropy (8 bits still needed).
-++Press keys on your keyboard to generate entropy (1128 bits still needed).
-++Press keys on your keyboard to generate entropy (504 bits still needed).
-++Press keys on your keyboard to generate entropy (128 bits still needed).
-++Press keys on your keyboard to generate entropy (32 bits still needed).
-+ Writing corosync key to /etc/corosync/authkey.
-+ .fi
-+ 
-diff --git a/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch b/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
-new file mode 100644
-index 00000000..9daad20b
---- /dev/null
-+++ b/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
-@@ -0,0 +1,44 @@
-+From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
-+Date: Wed, 3 Apr 2019 21:57:30 +0200
-+Subject: set totem.keyfile and totem.key to RO
-+MIME-Version: 1.0
-+Content-Type: text/plain; charset="utf-8"
-+Content-Transfer-Encoding: 8bit
-+
-+so that we get the nice log message when attempting to modify them at
-+runtime, just like for totem.crypto_* and co.
-+
-+Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
-+Reviewed-by: Jan Friesse <jfriesse at redhat.com>
-+(cherry picked from commit 03fba21503f1b8395519190cc537f63100e995f5)
-+---
-+ exec/cfg.c  | 2 ++
-+ exec/main.c | 2 ++
-+ 2 files changed, 4 insertions(+)
-+
-+diff --git a/exec/cfg.c b/exec/cfg.c
-+index dec7dbf..9aeba0c 100644
-+--- a/exec/cfg.c
-++++ b/exec/cfg.c
-+@@ -578,6 +578,8 @@ static void remove_ro_entries(icmap_map_t temp_map)
-+ 	delete_and_notify_if_changed(temp_map, "totem.secauth");
-+ 	delete_and_notify_if_changed(temp_map, "totem.crypto_hash");
-+ 	delete_and_notify_if_changed(temp_map, "totem.crypto_cipher");
-++	delete_and_notify_if_changed(temp_map, "totem.keyfile");
-++	delete_and_notify_if_changed(temp_map, "totem.key");
-+ 	delete_and_notify_if_changed(temp_map, "totem.version");
-+ 	delete_and_notify_if_changed(temp_map, "totem.threads");
-+ 	delete_and_notify_if_changed(temp_map, "totem.ip_version");
-+diff --git a/exec/main.c b/exec/main.c
-+index 8554036..06a519c 100644
-+--- a/exec/main.c
-++++ b/exec/main.c
-+@@ -1036,6 +1036,8 @@ static void set_icmap_ro_keys_flag (void)
-+ 	 */
-+ 	icmap_set_ro_access("totem.crypto_cipher", CS_FALSE, CS_TRUE);
-+ 	icmap_set_ro_access("totem.crypto_hash", CS_FALSE, CS_TRUE);
-++	icmap_set_ro_access("totem.keyfile", CS_FALSE, CS_TRUE);
-++	icmap_set_ro_access("totem.key", CS_FALSE, CS_TRUE);
-+ 	icmap_set_ro_access("totem.secauth", CS_FALSE, CS_TRUE);
-+ 	icmap_set_ro_access("totem.ip_version", CS_FALSE, CS_TRUE);
-+ 	icmap_set_ro_access("totem.rrp_mode", CS_FALSE, CS_TRUE);
-diff --git a/debian/patches/totemconfig-Remove-support-for-3des.patch b/debian/patches/totemconfig-Remove-support-for-3des.patch
-new file mode 100644
-index 00000000..c46f137f
---- /dev/null
-+++ b/debian/patches/totemconfig-Remove-support-for-3des.patch
-@@ -0,0 +1,138 @@
-+From: Jan Friesse <jfriesse at redhat.com>
-+Date: Thu, 11 Apr 2019 08:23:29 +0200
-+Subject: totemconfig: Remove support for 3des
-+
-+Triple DES is considered as a "weak cipher" since 2016 so there is
-+really no need to support it in the corosync. Thanks to bug in
-+Corosync/Knet/NSS which caused 3des to not work at all,
-+no matter what library was used, we can just remove support for 3des
-+without braking the compatibility.
-+
-+Also fix coroparse so:
-+- totem.crypto_type is removed (this is 1.x construct which was not used
-+even in 2.x)
-+- Add checking of totem.crypto_model.
-+- Enumarate possible values for crypto_model, crypto_cipher and
-+crypto_hash error messages
-+
-+Signed-off-by: Jan Friesse <jfriesse at redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie at redhat.com>
-+(cherry picked from commit d05636b738e3cb1cd7a491e4ef492cd44a8bf6a9)
-+---
-+ exec/coroparse.c         | 21 ++++++++++-----------
-+ exec/totemconfig.c       |  3 ---
-+ conf/lenses/corosync.aug |  4 ++--
-+ man/corosync.conf.5      |  6 +++---
-+ 4 files changed, 15 insertions(+), 19 deletions(-)
-+
-+diff --git a/exec/coroparse.c b/exec/coroparse.c
-+index bee0a8c..16e0257 100644
-+--- a/exec/coroparse.c
-++++ b/exec/coroparse.c
-+@@ -1,5 +1,5 @@
-+ /*
-+- * Copyright (c) 2006-2018 Red Hat, Inc.
-++ * Copyright (c) 2006-2019 Red Hat, Inc.
-+  *
-+  * All rights reserved.
-+  *
-+@@ -747,13 +747,11 @@ static int main_config_parser_cb(const char *path,
-+ 					return (0);
-+ 				}
-+ 			}
-+-			if (strcmp(path, "totem.crypto_type") == 0) {
-++			if (strcmp(path, "totem.crypto_model") == 0) {
-+ 				if ((strcmp(value, "nss") != 0) &&
-+-				    (strcmp(value, "aes256") != 0) &&
-+-				    (strcmp(value, "aes192") != 0) &&
-+-				    (strcmp(value, "aes128") != 0) &&
-+-				    (strcmp(value, "3des") != 0)) {
-+-					*error_string = "Invalid crypto type";
-++				    (strcmp(value, "openssl") != 0)) {
-++					*error_string = "Invalid crypto model. "
-++					    "Should be nss or openssl";
-+ 
-+ 					return (0);
-+ 				}
-+@@ -762,9 +760,9 @@ static int main_config_parser_cb(const char *path,
-+ 				if ((strcmp(value, "none") != 0) &&
-+ 				    (strcmp(value, "aes256") != 0) &&
-+ 				    (strcmp(value, "aes192") != 0) &&
-+-				    (strcmp(value, "aes128") != 0) &&
-+-				    (strcmp(value, "3des") != 0)) {
-+-					*error_string = "Invalid cipher type";
-++				    (strcmp(value, "aes128") != 0)) {
-++					*error_string = "Invalid cipher type. "
-++					    "Should be none, aes256, aes192 or aes128";
-+ 
-+ 					return (0);
-+ 				}
-+@@ -776,7 +774,8 @@ static int main_config_parser_cb(const char *path,
-+ 				    (strcmp(value, "sha256") != 0) &&
-+ 				    (strcmp(value, "sha384") != 0) &&
-+ 				    (strcmp(value, "sha512") != 0)) {
-+-					*error_string = "Invalid hash type";
-++					*error_string = "Invalid hash type. "
-++					    "Should be none, md5, sha1, sha256, sha384 or sha512";
-+ 
-+ 					return (0);
-+ 				}
-+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
-+index d57562a..4f69fd5 100644
-+--- a/exec/totemconfig.c
-++++ b/exec/totemconfig.c
-+@@ -463,9 +463,6 @@ static int totem_get_crypto(struct totem_config *totem_config, const char **erro
-+ 		if (strcmp(str, "aes128") == 0) {
-+ 			tmp_cipher = "aes128";
-+ 		}
-+-		if (strcmp(str, "3des") == 0) {
-+-			tmp_cipher = "3des";
-+-		}
-+ 		free(str);
-+ 	}
-+ 
-+diff --git a/conf/lenses/corosync.aug b/conf/lenses/corosync.aug
-+index 39334f1..edeb4fb 100644
-+--- a/conf/lenses/corosync.aug
-++++ b/conf/lenses/corosync.aug
-+@@ -51,8 +51,8 @@ let totem =
-+     |kv "rrp_mode" /none|active|passive/
-+     |kv "vsftype" /none|ykd/
-+     |kv "secauth" /on|off/
-+-    |kv "crypto_type" /nss|aes256|aes192|aes128|3des/
-+-    |kv "crypto_cipher" /none|nss|aes256|aes192|aes128|3des/
-++    |kv "crypto_model" /nss|openssl/
-++    |kv "crypto_cipher" /none|nss|aes256|aes192|aes128/
-+     |kv "crypto_hash" /none|md5|sha1|sha256|sha384|sha512/
-+     |kv "transport" /udp|iba|udpu/
-+     |kv "version" Rx.integer
-+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
-+index dd6f3ba..216dfc5 100644
-+--- a/man/corosync.conf.5
-++++ b/man/corosync.conf.5
-+@@ -1,6 +1,6 @@
-+ .\"/*
-+ .\" * Copyright (c) 2005 MontaVista Software, Inc.
-+-.\" * Copyright (c) 2006-2018 Red Hat, Inc.
-++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
-+ .\" *
-+ .\" * All rights reserved.
-+ .\" *
-+@@ -32,7 +32,7 @@
-+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
-+ .\" */
-+-.TH COROSYNC_CONF 5 2019-01-10 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
-++.TH COROSYNC_CONF 5 2019-04-11 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
-+ .SH NAME
-+ corosync.conf - corosync executive configuration file
-+ 
-+@@ -218,7 +218,7 @@ The default is none.
-+ .TP
-+ crypto_cipher
-+ This specifies which cipher should be used to encrypt all messages.
-+-Valid values are none (no encryption), aes256, aes192, aes128 and 3des.
-++Valid values are none (no encryption), aes256, aes192 and aes128.
-+ Enabling crypto_cipher, requires also enabling of crypto_hash. Encrypted
-+ transmission is only supported for the knet transport.
-+ 
-diff --git a/debian/patches/series b/debian/patches/series
-index 3b4e2901..76328bab 100644
---- a/debian/patches/series
-+++ b/debian/patches/series
-@@ -9,3 +9,7 @@ pve__only-start-corosync.service-if-conf-exists.patch
- cfgtool-Improve-link-status-display.patch
- cfgtool-Fix-link-status-display.patch
- Revert-init-Enable-StopWhenUnneeded.patch
-+set-totem.keyfile-and-totem.key-to-RO.patch
-+keygen-Reflect-change-in-knet.patch
-+totemconfig-Remove-support-for-3des.patch
-+crypto-re-introduce-secauth-parameter.patch
diff --git a/patches/0007-bump-version-to-3.0.2.patch b/patches/0007-bump-version-to-3.0.2.patch
new file mode 100644
index 0000000..466ea95
--- /dev/null
+++ b/patches/0007-bump-version-to-3.0.2.patch
@@ -0,0 +1,57 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
+Date: Wed, 19 Jun 2019 13:50:23 +0200
+Subject: [PATCH] bump version to 3.0.2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
+---
+ debian/patches/bump-version-to-3.0.2.patch | 27 ++++++++++++++++++++++
+ debian/patches/series                      |  1 +
+ 2 files changed, 28 insertions(+)
+ create mode 100644 debian/patches/bump-version-to-3.0.2.patch
+
+diff --git a/debian/patches/bump-version-to-3.0.2.patch b/debian/patches/bump-version-to-3.0.2.patch
+new file mode 100644
+index 00000000..528ef7a6
+--- /dev/null
++++ b/debian/patches/bump-version-to-3.0.2.patch
+@@ -0,0 +1,27 @@
++From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler at proxmox.com>
++Date: Wed, 19 Jun 2019 13:30:39 +0200
++Subject: bump version to 3.0.2
++MIME-Version: 1.0
++Content-Type: text/plain; charset="utf-8"
++Content-Transfer-Encoding: 8bit
++
++Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
++---
++ .tarball-version | 2 +-
++ .version         | 2 +-
++ 2 files changed, 2 insertions(+), 2 deletions(-)
++
++diff --git a/.tarball-version b/.tarball-version
++index cb2b00e..b502146 100644
++--- a/.tarball-version
+++++ b/.tarball-version
++@@ -1 +1 @@
++-3.0.1
+++3.0.2
++diff --git a/.version b/.version
++index cb2b00e..b502146 100644
++--- a/.version
+++++ b/.version
++@@ -1 +1 @@
++-3.0.1
+++3.0.2
+diff --git a/debian/patches/series b/debian/patches/series
+index fec11c03..36735b84 100644
+--- a/debian/patches/series
++++ b/debian/patches/series
+@@ -56,3 +56,4 @@ cpg-notify_lib_joinlist-drop-conn-parameter.patch
+ cpg-send-single-confchg-event-per-group-on-joinlist.patch
+ cpg-Add-more-comments-to-notify_lib_joinlist.patch
+ cpg-Move-filling-of-member_list-to-subfunction.patch
++bump-version-to-3.0.2.patch
diff --git a/patches/series b/patches/series
index 18e0ab4..f505390 100644
--- a/patches/series
+++ b/patches/series
@@ -1,8 +1,7 @@
-0001-don-t-install-default-corosync.conf.patch
-0002-remove-init-script.patch
-0003-only-start-corosync.service-if-conf-exists.patch
+0001-cherry-pick-3.0.2-as-patches.patch
+0002-don-t-install-default-corosync.conf.patch
+0003-remove-init-script.patch
 0004-bsys-disable-augeas-tools.patch
-0005-cfgtool-Improve-link-status-display.patch
-0006-Revert-init-Enable-StopWhenUnneeded.patch
-0007-add-crypto-patches.patch
-0008-CPG-callback-merging.patch
+0005-only-start-corosync.service-if-conf-exists.patch
+0006-CPG-callback-merging.patch
+0007-bump-version-to-3.0.2.patch
-- 
2.20.1





More information about the pve-devel mailing list