+++ /dev/null
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@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@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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=-@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@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@debian.org>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@debian.org>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@proxmox.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@debian.org>
-+Reviewed-by: Jan Friesse <jfriesse@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@redhat.com>
-+Date: Tue, 26 Feb 2019 13:28:08 +0100
-+Subject: coroparse: Fix compiler warning
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@debian.org>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@debian.org>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@proxmox.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@redhat.com>
-+Date: Fri, 24 May 2019 09:33:13 +0200
-+Subject: knet: Use block_unlisted_ips
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@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@redhat.com>
-+Date: Fri, 31 May 2019 09:34:33 +0200
-+Subject: man: Enahnce block_unlisted_ips description
-+
-+Thanks Christine Caulfield <ccaulfie@redhat.com> for
-+Englishify and refining the description.
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@rz.uni-regensburg.de>
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@suse.com>
-+Date: Thu, 16 May 2019 18:31:44 +0800
-+Subject: man: Enhance token_retransmit description
-+
-+Signed-off-by: yuan ren <yren@suse.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@proxmox.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@redhat.com>
-+Date: Wed, 24 Apr 2019 14:47:47 +0200
-+Subject: totemconfig: Ensure nodeid is specified for IPv6
-+
-+Thanks Yuan Ren <yren@suse.com> for finding this problem.
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@suse.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@suse.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@suse.com>
-+Date: Fri, 29 Mar 2019 15:43:10 +0800
-+Subject: totemsrp: Word spelling mistake
-+
-+Signed-off-by: yuan ren <reyren179@gmail.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@redhat.com>
-+Date: Tue, 11 Jun 2019 15:30:00 +0200
-+Subject: vqsim: Check length of copied optarg
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@redhat.com>
-+Date: Tue, 11 Jun 2019 14:48:41 +0200
-+Subject: vqsim: Check length of received message
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@redhat.com>
-+Date: Tue, 11 Jun 2019 14:46:34 +0200
-+Subject: vqsim: Check write result
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@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@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@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@redhat.com>
-+Reviewed-by: Jan Friesse <jfriesse@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@redhat.com>
-+Date: Tue, 11 Jun 2019 14:50:03 +0200
-+Subject: vqsim: Free allocated newvq on error
-+
-+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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@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@redhat.com>
-+Reviewed-by: Christine Caulfield <ccaulfie@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