]> git.proxmox.com Git - corosync-pve.git/blame - patches/0001-cherry-pick-3.0.2-as-patches.patch
bump version to 3.0.2-pve1
[corosync-pve.git] / patches / 0001-cherry-pick-3.0.2-as-patches.patch
CommitLineData
7e9f3a04
FG
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
3Date: Wed, 22 May 2019 12:26:43 +0200
4Subject: [PATCH] cherry-pick 3.0.2 as patches
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
10---
11 ...vateTmp-in-the-systemd-service-files.patch | 4 +-
12 .../Revert-init-Enable-StopWhenUnneeded.patch | 31 +
13 ...-AWK-variable-provided-by-configure.patch} | 8 +-
14 ...-SED-variable-provided-by-configure.patch} | 10 +-
15 .../cfgtool-Fix-link-status-display.patch | 65 +
16 .../cfgtool-Improve-link-status-display.patch | 134 ++
17 .../configure-Do-not-autodetect-nozzle.patch | 114 ++
18 .../configure-Fix-GDB_CFLAGS-typo.patch | 27 +
19 ...e.ac-AC_PROG_SED-is-already-present.patch} | 8 +-
20 .../coroparse-Fix-compiler-warning.patch | 24 +
21 .../corosync-cfgtool-Fix-i-matching.patch | 115 ++
22 .../patches/corosync.conf.5-fix-grammar.patch | 8 +-
23 .../corosync.conf.5-typography-fixes.patch | 8 +-
24 .../cpg-Add-CPG_REASON_UNDEFINED.patch | 152 +++
25 ...rypto-re-introduce-secauth-parameter.patch | 62 +
26 debian/patches/doc-Update-INSTALL-file.patch | 124 ++
27 .../keygen-Reflect-change-in-knet.patch | 100 ++
28 ...ple-of-errors-when-adding-a-new-link.patch | 82 ++
29 ...ix-initialising-of-knet-access-lists.patch | 70 +
30 .../patches/knet-Use-block_unlisted_ips.patch | 67 +
31 ...ow-corosync-to-use-knet-access-lists.patch | 93 ++
32 ...im-man-page-into-distributed-tarball.patch | 40 +
33 ...ahnce-block_unlisted_ips-description.patch | 33 +
34 .../man-Enhance-corosync.conf-mp-a-bit.patch | 37 +
35 ...Enhance-token_retransmit-description.patch | 28 +
36 ...le-Add-support-for-libnozzle-devices.patch | 707 ++++++++++
37 .../quorumtool-Fix-exit-status-codes.patch | 237 ++++
38 ...et-totem.keyfile-and-totem.key-to-RO.patch | 44 +
39 ...port-for-user-flags-configure-option.patch | 43 +
40 ...-Ensure-nodeid-is-specified-for-IPv6.patch | 48 +
41 ...g-Fix-minimum-limit-for-hold-timeout.patch | 67 +
42 .../totemconfig-Remove-support-for-3des.patch | 138 ++
43 ...fig-fix-autogen-mcastaddr-for-ipv6-4.patch | 51 +
44 ...ig-ipaddr_equal-check-just-addr-part.patch | 86 ++
45 .../totemconfig-ipaddr_equal-use-switch.patch | 44 +
46 .../totemip-Use-res-in-totemip_sa_equal.patch | 32 +
47 ...mknet-Ignore-icmap_get_string-result.patch | 32 +
48 ...tialize-return-value-in-setup_nozzle.patch | 39 +
49 ...-create_nozzle_device-simplify-check.patch | 34 +
50 .../totemknet-macaddr_str-is-always-set.patch | 27 +
51 .../totemsrp-Word-spelling-mistake.patch | 24 +
52 .../udpu-Drop-packets-from-unlisted-IPs.patch | 254 ++++
53 .../vqsim-Check-length-of-copied-optarg.patch | 37 +
54 ...sim-Check-length-of-received-message.patch | 42 +
55 ...sim-Check-result-of-icmap_set_uint32.patch | 31 +
56 debian/patches/vqsim-Check-write-result.patch | 33 +
57 ...sim-Do-not-access-unitialized-argv-0.patch | 24 +
58 debian/patches/vqsim-Enhance-vqsim.patch | 1155 +++++++++++++++++
59 .../vqsim-Fix-vqsim-for-corosync-3.0.patch | 102 ++
60 .../vqsim-Free-allocated-newvq-on-error.patch | 23 +
61 debian/patches/vqsim-Make-vqsim-compile.patch | 131 ++
62 .../vqsim-Remove-unused-total_nodes.patch | 62 +
63 debian/patches/series | 57 +-
64 53 files changed, 5034 insertions(+), 14 deletions(-)
65 create mode 100644 debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
66 rename debian/patches/{Use-the-AWK-variable-provided-by-configure.patch => build-Use-the-AWK-variable-provided-by-configure.patch} (78%)
67 rename debian/patches/{Use-the-SED-variable-provided-by-configure.patch => build-Use-the-SED-variable-provided-by-configure.patch} (94%)
68 create mode 100644 debian/patches/cfgtool-Fix-link-status-display.patch
69 create mode 100644 debian/patches/cfgtool-Improve-link-status-display.patch
70 create mode 100644 debian/patches/configure-Do-not-autodetect-nozzle.patch
71 create mode 100644 debian/patches/configure-Fix-GDB_CFLAGS-typo.patch
72 rename debian/patches/{AC_PROG_SED-is-already-present.patch => configure.ac-AC_PROG_SED-is-already-present.patch} (62%)
73 create mode 100644 debian/patches/coroparse-Fix-compiler-warning.patch
74 create mode 100644 debian/patches/corosync-cfgtool-Fix-i-matching.patch
75 create mode 100644 debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
76 create mode 100644 debian/patches/crypto-re-introduce-secauth-parameter.patch
77 create mode 100644 debian/patches/doc-Update-INSTALL-file.patch
78 create mode 100644 debian/patches/keygen-Reflect-change-in-knet.patch
79 create mode 100644 debian/patches/knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
80 create mode 100644 debian/patches/knet-Fix-initialising-of-knet-access-lists.patch
81 create mode 100644 debian/patches/knet-Use-block_unlisted_ips.patch
82 create mode 100644 debian/patches/knet-allow-corosync-to-use-knet-access-lists.patch
83 create mode 100644 debian/patches/man-Add-vqsim-man-page-into-distributed-tarball.patch
84 create mode 100644 debian/patches/man-Enahnce-block_unlisted_ips-description.patch
85 create mode 100644 debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch
86 create mode 100644 debian/patches/man-Enhance-token_retransmit-description.patch
87 create mode 100644 debian/patches/nozzle-Add-support-for-libnozzle-devices.patch
88 create mode 100644 debian/patches/quorumtool-Fix-exit-status-codes.patch
89 create mode 100644 debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
90 create mode 100644 debian/patches/spec-Add-support-for-user-flags-configure-option.patch
91 create mode 100644 debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
92 create mode 100644 debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch
93 create mode 100644 debian/patches/totemconfig-Remove-support-for-3des.patch
94 create mode 100644 debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
95 create mode 100644 debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch
96 create mode 100644 debian/patches/totemconfig-ipaddr_equal-use-switch.patch
97 create mode 100644 debian/patches/totemip-Use-res-in-totemip_sa_equal.patch
98 create mode 100644 debian/patches/totemknet-Ignore-icmap_get_string-result.patch
99 create mode 100644 debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch
100 create mode 100644 debian/patches/totemknet-create_nozzle_device-simplify-check.patch
101 create mode 100644 debian/patches/totemknet-macaddr_str-is-always-set.patch
102 create mode 100644 debian/patches/totemsrp-Word-spelling-mistake.patch
103 create mode 100644 debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch
104 create mode 100644 debian/patches/vqsim-Check-length-of-copied-optarg.patch
105 create mode 100644 debian/patches/vqsim-Check-length-of-received-message.patch
106 create mode 100644 debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch
107 create mode 100644 debian/patches/vqsim-Check-write-result.patch
108 create mode 100644 debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch
109 create mode 100644 debian/patches/vqsim-Enhance-vqsim.patch
110 create mode 100644 debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch
111 create mode 100644 debian/patches/vqsim-Free-allocated-newvq-on-error.patch
112 create mode 100644 debian/patches/vqsim-Make-vqsim-compile.patch
113 create mode 100644 debian/patches/vqsim-Remove-unused-total_nodes.patch
114
115diff --git a/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch b/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch
116index 45d24d3d..b4644516 100644
117--- a/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch
118+++ b/debian/patches/Enable-PrivateTmp-in-the-systemd-service-files.patch
119@@ -20,10 +20,10 @@ index 410a683..9247cbc 100644
120 [Install]
121 WantedBy=multi-user.target
122 diff --git a/init/corosync.service.in b/init/corosync.service.in
123-index bf757d8..dc99a4a 100644
124+index 654e41f..0c74306 100644
125 --- a/init/corosync.service.in
126 +++ b/init/corosync.service.in
127-@@ -29,6 +29,7 @@ StandardError=null
128+@@ -28,6 +28,7 @@ StandardError=null
129 #RestartSec=70
130 # rewrite according to environment.
131 #ExecStartPre=/sbin/modprobe softdog
132diff --git a/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch b/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
133new file mode 100644
134index 00000000..29fb842d
135--- /dev/null
136+++ b/debian/patches/Revert-init-Enable-StopWhenUnneeded.patch
137@@ -0,0 +1,31 @@
138+From: Jan Friesse <jfriesse@redhat.com>
139+Date: Thu, 4 Apr 2019 11:40:19 +0200
140+Subject: Revert "init: Enable StopWhenUnneeded"
141+
142+This reverts commit 03d9321bc80887d4578744c26c05d61e2d9d4278.
143+
144+Reverted because when corosync service is not enabled and corosync
145+is executed by "systemctl start corosync" it is then immediately
146+shutdown because of "Unit not needed anymore. Stopping.".
147+
148+This is really not expected behavior.
149+
150+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
151+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
152+(cherry picked from commit 527e30a8d050c077d8adff2a5aa77d9b683a8f28)
153+---
154+ init/corosync.service.in | 1 -
155+ 1 file changed, 1 deletion(-)
156+
157+diff --git a/init/corosync.service.in b/init/corosync.service.in
158+index bf757d8..654e41f 100644
159+--- a/init/corosync.service.in
160++++ b/init/corosync.service.in
161+@@ -4,7 +4,6 @@ Documentation=man:corosync man:corosync.conf man:corosync_overview
162+ ConditionKernelCommandLine=!nocluster
163+ Requires=network-online.target
164+ After=network-online.target
165+-StopWhenUnneeded=yes
166+
167+ [Service]
168+ EnvironmentFile=-@INITCONFIGDIR@/corosync
169diff --git a/debian/patches/Use-the-AWK-variable-provided-by-configure.patch b/debian/patches/build-Use-the-AWK-variable-provided-by-configure.patch
170similarity index 78%
171rename from debian/patches/Use-the-AWK-variable-provided-by-configure.patch
172rename to debian/patches/build-Use-the-AWK-variable-provided-by-configure.patch
173index 85511c66..61407483 100644
174--- a/debian/patches/Use-the-AWK-variable-provided-by-configure.patch
175+++ b/debian/patches/build-Use-the-AWK-variable-provided-by-configure.patch
176@@ -1,7 +1,13 @@
177 From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi@debian.org>
178 Date: Tue, 29 Jan 2019 15:25:18 +0100
179-Subject: Use the AWK variable provided by configure
180+Subject: build: Use the AWK variable provided by configure
181+MIME-Version: 1.0
182+Content-Type: text/plain; charset="utf-8"
183+Content-Transfer-Encoding: 8bit
184
185+Signed-off-by: Ferenc Wágner <wferi@debian.org>
186+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
187+(cherry picked from commit b09b96fe6ff5a77e637efb692ed37b6c80f40ba3)
188 ---
189 man/Makefile.am | 4 ++--
190 1 file changed, 2 insertions(+), 2 deletions(-)
191diff --git a/debian/patches/Use-the-SED-variable-provided-by-configure.patch b/debian/patches/build-Use-the-SED-variable-provided-by-configure.patch
192similarity index 94%
193rename from debian/patches/Use-the-SED-variable-provided-by-configure.patch
194rename to debian/patches/build-Use-the-SED-variable-provided-by-configure.patch
195index 672d4817..1c2941c5 100644
196--- a/debian/patches/Use-the-SED-variable-provided-by-configure.patch
197+++ b/debian/patches/build-Use-the-SED-variable-provided-by-configure.patch
198@@ -1,7 +1,13 @@
199 From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi@debian.org>
200 Date: Tue, 29 Jan 2019 15:24:19 +0100
201-Subject: Use the SED variable provided by configure
202+Subject: build: Use the SED variable provided by configure
203+MIME-Version: 1.0
204+Content-Type: text/plain; charset="utf-8"
205+Content-Transfer-Encoding: 8bit
206
207+Signed-off-by: Ferenc Wágner <wferi@debian.org>
208+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
209+(cherry picked from commit 6a476017b998e02bc4c1b88e78f86bc11f16ae7f)
210 ---
211 Makefile.am | 8 ++++----
212 conf/logrotate/Makefile.am | 10 +++++-----
213@@ -141,7 +147,7 @@ index 131d675..1994a3c 100644
214
215 LINT_FILES1:=$(filter-out sa_error.c, $(wildcard *.c))
216 diff --git a/tools/Makefile.am b/tools/Makefile.am
217-index 14520c2..7a9ab04 100644
218+index 8825498..0793884 100644
219 --- a/tools/Makefile.am
220 +++ b/tools/Makefile.am
221 @@ -49,12 +49,12 @@ EXTRA_DIST = corosync-xmlproc.sh \
222diff --git a/debian/patches/cfgtool-Fix-link-status-display.patch b/debian/patches/cfgtool-Fix-link-status-display.patch
223new file mode 100644
224index 00000000..b441458b
225--- /dev/null
226+++ b/debian/patches/cfgtool-Fix-link-status-display.patch
227@@ -0,0 +1,65 @@
228+From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
229+Date: Wed, 29 May 2019 14:57:09 +0200
230+Subject: cfgtool: Fix link status display
231+MIME-Version: 1.0
232+Content-Type: text/plain; charset="utf-8"
233+Content-Transfer-Encoding: 8bit
234+
235+instead of the nodeid, this displayed arbitrary values (usually '1')
236+from other cmap keys under nodelist.node.XX.
237+
238+sscanf returns the number of conversions even on mismatch, e.g. it also
239+returns 1 for
240+
241+nodelist.node.2.quorum_votes
242+nodelist.node.2.ring0_addr
243+nodelist.node.2.name
244+...
245+
246+instead of just
247+
248+nodelist.node.2.nodeid
249+
250+which leads to the value of (at least) quorum_votes being stored in
251+nodeid_list in addition to the actual nodeid.
252+
253+storing the returned int in a cs_error_t enum also potentially masks
254+errors, so just compare the result with the expectation directly.
255+
256+Fixes: c0d14485c3ebdeb2332f7c48acd155163e5b7fc1
257+
258+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
259+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
260+(cherry picked from commit ef2569d323c68633a63dc15e59805ec491b69348)
261+---
262+ tools/corosync-cfgtool.c | 10 +++++++---
263+ 1 file changed, 7 insertions(+), 3 deletions(-)
264+
265+diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
266+index a43ee1e..f51b9d4 100644
267+--- a/tools/corosync-cfgtool.c
268++++ b/tools/corosync-cfgtool.c
269+@@ -100,7 +100,7 @@ linkstatusget_do (char *interface_name, int brief)
270+ unsigned int i;
271+ cmap_iter_handle_t iter;
272+ unsigned int nodeid;
273+- unsigned int node_pos;
274++ int nodeid_match_guard;
275+ cmap_value_types_t type;
276+ size_t value_len;
277+ int rc = 0;
278+@@ -128,8 +128,12 @@ linkstatusget_do (char *interface_name, int brief)
279+ }
280+
281+ while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
282+- result = sscanf(iter_key, "nodelist.node.%u.nodeid", &node_pos);
283+- if (result != 1) {
284++ nodeid_match_guard = 0;
285++ if (sscanf(iter_key, "nodelist.node.%*u.nodeid%n", &nodeid_match_guard) != 0) {
286++ continue;
287++ }
288++ /* check for exact match */
289++ if (nodeid_match_guard != strlen(iter_key)) {
290+ continue;
291+ }
292+ if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
293diff --git a/debian/patches/cfgtool-Improve-link-status-display.patch b/debian/patches/cfgtool-Improve-link-status-display.patch
294new file mode 100644
295index 00000000..e05732bf
296--- /dev/null
297+++ b/debian/patches/cfgtool-Improve-link-status-display.patch
298@@ -0,0 +1,134 @@
299+From: Christine Caulfield <ccaulfie@redhat.com>
300+Date: Tue, 22 Jan 2019 10:06:29 +0000
301+Subject: cfgtool: Improve link status display
302+
303+Now show the nodeids properly, rather than node indexes which were
304+annoying and unhelpful.
305+
306+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
307+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
308+(cherry picked from commit c0d14485c3ebdeb2332f7c48acd155163e5b7fc1)
309+---
310+ tools/Makefile.am | 2 +-
311+ tools/corosync-cfgtool.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++--
312+ 2 files changed, 55 insertions(+), 3 deletions(-)
313+
314+diff --git a/tools/Makefile.am b/tools/Makefile.am
315+index 14520c2..8825498 100644
316+--- a/tools/Makefile.am
317++++ b/tools/Makefile.am
318+@@ -58,7 +58,7 @@ corosync-blackbox: corosync-blackbox.sh
319+
320+ corosync_cmapctl_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcmap.la
321+
322+-corosync_cfgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la
323++corosync_cfgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la $(top_builddir)/lib/libcmap.la
324+
325+ corosync_cpgtool_LDADD = $(LIBQB_LIBS) $(top_builddir)/lib/libcfg.la \
326+ $(top_builddir)/lib/libcpg.la
327+diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
328+index c138085..ed29694 100644
329+--- a/tools/corosync-cfgtool.c
330++++ b/tools/corosync-cfgtool.c
331+@@ -50,6 +50,7 @@
332+ #include <corosync/corotypes.h>
333+ #include <corosync/totem/totem.h>
334+ #include <corosync/cfg.h>
335++#include <corosync/cmap.h>
336+
337+ #define cs_repeat(result, max, code) \
338+ do { \
339+@@ -75,16 +76,33 @@ enum user_action {
340+ ACTION_KILL_NODE,
341+ };
342+
343++static int node_compare(const void *aptr, const void *bptr)
344++{
345++ uint32_t a,b;
346++
347++ a = *(uint32_t *)aptr;
348++ b = *(uint32_t *)bptr;
349++
350++ return a > b;
351++}
352++
353+ static int
354+ linkstatusget_do (char *interface_name, int brief)
355+ {
356+ cs_error_t result;
357+ corosync_cfg_handle_t handle;
358++ cmap_handle_t cmap_handle;
359+ unsigned int interface_count;
360+ char **interface_names;
361+ char **interface_status;
362++ uint32_t nodeid_list[KNET_MAX_HOST];
363++ char iter_key[CMAP_KEYNAME_MAXLEN];
364+ unsigned int i;
365++ cmap_iter_handle_t iter;
366+ unsigned int nodeid;
367++ unsigned int node_pos;
368++ cmap_value_types_t type;
369++ size_t value_len;
370+ int rc = 0;
371+ int len, s = 0, t;
372+
373+@@ -95,6 +113,37 @@ linkstatusget_do (char *interface_name, int brief)
374+ exit (1);
375+ }
376+
377++ result = cmap_initialize (&cmap_handle);
378++ if (result != CS_OK) {
379++ printf ("Could not initialize corosync cmap API error %d\n", result);
380++ exit (1);
381++ }
382++ /* Get a list of nodes. We do it this way rather than using votequorum as cfgtool
383++ * needs to be independent of quorum type
384++ */
385++ result = cmap_iter_init(cmap_handle, "nodelist.node.", &iter);
386++ if (result != CS_OK) {
387++ printf ("Could not get nodelist from cmap. error %d\n", result);
388++ exit (1);
389++ }
390++
391++ while ((cmap_iter_next(cmap_handle, iter, iter_key, &value_len, &type)) == CS_OK) {
392++ result = sscanf(iter_key, "nodelist.node.%u.nodeid", &node_pos);
393++ if (result != 1) {
394++ continue;
395++ }
396++ if (cmap_get_uint32(cmap_handle, iter_key, &nodeid) == CS_OK) {
397++ nodeid_list[s++] = nodeid;
398++ }
399++ }
400++
401++ /* totemknet returns nodes in nodeid order - even though it doesn't tell us
402++ what the nodeid is. So sort our node list and we can then look up
403++ knet node pos to get an actual nodeid.
404++ Yep, I really should have totally rewritten the cfg interface for this.
405++ */
406++ qsort(nodeid_list, s, sizeof(uint32_t), node_compare);
407++
408+ result = corosync_cfg_local_get(handle, &nodeid);
409+ if (result != CS_OK) {
410+ printf ("Could not get the local node id, the error is: %d\n", result);
411+@@ -134,9 +183,11 @@ linkstatusget_do (char *interface_name, int brief)
412+ (!strstr(interface_status[i], "FAULTY"))) {
413+ len = strlen(interface_status[i]);
414+ printf ("\tstatus:\n");
415+- while(s < len) {
416++ while (s < len) {
417++ nodeid = nodeid_list[s];
418+ t = interface_status[i][s] - '0';
419+- printf("\t\tnode %d:\t", s++);
420++ s++;
421++ printf("\t\tnodeid %2d:\t", nodeid);
422+ printf("link enabled:%d\t", t&1? 1 : 0);
423+ printf("link connected:%d\n", t&2? 1: 0);
424+ }
425+@@ -157,6 +208,7 @@ linkstatusget_do (char *interface_name, int brief)
426+ free(interface_names);
427+ }
428+
429++ (void)cmap_finalize (cmap_handle);
430+ (void)corosync_cfg_finalize (handle);
431+ return rc;
432+ }
433diff --git a/debian/patches/configure-Do-not-autodetect-nozzle.patch b/debian/patches/configure-Do-not-autodetect-nozzle.patch
434new file mode 100644
435index 00000000..6d66e433
436--- /dev/null
437+++ b/debian/patches/configure-Do-not-autodetect-nozzle.patch
438@@ -0,0 +1,114 @@
439+From: Jan Friesse <jfriesse@redhat.com>
440+Date: Tue, 26 Feb 2019 11:04:16 +0100
441+Subject: configure: Do not autodetect nozzle
442+
443+Nozzle is part of kronosnet but it is independent library. Enabling it
444+when detected without ability to turn it off is not in line with
445+other libraries.
446+
447+Solution is to use same method as for other libraries - add
448+--enable-nozzle to configure script and add support for this option into
449+spec file.
450+
451+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
452+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
453+(cherry picked from commit 83dc407f550a5b67f134dc41da6282f7b80d0ba2)
454+---
455+ configure.ac | 21 ++++++++++++++-------
456+ corosync.spec.in | 7 +++++++
457+ 2 files changed, 21 insertions(+), 7 deletions(-)
458+
459+diff --git a/configure.ac b/configure.ac
460+index 95cdb35..14c0e17 100644
461+--- a/configure.ac
462++++ b/configure.ac
463+@@ -174,7 +174,6 @@ LIBS="$SAVE_LIBS"
464+ AC_CHECK_LIB([pthread], [pthread_create])
465+ AC_CHECK_LIB([socket], [socket])
466+ PKG_CHECK_MODULES([knet],[libknet])
467+-PKG_CHECK_MODULES([nozzle],[libnozzle], [AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [Have libnozzle])], [have_nozzle="no"])
468+ AC_CHECK_LIB([nsl], [t_open])
469+ AC_CHECK_LIB([rt], [sched_getscheduler])
470+ AC_CHECK_LIB([z], [crc32],
471+@@ -395,21 +394,20 @@ AC_ARG_ENABLE([xmlconf],
472+ AM_CONDITIONAL(INSTALL_XMLCONF, test x$enable_xmlconf = xyes)
473+
474+ AC_ARG_ENABLE([vqsim],
475+- [ --enable-vqsim : Quorum simulator support ],,
476++ [ --enable-vqsim : Quorum simulator support ],,
477+ [ enable_vqsim="no" ])
478+ AM_CONDITIONAL(BUILD_VQSIM, test x$enable_vqsim = xyes)
479+
480++AC_ARG_ENABLE([nozzle],
481++ [ --enable-nozzle : Support for nozzle ],,
482++ [ enable_nozzle="no" ])
483++
484+ # *FLAGS handling goes here
485+
486+ ENV_CFLAGS="$CFLAGS"
487+ ENV_CPPFLAGS="$CPPFLAGS"
488+ ENV_LDFLAGS="$LDFLAGS"
489+
490+-# Add nozzle to Package features if enabled
491+-if test "x$have_nozzle" != xno; then
492+- PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
493+-fi
494+-
495+ # debug build stuff
496+ if test "x${enable_debug}" = xyes; then
497+ AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
498+@@ -426,6 +424,7 @@ else
499+ GDB_FLAGS="-g"
500+ fi
501+
502++
503+ # Look for dbus-1
504+ if test "x${enable_dbus}" = xyes; then
505+ PKG_CHECK_MODULES([DBUS],[dbus-1])
506+@@ -474,6 +473,14 @@ if test "x${enable_vqsim}" = xyes; then
507+ fi
508+ AM_CONDITIONAL(VQSIM_READLINE, [test "x${ac_cv_header_readline_readline_h}" = xyes])
509+
510++# Look for nozzle
511++if test "x${enable_nozzle}" = xyes; then
512++ PKG_CHECK_MODULES([nozzle],[libnozzle])
513++ AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [have nozzle])
514++ PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
515++ WITH_LIST="$WITH_LIST --with nozzle"
516++fi
517++
518+ do_snmp=0
519+ if test "x${enable_snmp}" = xyes; then
520+ AC_PATH_PROGS([SNMPCONFIG], [net-snmp-config])
521+diff --git a/corosync.spec.in b/corosync.spec.in
522+index bf5bfc2..07c004c 100644
523+--- a/corosync.spec.in
524++++ b/corosync.spec.in
525+@@ -11,6 +11,7 @@
526+ %bcond_with dbus
527+ %bcond_with systemd
528+ %bcond_with xmlconf
529++%bcond_with nozzle
530+ %bcond_with runautogen
531+
532+ %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
533+@@ -55,6 +56,9 @@ BuildRequires: dbus-1-devel
534+ BuildRequires: dbus-devel
535+ %endif
536+ %endif
537++%if %{with nozzle}
538++BuildRequires: libnozzle1-devel
539++%endif
540+ %if %{with systemd}
541+ %{?systemd_requires}
542+ BuildRequires: systemd
543+@@ -93,6 +97,9 @@ Requires: libxslt
544+ %endif
545+ %if %{with xmlconf}
546+ --enable-xmlconf \
547++%endif
548++%if %{with nozzle}
549++ --enable-nozzle \
550+ %endif
551+ --with-initddir=%{_initrddir} \
552+ --with-systemddir=%{_unitdir} \
553diff --git a/debian/patches/configure-Fix-GDB_CFLAGS-typo.patch b/debian/patches/configure-Fix-GDB_CFLAGS-typo.patch
554new file mode 100644
555index 00000000..8c1340d6
556--- /dev/null
557+++ b/debian/patches/configure-Fix-GDB_CFLAGS-typo.patch
558@@ -0,0 +1,27 @@
559+From: Jan Friesse <jfriesse@redhat.com>
560+Date: Mon, 10 Jun 2019 10:56:10 +0200
561+Subject: configure: Fix GDB_CFLAGS typo
562+
563+GDB_FLAGS (without C) is the correct name of variable
564+to print in the summary.
565+
566+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
567+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
568+(cherry picked from commit 45d19a2d90bc2e926974e5668f85c17b37688637)
569+---
570+ configure.ac | 2 +-
571+ 1 file changed, 1 insertion(+), 1 deletion(-)
572+
573+diff --git a/configure.ac b/configure.ac
574+index 82479f9..22b7898 100644
575+--- a/configure.ac
576++++ b/configure.ac
577+@@ -746,7 +746,7 @@ AC_MSG_RESULT([$PACKAGE build info:])
578+ AC_MSG_RESULT([ Library SONAME = ${SONAME}])
579+ LIB_MSG_RESULT(m4_shift(local_soname_list))dnl
580+ AC_MSG_RESULT([ Default optimization = ${OPT_CFLAGS}])
581+-AC_MSG_RESULT([ Default debug options = ${GDB_CFLAGS}])
582++AC_MSG_RESULT([ Default debug options = ${GDB_FLAGS}])
583+ AC_MSG_RESULT([ Extra compiler warnings = ${EXTRA_WARNING}])
584+ AC_MSG_RESULT([ Env. defined CFLAG = ${ENV_CFLAGS}])
585+ AC_MSG_RESULT([ Env. defined CPPFLAGS = ${ENV_CPPFLAGS}])
586diff --git a/debian/patches/AC_PROG_SED-is-already-present.patch b/debian/patches/configure.ac-AC_PROG_SED-is-already-present.patch
587similarity index 62%
588rename from debian/patches/AC_PROG_SED-is-already-present.patch
589rename to debian/patches/configure.ac-AC_PROG_SED-is-already-present.patch
590index 7547a7e7..fa970bcf 100644
591--- a/debian/patches/AC_PROG_SED-is-already-present.patch
592+++ b/debian/patches/configure.ac-AC_PROG_SED-is-already-present.patch
593@@ -1,7 +1,13 @@
594 From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi@debian.org>
595 Date: Tue, 29 Jan 2019 15:15:27 +0100
596-Subject: AC_PROG_SED is already present
597+Subject: configure.ac: AC_PROG_SED is already present
598+MIME-Version: 1.0
599+Content-Type: text/plain; charset="utf-8"
600+Content-Transfer-Encoding: 8bit
601
602+Signed-off-by: Ferenc Wágner <wferi@debian.org>
603+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
604+(cherry picked from commit b9cc5be3a2ee7acd45486c821785cddffba3a48e)
605 ---
606 configure.ac | 1 -
607 1 file changed, 1 deletion(-)
608diff --git a/debian/patches/coroparse-Fix-compiler-warning.patch b/debian/patches/coroparse-Fix-compiler-warning.patch
609new file mode 100644
610index 00000000..418a4625
611--- /dev/null
612+++ b/debian/patches/coroparse-Fix-compiler-warning.patch
613@@ -0,0 +1,24 @@
614+From: Jan Friesse <jfriesse@redhat.com>
615+Date: Tue, 26 Feb 2019 13:28:08 +0100
616+Subject: coroparse: Fix compiler warning
617+
618+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
619+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
620+(cherry picked from commit 7c825173deae33645d4c24d091a86162ac5ba28e)
621+---
622+ exec/coroparse.c | 2 +-
623+ 1 file changed, 1 insertion(+), 1 deletion(-)
624+
625+diff --git a/exec/coroparse.c b/exec/coroparse.c
626+index bee0a8c..08f8f14 100644
627+--- a/exec/coroparse.c
628++++ b/exec/coroparse.c
629+@@ -596,7 +596,7 @@ static int main_config_parser_cb(const char *path,
630+ * Key_name is used in atoi_error/icmap_set_error, but many of icmap_set*
631+ * are using path, so initialize key_name to valid value
632+ */
633+- strncpy(key_name, path, sizeof(key_name));
634++ strncpy(key_name, path, sizeof(key_name) - 1);
635+
636+ switch (type) {
637+ case PARSER_CB_START:
638diff --git a/debian/patches/corosync-cfgtool-Fix-i-matching.patch b/debian/patches/corosync-cfgtool-Fix-i-matching.patch
639new file mode 100644
640index 00000000..bb8cb73d
641--- /dev/null
642+++ b/debian/patches/corosync-cfgtool-Fix-i-matching.patch
643@@ -0,0 +1,115 @@
644+From: Jan Friesse <jfriesse@redhat.com>
645+Date: Wed, 13 Feb 2019 12:54:55 +0100
646+Subject: corosync-cfgtool: Fix -i matching
647+
648+Previously it was required to use link id together with IP address (ex.
649+"0 127.0.0.1") as a -i parameter.
650+
651+This was reported as not very user friendly. Solution is to split
652+returned interface name and try match link id and ip address
653+separately.
654+
655+Also fix typo in description of parameter -s.
656+
657+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
658+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
659+(cherry picked from commit 4f9e46e7a820986c81a528cae0e0f44a6f17db3c)
660+---
661+ tools/corosync-cfgtool.c | 42 +++++++++++++++++++++++-------------------
662+ man/corosync-cfgtool.8 | 6 +++---
663+ 2 files changed, 26 insertions(+), 22 deletions(-)
664+
665+diff --git a/tools/corosync-cfgtool.c b/tools/corosync-cfgtool.c
666+index ed29694..a43ee1e 100644
667+--- a/tools/corosync-cfgtool.c
668++++ b/tools/corosync-cfgtool.c
669+@@ -1,5 +1,5 @@
670+ /*
671+- * Copyright (c) 2006-2017 Red Hat, Inc.
672++ * Copyright (c) 2006-2019 Red Hat, Inc.
673+ *
674+ * All rights reserved.
675+ *
676+@@ -160,25 +160,29 @@ linkstatusget_do (char *interface_name, int brief)
677+ printf ("Could not get the link status, the error is: %d\n", result);
678+ } else {
679+ for (i = 0; i < interface_count; i++) {
680++ char *cur_iface_name_space = strchr(interface_names[i], ' ');
681++ int show_current_iface;
682++
683+ s = 0;
684+- if ( (interface_name &&
685+- interface_names[i][0] != '\0' &&
686+- (interface_name[0]=='\0' ||
687+- strcasecmp (interface_name, interface_names[i]) == 0)) ||
688+- !interface_name ) {
689+-
690+- /*
691+- * Interface_name is "<linkid> <IP address>"
692+- * separate them out
693+- */
694+- char *space = strchr(interface_names[i], ' ');
695+- if (!space) {
696+- continue;
697+- }
698+- *space = '\0';
699++ /*
700++ * Interface_name is "<linkid> <IP address>"
701++ * separate them out
702++ */
703++ if (!cur_iface_name_space) {
704++ continue;
705++ }
706++ *cur_iface_name_space = '\0';
707++
708++ show_current_iface = 1;
709++ if (interface_name != NULL && interface_name[0] != '\0' &&
710++ strcmp(interface_name, interface_names[i]) != 0 &&
711++ strcmp(interface_name, cur_iface_name_space + 1) != 0) {
712++ show_current_iface = 0;
713++ }
714+
715++ if (show_current_iface) {
716+ printf ("LINK ID %s\n", interface_names[i]);
717+- printf ("\taddr\t= %s\n", space+1);
718++ printf ("\taddr\t= %s\n", cur_iface_name_space + 1);
719+ if((!brief) && (strcmp(interface_status[i], "OK") != 0) &&
720+ (!strstr(interface_status[i], "FAULTY"))) {
721+ len = strlen(interface_status[i]);
722+@@ -361,8 +365,8 @@ static void usage_do (void)
723+ printf ("corosync-cfgtool [[-i <interface ip>] [-b] -s] [-R] [-L] [-k nodeid] [-a nodeid] [-h] [-H]\n\n");
724+ printf ("A tool for displaying and configuring active parameters within corosync.\n");
725+ printf ("options:\n");
726+- printf ("\t-i\tFinds only information about the specified interface IP address when used with -s..\n");
727+- printf ("\t-s\tDisplays the status of the current links on this node(UDP/UDPU), while extended status for KNET.\n");
728++ printf ("\t-i\tFinds only information about the specified interface IP address or link id when used with -s..\n");
729++ printf ("\t-s\tDisplays the status of the current links on this node(UDP/UDPU), with extended status for KNET.\n");
730+ printf ("\t-b\tDisplays the brief status of the current links on this node when used with -s.(KNET only)\n");
731+ printf ("\t-R\tTell all instances of corosync in this cluster to reload corosync.conf.\n");
732+ printf ("\t-L\tTell corosync to reopen all logging files.\n");
733+diff --git a/man/corosync-cfgtool.8 b/man/corosync-cfgtool.8
734+index 9ac3da9..07e63b4 100644
735+--- a/man/corosync-cfgtool.8
736++++ b/man/corosync-cfgtool.8
737+@@ -31,7 +31,7 @@
738+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
739+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
740+ .\" */
741+-.TH "COROSYNC-CFGTOOL" "8" "2018-10-15" "" ""
742++.TH "COROSYNC-CFGTOOL" "8" "2019-02-13" "" ""
743+ .SH "NAME"
744+ corosync-cfgtool \- An administrative tool for corosync.
745+ .SH "SYNOPSIS"
746+@@ -42,10 +42,10 @@ A tool for displaying and configuring active parameters within corosync.
747+ .SH "OPTIONS"
748+ .TP
749+ .B -i
750+-Finds only information about the specified interface IP address with -s.
751++Finds only information about the specified interface IP address or link id with -s.
752+ .TP
753+ .B -s
754+-Displays the status of the current links on this node for UDP/UDPU, while extended status
755++Displays the status of the current links on this node for UDP/UDPU, with extended status
756+ for KNET. If any interfaces are faulty, 1 is returned by the binary. If all interfaces are
757+ active 0 is returned to the shell.
758+ After each link, the nodes on that link are displayed in order with their status,
759diff --git a/debian/patches/corosync.conf.5-fix-grammar.patch b/debian/patches/corosync.conf.5-fix-grammar.patch
760index e28efba4..c0331169 100644
761--- a/debian/patches/corosync.conf.5-fix-grammar.patch
762+++ b/debian/patches/corosync.conf.5-fix-grammar.patch
763@@ -1,13 +1,19 @@
764 From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi@debian.org>
765 Date: Sat, 22 Dec 2018 18:56:01 +0100
766 Subject: corosync.conf.5: fix grammar
767+MIME-Version: 1.0
768+Content-Type: text/plain; charset="utf-8"
769+Content-Transfer-Encoding: 8bit
770
771+Signed-off-by: Ferenc Wágner <wferi@debian.org>
772+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
773+(cherry picked from commit 059c22a1545371175d38d7e7171ec6c3db64a99e)
774 ---
775 man/corosync.conf.5 | 2 +-
776 1 file changed, 1 insertion(+), 1 deletion(-)
777
778 diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
779-index 0e752bc..433a9b2 100644
780+index 0b2ee03..a72650b 100644
781 --- a/man/corosync.conf.5
782 +++ b/man/corosync.conf.5
783 @@ -322,7 +322,7 @@ otherwise use first IPv4 address).
784diff --git a/debian/patches/corosync.conf.5-typography-fixes.patch b/debian/patches/corosync.conf.5-typography-fixes.patch
785index ebfb7f07..4e901a1e 100644
786--- a/debian/patches/corosync.conf.5-typography-fixes.patch
787+++ b/debian/patches/corosync.conf.5-typography-fixes.patch
788@@ -1,13 +1,19 @@
789 From: =?utf-8?q?Ferenc_W=C3=A1gner?= <wferi@debian.org>
790 Date: Sat, 22 Dec 2018 18:58:27 +0100
791 Subject: corosync.conf.5: typography fixes
792+MIME-Version: 1.0
793+Content-Type: text/plain; charset="utf-8"
794+Content-Transfer-Encoding: 8bit
795
796+Signed-off-by: Ferenc Wágner <wferi@debian.org>
797+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
798+(cherry picked from commit 4d0e764310b318a35da984cc125ef99010502172)
799 ---
800 man/corosync.conf.5 | 6 +++++-
801 1 file changed, 5 insertions(+), 1 deletion(-)
802
803 diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
804-index 433a9b2..dd6f3ba 100644
805+index a72650b..aa928bc 100644
806 --- a/man/corosync.conf.5
807 +++ b/man/corosync.conf.5
808 @@ -320,7 +320,11 @@ otherwise use first IPv6 address) and
809diff --git a/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
810new file mode 100644
811index 00000000..a69b53ac
812--- /dev/null
813+++ b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
814@@ -0,0 +1,152 @@
815+From: Jan Friesse <jfriesse@redhat.com>
816+Date: Tue, 16 Apr 2019 12:52:31 +0200
817+Subject: cpg: Add CPG_REASON_UNDEFINED
818+
819+Previously the reason field for the member_list items
820+in cpg_totem_confchg_fn was unset what may be little confusing.
821+
822+Solution is to add a special value CPG_REASON_UNDEFINED and use it for
823+the member_list items.
824+
825+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
826+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
827+(cherry picked from commit 41f9e966bb1cfa70d0f6ec1ce46d9c845845b599)
828+---
829+ include/corosync/cpg.h | 3 ++-
830+ man/cpg_initialize.3.in | 18 ++++++++++--------
831+ man/cpg_model_initialize.3.in | 18 ++++++++++--------
832+ exec/cpg.c | 3 ++-
833+ 4 files changed, 24 insertions(+), 18 deletions(-)
834+
835+diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h
836+index 5ebd478..600bbf7 100644
837+--- a/include/corosync/cpg.h
838++++ b/include/corosync/cpg.h
839+@@ -1,5 +1,5 @@
840+ /*
841+- * Copyright (c) 2006-2011 Red Hat, Inc.
842++ * Copyright (c) 2006-2019 Red Hat, Inc.
843+ *
844+ * All rights reserved.
845+ *
846+@@ -80,6 +80,7 @@ typedef enum {
847+ * @brief The cpg_reason_t enum
848+ */
849+ typedef enum {
850++ CPG_REASON_UNDEFINED = 0,
851+ CPG_REASON_JOIN = 1,
852+ CPG_REASON_LEAVE = 2,
853+ CPG_REASON_NODEDOWN = 3,
854+diff --git a/man/cpg_initialize.3.in b/man/cpg_initialize.3.in
855+index bdecc1e..38c7de5 100644
856+--- a/man/cpg_initialize.3.in
857++++ b/man/cpg_initialize.3.in
858+@@ -1,5 +1,5 @@
859+ .\"/*
860+-.\" * Copyright (c) 2006-2009 Red Hat, Inc.
861++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
862+ .\" *
863+ .\" * All rights reserved.
864+ .\" *
865+@@ -31,7 +31,7 @@
866+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
867+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
868+ .\" */
869+-.TH CPG_INITIALIZE 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
870++.TH CPG_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
871+ .SH NAME
872+ cpg_initialize \- Create a new connection to the CPG service
873+ .SH SYNOPSIS
874+@@ -132,18 +132,20 @@ struct cpg_address {
875+ .IP
876+ .PP
877+ where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
878+-or sent the message, and reason is an integer code indicating why the node joined/left the group.
879++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
880++set for the member_list items).
881+ .PP
882+ .IP
883+ .RS
884+ .ne 18
885+ .nf
886+ .PP
887+-CPG_REASON_JOIN - the process joined a group using cpg_join().
888+-CPG_REASON_LEAVE - the process left a group using cpg_leave()
889+-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
890+-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
891+-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
892++CPG_REASON_JOIN - the process joined a group using cpg_join().
893++CPG_REASON_LEAVE - the process left a group using cpg_leave()
894++CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
895++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
896++CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
897++CPG_REASON_UNDEFINED - a special value used for the member_list items
898+ .ta
899+ .fi
900+ .RE
901+diff --git a/man/cpg_model_initialize.3.in b/man/cpg_model_initialize.3.in
902+index e06325d..17ca16a 100644
903+--- a/man/cpg_model_initialize.3.in
904++++ b/man/cpg_model_initialize.3.in
905+@@ -1,5 +1,5 @@
906+ .\"/*
907+-.\" * Copyright (c) 2010 Red Hat, Inc.
908++.\" * Copyright (c) 2010-2019 Red Hat, Inc.
909+ .\" *
910+ .\" * All rights reserved.
911+ .\" *
912+@@ -32,7 +32,7 @@
913+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
914+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
915+ .\" */
916+-.TH CPG_MODEL_INITIALIZE 3 2010-04-07 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
917++.TH CPG_MODEL_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
918+ .SH NAME
919+ cpg_model_initialize \- Create a new connection to the CPG service
920+ .SH SYNOPSIS
921+@@ -166,18 +166,20 @@ struct cpg_address {
922+ .IP
923+ .PP
924+ where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
925+-or sent the message, and reason is an integer code indicating why the node joined/left the group.
926++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
927++set for the member_list items).
928+ .PP
929+ .IP
930+ .RS
931+ .ne 18
932+ .nf
933+ .PP
934+-CPG_REASON_JOIN - the process joined a group using cpg_join().
935+-CPG_REASON_LEAVE - the process left a group using cpg_leave()
936+-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
937+-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
938+-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
939++CPG_REASON_JOIN - the process joined a group using cpg_join().
940++CPG_REASON_LEAVE - the process left a group using cpg_leave()
941++CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
942++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
943++CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
944++CPG_REASON_UNDEFINED - a special value used for the member_list items
945+ .ta
946+ .fi
947+ .RE
948+diff --git a/exec/cpg.c b/exec/cpg.c
949+index b7ac579..e39ca34 100644
950+--- a/exec/cpg.c
951++++ b/exec/cpg.c
952+@@ -1,5 +1,5 @@
953+ /*
954+- * Copyright (c) 2006-2015 Red Hat, Inc.
955++ * Copyright (c) 2006-2019 Red Hat, Inc.
956+ *
957+ * All rights reserved.
958+ *
959+@@ -712,6 +712,7 @@ static int notify_lib_joinlist(
960+ if (!founded) {
961+ retgi->nodeid = pi->nodeid;
962+ retgi->pid = pi->pid;
963++ retgi->reason = CPG_REASON_UNDEFINED;
964+ retgi++;
965+ }
966+ }
967diff --git a/debian/patches/crypto-re-introduce-secauth-parameter.patch b/debian/patches/crypto-re-introduce-secauth-parameter.patch
968new file mode 100644
969index 00000000..84e009e2
970--- /dev/null
971+++ b/debian/patches/crypto-re-introduce-secauth-parameter.patch
972@@ -0,0 +1,62 @@
973+From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
974+Date: Wed, 10 Apr 2019 09:43:33 +0200
975+Subject: crypto: re-introduce secauth parameter
976+MIME-Version: 1.0
977+Content-Type: text/plain; charset="utf-8"
978+Content-Transfer-Encoding: 8bit
979+
980+with the following semantics:
981+- default off
982+- implies crypto_hash SHA256 and crypto_cipher AES256
983+- crypto_* have higher precedence
984+- only applicable for knet, like crypto_*
985+
986+this should make upgrading from Corosync 2.x less painful for users that
987+have an explicit secauth=on in their configuration.
988+
989+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
990+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
991+(cherry picked from commit b97ca8e9f026aaaf2fe9cf697d89803004587f60)
992+---
993+ exec/totemconfig.c | 8 ++++++++
994+ man/corosync.conf.5 | 8 ++++++++
995+ 2 files changed, 16 insertions(+)
996+
997+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
998+index 4f69fd5..1954f76 100644
999+--- a/exec/totemconfig.c
1000++++ b/exec/totemconfig.c
1001+@@ -450,6 +450,14 @@ static int totem_get_crypto(struct totem_config *totem_config, const char **erro
1002+ tmp_model = "nss";
1003+ }
1004+
1005++ if (icmap_get_string("totem.secauth", &str) == CS_OK) {
1006++ if (strcmp(str, "on") == 0) {
1007++ tmp_cipher = "aes256";
1008++ tmp_hash = "sha256";
1009++ }
1010++ free(str);
1011++ }
1012++
1013+ if (icmap_get_string("totem.crypto_cipher", &str) == CS_OK) {
1014+ if (strcmp(str, "none") == 0) {
1015+ tmp_cipher = "none";
1016+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1017+index 887a52b..e2fd9ed 100644
1018+--- a/man/corosync.conf.5
1019++++ b/man/corosync.conf.5
1020+@@ -227,6 +227,14 @@ transmission is only supported for the knet transport.
1021+
1022+ The default is none.
1023+
1024++.TP
1025++secauth
1026++This implies crypto_cipher=aes256 and crypto_hash=sha256, unless those options
1027++are explicitly set. Encrypted transmission is only supported for the knet
1028++transport.
1029++
1030++The default is off.
1031++
1032+ .TP
1033+ keyfile
1034+ This specifies the fully qualified path to the shared key used to
1035diff --git a/debian/patches/doc-Update-INSTALL-file.patch b/debian/patches/doc-Update-INSTALL-file.patch
1036new file mode 100644
1037index 00000000..0404de43
1038--- /dev/null
1039+++ b/debian/patches/doc-Update-INSTALL-file.patch
1040@@ -0,0 +1,124 @@
1041+From: Jan Friesse <jfriesse@redhat.com>
1042+Date: Wed, 16 Jan 2019 14:39:42 +0100
1043+Subject: doc: Update INSTALL file
1044+
1045+- Add LibQB and Knet links
1046+- Remove old (pre udpu) config file example
1047+- Change corosync.conf man page to contain useful information about
1048+token timeout
1049+
1050+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
1051+Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
1052+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
1053+(cherry picked from commit ce29717491160dec3104245af1fa98910e1e6951)
1054+---
1055+ INSTALL | 58 ++++++++---------------------------------------------
1056+ man/corosync.conf.5 | 5 ++++-
1057+ 2 files changed, 12 insertions(+), 51 deletions(-)
1058+
1059+diff --git a/INSTALL b/INSTALL
1060+index 85655ca..bfe684d 100644
1061+--- a/INSTALL
1062++++ b/INSTALL
1063+@@ -43,7 +43,8 @@ balance:~/corosync# make install
1064+ * A notice about dependencies *
1065+ -------------------------------
1066+ We have strived very hard to avoid dependencies as much as possible, but there
1067+-are two required libraries: LibQB and KNET.
1068++are two required libraries: LibQB (https://github.com/ClusterLabs/libqb)
1069++and KNET (https://kronosnet.org/).
1070+
1071+ Optional dependencies are support for DBUS, SNMP and libstatgrab.
1072+
1073+@@ -102,54 +103,11 @@ And you should get traps
1074+ ------------------------
1075+ * Configuring Corosync *
1076+ ------------------------
1077+-The corosync executive will automatically determine cluster membership by
1078+-communicating on a specified multicast address and port.
1079+-
1080+-The directory conf contains the file corosync.conf.example
1081+-
1082+-# Please read the corosync.conf.5 manual page
1083+-totem {
1084+- version: 2
1085+- secauth: off
1086+- threads: 0
1087+- interface {
1088+- ringnumber: 0
1089+- bindnetaddr: 192.168.1.1
1090+- mcastaddr: 226.94.1.1
1091+- mcastport: 5405
1092+- }
1093+-}
1094+-
1095+-logging {
1096+- fileline: off
1097+- to_stderr: yes
1098+- to_file: yes
1099+- to_syslog: yes
1100+- logfile: /tmp/corosync.log
1101+- debug: off
1102+- timestamp: on
1103+-}
1104+-
1105+-The totem section contains three values. All three values must be set
1106+-or the corosync executive wll exit with an error.
1107+-
1108+-bindnetaddr specifies the address which the corosync Executive should bind to.
1109+-This address should always end in zero. If the local interface taffic
1110+-should routed over is 192.168.5.92, set bindnetaddr to 192.168.5.0.
1111+-
1112+-mcastaddr is a multicast address. The default should work but you may have
1113+-a different network configuration. Avoid 224.x.x.x because this is a "config"
1114+-multicast address.
1115+-
1116+-mcastport specifies the UDP port number. It is possible to use the same
1117+-multicast address on a network with the corosync services configured for
1118+-different UDP ports.
1119+-
1120+-The timeout section contains seven values. This section is not normally used,
1121+-but rather used to override the program defaults for the purposes of fine
1122+-tuning for a given networking/processor combination or for debugging purposes.
1123+-Be careful to use the same timeout values on each of the nodes in the cluster
1124+-or unpredictable results may occur.
1125++The configuration directory (usually /etc/corosync) contains an example
1126++configuration file (corosync.conf.example). Please copy it as corosync.conf
1127++and edit it as needed. At the very minimum, the nodelist section will have to be changed
1128++to list all cluster nodes. For more information about the configuration file
1129++please read the corosync.conf.5 manual page.
1130+
1131+ Generate a private key
1132+ ----------------------
1133+@@ -161,7 +119,7 @@ First generate the key on one of the nodes:
1134+
1135+ balance# corosync-keygen
1136+ Corosync Authentication key generator.
1137+-Gathering 1024 bits for key from /dev/random.
1138++Gathering 8192 bits for key from /dev/random.
1139+ Writing corosync key to /etc/corosync/authkey.
1140+
1141+ After this is complete, a private key will be in the file /etc/corosync/authkey.
1142+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1143+index 0e752bc..0b2ee03 100644
1144+--- a/man/corosync.conf.5
1145++++ b/man/corosync.conf.5
1146+@@ -32,7 +32,7 @@
1147+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
1148+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
1149+ .\" */
1150+-.TH COROSYNC_CONF 5 2019-01-10 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
1151++.TH COROSYNC_CONF 5 2019-01-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
1152+ .SH NAME
1153+ corosync.conf - corosync executive configuration file
1154+
1155+@@ -347,6 +347,9 @@ For real token timeout used by totem it's possible to read cmap value of
1156+ .B runtime.config.totem.token
1157+ key.
1158+
1159++Be careful to use the same timeout values on each of the nodes in the cluster
1160++or unpredictable results may occur.
1161++
1162+ The default is 1000 milliseconds.
1163+
1164+ .TP
1165diff --git a/debian/patches/keygen-Reflect-change-in-knet.patch b/debian/patches/keygen-Reflect-change-in-knet.patch
1166new file mode 100644
1167index 00000000..068f481f
1168--- /dev/null
1169+++ b/debian/patches/keygen-Reflect-change-in-knet.patch
1170@@ -0,0 +1,100 @@
1171+From: Jan Friesse <jfriesse@redhat.com>
1172+Date: Tue, 9 Apr 2019 17:09:34 +0200
1173+Subject: keygen: Reflect change in knet
1174+
1175+Knet commit 1cb36f0cffd4559971826ca4774a88c5b05882fb reduced minimal
1176+key length to 1024-bit. Keygen should keep compatibility with already
1177+released 3.0.[0-1] so default key length should be 2048 bits. It's
1178+possible to use -s argument to generate shorter key - keygen respects
1179+minimum/maximum as defined by knet.
1180+
1181+Also fix man page to reflect this change.
1182+
1183+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
1184+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
1185+(cherry picked from commit c260bce45b1f5b4a82c74513c4b3302d32daf179)
1186+---
1187+ tools/corosync-keygen.c | 4 ++--
1188+ man/corosync-keygen.8 | 21 +++++++++------------
1189+ 2 files changed, 11 insertions(+), 14 deletions(-)
1190+
1191+diff --git a/tools/corosync-keygen.c b/tools/corosync-keygen.c
1192+index 40e4d6e..243661a 100644
1193+--- a/tools/corosync-keygen.c
1194++++ b/tools/corosync-keygen.c
1195+@@ -1,6 +1,6 @@
1196+ /*
1197+ * Copyright (c) 2004 MontaVista Software, Inc.
1198+- * Copyright (c) 2005-2017 Red Hat, Inc.
1199++ * Copyright (c) 2005-2019 Red Hat, Inc.
1200+ *
1201+ * All rights reserved.
1202+ *
1203+@@ -52,7 +52,7 @@
1204+
1205+ #define DEFAULT_KEYFILE COROSYSCONFDIR "/authkey"
1206+
1207+-#define DEFAULT_KEYFILE_LEN TOTEM_PRIVATE_KEY_LEN_MIN
1208++#define DEFAULT_KEYFILE_LEN 256
1209+
1210+ #define DEFAULT_RANDOM_DEV "/dev/urandom"
1211+
1212+diff --git a/man/corosync-keygen.8 b/man/corosync-keygen.8
1213+index 0839621..8767ddc 100644
1214+--- a/man/corosync-keygen.8
1215++++ b/man/corosync-keygen.8
1216+@@ -1,5 +1,5 @@
1217+ .\"/*
1218+-.\" * Copyright (C) 2010-2017 Red Hat, Inc.
1219++.\" * Copyright (C) 2010-2019 Red Hat, Inc.
1220+ .\" *
1221+ .\" * All rights reserved.
1222+ .\" *
1223+@@ -31,7 +31,7 @@
1224+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
1225+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
1226+ .\" */
1227+-.TH COROSYNC-KEYGEN 8 2017-07-03
1228++.TH COROSYNC-KEYGEN 8 2019-04-09
1229+ .SH NAME
1230+ corosync-keygen \- Generate an authentication key for Corosync.
1231+ .SH SYNOPSIS
1232+@@ -69,7 +69,7 @@ Random number source file. Default is /dev/urandom. As an example /dev/random ma
1233+ used when really superb randomness is needed.
1234+ .TP
1235+ .B -s size
1236+-Size of the generated key in bytes. Default is 1024 bytes. Allowed range is <1024, 4096>.
1237++Size of the generated key in bytes. Default is 256 bytes. Allowed range is <128, 4096>.
1238+ .TP
1239+ .TP
1240+ .B -l
1241+@@ -84,7 +84,7 @@ Generate the key.
1242+ .nf
1243+ # corosync-keygen
1244+ Corosync Cluster Engine Authentication key generator.
1245+-Gathering 8192 bits for key from /dev/urandom.
1246++Gathering 2048 bits for key from /dev/urandom.
1247+ Writing corosync key to /etc/corosync/authkey
1248+ .fi
1249+
1250+@@ -101,15 +101,12 @@ Writing corosync key to /tmp/authkey.
1251+ Generate superb key using /dev/random
1252+ .nf
1253+ # corosync-keygen -r /dev/random
1254+-Corosync Cluster Engine Authentication key generator.
1255+-Gathering 8192 bits for key from /dev/random.
1256++Gathering 2048 bits for key from /dev/random.
1257+ Press keys on your keyboard to generate entropy.
1258+-Press keys on your keyboard to generate entropy (7928 bits still needed).
1259+-Press keys on your keyboard to generate entropy (7880 bits still needed).
1260+- ...
1261+-Press keys on your keyboard to generate entropy (104 bits still needed).
1262+-Press keys on your keyboard to generate entropy (56 bits still needed).
1263+-Press keys on your keyboard to generate entropy (8 bits still needed).
1264++Press keys on your keyboard to generate entropy (1128 bits still needed).
1265++Press keys on your keyboard to generate entropy (504 bits still needed).
1266++Press keys on your keyboard to generate entropy (128 bits still needed).
1267++Press keys on your keyboard to generate entropy (32 bits still needed).
1268+ Writing corosync key to /etc/corosync/authkey.
1269+ .fi
1270+
1271diff --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
1272new file mode 100644
1273index 00000000..1b3fd495
1274--- /dev/null
1275+++ b/debian/patches/knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
1276@@ -0,0 +1,82 @@
1277+From: Christine Caulfield <ccaulfie@redhat.com>
1278+Date: Thu, 2 May 2019 14:22:47 +0100
1279+Subject: knet: Fix a couple of errors when adding a new link
1280+
1281+When adding a new link for the first time you will often see:
1282+1) knet_link_set_ping_timers for nodeid 1, link 1 failed: Invalid
1283+argument (22)
1284+2) New config has different knet transport for link 1. Internal value
1285+was NOT changed. To reconfigure an interface it must be deleted and
1286+recreated. A working interface needs to be available to corosync at all
1287+times
1288+
1289+1) is caused by setting the ping timers twice, once in
1290+totemknet_member_add() and once in totemknet_refresh_config().
1291+The first time we don't know the value
1292+so it's zero and thus display an error. For this we simply check
1293+for the zero and skip the knet API call. It's not ideal, but
1294+totemconfig needs a lot of reconfiguring itself before we can
1295+make this more sane.
1296+
1297+2) was caused by simply comparing an unconfigured link with
1298+a configured one, so OF COURSE, they are going to be different!
1299+
1300+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
1301+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
1302+(cherry picked from commit 01ce5a96ef9dea2d517d84abec7aecc6af99e7aa)
1303+---
1304+ exec/totemconfig.c | 3 ++-
1305+ exec/totemknet.c | 26 +++++++++++++++-----------
1306+ 2 files changed, 17 insertions(+), 12 deletions(-)
1307+
1308+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
1309+index 3b4dbae..091eedc 100644
1310+--- a/exec/totemconfig.c
1311++++ b/exec/totemconfig.c
1312+@@ -1152,7 +1152,8 @@ static void check_things_have_not_changed(struct totem_config *totem_config)
1313+ int changed = 0;
1314+
1315+ for (i = 0; i<INTERFACE_MAX; i++) {
1316+- if (totem_config->interfaces[i].configured) {
1317++ if (totem_config->interfaces[i].configured &&
1318++ totem_config->orig_interfaces[i].configured) {
1319+ if (totem_config->interfaces[i].knet_transport !=
1320+ totem_config->orig_interfaces[i].knet_transport) {
1321+ log_printf(LOGSYS_LEVEL_ERROR,
1322+diff --git a/exec/totemknet.c b/exec/totemknet.c
1323+index 77cb65a..2c3f47f 100644
1324+--- a/exec/totemknet.c
1325++++ b/exec/totemknet.c
1326+@@ -1306,17 +1306,21 @@ int totemknet_member_add (
1327+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_priority for nodeid %d, link %d failed", member->nodeid, link_no);
1328+ }
1329+
1330+- err = knet_link_set_ping_timers(instance->knet_handle, member->nodeid, link_no,
1331+- instance->totem_config->interfaces[link_no].knet_ping_interval,
1332+- instance->totem_config->interfaces[link_no].knet_ping_timeout,
1333+- instance->totem_config->interfaces[link_no].knet_ping_precision);
1334+- if (err) {
1335+- KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_ping_timers for nodeid %d, link %d failed", member->nodeid, link_no);
1336+- }
1337+- err = knet_link_set_pong_count(instance->knet_handle, member->nodeid, link_no,
1338+- instance->totem_config->interfaces[link_no].knet_pong_count);
1339+- if (err) {
1340+- KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_pong_count for nodeid %d, link %d failed", member->nodeid, link_no);
1341++ /* ping timeouts maybe 0 here for a newly added interface so we leave this till later, it will
1342++ get done in totemknet_refresh_config */
1343++ if (instance->totem_config->interfaces[link_no].knet_ping_interval != 0) {
1344++ err = knet_link_set_ping_timers(instance->knet_handle, member->nodeid, link_no,
1345++ instance->totem_config->interfaces[link_no].knet_ping_interval,
1346++ instance->totem_config->interfaces[link_no].knet_ping_timeout,
1347++ instance->totem_config->interfaces[link_no].knet_ping_precision);
1348++ if (err) {
1349++ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_ping_timers for nodeid %d, link %d failed", member->nodeid, link_no);
1350++ }
1351++ err = knet_link_set_pong_count(instance->knet_handle, member->nodeid, link_no,
1352++ instance->totem_config->interfaces[link_no].knet_pong_count);
1353++ if (err) {
1354++ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_link_set_pong_count for nodeid %d, link %d failed", member->nodeid, link_no);
1355++ }
1356+ }
1357+
1358+ err = knet_link_set_enable(instance->knet_handle, member->nodeid, link_no, 1);
1359diff --git a/debian/patches/knet-Fix-initialising-of-knet-access-lists.patch b/debian/patches/knet-Fix-initialising-of-knet-access-lists.patch
1360new file mode 100644
1361index 00000000..b50865ec
1362--- /dev/null
1363+++ b/debian/patches/knet-Fix-initialising-of-knet-access-lists.patch
1364@@ -0,0 +1,70 @@
1365+From: Christine Caulfield <ccaulfie@redhat.com>
1366+Date: Tue, 19 Mar 2019 10:47:58 +0000
1367+Subject: knet: Fix initialising of knet access lists.
1368+
1369+It needs to be done at both reload and initialize time.
1370+Also disable access lists if the config key is removed.
1371+
1372+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
1373+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
1374+(cherry picked from commit 482df5d67b6b9fe021a1252537c4c499a66de0f8)
1375+---
1376+ exec/totemknet.c | 31 ++++++++++++++++++++++---------
1377+ 1 file changed, 22 insertions(+), 9 deletions(-)
1378+
1379+diff --git a/exec/totemknet.c b/exec/totemknet.c
1380+index 7984b55..884eefe 100644
1381+--- a/exec/totemknet.c
1382++++ b/exec/totemknet.c
1383+@@ -737,6 +737,24 @@ static void timer_function_netif_check_timeout (
1384+ }
1385+ }
1386+
1387++static void knet_set_access_list_config(struct totemknet_instance *instance)
1388++{
1389++#ifdef HAVE_KNET_ACCESS_LIST
1390++ uint32_t value = 0; /* disable by default */
1391++ cs_error_t err;
1392++
1393++ if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
1394++ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
1395++ }
1396++
1397++ err = knet_handle_enable_access_lists(instance->knet_handle, value);
1398++ if (err) {
1399++ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
1400++ }
1401++#endif
1402++}
1403++
1404++
1405+ /* NOTE: this relies on the fact that totem_reload_notify() is called first */
1406+ static void totemknet_refresh_config(
1407+ int32_t event,
1408+@@ -764,15 +782,7 @@ static void totemknet_refresh_config(
1409+ return;
1410+ }
1411+
1412+-#ifdef HAVE_KNET_ACCESS_LIST
1413+- if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
1414+- knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
1415+- err = knet_handle_enable_access_lists(instance->knet_handle, value);
1416+- if (err) {
1417+- KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
1418+- }
1419+- }
1420+-#endif
1421++ knet_set_access_list_config(instance);
1422+
1423+ if (icmap_get_uint32("totem.knet_pmtud_interval", &value) == CS_OK) {
1424+
1425+@@ -944,6 +954,9 @@ int totemknet_initialize (
1426+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_CRIT, "knet_handle_new failed");
1427+ goto exit_error;
1428+ }
1429++
1430++ knet_set_access_list_config(instance);
1431++
1432+ res = knet_handle_pmtud_setfreq(instance->knet_handle, instance->totem_config->knet_pmtud_interval);
1433+ if (res) {
1434+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_pmtud_setfreq failed");
1435diff --git a/debian/patches/knet-Use-block_unlisted_ips.patch b/debian/patches/knet-Use-block_unlisted_ips.patch
1436new file mode 100644
1437index 00000000..c3ff3092
1438--- /dev/null
1439+++ b/debian/patches/knet-Use-block_unlisted_ips.patch
1440@@ -0,0 +1,67 @@
1441+From: Jan Friesse <jfriesse@redhat.com>
1442+Date: Fri, 24 May 2019 09:33:13 +0200
1443+Subject: knet: Use block_unlisted_ips
1444+
1445+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
1446+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
1447+(cherry picked from commit 9bba026bcd99bfc27c24e749262210513bd43ccc)
1448+---
1449+ exec/coroparse.c | 3 ---
1450+ exec/totemknet.c | 7 +++----
1451+ man/corosync.conf.5 | 7 +------
1452+ 3 files changed, 4 insertions(+), 13 deletions(-)
1453+
1454+diff --git a/exec/coroparse.c b/exec/coroparse.c
1455+index 87bbceb..0acb4c2 100644
1456+--- a/exec/coroparse.c
1457++++ b/exec/coroparse.c
1458+@@ -708,9 +708,6 @@ static int main_config_parser_cb(const char *path,
1459+ (strcmp(path, "totem.miss_count_const") == 0) ||
1460+ (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
1461+ (strcmp(path, "totem.knet_compression_threshold") == 0) ||
1462+-#ifdef HAVE_KNET_ACCESS_LIST
1463+- (strcmp(path, "totem.knet_enable_access_lists") == 0) ||
1464+-#endif
1465+ (strcmp(path, "totem.netmtu") == 0)) {
1466+ val_type = ICMAP_VALUETYPE_UINT32;
1467+ if (safe_atoq(value, &val, val_type) != 0) {
1468+diff --git a/exec/totemknet.c b/exec/totemknet.c
1469+index 884eefe..2af69b3 100644
1470+--- a/exec/totemknet.c
1471++++ b/exec/totemknet.c
1472+@@ -740,12 +740,11 @@ static void timer_function_netif_check_timeout (
1473+ static void knet_set_access_list_config(struct totemknet_instance *instance)
1474+ {
1475+ #ifdef HAVE_KNET_ACCESS_LIST
1476+- uint32_t value = 0; /* disable by default */
1477++ uint32_t value;
1478+ cs_error_t err;
1479+
1480+- if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
1481+- knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
1482+- }
1483++ value = instance->totem_config->block_unlisted_ips;
1484++ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
1485+
1486+ err = knet_handle_enable_access_lists(instance->knet_handle, value);
1487+ if (err) {
1488+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1489+index 953c830..0e1ef88 100644
1490+--- a/man/corosync.conf.5
1491++++ b/man/corosync.conf.5
1492+@@ -566,14 +566,9 @@ knet_pmtud_interval
1493+ How often the knet PMTUd runs to look for network MTU changes.
1494+ Value in seconds, default: 30
1495+
1496+-.TP
1497+-knet_enable_access_lists
1498+-Allow knet to drop packets from IP addresses that are not known to corosync.
1499+-Value is 0 (off) and 1 (on). Default: 0.
1500+-
1501+ .TP
1502+ block_unlisted_ips
1503+-Allow UDPU to drop packets from IP addresses that are not known
1504++Allow UDPU and KNET to drop packets from IP addresses that are not known
1505+ (nodes which don't exist in the nodelist) to corosync.
1506+ Value is yes or no.
1507+
1508diff --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
1509new file mode 100644
1510index 00000000..f5cb424d
1511--- /dev/null
1512+++ b/debian/patches/knet-allow-corosync-to-use-knet-access-lists.patch
1513@@ -0,0 +1,93 @@
1514+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
1515+Date: Sun, 10 Mar 2019 08:23:38 +0100
1516+Subject: knet: allow corosync to use knet access lists
1517+MIME-Version: 1.0
1518+Content-Type: text/plain; charset="utf-8"
1519+Content-Transfer-Encoding: 8bit
1520+
1521+currently knet acl are only available on master
1522+but they might be backported
1523+to stable1 as they don´t break onwire protocol.
1524+
1525+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
1526+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
1527+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
1528+(cherry picked from commit 5c9a2b1c0676aa7581b31b5cfb6ae2d969abd1b2)
1529+---
1530+ configure.ac | 9 +++++++++
1531+ exec/coroparse.c | 3 +++
1532+ exec/totemknet.c | 10 ++++++++++
1533+ man/corosync.conf.5 | 5 +++++
1534+ 4 files changed, 27 insertions(+)
1535+
1536+diff --git a/configure.ac b/configure.ac
1537+index a27ba95..82479f9 100644
1538+--- a/configure.ac
1539++++ b/configure.ac
1540+@@ -180,6 +180,15 @@ AC_CHECK_LIB([z], [crc32],
1541+ AM_CONDITIONAL([HAVE_CRC32], true),
1542+ AM_CONDITIONAL([HAVE_CRC32], false))
1543+
1544++# this hack is necessary to check for symbols on out of tree builds
1545++# but it is as horrible as it gets and in theory users should be
1546++# invoking ./configure with proper LIBRARY_PATH set.
1547++OLDLIBS="$LIBS"
1548++LIBS="$knet_LIBS $LIBS"
1549++AC_CHECK_LIB([knet],[knet_handle_enable_access_lists],
1550++ [AC_DEFINE_UNQUOTED([HAVE_KNET_ACCESS_LIST], 1, [have knet access list])])
1551++LIBS="$OLDLIBS"
1552++
1553+ # Checks for library functions.
1554+ AC_FUNC_ALLOCA
1555+ AC_FUNC_CLOSEDIR_VOID
1556+diff --git a/exec/coroparse.c b/exec/coroparse.c
1557+index 0acb4c2..87bbceb 100644
1558+--- a/exec/coroparse.c
1559++++ b/exec/coroparse.c
1560+@@ -708,6 +708,9 @@ static int main_config_parser_cb(const char *path,
1561+ (strcmp(path, "totem.miss_count_const") == 0) ||
1562+ (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
1563+ (strcmp(path, "totem.knet_compression_threshold") == 0) ||
1564++#ifdef HAVE_KNET_ACCESS_LIST
1565++ (strcmp(path, "totem.knet_enable_access_lists") == 0) ||
1566++#endif
1567+ (strcmp(path, "totem.netmtu") == 0)) {
1568+ val_type = ICMAP_VALUETYPE_UINT32;
1569+ if (safe_atoq(value, &val, val_type) != 0) {
1570+diff --git a/exec/totemknet.c b/exec/totemknet.c
1571+index 2c3f47f..7984b55 100644
1572+--- a/exec/totemknet.c
1573++++ b/exec/totemknet.c
1574+@@ -764,6 +764,16 @@ static void totemknet_refresh_config(
1575+ return;
1576+ }
1577+
1578++#ifdef HAVE_KNET_ACCESS_LIST
1579++ if (icmap_get_uint32("totem.knet_enable_access_lists", &value) == CS_OK) {
1580++ knet_log_printf (LOGSYS_LEVEL_DEBUG, "knet_enable access list: %d", value);
1581++ err = knet_handle_enable_access_lists(instance->knet_handle, value);
1582++ if (err) {
1583++ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING, "knet_handle_enable_access_lists failed");
1584++ }
1585++ }
1586++#endif
1587++
1588+ if (icmap_get_uint32("totem.knet_pmtud_interval", &value) == CS_OK) {
1589+
1590+ instance->totem_config->knet_pmtud_interval = value;
1591+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1592+index 5fef28a..674179d 100644
1593+--- a/man/corosync.conf.5
1594++++ b/man/corosync.conf.5
1595+@@ -566,6 +566,11 @@ knet_pmtud_interval
1596+ How often the knet PMTUd runs to look for network MTU changes.
1597+ Value in seconds, default: 30
1598+
1599++.TP
1600++knet_enable_access_lists
1601++Allow knet to drop packets from IP addresses that are not known to corosync.
1602++Value is 0 (off) and 1 (on). Default: 0.
1603++
1604+ .PP
1605+ Within the
1606+ .B logging
1607diff --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
1608new file mode 100644
1609index 00000000..c13e4f97
1610--- /dev/null
1611+++ b/debian/patches/man-Add-vqsim-man-page-into-distributed-tarball.patch
1612@@ -0,0 +1,40 @@
1613+From: Jan Friesse <jfriesse@redhat.com>
1614+Date: Mon, 10 Jun 2019 08:04:50 +0200
1615+Subject: man: Add vqsim man page into distributed tarball
1616+
1617+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
1618+(cherry picked from commit 8ced7e545dde485ac57886e8713330ec82eaa35c)
1619+---
1620+ man/Makefile.am | 5 ++++-
1621+ 1 file changed, 4 insertions(+), 1 deletion(-)
1622+
1623+diff --git a/man/Makefile.am b/man/Makefile.am
1624+index 8e4eda3..2ef5dcd 100644
1625+--- a/man/Makefile.am
1626++++ b/man/Makefile.am
1627+@@ -37,6 +37,8 @@ MAINTAINERCLEANFILES = Makefile.in
1628+ xml_man = corosync-xmlproc.8 \
1629+ corosync.xml.5
1630+
1631++corosync_vqsim_man = corosync-vqsim.8
1632++
1633+ INDEX_HTML = index.html
1634+
1635+ autogen_man = cpg_context_get.3 \
1636+@@ -116,6 +118,7 @@ autogen_common = ipc_common.sh.errors
1637+
1638+ EXTRA_DIST = $(INDEX_HTML) \
1639+ $(xml_man) \
1640++ $(corosync_vqsim_man) \
1641+ $(autogen_man:%=%.in) \
1642+ $(autogen_common)
1643+
1644+@@ -140,7 +143,7 @@ dist_man_MANS = corosync.conf.5 \
1645+ cmap_keys.8
1646+
1647+ if BUILD_VQSIM
1648+-dist_man_MANS += corosync-vqsim.8
1649++dist_man_MANS += $(corosync_vqsim_man)
1650+ endif
1651+
1652+ if INSTALL_XMLCONF
1653diff --git a/debian/patches/man-Enahnce-block_unlisted_ips-description.patch b/debian/patches/man-Enahnce-block_unlisted_ips-description.patch
1654new file mode 100644
1655index 00000000..effd8231
1656--- /dev/null
1657+++ b/debian/patches/man-Enahnce-block_unlisted_ips-description.patch
1658@@ -0,0 +1,33 @@
1659+From: Jan Friesse <jfriesse@redhat.com>
1660+Date: Fri, 31 May 2019 09:34:33 +0200
1661+Subject: man: Enahnce block_unlisted_ips description
1662+
1663+Thanks Christine Caulfield <ccaulfie@redhat.com> for
1664+Englishify and refining the description.
1665+
1666+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
1667+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
1668+(cherry picked from commit d775f1425d6ebbfa25c7ba43c0fc69902507a8d6)
1669+---
1670+ man/corosync.conf.5 | 8 ++++++++
1671+ 1 file changed, 8 insertions(+)
1672+
1673+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1674+index ba1397f..3b77733 100644
1675+--- a/man/corosync.conf.5
1676++++ b/man/corosync.conf.5
1677+@@ -572,6 +572,14 @@ Allow UDPU and KNET to drop packets from IP addresses that are not known
1678+ (nodes which don't exist in the nodelist) to corosync.
1679+ Value is yes or no.
1680+
1681++This feature is mainly to protect against the joining of nodes
1682++with outdated configurations after a cluster split.
1683++Another use case is to allow the atomic merge of two independent clusters.
1684++
1685++Changing the default value is not recommended, the overhead is tiny and
1686++an existing cluster may fail if corosync is started on an unlisted node
1687++with an old configuration.
1688++
1689+ The default value is yes.
1690+
1691+ .PP
1692diff --git a/debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch b/debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch
1693new file mode 100644
1694index 00000000..33098378
1695--- /dev/null
1696+++ b/debian/patches/man-Enhance-corosync.conf-mp-a-bit.patch
1697@@ -0,0 +1,37 @@
1698+From: Jan Friesse <jfriesse@redhat.com>
1699+Date: Tue, 28 May 2019 10:08:37 +0200
1700+Subject: man: Enhance corosync.conf mp a bit
1701+
1702+Fix issues found by Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>
1703+
1704+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
1705+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
1706+(cherry picked from commit 183d5da5eb3d74043464dbc5d6e92f8b38a2e9cb)
1707+---
1708+ man/corosync.conf.5 | 6 +++---
1709+ 1 file changed, 3 insertions(+), 3 deletions(-)
1710+
1711+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1712+index 0e1ef88..ba1397f 100644
1713+--- a/man/corosync.conf.5
1714++++ b/man/corosync.conf.5
1715+@@ -191,7 +191,7 @@ version
1716+ This specifies the version of the configuration file. Currently the only
1717+ valid version for this directive is 2.
1718+
1719+-.PP
1720++.TP
1721+ clear_node_high_bit
1722+ This configuration option is optional and is only relevant when no nodeid is
1723+ specified. Some corosync clients require a signed 32 bit nodeid that is greater
1724+@@ -432,8 +432,8 @@ The default is 180 milliseconds.
1725+ .TP
1726+ token_retransmits_before_loss_const
1727+ This value identifies how many token retransmits should be attempted before
1728+-forming a new configuration. If this value is set, retransmit and hold will
1729+-be automatically calculated from retransmits_before_loss and token.
1730++forming a new configuration. It is also used for token_retransmit
1731++and hold calculations.
1732+
1733+ The default is 4 retransmissions.
1734+
1735diff --git a/debian/patches/man-Enhance-token_retransmit-description.patch b/debian/patches/man-Enhance-token_retransmit-description.patch
1736new file mode 100644
1737index 00000000..9b9f3def
1738--- /dev/null
1739+++ b/debian/patches/man-Enhance-token_retransmit-description.patch
1740@@ -0,0 +1,28 @@
1741+From: yuan ren <yren@suse.com>
1742+Date: Thu, 16 May 2019 18:31:44 +0800
1743+Subject: man: Enhance token_retransmit description
1744+
1745+Signed-off-by: yuan ren <yren@suse.com>
1746+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
1747+(cherry picked from commit 3e8b525e3289e19c773e18c7fce9812393356ddc)
1748+---
1749+ man/corosync.conf.5 | 6 +++++-
1750+ 1 file changed, 5 insertions(+), 1 deletion(-)
1751+
1752+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
1753+index e2fd9ed..5fef28a 100644
1754+--- a/man/corosync.conf.5
1755++++ b/man/corosync.conf.5
1756+@@ -394,7 +394,11 @@ the token is retransmitted. This will be automatically calculated if token
1757+ is modified. It is not recommended to alter this value without guidance from
1758+ the corosync community.
1759+
1760+-The default is 238 milliseconds.
1761++The minimum is 30 milliseconds. If not set and error occur, make sure
1762++token / (token_retransmits_before_loss_const + 0.2) is more than 30.
1763++
1764++The default is 238 milliseconds for two nodes cluster. Three or more nodes reference
1765++.B token_coefficient.
1766+
1767+ .TP
1768+ knet_compression_model
1769diff --git a/debian/patches/nozzle-Add-support-for-libnozzle-devices.patch b/debian/patches/nozzle-Add-support-for-libnozzle-devices.patch
1770new file mode 100644
1771index 00000000..47f9bda6
1772--- /dev/null
1773+++ b/debian/patches/nozzle-Add-support-for-libnozzle-devices.patch
1774@@ -0,0 +1,707 @@
1775+From: Christine Caulfield <ccaulfie@redhat.com>
1776+Date: Tue, 15 Jan 2019 15:18:18 +0000
1777+Subject: nozzle: Add support for libnozzle devices
1778+
1779+A nozzle device is a pseudo ethernet device that routes network
1780+traffic through a channel on the corosync knet network (NOT cpg or any
1781+corosync internal service) to other nodes in the cluster. It allows
1782+applications to take advantage of knet features such as multipathing,
1783+automatic failover, link switching etc.
1784+
1785+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
1786+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
1787+(cherry picked from commit eab55e7384c33f16d3d9b2c9c9d0878ddd234e38)
1788+---
1789+ configure.ac | 6 +
1790+ exec/Makefile.am | 4 +-
1791+ exec/cfg.c | 1 +
1792+ exec/totemknet.c | 413 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1793+ man/corosync.conf.5 | 68 +++++++--
1794+ 5 files changed, 476 insertions(+), 16 deletions(-)
1795+
1796+diff --git a/configure.ac b/configure.ac
1797+index c85edf8..95cdb35 100644
1798+--- a/configure.ac
1799++++ b/configure.ac
1800+@@ -174,6 +174,7 @@ LIBS="$SAVE_LIBS"
1801+ AC_CHECK_LIB([pthread], [pthread_create])
1802+ AC_CHECK_LIB([socket], [socket])
1803+ PKG_CHECK_MODULES([knet],[libknet])
1804++PKG_CHECK_MODULES([nozzle],[libnozzle], [AC_DEFINE_UNQUOTED([HAVE_LIBNOZZLE], 1, [Have libnozzle])], [have_nozzle="no"])
1805+ AC_CHECK_LIB([nsl], [t_open])
1806+ AC_CHECK_LIB([rt], [sched_getscheduler])
1807+ AC_CHECK_LIB([z], [crc32],
1808+@@ -404,6 +405,11 @@ ENV_CFLAGS="$CFLAGS"
1809+ ENV_CPPFLAGS="$CPPFLAGS"
1810+ ENV_LDFLAGS="$LDFLAGS"
1811+
1812++# Add nozzle to Package features if enabled
1813++if test "x$have_nozzle" != xno; then
1814++ PACKAGE_FEATURES="$PACKAGE_FEATURES nozzle"
1815++fi
1816++
1817+ # debug build stuff
1818+ if test "x${enable_debug}" = xyes; then
1819+ AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
1820+diff --git a/exec/Makefile.am b/exec/Makefile.am
1821+index 4602663..1c31f8c 100644
1822+--- a/exec/Makefile.am
1823++++ b/exec/Makefile.am
1824+@@ -59,10 +59,10 @@ endif
1825+
1826+ corosync_CPPFLAGS = -DLOGCONFIG_USE_ICMAP=1
1827+
1828+-corosync_CFLAGS = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS)
1829++corosync_CFLAGS = $(statgrab_CFLAGS) $(libsystemd_CFLAGS) $(knet_CFLAGS) $(nozzle_CFLAGS)
1830+
1831+ corosync_LDADD = ../common_lib/libcorosync_common.la \
1832+- $(LIBQB_LIBS) $(statgrab_LIBS) $(libsystemd_LIBS) $(knet_LIBS)
1833++ $(LIBQB_LIBS) $(statgrab_LIBS) $(libsystemd_LIBS) $(knet_LIBS) $(nozzle_LIBS)
1834+
1835+ corosync_DEPENDENCIES = ../common_lib/libcorosync_common.la
1836+
1837+diff --git a/exec/cfg.c b/exec/cfg.c
1838+index dec7dbf..c02f739 100644
1839+--- a/exec/cfg.c
1840++++ b/exec/cfg.c
1841+@@ -701,6 +701,7 @@ static void message_handler_req_exec_cfg_reload_config (
1842+ remove_deleted_entries(temp_map, "nodelist.");
1843+ remove_deleted_entries(temp_map, "quorum.");
1844+ remove_deleted_entries(temp_map, "uidgid.config.");
1845++ remove_deleted_entries(temp_map, "nozzle.");
1846+
1847+ /* Remove entries that cannot be changed */
1848+ remove_ro_entries(temp_map);
1849+diff --git a/exec/totemknet.c b/exec/totemknet.c
1850+index 1098bdb..77cb65a 100644
1851+--- a/exec/totemknet.c
1852++++ b/exec/totemknet.c
1853+@@ -1,6 +1,5 @@
1854+-
1855+ /*
1856+- * Copyright (c) 2016-2018 Red Hat, Inc.
1857++ * Copyright (c) 2016-2019 Red Hat, Inc.
1858+ *
1859+ * All rights reserved.
1860+ *
1861+@@ -45,6 +44,7 @@
1862+ #include <sys/ioctl.h>
1863+ #include <sys/param.h>
1864+ #include <netinet/in.h>
1865++#include <net/ethernet.h>
1866+ #include <arpa/inet.h>
1867+ #include <unistd.h>
1868+ #include <fcntl.h>
1869+@@ -60,6 +60,10 @@
1870+
1871+ #include <qb/qbdefs.h>
1872+ #include <qb/qbloop.h>
1873++#ifdef HAVE_LIBNOZZLE
1874++#include <libgen.h>
1875++#include <libnozzle.h>
1876++#endif
1877+
1878+ #include <corosync/sq.h>
1879+ #include <corosync/swab.h>
1880+@@ -68,6 +72,7 @@
1881+ #include <corosync/totem/totemip.h>
1882+ #include "totemknet.h"
1883+
1884++#include "main.h"
1885+ #include "util.h"
1886+
1887+ #include <libknet.h>
1888+@@ -77,6 +82,10 @@
1889+ #define MSG_NOSIGNAL 0
1890+ #endif
1891+
1892++#ifdef HAVE_LIBNOZZLE
1893++static int setup_nozzle(void *knet_context);
1894++#endif
1895++
1896+ /* Should match that used by cfg */
1897+ #define CFG_INTERFACE_STATUS_MAX_LEN 512
1898+
1899+@@ -162,6 +171,13 @@ struct totemknet_instance {
1900+
1901+ int logpipes[2];
1902+ int knet_fd;
1903++#ifdef HAVE_LIBNOZZLE
1904++ char *nozzle_name;
1905++ char *nozzle_ipaddr;
1906++ char *nozzle_prefix;
1907++ char *nozzle_macaddr;
1908++ nozzle_t nozzle_handle;
1909++#endif
1910+ };
1911+
1912+ /* Awkward. But needed to get stats from knet */
1913+@@ -217,6 +233,46 @@ do { \
1914+ } while(0)
1915+
1916+
1917++#ifdef HAVE_LIBNOZZLE
1918++static inline int is_ether_addr_multicast(const uint8_t *addr)
1919++{
1920++ return (addr[0] & 0x01);
1921++}
1922++static inline int is_ether_addr_zero(const uint8_t *addr)
1923++{
1924++ return (!addr[0] && !addr[1] && !addr[2] && !addr[3] && !addr[4] && !addr[5]);
1925++}
1926++
1927++static int ether_host_filter_fn(void *private_data,
1928++ const unsigned char *outdata,
1929++ ssize_t outdata_len,
1930++ uint8_t tx_rx,
1931++ knet_node_id_t this_host_id,
1932++ knet_node_id_t src_host_id,
1933++ int8_t *channel,
1934++ knet_node_id_t *dst_host_ids,
1935++ size_t *dst_host_ids_entries)
1936++{
1937++ struct ether_header *eth_h = (struct ether_header *)outdata;
1938++ uint8_t *dst_mac = (uint8_t *)eth_h->ether_dhost;
1939++ uint16_t dst_host_id;
1940++
1941++ if (is_ether_addr_zero(dst_mac))
1942++ return -1;
1943++
1944++ if (is_ether_addr_multicast(dst_mac)) {
1945++ return 1;
1946++ }
1947++
1948++ memmove(&dst_host_id, &dst_mac[4], 2);
1949++
1950++ dst_host_ids[0] = ntohs(dst_host_id);
1951++ *dst_host_ids_entries = 1;
1952++
1953++ return 0;
1954++}
1955++#endif
1956++
1957+ static int dst_host_filter_callback_fn(void *private_data,
1958+ const unsigned char *outdata,
1959+ ssize_t outdata_len,
1960+@@ -230,7 +286,17 @@ static int dst_host_filter_callback_fn(void *private_data,
1961+ struct totem_message_header *header = (struct totem_message_header *)outdata;
1962+ int res;
1963+
1964+- *channel = 0;
1965++#ifdef HAVE_LIBNOZZLE
1966++ if (*channel != 0) {
1967++ return ether_host_filter_fn(private_data,
1968++ outdata, outdata_len,
1969++ tx_rx,
1970++ this_host_id, src_host_id,
1971++ channel,
1972++ dst_host_ids,
1973++ dst_host_ids_entries);
1974++ }
1975++#endif
1976+ if (header->target_nodeid) {
1977+ dst_host_ids[0] = header->target_nodeid;
1978+ *dst_host_ids_entries = 1;
1979+@@ -1334,6 +1400,11 @@ int totemknet_reconfigure (
1980+ KNET_LOGSYS_PERROR(errno, LOGSYS_LEVEL_ERROR, "knet_handle_compress failed");
1981+ }
1982+ }
1983++
1984++#ifdef HAVE_LIBNOZZLE
1985++ /* Set up nozzle device(s) */
1986++ setup_nozzle(instance);
1987++#endif
1988+ return (res);
1989+ }
1990+
1991+@@ -1454,3 +1525,339 @@ static void log_flush_messages (void *knet_context)
1992+ }
1993+ }
1994+ }
1995++
1996++
1997++#ifdef HAVE_LIBNOZZLE
1998++#define NOZZLE_NAME "nozzle.name"
1999++#define NOZZLE_IPADDR "nozzle.ipaddr"
2000++#define NOZZLE_PREFIX "nozzle.ipprefix"
2001++#define NOZZLE_MACADDR "nozzle.macaddr"
2002++
2003++#define NOZZLE_CHANNEL 1
2004++
2005++
2006++static char *get_nozzle_script_dir(void *knet_context)
2007++{
2008++ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
2009++ char filename[PATH_MAX + FILENAME_MAX + 1];
2010++ static char updown_dirname[PATH_MAX + FILENAME_MAX + 1];
2011++ int res;
2012++ const char *dirname_res;
2013++
2014++ /*
2015++ * Build script directory based on corosync.conf file location
2016++ */
2017++ res = snprintf(filename, sizeof(filename), "%s",
2018++ corosync_get_config_file());
2019++ if (res >= sizeof(filename)) {
2020++ knet_log_printf (LOGSYS_LEVEL_DEBUG, "nozzle up/down path too long");
2021++ return NULL;
2022++ }
2023++
2024++ dirname_res = dirname(filename);
2025++
2026++ res = snprintf(updown_dirname, sizeof(updown_dirname), "%s/%s",
2027++ dirname_res, "updown.d");
2028++ if (res >= sizeof(updown_dirname)) {
2029++ knet_log_printf (LOGSYS_LEVEL_DEBUG, "nozzle up/down path too long");
2030++ return NULL;
2031++ }
2032++ return updown_dirname;
2033++}
2034++
2035++/*
2036++ * Deliberately doesn't return the status as caller doesn't care.
2037++ * The result will be logged though
2038++ */
2039++static void run_nozzle_script(struct totemknet_instance *instance, int type, const char *typename)
2040++{
2041++ int res;
2042++ char *exec_string;
2043++
2044++ res = nozzle_run_updown(instance->nozzle_handle, type, &exec_string);
2045++ if (res == -1 && errno != ENOENT) {
2046++ knet_log_printf (LOGSYS_LEVEL_INFO, "exec nozzle %s script failed: %s", typename, strerror(errno));
2047++ } else if (res == -2) {
2048++ knet_log_printf (LOGSYS_LEVEL_INFO, "nozzle %s script failed", typename);
2049++ knet_log_printf (LOGSYS_LEVEL_INFO, "%s", exec_string);
2050++ }
2051++}
2052++
2053++/*
2054++ * Reparse IP address to add in our node ID
2055++ * IPv6 addresses must end in '::'
2056++ * IPv4 addresses must just be valid
2057++ * '/xx' lengths are optional for IPv6, mandatory for IPv4
2058++ *
2059++ * Returns the modified IP address as a string to pass into libnozzle
2060++ */
2061++static int reparse_nozzle_ip_address(struct totemknet_instance *instance,
2062++ const char *input_addr,
2063++ const char *prefix, int nodeid,
2064++ char *output_addr, size_t output_len)
2065++{
2066++ char *coloncolon;
2067++ int bits;
2068++ int max_prefix = 64;
2069++ uint32_t nodeid_mask;
2070++ uint32_t addr_mask;
2071++ uint32_t masked_nodeid;
2072++ struct in_addr *addr;
2073++ struct totem_ip_address totemip;
2074++
2075++ coloncolon = strstr(input_addr, "::");
2076++ if (!coloncolon) {
2077++ max_prefix = 30;
2078++ }
2079++
2080++ bits = atoi(prefix);
2081++ if (bits < 8 || bits > max_prefix) {
2082++ knet_log_printf(LOGSYS_LEVEL_ERROR, "nozzle IP address prefix must be >= 8 and <= %d (got %d)", max_prefix, bits);
2083++ return -1;
2084++ }
2085++
2086++ /* IPv6 is easy */
2087++ if (coloncolon) {
2088++ memcpy(output_addr, input_addr, coloncolon-input_addr);
2089++ sprintf(output_addr + (coloncolon-input_addr), "::%x", nodeid);
2090++ return 0;
2091++ }
2092++
2093++ /* For IPv4 we need to parse the address into binary, mask off the required bits,
2094++ * add in the masked_nodeid and 'print' it out again
2095++ */
2096++ nodeid_mask = UINT32_MAX & ((1<<(32 - bits)) - 1);
2097++ addr_mask = UINT32_MAX ^ nodeid_mask;
2098++ masked_nodeid = nodeid & nodeid_mask;
2099++
2100++ if (totemip_parse(&totemip, input_addr, AF_INET)) {
2101++ knet_log_printf(LOGSYS_LEVEL_ERROR, "Failed to parse IPv4 nozzle IP address");
2102++ return -1;
2103++ }
2104++ addr = (struct in_addr *)&totemip.addr;
2105++ addr->s_addr &= htonl(addr_mask);
2106++ addr->s_addr |= htonl(masked_nodeid);
2107++
2108++ inet_ntop(AF_INET, addr, output_addr, output_len);
2109++ return 0;
2110++}
2111++
2112++static int create_nozzle_device(void *knet_context, const char *name,
2113++ const char *ipaddr, const char *prefix,
2114++ const char *macaddr)
2115++{
2116++ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
2117++ char device_name[IFNAMSIZ+1];
2118++ size_t size = IFNAMSIZ;
2119++ int8_t channel = NOZZLE_CHANNEL;
2120++ nozzle_t nozzle_dev;
2121++ int nozzle_fd;
2122++ int res;
2123++ char *updown_dir;
2124++ char parsed_ipaddr[INET6_ADDRSTRLEN];
2125++ char mac[19];
2126++
2127++ memset(device_name, 0, size);
2128++ memset(&mac, 0, sizeof(mac));
2129++ strncpy(device_name, name, size);
2130++
2131++ updown_dir = get_nozzle_script_dir(knet_context);
2132++ knet_log_printf (LOGSYS_LEVEL_INFO, "nozzle script dir is %s", updown_dir);
2133++
2134++ nozzle_dev = nozzle_open(device_name, size, updown_dir);
2135++ if (!nozzle_dev) {
2136++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to init nozzle device %s: %s", device_name, strerror(errno));
2137++ return -1;
2138++ }
2139++ instance->nozzle_handle = nozzle_dev;
2140++
2141++ if (nozzle_set_mac(nozzle_dev, macaddr) < 0) {
2142++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle MAC to %s: %s", mac, strerror(errno));
2143++ goto out_clean;
2144++ }
2145++
2146++ if (reparse_nozzle_ip_address(instance, ipaddr, prefix, instance->our_nodeid, parsed_ipaddr, sizeof(parsed_ipaddr))) {
2147++ /* Prints its own errors */
2148++ goto out_clean;
2149++ }
2150++ knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle IP address is %s / %d", parsed_ipaddr, atoi(prefix));
2151++ if (ipaddr) {
2152++ if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
2153++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
2154++ goto out_clean;
2155++ }
2156++ }
2157++
2158++ nozzle_fd = nozzle_get_fd(nozzle_dev);
2159++ knet_log_printf (LOGSYS_LEVEL_INFO, "Opened '%s' on fd %d", device_name, nozzle_fd);
2160++
2161++ res = knet_handle_add_datafd(instance->knet_handle, &nozzle_fd, &channel);
2162++ if (res != 0) {
2163++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add nozzle FD to knet: %s", strerror(errno));
2164++ goto out_clean;
2165++ }
2166++
2167++ run_nozzle_script(instance, NOZZLE_PREUP, "pre-up");
2168++
2169++ res = nozzle_set_up(nozzle_dev);
2170++ if (res != 0) {
2171++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to set nozzle interface UP: %s", strerror(errno));
2172++ goto out_clean;
2173++ }
2174++ run_nozzle_script(instance, NOZZLE_UP, "up");
2175++
2176++ return 0;
2177++
2178++out_clean:
2179++ nozzle_close(nozzle_dev);
2180++ return -1;
2181++}
2182++
2183++static int remove_nozzle_device(void *knet_context)
2184++{
2185++ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
2186++ int res;
2187++ int datafd;
2188++
2189++ res = knet_handle_get_datafd(instance->knet_handle, NOZZLE_CHANNEL, &datafd);
2190++ if (res != 0) {
2191++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't find datafd for channel %d: %s", NOZZLE_CHANNEL, strerror(errno));
2192++ return -1;
2193++ }
2194++
2195++ res = knet_handle_remove_datafd(instance->knet_handle, datafd);
2196++ if (res != 0) {
2197++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't remove datafd for nozzle channel %d: %s", NOZZLE_CHANNEL, strerror(errno));
2198++ return -1;
2199++ }
2200++
2201++ run_nozzle_script(instance, NOZZLE_DOWN, "pre-down");
2202++ res = nozzle_set_down(instance->nozzle_handle);
2203++ if (res != 0) {
2204++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't set nozzle device down: %s", strerror(errno));
2205++ return -1;
2206++ }
2207++ run_nozzle_script(instance, NOZZLE_POSTDOWN, "post-down");
2208++
2209++ res = nozzle_close(instance->nozzle_handle);
2210++ if (res != 0) {
2211++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Can't close nozzle device: %s", strerror(errno));
2212++ return -1;
2213++ }
2214++ knet_log_printf (LOGSYS_LEVEL_INFO, "Removed nozzle device");
2215++ return 0;
2216++}
2217++
2218++static void free_nozzle(struct totemknet_instance *instance)
2219++{
2220++ free(instance->nozzle_name);
2221++ free(instance->nozzle_ipaddr);
2222++ free(instance->nozzle_prefix);
2223++ free(instance->nozzle_macaddr);
2224++
2225++ instance->nozzle_name = instance->nozzle_ipaddr = instance->nozzle_prefix =
2226++ instance->nozzle_macaddr = NULL;
2227++}
2228++
2229++static int setup_nozzle(void *knet_context)
2230++{
2231++ struct totemknet_instance *instance = (struct totemknet_instance *)knet_context;
2232++ char *ipaddr_str = NULL;
2233++ char *name_str = NULL;
2234++ char *prefix_str = NULL;
2235++ char *macaddr_str = NULL;
2236++ char mac[32];
2237++ int name_res;
2238++ int macaddr_res;
2239++ int res;
2240++
2241++ icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
2242++ icmap_get_string(NOZZLE_PREFIX, &prefix_str);
2243++ macaddr_res = icmap_get_string(NOZZLE_MACADDR, &macaddr_str);
2244++ name_res = icmap_get_string(NOZZLE_NAME, &name_str);
2245++
2246++ /* Is is being removed? */
2247++ if (name_res == CS_ERR_NOT_EXIST && instance->nozzle_handle) {
2248++ remove_nozzle_device(instance);
2249++ free_nozzle(instance);
2250++ goto out_free;
2251++ }
2252++
2253++ if (!name_str) {
2254++ /* no nozzle */
2255++ goto out_free;
2256++ }
2257++
2258++ if (!ipaddr_str) {
2259++ knet_log_printf (LOGSYS_LEVEL_ERROR, "No IP address supplied for Nozzle device");
2260++ goto out_free;
2261++ }
2262++
2263++ if (!prefix_str) {
2264++ knet_log_printf (LOGSYS_LEVEL_ERROR, "No prefix supplied for Nozzle IP address");
2265++ goto out_free;
2266++ }
2267++
2268++ if (macaddr_str && strlen(macaddr_str) != 17) {
2269++ knet_log_printf (LOGSYS_LEVEL_ERROR, "macaddr for nozzle device is not in the correct format '%s'", macaddr_str);
2270++ goto out_free;
2271++ }
2272++ if (!macaddr_str) {
2273++ macaddr_str = (char*)"54:54:01:00:00:00";
2274++ }
2275++
2276++ if (instance->nozzle_name &&
2277++ (strcmp(name_str, instance->nozzle_name) == 0) &&
2278++ (strcmp(ipaddr_str, instance->nozzle_ipaddr) == 0) &&
2279++ (strcmp(prefix_str, instance->nozzle_prefix) == 0) &&
2280++ ((macaddr_str == NULL && instance->nozzle_macaddr == NULL) ||
2281++ strcmp(macaddr_str, instance->nozzle_macaddr) == 0)) {
2282++ /* Nothing has changed */
2283++ knet_log_printf (LOGSYS_LEVEL_DEBUG, "Nozzle device info not changed");
2284++ goto out_free;
2285++ }
2286++
2287++ /* Add nodeid into MAC address */
2288++ memcpy(mac, macaddr_str, 12);
2289++ snprintf(mac+12, sizeof(mac) - 13, "%02x:%02x",
2290++ instance->our_nodeid >> 8,
2291++ instance->our_nodeid & 0xFF);
2292++ knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle MAC address is %s", mac);
2293++
2294++ if (name_res == CS_OK && name_str) {
2295++ /* Reconfigure */
2296++ if (instance->nozzle_name) {
2297++ remove_nozzle_device(instance);
2298++ free_nozzle(instance);
2299++ }
2300++
2301++ res = create_nozzle_device(knet_context, name_str, ipaddr_str, prefix_str,
2302++ mac);
2303++
2304++ instance->nozzle_name = strdup(name_str);
2305++ instance->nozzle_ipaddr = strdup(ipaddr_str);
2306++ instance->nozzle_prefix = strdup(prefix_str);
2307++ instance->nozzle_macaddr = strdup(macaddr_str);
2308++ if (!instance->nozzle_name || !instance->nozzle_ipaddr ||
2309++ !instance->nozzle_prefix) {
2310++ knet_log_printf (LOGSYS_LEVEL_ERROR, "strdup failed in nozzle allocation");
2311++ /*
2312++ * This 'free' will cause a complete reconfigure of the device next time we reload
2313++ * but will also let the the current device keep working until then.
2314++ * remove_nozzle() only needs the, statically-allocated, nozzle_handle
2315++ */
2316++ free_nozzle(instance);
2317++ }
2318++ }
2319++
2320++out_free:
2321++ free(name_str);
2322++ free(ipaddr_str);
2323++ free(prefix_str);
2324++ if (macaddr_res == CS_OK) {
2325++ free(macaddr_str);
2326++ }
2327++
2328++ return res;
2329++}
2330++#endif // HAVE_LIBNOZZLE
2331+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
2332+index aa928bc..52eb7b1 100644
2333+--- a/man/corosync.conf.5
2334++++ b/man/corosync.conf.5
2335+@@ -63,9 +63,12 @@ This top level directive contains configuration options related to system.
2336+ .TP
2337+ resources { }
2338+ This top level directive contains configuration options for resources.
2339++.TP
2340++nozzle { }
2341++This top level directive contains configuration options for a libnozzle device.
2342+
2343+ .PP
2344+-The
2345++The
2346+ .B interface sub-directive of totem is optional for UDP and knet transports.
2347+
2348+ For knet, multiple interface subsections define parameters for each knet link on the
2349+@@ -78,7 +81,7 @@ is used to define cluster nodes.
2350+ linknumber
2351+ This specifies the link number for the interface. When using the knet
2352+ protocol, each interface should specify separate link numbers to uniquely
2353+-identify to the membership protocol which interface to use for which link.
2354++identify to the membership protocol which interface to use for which link.
2355+ The linknumber must start at 0. For UDP the only supported linknumber is 0.
2356+
2357+ .TP
2358+@@ -88,7 +91,7 @@ mode. (see link_mode below)
2359+
2360+ .TP
2361+ knet_ping_interval
2362+-This specifies the interval between knet link pings.
2363++This specifies the interval between knet link pings.
2364+ knet_ping_interval and knet_ping_timeout
2365+ are a pair, if one is specified the other should be too, otherwise one will be calculated from
2366+ the token timeout and one will be taken from the config file.
2367+@@ -96,7 +99,7 @@ the token timeout and one will be taken from the config file.
2368+
2369+ .TP
2370+ knet_ping_timeout
2371+-If no ping is received within this time, the knet link is declared dead.
2372++If no ping is received within this time, the knet link is declared dead.
2373+ knet_ping_interval and knet_ping_timeout
2374+ are a pair, if one is specified the other should be too, otherwise one will be calculated from
2375+ the token timeout and one will be taken from the config file.
2376+@@ -120,7 +123,7 @@ bindnetaddr (udp only)
2377+ This specifies the network address the corosync executive should bind
2378+ to when using udp.
2379+
2380+-bindnetaddr (udp only)
2381++bindnetaddr (udp only)
2382+ should be an IP address configured on the system, or a network
2383+ address.
2384+
2385+@@ -160,9 +163,9 @@ mcastport (udp only)
2386+ This specifies the UDP port number. It is possible to use the same multicast
2387+ address on a network with the corosync services configured for different
2388+ UDP ports.
2389+-Please note corosync uses two UDP ports mcastport (for mcast receives) and
2390++Please note corosync uses two UDP ports mcastport (for mcast receives) and
2391+ mcastport - 1 (for mcast sends).
2392+-If you have multiple clusters on the same network using the same mcastaddr
2393++If you have multiple clusters on the same network using the same mcastaddr
2394+ please configure the mcastports with a gap.
2395+
2396+ .TP
2397+@@ -243,14 +246,14 @@ link_mode
2398+ This specifies the Kronosnet mode, which may be passive, active, or
2399+ rr (round-robin).
2400+ .B passive:
2401+-the active link with the lowest priority will be used. If one or more
2402++the active link with the lowest priority will be used. If one or more
2403+ links share the same priority the one with the lowest link ID will
2404+ be used.
2405+ .B active:
2406+ All active links will be used simultaneously to send traffic.
2407+ link priority is ignored.
2408+ .B rr:
2409+-Round-Robin policy. Each packet will be sent to the next active link in
2410++Round-Robin policy. Each packet will be sent to the next active link in
2411+ order.
2412+
2413+ If only one interface directive is specified, passive is automatically chosen.
2414+@@ -284,7 +287,7 @@ The default is 1500.
2415+
2416+ .TP
2417+ transport
2418+-This directive controls the transport mechanism used.
2419++This directive controls the transport mechanism used.
2420+ The default is knet. The transport type can also be set to udpu or udp.
2421+ Only knet allows crypto or multiple interfaces per node.
2422+
2423+@@ -604,7 +607,7 @@ and
2424+ The default is syslog and stderr.
2425+
2426+ Please note, if you are using to_logfile and want to rotate the file, use logrotate(8)
2427+-with the option
2428++with the option
2429+ .B
2430+ copytruncate.
2431+ eg.
2432+@@ -797,6 +800,49 @@ potentially breaking down membership. IPMI watchdogs are particularly
2433+ notorious in this regard: read about kipmid_max_busy_us in IPMI.txt in
2434+ the Linux kernel documentation.
2435+
2436++
2437++.PP
2438++Within the
2439++.B nozzle
2440++directive it is possible to specify options for a libnozzle device. This is a pseudo
2441++ethernet device that routes network traffic through a channel on the corosync knet network
2442++(NOT cpg or any corosync internal service) to other nodes in the cluster. This allows
2443++applications to take advantage of knet features such as multipathing, automatic failover,
2444++link switching etc. Note that libnozzle is not a reliable transport, but you can tunnel TCP
2445++through it for reliable communications.
2446++.br
2447++libnozzle also supports optional interface up/down scripts that are kept under a
2448++/etc/corosync/updown.d/ directory. See the knet documentation for more information.
2449++.br
2450++Only one nozzle device is allowed.
2451++.br
2452++The nozzle stanza takes several options:
2453++.TP
2454++name
2455++The name of the network device to be created. On Linux this may be any name at all, other
2456++platforms have restrictions on the name.
2457++.TP
2458++ipaddr
2459++The IP address (IPv6 or IPv4) of the interface. The bottom part of this address will be replaced
2460++by the local node's nodeid in conjunction with ipprefix. so, eg
2461++ipaddr: 192.168.1.0
2462++ipprefix: 24
2463++will make nodeids 1,2,5 use IP addresses 192.168.1.1, 192.168.1.2 & 192.168.1.5.
2464++If a prefix length of 16 is used then the bottom two bytes will be filled in with nodeid numbers.
2465++IPv6 addresses must end in '::', the nodeid will be added after the two colons to make the
2466++local IP address.
2467++Only one IP address is currently supported in the corosync.conf file. Additional IP addresses
2468++can be added in the ifup script if necessary.
2469++.TP
2470++ipprefix
2471++specifies the IP address prefix for the nozzle device (see above)
2472++.TP
2473++macaddr
2474++Specifies the MAC address prefix for the nozzle device. As for the IP address, the bottom part
2475++of the MAC address will be filled in with the node id. In this case no prefix applies, the bottom
2476++two bytes of the MAC address will always be overwritten with the node id. So specifying
2477++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
2478++
2479+ .SH "TO ADD A NEW NODE TO THE CLUSTER"
2480+ For example to add a node with address 10.24.38.108 with nodeid 3. The node has the name NEW
2481+ (in DNS or /etc/hosts) and is not currently running corosync. The current corosync.conf nodelist
2482diff --git a/debian/patches/quorumtool-Fix-exit-status-codes.patch b/debian/patches/quorumtool-Fix-exit-status-codes.patch
2483new file mode 100644
2484index 00000000..e001d123
2485--- /dev/null
2486+++ b/debian/patches/quorumtool-Fix-exit-status-codes.patch
2487@@ -0,0 +1,237 @@
2488+From: Jan Friesse <jfriesse@redhat.com>
2489+Date: Thu, 14 Feb 2019 16:05:59 +0100
2490+Subject: quorumtool: Fix exit status codes
2491+
2492+1. Use EXIT_SUCCESS and EXIT_FAILURE when possible
2493+2. For -s option return EXIT_SUCCESS when no problem appeared and node
2494+ is quorate, EXIT_FAILURE if problem appeared and exit code 2
2495+ (EXIT_NOT_QUORATE) when no problem appeared but node is not quorate.
2496+3. Document exit codes in the man page
2497+
2498+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
2499+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
2500+(cherry picked from commit db38e3958c4f88d5d06e8f7c83d6d90334d9fbd2)
2501+---
2502+ tools/corosync-quorumtool.c | 53 ++++++++++++++++++++++++++-------------------
2503+ man/corosync-quorumtool.8 | 17 ++++++++++++++-
2504+ 2 files changed, 47 insertions(+), 23 deletions(-)
2505+
2506+diff --git a/tools/corosync-quorumtool.c b/tools/corosync-quorumtool.c
2507+index 8f128e0..4819951 100644
2508+--- a/tools/corosync-quorumtool.c
2509++++ b/tools/corosync-quorumtool.c
2510+@@ -1,5 +1,5 @@
2511+ /*
2512+- * Copyright (c) 2009-2014 Red Hat, Inc.
2513++ * Copyright (c) 2009-2019 Red Hat, Inc.
2514+ *
2515+ * All rights reserved.
2516+ *
2517+@@ -75,6 +75,8 @@ typedef enum {
2518+ SORT_NODENAME
2519+ } sorttype_t;
2520+
2521++#define EXIT_NOT_QUORATE 2
2522++
2523+ /*
2524+ * global vars
2525+ */
2526+@@ -238,7 +240,7 @@ static int set_votes(uint32_t nodeid, int votes)
2527+ votes, nodeid, cs_strerror(err));
2528+ }
2529+
2530+- return err==CS_OK?0:err;
2531++ return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
2532+ }
2533+
2534+ static int set_expected(int expected_votes)
2535+@@ -249,7 +251,7 @@ static int set_expected(int expected_votes)
2536+ fprintf(stderr, "Unable to set expected votes: %s\n", cs_strerror(err));
2537+ }
2538+
2539+- return err==CS_OK?0:err;
2540++ return (err == CS_OK ? EXIT_SUCCESS : EXIT_FAILURE);
2541+ }
2542+
2543+ /*
2544+@@ -642,9 +644,9 @@ static int display_quorum_data(int is_quorate,
2545+ }
2546+
2547+ /*
2548+- * return 1 if quorate
2549+- * 0 if not quorate
2550+- * -1 on error
2551++ * return EXIT_SUCCESS if quorate
2552++ * EXIT_NOT_QUORATE if not quorate
2553++ * EXIT_FAILURE on error
2554+ */
2555+ static int show_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
2556+ {
2557+@@ -693,15 +695,15 @@ static int show_status(nodeid_format_t nodeid_format, name_format_t name_format,
2558+
2559+ quorum_err:
2560+ if (err != CS_OK) {
2561+- return -1;
2562++ return EXIT_FAILURE;
2563+ }
2564+
2565+ err = display_quorum_data(is_quorate, nodeid_format, name_format, sort_type, 0);
2566+ if (err != CS_OK) {
2567+- return -1;
2568++ return EXIT_FAILURE;
2569+ }
2570+
2571+- return is_quorate;
2572++ return (is_quorate ? EXIT_SUCCESS : EXIT_NOT_QUORATE);
2573+ }
2574+
2575+ static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type) {
2576+@@ -754,7 +756,7 @@ static int monitor_status(nodeid_format_t nodeid_format, name_format_t name_form
2577+ }
2578+
2579+ quorum_err:
2580+- return -1;
2581++ return EXIT_FAILURE;
2582+ }
2583+
2584+ static int show_nodes(nodeid_format_t nodeid_format, name_format_t name_format, sorttype_t sort_type)
2585+@@ -788,23 +790,30 @@ static int unregister_qdevice(void)
2586+ {
2587+ int err;
2588+ struct votequorum_info info;
2589++ int result;
2590++
2591++ result = EXIT_FAILURE;
2592+
2593+ err = votequorum_getinfo(v_handle, our_nodeid, &info);
2594+ if (err != CS_OK) {
2595+ fprintf(stderr, "Unable to get quorum device info: %s\n", cs_strerror(err));
2596+- return -1;
2597++ goto err_exit;
2598+ }
2599+
2600+ if (!(info.flags & VOTEQUORUM_INFO_QDEVICE_REGISTERED)) {
2601+- return 0;
2602++ result = EXIT_SUCCESS;
2603++ goto err_exit;
2604+ }
2605+
2606+ err = votequorum_qdevice_unregister(v_handle, info.qdevice_name);
2607+ if (err != CS_OK) {
2608+ fprintf(stderr, "Unable to unregister quorum device: %s\n", cs_strerror(err));
2609+- return -1;
2610++ goto err_exit;
2611+ }
2612+- return 0;
2613++
2614++ result = EXIT_SUCCESS;
2615++err_exit:
2616++ return result;
2617+ }
2618+
2619+ /*
2620+@@ -888,7 +897,7 @@ int main (int argc, char *argv[]) {
2621+
2622+ if (init_all()) {
2623+ close_all();
2624+- exit(1);
2625++ exit(EXIT_FAILURE);
2626+ }
2627+
2628+ while ( (opt = getopt(argc, argv, options)) != -1 ) {
2629+@@ -898,7 +907,7 @@ int main (int argc, char *argv[]) {
2630+ command_opt = CMD_UNREGISTER_QDEVICE;
2631+ } else {
2632+ fprintf(stderr, "You cannot unregister quorum device, corosync is not using votequorum\n");
2633+- exit(2);
2634++ exit(EXIT_FAILURE);
2635+ }
2636+ break;
2637+ case 's':
2638+@@ -932,14 +941,14 @@ int main (int argc, char *argv[]) {
2639+ }
2640+ } else {
2641+ fprintf(stderr, "You cannot change expected votes, corosync is not using votequorum\n");
2642+- exit(2);
2643++ exit(EXIT_FAILURE);
2644+ }
2645+ break;
2646+ case 'n':
2647+ l = strtol(optarg, &endptr, 0);
2648+ if ((l == 0 && endptr == optarg) || l < 0) {
2649+ fprintf(stderr, "The nodeid was not valid, try a positive number\n");
2650+- exit(2);
2651++ exit(EXIT_FAILURE);
2652+ }
2653+ nodeid = l;
2654+ nodeid_set = 1;
2655+@@ -949,14 +958,14 @@ int main (int argc, char *argv[]) {
2656+ votes = strtol(optarg, &endptr, 0);
2657+ if ((votes == 0 && endptr == optarg) || votes < 0) {
2658+ fprintf(stderr, "New votes value was not valid, try a positive number or zero\n");
2659+- exit(2);
2660++ exit(EXIT_FAILURE);
2661+ } else {
2662+ command_opt = CMD_SETVOTES;
2663+ }
2664+ }
2665+ else {
2666+ fprintf(stderr, "You cannot change node votes, corosync is not using votequorum\n");
2667+- exit(2);
2668++ exit(EXIT_FAILURE);
2669+ }
2670+ break;
2671+ case 'o':
2672+@@ -970,7 +979,7 @@ int main (int argc, char *argv[]) {
2673+ break;
2674+ default:
2675+ fprintf(stderr, "Invalid ordering option. valid orders are a(address), i(node ID) or n(name)\n");
2676+- exit(2);
2677++ exit(EXIT_FAILURE);
2678+ break;
2679+ }
2680+ break;
2681+@@ -989,7 +998,7 @@ int main (int argc, char *argv[]) {
2682+ switch (command_opt) {
2683+ case CMD_UNKNOWN:
2684+ show_usage(argv[0]);
2685+- ret = -1;
2686++ ret = EXIT_FAILURE;
2687+ break;
2688+ case CMD_SHOWNODES:
2689+ ret = show_nodes(nodeid_format, address_format, sort_opt);
2690+diff --git a/man/corosync-quorumtool.8 b/man/corosync-quorumtool.8
2691+index 0fdfccf..24c9112 100644
2692+--- a/man/corosync-quorumtool.8
2693++++ b/man/corosync-quorumtool.8
2694+@@ -31,7 +31,7 @@
2695+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2696+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
2697+ .\" */
2698+-.TH COROSYNC-QUORUMTOOL 8 2012-01-12
2699++.TH COROSYNC-QUORUMTOOL 8 2019-02-14
2700+ .SH NAME
2701+ corosync-quorumtool \- Set and display quorum settings.
2702+ .SH SYNOPSIS
2703+@@ -89,6 +89,21 @@ show this help text
2704+ show version and exit
2705+ .PP
2706+ * Starred items only work if votequorum is the quorum provider for corosync
2707++.SH EXIT STATUS
2708++corosync-quorumtool may return one of several error codes if it encounters problems.
2709++.TP
2710++0
2711++No problems occurred (quorate for
2712++.B -s
2713++operation).
2714++.TP
2715++1
2716++Generic error code.
2717++.TP
2718++2
2719++Not quorate (returned only for
2720++.B -s
2721++operation).
2722+ .SH SEE ALSO
2723+ .BR corosync_overview (7),
2724+ .BR votequorum_overview (3),
2725diff --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
2726new file mode 100644
2727index 00000000..6bd733e7
2728--- /dev/null
2729+++ b/debian/patches/set-totem.keyfile-and-totem.key-to-RO.patch
2730@@ -0,0 +1,44 @@
2731+From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
2732+Date: Wed, 3 Apr 2019 21:57:30 +0200
2733+Subject: set totem.keyfile and totem.key to RO
2734+MIME-Version: 1.0
2735+Content-Type: text/plain; charset="utf-8"
2736+Content-Transfer-Encoding: 8bit
2737+
2738+so that we get the nice log message when attempting to modify them at
2739+runtime, just like for totem.crypto_* and co.
2740+
2741+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2742+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
2743+(cherry picked from commit 03fba21503f1b8395519190cc537f63100e995f5)
2744+---
2745+ exec/cfg.c | 2 ++
2746+ exec/main.c | 2 ++
2747+ 2 files changed, 4 insertions(+)
2748+
2749+diff --git a/exec/cfg.c b/exec/cfg.c
2750+index c02f739..f42cb60 100644
2751+--- a/exec/cfg.c
2752++++ b/exec/cfg.c
2753+@@ -578,6 +578,8 @@ static void remove_ro_entries(icmap_map_t temp_map)
2754+ delete_and_notify_if_changed(temp_map, "totem.secauth");
2755+ delete_and_notify_if_changed(temp_map, "totem.crypto_hash");
2756+ delete_and_notify_if_changed(temp_map, "totem.crypto_cipher");
2757++ delete_and_notify_if_changed(temp_map, "totem.keyfile");
2758++ delete_and_notify_if_changed(temp_map, "totem.key");
2759+ delete_and_notify_if_changed(temp_map, "totem.version");
2760+ delete_and_notify_if_changed(temp_map, "totem.threads");
2761+ delete_and_notify_if_changed(temp_map, "totem.ip_version");
2762+diff --git a/exec/main.c b/exec/main.c
2763+index 8554036..06a519c 100644
2764+--- a/exec/main.c
2765++++ b/exec/main.c
2766+@@ -1036,6 +1036,8 @@ static void set_icmap_ro_keys_flag (void)
2767+ */
2768+ icmap_set_ro_access("totem.crypto_cipher", CS_FALSE, CS_TRUE);
2769+ icmap_set_ro_access("totem.crypto_hash", CS_FALSE, CS_TRUE);
2770++ icmap_set_ro_access("totem.keyfile", CS_FALSE, CS_TRUE);
2771++ icmap_set_ro_access("totem.key", CS_FALSE, CS_TRUE);
2772+ icmap_set_ro_access("totem.secauth", CS_FALSE, CS_TRUE);
2773+ icmap_set_ro_access("totem.ip_version", CS_FALSE, CS_TRUE);
2774+ icmap_set_ro_access("totem.rrp_mode", CS_FALSE, CS_TRUE);
2775diff --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
2776new file mode 100644
2777index 00000000..d7254b82
2778--- /dev/null
2779+++ b/debian/patches/spec-Add-support-for-user-flags-configure-option.patch
2780@@ -0,0 +1,43 @@
2781+From: Jan Friesse <jfriesse@redhat.com>
2782+Date: Fri, 7 Jun 2019 10:20:04 +0200
2783+Subject: spec: Add support for user-flags configure option
2784+
2785+Passing -ggdb3 (or -g3) during compiler may result in corrupted
2786+debuginfo files (bug in debugedit - for Fedora filed as a
2787+https://bugzilla.redhat.com/show_bug.cgi?id=1708786). Until the bug is
2788+fixed it's possible to ether change configure to add -ggdb2/-g2 or use
2789+already existing --enable-user-flags option and rely on environment set
2790+by rpmbuild.
2791+
2792+Patch implements second option so RPM distros without broken debugedit
2793+are not affected.
2794+
2795+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
2796+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
2797+(cherry picked from commit 5cced85cd58905638c81892f79e9f457efac338e)
2798+---
2799+ corosync.spec.in | 4 ++++
2800+ 1 file changed, 4 insertions(+)
2801+
2802+diff --git a/corosync.spec.in b/corosync.spec.in
2803+index 8af686e..c06675d 100644
2804+--- a/corosync.spec.in
2805++++ b/corosync.spec.in
2806+@@ -14,6 +14,7 @@
2807+ %bcond_with nozzle
2808+ %bcond_with vqsim
2809+ %bcond_with runautogen
2810++%bcond_with userflags
2811+
2812+ %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
2813+ %global gittarver %{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}
2814+@@ -107,6 +108,9 @@ BuildRequires: readline-devel
2815+ %endif
2816+ %if %{with vqsim}
2817+ --enable-vqsim \
2818++%endif
2819++%if %{with userflags}
2820++ --enable-user-flags \
2821+ %endif
2822+ --with-initddir=%{_initrddir} \
2823+ --with-systemddir=%{_unitdir} \
2824diff --git a/debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch b/debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
2825new file mode 100644
2826index 00000000..27b55a98
2827--- /dev/null
2828+++ b/debian/patches/totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
2829@@ -0,0 +1,48 @@
2830+From: Jan Friesse <jfriesse@redhat.com>
2831+Date: Wed, 24 Apr 2019 14:47:47 +0200
2832+Subject: totemconfig: Ensure nodeid is specified for IPv6
2833+
2834+Thanks Yuan Ren <yren@suse.com> for finding this problem.
2835+
2836+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
2837+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
2838+(cherry picked from commit 3172a76d12d16dd6c72182e005ac0bc63e58208b)
2839+---
2840+ exec/totemconfig.c | 17 +++++++++++++++++
2841+ 1 file changed, 17 insertions(+)
2842+
2843+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
2844+index b206eeb..6fcd6de 100644
2845+--- a/exec/totemconfig.c
2846++++ b/exec/totemconfig.c
2847+@@ -1258,6 +1258,16 @@ static int put_nodelist_members_to_config(struct totem_config *totem_config, int
2848+ snprintf(tmp_key, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos);
2849+ if (icmap_get_string(tmp_key, &str) == CS_OK) {
2850+ nodeid = generate_nodeid(totem_config, str);
2851++ if (nodeid == -1) {
2852++ sprintf(error_string_response,
2853++ "An IPV6 network requires that a node ID be specified "
2854++ "for address '%s'.", node_addr_str);
2855++ *error_string = error_string_response;
2856++ free(str);
2857++
2858++ return (-1);
2859++ }
2860++
2861+ log_printf(LOGSYS_LEVEL_DEBUG,
2862+ "Generated nodeid = 0x%x for %s", nodeid, str);
2863+ free(str);
2864+@@ -1750,6 +1760,13 @@ extern int totem_config_read (
2865+ icmap_get_string(tmp_key, &str);
2866+
2867+ totem_config->node_id = generate_nodeid(totem_config, str);
2868++ if (totem_config->node_id == -1) {
2869++ *error_string = "An IPV6 network requires that a node ID be specified";
2870++
2871++ free(str);
2872++ return (-1);
2873++ }
2874++
2875+ totem_config->interfaces[0].member_list[local_node_pos].nodeid = totem_config->node_id;
2876+
2877+ free(str);
2878diff --git a/debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch b/debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch
2879new file mode 100644
2880index 00000000..26b553c3
2881--- /dev/null
2882+++ b/debian/patches/totemconfig-Fix-minimum-limit-for-hold-timeout.patch
2883@@ -0,0 +1,67 @@
2884+From: yuan ren <yren@suse.com>
2885+Date: Tue, 14 May 2019 19:33:12 +0800
2886+Subject: totemconfig: Fix minimum limit for hold timeout
2887+
2888+Make sure the retransmit timeout have the lowest limit
2889+`MINIMUM_TIMEOUT`. So, the lowest limit of hold should be
2890+recalculated.
2891+
2892+Also token timeout and retransmits count should
2893+keep a relational expression.
2894+
2895+Signed-off-by: yuan ren <yren@suse.com>
2896+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
2897+(cherry picked from commit 2a4cd3c4af0256cc79e1ed1c7f070fd469e4cfaf)
2898+---
2899+ exec/totemconfig.c | 20 ++++++++++++++------
2900+ 1 file changed, 14 insertions(+), 6 deletions(-)
2901+
2902+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
2903+index 091eedc..262dcac 100644
2904+--- a/exec/totemconfig.c
2905++++ b/exec/totemconfig.c
2906+@@ -74,6 +74,7 @@
2907+ #define FAIL_TO_RECV_CONST 2500
2908+ #define SEQNO_UNCHANGED_CONST 30
2909+ #define MINIMUM_TIMEOUT (int)(1000/HZ)*3
2910++#define MINIMUM_TIMEOUT_HOLD (int)(MINIMUM_TIMEOUT * 0.8 - (1000/HZ))
2911+ #define MAX_NETWORK_DELAY 50
2912+ #define WINDOW_SIZE 50
2913+ #define MAX_MESSAGES 17
2914+@@ -313,6 +314,7 @@ static int totem_volatile_config_validate (
2915+ char name_key[ICMAP_KEYNAME_MAXLEN];
2916+ char *name_str;
2917+ int i, num_configured, members;
2918++ uint32_t tmp_config_value;
2919+
2920+ if (totem_config->max_network_delay < MINIMUM_TIMEOUT) {
2921+ snprintf (local_error_reason, sizeof(local_error_reason),
2922+@@ -336,16 +338,22 @@ static int totem_volatile_config_validate (
2923+ }
2924+
2925+ if (totem_config->token_retransmit_timeout < MINIMUM_TIMEOUT) {
2926+- snprintf (local_error_reason, sizeof(local_error_reason),
2927+- "The token retransmit timeout parameter (%d ms) may not be less than (%d ms).",
2928+- totem_config->token_retransmit_timeout, MINIMUM_TIMEOUT);
2929+- goto parse_error;
2930++ if (icmap_get_uint32("totem.token_retransmit", &tmp_config_value) == CS_OK) {
2931++ snprintf (local_error_reason, sizeof(local_error_reason),
2932++ "The token retransmit timeout parameter (%d ms) may not be less than (%d ms).",
2933++ totem_config->token_retransmit_timeout, MINIMUM_TIMEOUT);
2934++ goto parse_error;
2935++ } else {
2936++ snprintf (local_error_reason, sizeof(local_error_reason),
2937++ "Not appropriate token or token_retransmits_before_loss_const value set");
2938++ goto parse_error;
2939++ }
2940+ }
2941+
2942+- if (totem_config->token_hold_timeout < MINIMUM_TIMEOUT) {
2943++ if (totem_config->token_hold_timeout < MINIMUM_TIMEOUT_HOLD) {
2944+ snprintf (local_error_reason, sizeof(local_error_reason),
2945+ "The token hold timeout parameter (%d ms) may not be less than (%d ms).",
2946+- totem_config->token_hold_timeout, MINIMUM_TIMEOUT);
2947++ totem_config->token_hold_timeout, MINIMUM_TIMEOUT_HOLD);
2948+ goto parse_error;
2949+ }
2950+
2951diff --git a/debian/patches/totemconfig-Remove-support-for-3des.patch b/debian/patches/totemconfig-Remove-support-for-3des.patch
2952new file mode 100644
2953index 00000000..63dcc729
2954--- /dev/null
2955+++ b/debian/patches/totemconfig-Remove-support-for-3des.patch
2956@@ -0,0 +1,138 @@
2957+From: Jan Friesse <jfriesse@redhat.com>
2958+Date: Thu, 11 Apr 2019 08:23:29 +0200
2959+Subject: totemconfig: Remove support for 3des
2960+
2961+Triple DES is considered as a "weak cipher" since 2016 so there is
2962+really no need to support it in the corosync. Thanks to bug in
2963+Corosync/Knet/NSS which caused 3des to not work at all,
2964+no matter what library was used, we can just remove support for 3des
2965+without braking the compatibility.
2966+
2967+Also fix coroparse so:
2968+- totem.crypto_type is removed (this is 1.x construct which was not used
2969+even in 2.x)
2970+- Add checking of totem.crypto_model.
2971+- Enumarate possible values for crypto_model, crypto_cipher and
2972+crypto_hash error messages
2973+
2974+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
2975+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
2976+(cherry picked from commit d05636b738e3cb1cd7a491e4ef492cd44a8bf6a9)
2977+---
2978+ exec/coroparse.c | 21 ++++++++++-----------
2979+ exec/totemconfig.c | 3 ---
2980+ conf/lenses/corosync.aug | 4 ++--
2981+ man/corosync.conf.5 | 6 +++---
2982+ 4 files changed, 15 insertions(+), 19 deletions(-)
2983+
2984+diff --git a/exec/coroparse.c b/exec/coroparse.c
2985+index 08f8f14..0acb4c2 100644
2986+--- a/exec/coroparse.c
2987++++ b/exec/coroparse.c
2988+@@ -1,5 +1,5 @@
2989+ /*
2990+- * Copyright (c) 2006-2018 Red Hat, Inc.
2991++ * Copyright (c) 2006-2019 Red Hat, Inc.
2992+ *
2993+ * All rights reserved.
2994+ *
2995+@@ -747,13 +747,11 @@ static int main_config_parser_cb(const char *path,
2996+ return (0);
2997+ }
2998+ }
2999+- if (strcmp(path, "totem.crypto_type") == 0) {
3000++ if (strcmp(path, "totem.crypto_model") == 0) {
3001+ if ((strcmp(value, "nss") != 0) &&
3002+- (strcmp(value, "aes256") != 0) &&
3003+- (strcmp(value, "aes192") != 0) &&
3004+- (strcmp(value, "aes128") != 0) &&
3005+- (strcmp(value, "3des") != 0)) {
3006+- *error_string = "Invalid crypto type";
3007++ (strcmp(value, "openssl") != 0)) {
3008++ *error_string = "Invalid crypto model. "
3009++ "Should be nss or openssl";
3010+
3011+ return (0);
3012+ }
3013+@@ -762,9 +760,9 @@ static int main_config_parser_cb(const char *path,
3014+ if ((strcmp(value, "none") != 0) &&
3015+ (strcmp(value, "aes256") != 0) &&
3016+ (strcmp(value, "aes192") != 0) &&
3017+- (strcmp(value, "aes128") != 0) &&
3018+- (strcmp(value, "3des") != 0)) {
3019+- *error_string = "Invalid cipher type";
3020++ (strcmp(value, "aes128") != 0)) {
3021++ *error_string = "Invalid cipher type. "
3022++ "Should be none, aes256, aes192 or aes128";
3023+
3024+ return (0);
3025+ }
3026+@@ -776,7 +774,8 @@ static int main_config_parser_cb(const char *path,
3027+ (strcmp(value, "sha256") != 0) &&
3028+ (strcmp(value, "sha384") != 0) &&
3029+ (strcmp(value, "sha512") != 0)) {
3030+- *error_string = "Invalid hash type";
3031++ *error_string = "Invalid hash type. "
3032++ "Should be none, md5, sha1, sha256, sha384 or sha512";
3033+
3034+ return (0);
3035+ }
3036+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
3037+index d57562a..4f69fd5 100644
3038+--- a/exec/totemconfig.c
3039++++ b/exec/totemconfig.c
3040+@@ -463,9 +463,6 @@ static int totem_get_crypto(struct totem_config *totem_config, const char **erro
3041+ if (strcmp(str, "aes128") == 0) {
3042+ tmp_cipher = "aes128";
3043+ }
3044+- if (strcmp(str, "3des") == 0) {
3045+- tmp_cipher = "3des";
3046+- }
3047+ free(str);
3048+ }
3049+
3050+diff --git a/conf/lenses/corosync.aug b/conf/lenses/corosync.aug
3051+index 39334f1..edeb4fb 100644
3052+--- a/conf/lenses/corosync.aug
3053++++ b/conf/lenses/corosync.aug
3054+@@ -51,8 +51,8 @@ let totem =
3055+ |kv "rrp_mode" /none|active|passive/
3056+ |kv "vsftype" /none|ykd/
3057+ |kv "secauth" /on|off/
3058+- |kv "crypto_type" /nss|aes256|aes192|aes128|3des/
3059+- |kv "crypto_cipher" /none|nss|aes256|aes192|aes128|3des/
3060++ |kv "crypto_model" /nss|openssl/
3061++ |kv "crypto_cipher" /none|nss|aes256|aes192|aes128/
3062+ |kv "crypto_hash" /none|md5|sha1|sha256|sha384|sha512/
3063+ |kv "transport" /udp|iba|udpu/
3064+ |kv "version" Rx.integer
3065+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
3066+index 52eb7b1..887a52b 100644
3067+--- a/man/corosync.conf.5
3068++++ b/man/corosync.conf.5
3069+@@ -1,6 +1,6 @@
3070+ .\"/*
3071+ .\" * Copyright (c) 2005 MontaVista Software, Inc.
3072+-.\" * Copyright (c) 2006-2018 Red Hat, Inc.
3073++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
3074+ .\" *
3075+ .\" * All rights reserved.
3076+ .\" *
3077+@@ -32,7 +32,7 @@
3078+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3079+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
3080+ .\" */
3081+-.TH COROSYNC_CONF 5 2019-01-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
3082++.TH COROSYNC_CONF 5 2019-04-11 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
3083+ .SH NAME
3084+ corosync.conf - corosync executive configuration file
3085+
3086+@@ -221,7 +221,7 @@ The default is none.
3087+ .TP
3088+ crypto_cipher
3089+ This specifies which cipher should be used to encrypt all messages.
3090+-Valid values are none (no encryption), aes256, aes192, aes128 and 3des.
3091++Valid values are none (no encryption), aes256, aes192 and aes128.
3092+ Enabling crypto_cipher, requires also enabling of crypto_hash. Encrypted
3093+ transmission is only supported for the knet transport.
3094+
3095diff --git a/debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch b/debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
3096new file mode 100644
3097index 00000000..43e02d43
3098--- /dev/null
3099+++ b/debian/patches/totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
3100@@ -0,0 +1,51 @@
3101+From: yuan ren <yren@suse.com>
3102+Date: Sun, 28 Apr 2019 18:29:37 +0800
3103+Subject: totemconfig: fix autogen mcastaddr for ipv6-4
3104+
3105+When UDP is used as a transport, the error would occur
3106+"Multicast address family does not match bind address family"
3107+because there is no ipv6 in /etc/hosts specified but using the
3108+totem.ip_version: ipv6-4. because
3109+the mcastaddr generated (if not specified) only according to
3110+the totem.ip_version.
3111+
3112+Solution is to use bindnetaddr (configured or generated from
3113+nodelist) addr family.
3114+
3115+Signed-off-by: yuan ren <yren@suse.com>
3116+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
3117+(cherry picked from commit 70cda5d55f57b99c564be5e7871d291118553a74)
3118+---
3119+ exec/totemconfig.c | 10 +++++++++-
3120+ 1 file changed, 9 insertions(+), 1 deletion(-)
3121+
3122+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
3123+index 6fcd6de..3b4dbae 100644
3124+--- a/exec/totemconfig.c
3125++++ b/exec/totemconfig.c
3126+@@ -1370,6 +1370,7 @@ static int get_interface_params(struct totem_config *totem_config,
3127+ uint32_t u32;
3128+ char *str;
3129+ char *cluster_name = NULL;
3130++ enum totem_ip_version_enum tmp_ip_version = TOTEM_IP_VERSION_4;
3131+
3132+ if (reload) {
3133+ for (i=0; i<INTERFACE_MAX; i++) {
3134+@@ -1460,9 +1461,16 @@ static int get_interface_params(struct totem_config *totem_config,
3135+ * udpu doesn't need mcastaddr and validity of mcastaddr for udp is
3136+ * checked later anyway.
3137+ */
3138++
3139++ if (totem_config->interfaces[0].bindnet.family == AF_INET) {
3140++ tmp_ip_version = TOTEM_IP_VERSION_4;
3141++ } else if (totem_config->interfaces[0].bindnet.family == AF_INET6) {
3142++ tmp_ip_version = TOTEM_IP_VERSION_6;
3143++ }
3144++
3145+ (void)get_cluster_mcast_addr (cluster_name,
3146+ linknumber,
3147+- totem_config->ip_version,
3148++ tmp_ip_version,
3149+ &totem_config->interfaces[linknumber].mcast_addr);
3150+ }
3151+
3152diff --git a/debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch b/debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch
3153new file mode 100644
3154index 00000000..a3c47f7b
3155--- /dev/null
3156+++ b/debian/patches/totemconfig-ipaddr_equal-check-just-addr-part.patch
3157@@ -0,0 +1,86 @@
3158+From: Jan Friesse <jfriesse@redhat.com>
3159+Date: Tue, 23 Apr 2019 12:38:04 +0200
3160+Subject: totemconfig: ipaddr_equal check just addr part
3161+
3162+Checking whole structure is fine for IPv4, but IPv6 contains also scope
3163+id, what may be problem for local address. It's possible to use a zone
3164+index, but because it's not required when host name is used, it
3165+shouldn't be needed when IPv6 address is used.
3166+
3167+Example configuration snip which fails without patch:
3168+
3169+...
3170+nodelist {
3171+ node {
3172+ nodeid: 1
3173+ ring0_addr: fe80::1234:5678:9abc:def1
3174+ }
3175+}
3176+...
3177+
3178+(example succeed when %eth0 is used).
3179+
3180+With patch, zone index is not needed.
3181+
3182+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3183+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3184+(cherry picked from commit d05c1593a11c91d2f419418188ebc7a23f9cc38a)
3185+---
3186+ exec/totemconfig.c | 28 ++++++++++++++--------------
3187+ 1 file changed, 14 insertions(+), 14 deletions(-)
3188+
3189+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
3190+index 1954f76..b206eeb 100644
3191+--- a/exec/totemconfig.c
3192++++ b/exec/totemconfig.c
3193+@@ -560,27 +560,28 @@ static int nodelist_byname(const char *find_name, int strip_domain)
3194+ return -1;
3195+ }
3196+
3197+-/* Compare two addresses */
3198+-static int ipaddr_equal(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2)
3199++/* Compare two addresses - only address part (sin_addr/sin6_addr) is checked */
3200++static int ipaddr_equal(const struct sockaddr *addr1, const struct sockaddr *addr2)
3201+ {
3202+ int addrlen = 0;
3203++ const void *addr1p, *addr2p;
3204+
3205+- if (addr1->ss_family != addr2->ss_family)
3206++ if (addr1->sa_family != addr2->sa_family)
3207+ return 0;
3208+
3209+- if (addr1->ss_family == AF_INET) {
3210+- addrlen = sizeof(struct sockaddr_in);
3211++ if (addr1->sa_family == AF_INET) {
3212++ addrlen = sizeof(struct in_addr);
3213++ addr1p = &((struct sockaddr_in *)addr1)->sin_addr;
3214++ addr2p = &((struct sockaddr_in *)addr2)->sin_addr;
3215+ }
3216+- if (addr1->ss_family == AF_INET6) {
3217+- addrlen = sizeof(struct sockaddr_in6);
3218++ if (addr1->sa_family == AF_INET6) {
3219++ addrlen = sizeof(struct in6_addr);
3220++ addr1p = &((struct sockaddr_in6 *)addr1)->sin6_addr;
3221++ addr2p = &((struct sockaddr_in6 *)addr2)->sin6_addr;
3222+ }
3223+ assert(addrlen);
3224+
3225+- if (memcmp(addr1, addr2, addrlen) == 0)
3226+- return 1;
3227+- else
3228+- return 0;
3229+-
3230++ return (memcmp(addr1p, addr2p, addrlen) == 0);
3231+ }
3232+
3233+
3234+@@ -760,8 +761,7 @@ static int find_local_node(int use_cache)
3235+ for (rp = result; rp != NULL; rp = rp->ai_next) {
3236+ for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
3237+ if (ifa->ifa_addr &&
3238+- ipaddr_equal((struct sockaddr_storage *)rp->ai_addr,
3239+- (struct sockaddr_storage *)ifa->ifa_addr)) {
3240++ ipaddr_equal(rp->ai_addr, ifa->ifa_addr)) {
3241+ freeaddrinfo(result);
3242+ found = 1;
3243+ goto out2;
3244diff --git a/debian/patches/totemconfig-ipaddr_equal-use-switch.patch b/debian/patches/totemconfig-ipaddr_equal-use-switch.patch
3245new file mode 100644
3246index 00000000..f0cd1bbc
3247--- /dev/null
3248+++ b/debian/patches/totemconfig-ipaddr_equal-use-switch.patch
3249@@ -0,0 +1,44 @@
3250+From: Jan Friesse <jfriesse@redhat.com>
3251+Date: Tue, 11 Jun 2019 10:24:05 +0200
3252+Subject: totemconfig: ipaddr_equal use switch
3253+
3254+Compiler may have problem understanding relation between addr1p and
3255+addrlen. Small change makes code a little more readable and compiler
3256+happy.
3257+
3258+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3259+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3260+(cherry picked from commit 299c9c5b7016f4f8e423162791fcf4cb3fe70529)
3261+---
3262+ exec/totemconfig.c | 11 +++++++----
3263+ 1 file changed, 7 insertions(+), 4 deletions(-)
3264+
3265+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
3266+index 0501589..ff86e23 100644
3267+--- a/exec/totemconfig.c
3268++++ b/exec/totemconfig.c
3269+@@ -630,17 +630,20 @@ static int ipaddr_equal(const struct sockaddr *addr1, const struct sockaddr *add
3270+ if (addr1->sa_family != addr2->sa_family)
3271+ return 0;
3272+
3273+- if (addr1->sa_family == AF_INET) {
3274++ switch (addr1->sa_family) {
3275++ case AF_INET:
3276+ addrlen = sizeof(struct in_addr);
3277+ addr1p = &((struct sockaddr_in *)addr1)->sin_addr;
3278+ addr2p = &((struct sockaddr_in *)addr2)->sin_addr;
3279+- }
3280+- if (addr1->sa_family == AF_INET6) {
3281++ break;
3282++ case AF_INET6:
3283+ addrlen = sizeof(struct in6_addr);
3284+ addr1p = &((struct sockaddr_in6 *)addr1)->sin6_addr;
3285+ addr2p = &((struct sockaddr_in6 *)addr2)->sin6_addr;
3286++ break;
3287++ default:
3288++ assert(0);
3289+ }
3290+- assert(addrlen);
3291+
3292+ return (memcmp(addr1p, addr2p, addrlen) == 0);
3293+ }
3294diff --git a/debian/patches/totemip-Use-res-in-totemip_sa_equal.patch b/debian/patches/totemip-Use-res-in-totemip_sa_equal.patch
3295new file mode 100644
3296index 00000000..2a691774
3297--- /dev/null
3298+++ b/debian/patches/totemip-Use-res-in-totemip_sa_equal.patch
3299@@ -0,0 +1,32 @@
3300+From: Jan Friesse <jfriesse@redhat.com>
3301+Date: Tue, 11 Jun 2019 10:28:41 +0200
3302+Subject: totemip: Use res in totemip_sa_equal
3303+
3304+Setting res to -1 was not entirely following semantics of "equal"
3305+operation. Set it to 0 and return it when families differs makes
3306+compiler happy.
3307+
3308+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3309+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3310+(cherry picked from commit d4d48d9268ea5bb43382e4ed8241cccaa9d2e99a)
3311+---
3312+ exec/totemip.c | 4 ++--
3313+ 1 file changed, 2 insertions(+), 2 deletions(-)
3314+
3315+diff --git a/exec/totemip.c b/exec/totemip.c
3316+index 4c2eafe..7accf71 100644
3317+--- a/exec/totemip.c
3318++++ b/exec/totemip.c
3319+@@ -97,10 +97,10 @@ int totemip_sa_equal(const struct totem_ip_address *totem_ip,
3320+ {
3321+ int res;
3322+
3323+- res = -1;
3324++ res = 0;
3325+
3326+ if (totem_ip->family != sa->sa_family) {
3327+- return 0;
3328++ return (res);
3329+ }
3330+
3331+ switch (totem_ip->family) {
3332diff --git a/debian/patches/totemknet-Ignore-icmap_get_string-result.patch b/debian/patches/totemknet-Ignore-icmap_get_string-result.patch
3333new file mode 100644
3334index 00000000..432ce704
3335--- /dev/null
3336+++ b/debian/patches/totemknet-Ignore-icmap_get_string-result.patch
3337@@ -0,0 +1,32 @@
3338+From: Jan Friesse <jfriesse@redhat.com>
3339+Date: Tue, 11 Jun 2019 10:40:07 +0200
3340+Subject: totemknet: Ignore icmap_get_string result
3341+
3342+... and add comment why it is not a bug.
3343+
3344+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3345+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3346+(cherry picked from commit 9b809383e65a57b8604132d93e005d42b42c71a1)
3347+---
3348+ exec/totemknet.c | 8 ++++++--
3349+ 1 file changed, 6 insertions(+), 2 deletions(-)
3350+
3351+diff --git a/exec/totemknet.c b/exec/totemknet.c
3352+index 774cb2c..8762185 100644
3353+--- a/exec/totemknet.c
3354++++ b/exec/totemknet.c
3355+@@ -1795,8 +1795,12 @@ static int setup_nozzle(void *knet_context)
3356+ int macaddr_res;
3357+ int res;
3358+
3359+- icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
3360+- icmap_get_string(NOZZLE_PREFIX, &prefix_str);
3361++ /*
3362++ * Return value ignored on purpose. icmap_get_string changes
3363++ * ipaddr_str/prefix_str only on success.
3364++ */
3365++ (void)icmap_get_string(NOZZLE_IPADDR, &ipaddr_str);
3366++ (void)icmap_get_string(NOZZLE_PREFIX, &prefix_str);
3367+ macaddr_res = icmap_get_string(NOZZLE_MACADDR, &macaddr_str);
3368+ name_res = icmap_get_string(NOZZLE_NAME, &name_str);
3369+
3370diff --git a/debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch b/debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch
3371new file mode 100644
3372index 00000000..e2f6bcde
3373--- /dev/null
3374+++ b/debian/patches/totemknet-Initialize-return-value-in-setup_nozzle.patch
3375@@ -0,0 +1,39 @@
3376+From: Jan Friesse <jfriesse@redhat.com>
3377+Date: Tue, 11 Jun 2019 11:00:03 +0200
3378+Subject: totemknet: Initialize return value in setup_nozzle
3379+
3380+Also add comment why return value is currently not used.
3381+
3382+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3383+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3384+(cherry picked from commit 0839d3af82833342b43a64fbc403227a574bd63b)
3385+---
3386+ exec/totemknet.c | 8 +++++---
3387+ 1 file changed, 5 insertions(+), 3 deletions(-)
3388+
3389+diff --git a/exec/totemknet.c b/exec/totemknet.c
3390+index eb2ed2c..e6e04d3 100644
3391+--- a/exec/totemknet.c
3392++++ b/exec/totemknet.c
3393+@@ -1428,8 +1428,10 @@ int totemknet_reconfigure (
3394+ }
3395+
3396+ #ifdef HAVE_LIBNOZZLE
3397+- /* Set up nozzle device(s) */
3398+- setup_nozzle(instance);
3399++ /* Set up nozzle device(s). Return code is ignored, because unability
3400++ * configure nozzle is not fatal problem, errors are logged and
3401++ * there is not much else we can do */
3402++ (void)setup_nozzle(instance);
3403+ #endif
3404+ return (res);
3405+ }
3406+@@ -1793,7 +1795,7 @@ static int setup_nozzle(void *knet_context)
3407+ char mac[32];
3408+ int name_res;
3409+ int macaddr_res;
3410+- int res;
3411++ int res = -1;
3412+
3413+ /*
3414+ * Return value ignored on purpose. icmap_get_string changes
3415diff --git a/debian/patches/totemknet-create_nozzle_device-simplify-check.patch b/debian/patches/totemknet-create_nozzle_device-simplify-check.patch
3416new file mode 100644
3417index 00000000..e3260daf
3418--- /dev/null
3419+++ b/debian/patches/totemknet-create_nozzle_device-simplify-check.patch
3420@@ -0,0 +1,34 @@
3421+From: Jan Friesse <jfriesse@redhat.com>
3422+Date: Tue, 11 Jun 2019 10:32:40 +0200
3423+Subject: totemknet: create_nozzle_device simplify check
3424+
3425+ipaddr existence is checked for being not NULL by caller setup_nozzle.
3426+Also ipaddr was passed to reparse_nozzle_ip_address function unchecked
3427+so code would crash before reaching the actual check.
3428+
3429+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3430+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3431+(cherry picked from commit 9a0e7b584e3b217e0bdf1a017b5995cbce27f708)
3432+---
3433+ exec/totemknet.c | 8 +++-----
3434+ 1 file changed, 3 insertions(+), 5 deletions(-)
3435+
3436+diff --git a/exec/totemknet.c b/exec/totemknet.c
3437+index 2af69b3..774cb2c 100644
3438+--- a/exec/totemknet.c
3439++++ b/exec/totemknet.c
3440+@@ -1707,11 +1707,9 @@ static int create_nozzle_device(void *knet_context, const char *name,
3441+ goto out_clean;
3442+ }
3443+ knet_log_printf (LOGSYS_LEVEL_INFO, "Local nozzle IP address is %s / %d", parsed_ipaddr, atoi(prefix));
3444+- if (ipaddr) {
3445+- if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
3446+- knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
3447+- goto out_clean;
3448+- }
3449++ if (nozzle_add_ip(nozzle_dev, parsed_ipaddr, prefix) < 0) {
3450++ knet_log_printf (LOGSYS_LEVEL_ERROR, "Unable to add set nozzle IP addr to %s/%s: %s", parsed_ipaddr, prefix, strerror(errno));
3451++ goto out_clean;
3452+ }
3453+
3454+ nozzle_fd = nozzle_get_fd(nozzle_dev);
3455diff --git a/debian/patches/totemknet-macaddr_str-is-always-set.patch b/debian/patches/totemknet-macaddr_str-is-always-set.patch
3456new file mode 100644
3457index 00000000..c2574cae
3458--- /dev/null
3459+++ b/debian/patches/totemknet-macaddr_str-is-always-set.patch
3460@@ -0,0 +1,27 @@
3461+From: Jan Friesse <jfriesse@redhat.com>
3462+Date: Tue, 11 Jun 2019 10:44:17 +0200
3463+Subject: totemknet: macaddr_str is always set
3464+
3465+Check for NULL was invalid, because macaddr_str is ether defined in cmap
3466+or set to "54:54:01:00:00:00".
3467+
3468+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3469+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3470+(cherry picked from commit 0d82e23517e299dec877e632c9c9a4d441789be8)
3471+---
3472+ exec/totemknet.c | 2 +-
3473+ 1 file changed, 1 insertion(+), 1 deletion(-)
3474+
3475+diff --git a/exec/totemknet.c b/exec/totemknet.c
3476+index 8762185..eb2ed2c 100644
3477+--- a/exec/totemknet.c
3478++++ b/exec/totemknet.c
3479+@@ -1838,7 +1838,7 @@ static int setup_nozzle(void *knet_context)
3480+ (strcmp(name_str, instance->nozzle_name) == 0) &&
3481+ (strcmp(ipaddr_str, instance->nozzle_ipaddr) == 0) &&
3482+ (strcmp(prefix_str, instance->nozzle_prefix) == 0) &&
3483+- ((macaddr_str == NULL && instance->nozzle_macaddr == NULL) ||
3484++ (instance->nozzle_macaddr == NULL ||
3485+ strcmp(macaddr_str, instance->nozzle_macaddr) == 0)) {
3486+ /* Nothing has changed */
3487+ knet_log_printf (LOGSYS_LEVEL_DEBUG, "Nozzle device info not changed");
3488diff --git a/debian/patches/totemsrp-Word-spelling-mistake.patch b/debian/patches/totemsrp-Word-spelling-mistake.patch
3489new file mode 100644
3490index 00000000..99e1ffaa
3491--- /dev/null
3492+++ b/debian/patches/totemsrp-Word-spelling-mistake.patch
3493@@ -0,0 +1,24 @@
3494+From: yuan ren <yren@suse.com>
3495+Date: Fri, 29 Mar 2019 15:43:10 +0800
3496+Subject: totemsrp: Word spelling mistake
3497+
3498+Signed-off-by: yuan ren <reyren179@gmail.com>
3499+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
3500+(cherry picked from commit 24a72e9780f30d29e0097700b68bd2056845bc31)
3501+---
3502+ exec/totemsrp.c | 2 +-
3503+ 1 file changed, 1 insertion(+), 1 deletion(-)
3504+
3505+diff --git a/exec/totemsrp.c b/exec/totemsrp.c
3506+index ab27924..a48d97b 100644
3507+--- a/exec/totemsrp.c
3508++++ b/exec/totemsrp.c
3509+@@ -434,7 +434,7 @@ struct totemsrp_instance {
3510+
3511+ void (*totemsrp_log_printf) (
3512+ int level,
3513+- int sybsys,
3514++ int subsys,
3515+ const char *function,
3516+ const char *file,
3517+ int line,
3518diff --git a/debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch b/debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch
3519new file mode 100644
3520index 00000000..591e4873
3521--- /dev/null
3522+++ b/debian/patches/udpu-Drop-packets-from-unlisted-IPs.patch
3523@@ -0,0 +1,254 @@
3524+From: Jan Friesse <jfriesse@redhat.com>
3525+Date: Fri, 24 May 2019 08:48:01 +0200
3526+Subject: udpu: Drop packets from unlisted IPs
3527+
3528+This feature allows corosync to block packets received from unknown
3529+nodes (nodes with IP address which is not in the nodelist). This is
3530+mainly for situations when "forgotten" node is booted and tries to join
3531+cluster which already removed such node from configuration. Another use
3532+case is to allow atomic reconfiguration and rejoin of two separate
3533+clusters.
3534+
3535+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3536+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3537+(cherry picked from commit 72737d39292feb7c9253c26418e1e25ef0a7fad9)
3538+---
3539+ include/corosync/totem/totem.h | 2 ++
3540+ include/corosync/totem/totemip.h | 2 ++
3541+ exec/totemconfig.c | 55 +++++++++++++++++++++++++++++++++++++++-
3542+ exec/totemip.c | 27 ++++++++++++++++++++
3543+ exec/totemudpu.c | 34 +++++++++++++++++++++++++
3544+ man/corosync.conf.5 | 10 +++++++-
3545+ 6 files changed, 128 insertions(+), 2 deletions(-)
3546+
3547+diff --git a/include/corosync/totem/totem.h b/include/corosync/totem/totem.h
3548+index d9d8e46..00ee0ab 100644
3549+--- a/include/corosync/totem/totem.h
3550++++ b/include/corosync/totem/totem.h
3551+@@ -233,6 +233,8 @@ struct totem_config {
3552+
3553+ enum totem_ip_version_enum ip_version;
3554+
3555++ unsigned int block_unlisted_ips;
3556++
3557+ void (*totem_memb_ring_id_create_or_load) (
3558+ struct memb_ring_id *memb_ring_id,
3559+ unsigned int nodeid);
3560+diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h
3561+index b8da3c9..91b2266 100644
3562+--- a/include/corosync/totem/totemip.h
3563++++ b/include/corosync/totem/totemip.h
3564+@@ -86,6 +86,8 @@ struct totem_ip_if_address
3565+
3566+ extern int totemip_equal(const struct totem_ip_address *addr1,
3567+ const struct totem_ip_address *addr2);
3568++extern int totemip_sa_equal(const struct totem_ip_address *totem_ip,
3569++ const struct sockaddr *sa);
3570+ extern int totemip_compare(const void *a, const void *b);
3571+ extern int totemip_is_mcast(struct totem_ip_address *addr);
3572+ extern void totemip_copy(struct totem_ip_address *addr1,
3573+diff --git a/exec/totemconfig.c b/exec/totemconfig.c
3574+index 262dcac..0501589 100644
3575+--- a/exec/totemconfig.c
3576++++ b/exec/totemconfig.c
3577+@@ -79,6 +79,7 @@
3578+ #define WINDOW_SIZE 50
3579+ #define MAX_MESSAGES 17
3580+ #define MISS_COUNT_CONST 5
3581++#define BLOCK_UNLISTED_IPS 1
3582+
3583+ /* These currently match the defaults in libknet.h */
3584+ #define KNET_PING_INTERVAL 1000
3585+@@ -138,6 +139,8 @@ static void *totem_get_param_by_name(struct totem_config *totem_config, const ch
3586+ return &totem_config->knet_compression_level;
3587+ if (strcmp(param_name, "totem.knet_compression_model") == 0)
3588+ return &totem_config->knet_compression_model;
3589++ if (strcmp(param_name, "totem.block_unlisted_ips") == 0)
3590++ return &totem_config->block_unlisted_ips;
3591+
3592+ return NULL;
3593+ }
3594+@@ -235,6 +238,55 @@ static void totem_volatile_config_set_string_value (struct totem_config *totem_c
3595+ icmap_set_string(runtime_key_name, (char *)*config_value);
3596+ }
3597+
3598++/*
3599++ * Read string value stored in key_name from icmap, use it as a boolean (yes/no) type, convert it
3600++ * to integer value (1/0) and store into totem_config.
3601++ *
3602++ * If key is not found or key_name == delete_key default value is used
3603++ * and stored into totem_config.
3604++ */
3605++static void totem_volatile_config_set_boolean_value (struct totem_config *totem_config,
3606++ const char *key_name, const char *deleted_key, unsigned int default_value)
3607++{
3608++ char runtime_key_name[ICMAP_KEYNAME_MAXLEN];
3609++ char *str;
3610++ int val;
3611++
3612++ str = NULL;
3613++ val = default_value;
3614++
3615++ if ((deleted_key != NULL && strcmp(deleted_key, key_name) == 0) ||
3616++ (icmap_get_string(key_name, &str) != CS_OK)) {
3617++ /*
3618++ * Do nothing. str is NULL (icmap_get_string ether not called or
3619++ * not changed str).
3620++ */
3621++ } else {
3622++ if (strcmp(str, "yes") == 0) {
3623++ val = 1;
3624++ } else if (strcmp(str, "no") == 0) {
3625++ val = 0;
3626++ }
3627++ free(str);
3628++ }
3629++
3630++ /*
3631++ * Store totem_config value to cmap runtime section
3632++ */
3633++ if (strlen("runtime.config.") + strlen(key_name) >= ICMAP_KEYNAME_MAXLEN) {
3634++ /*
3635++ * This shouldn't happen
3636++ */
3637++ return ;
3638++ }
3639++
3640++ strcpy(runtime_key_name, "runtime.config.");
3641++ strcat(runtime_key_name, key_name);
3642++
3643++ *(uint32_t *)totem_get_param_by_name(totem_config, key_name) = val;
3644++
3645++ icmap_set_uint32(runtime_key_name, val);
3646++}
3647+
3648+ /*
3649+ * Read and validate config values from cmap and store them into totem_config. If key doesn't exists,
3650+@@ -302,7 +354,8 @@ static void totem_volatile_config_read (struct totem_config *totem_config, const
3651+
3652+ totem_volatile_config_set_string_value(totem_config, "totem.knet_compression_model", deleted_key, "none");
3653+
3654+-
3655++ totem_volatile_config_set_boolean_value(totem_config, "totem.block_unlisted_ips", deleted_key,
3656++ BLOCK_UNLISTED_IPS);
3657+ }
3658+
3659+ static int totem_volatile_config_validate (
3660+diff --git a/exec/totemip.c b/exec/totemip.c
3661+index 36d0a72..4c2eafe 100644
3662+--- a/exec/totemip.c
3663++++ b/exec/totemip.c
3664+@@ -92,6 +92,33 @@ int totemip_equal(const struct totem_ip_address *addr1,
3665+
3666+ }
3667+
3668++int totemip_sa_equal(const struct totem_ip_address *totem_ip,
3669++ const struct sockaddr *sa)
3670++{
3671++ int res;
3672++
3673++ res = -1;
3674++
3675++ if (totem_ip->family != sa->sa_family) {
3676++ return 0;
3677++ }
3678++
3679++ switch (totem_ip->family) {
3680++ case AF_INET:
3681++ res = (memcmp(totem_ip->addr,
3682++ &((const struct sockaddr_in *)sa)->sin_addr, sizeof(struct in_addr)) == 0);
3683++ break;
3684++ case AF_INET6:
3685++ res = (memcmp(totem_ip->addr,
3686++ &((const struct sockaddr_in6 *)sa)->sin6_addr, sizeof(struct in6_addr)) == 0);
3687++ break;
3688++ default:
3689++ assert(0);
3690++ }
3691++
3692++ return (res);
3693++}
3694++
3695+ /* Copy a totem_ip_address */
3696+ void totemip_copy(struct totem_ip_address *addr1,
3697+ const struct totem_ip_address *addr2)
3698+diff --git a/exec/totemudpu.c b/exec/totemudpu.c
3699+index 252962d..914a328 100644
3700+--- a/exec/totemudpu.c
3701++++ b/exec/totemudpu.c
3702+@@ -444,6 +444,32 @@ int totemudpu_finalize (
3703+ return (res);
3704+ }
3705+
3706++static struct totemudpu_member *find_member_by_sockaddr(
3707++ const void *udpu_context,
3708++ const struct sockaddr *sa)
3709++{
3710++ struct qb_list_head *list;
3711++ struct totemudpu_member *member;
3712++ struct totemudpu_member *res_member;
3713++ const struct totemudpu_instance *instance = (const struct totemudpu_instance *)udpu_context;
3714++
3715++ res_member = NULL;
3716++
3717++ qb_list_for_each(list, &(instance->member_list)) {
3718++ member = qb_list_entry (list,
3719++ struct totemudpu_member,
3720++ list);
3721++
3722++ if (totemip_sa_equal(&member->member, sa)) {
3723++ res_member = member;
3724++ break ;
3725++ }
3726++ }
3727++
3728++ return (res_member);
3729++}
3730++
3731++
3732+ static int net_deliver_fn (
3733+ int fd,
3734+ int revents,
3735+@@ -513,6 +539,14 @@ static int net_deliver_fn (
3736+ return (0);
3737+ }
3738+
3739++ if (instance->totem_config->block_unlisted_ips &&
3740++ find_member_by_sockaddr(instance, (const struct sockaddr *)&system_from) == NULL) {
3741++ log_printf(instance->totemudpu_log_level_debug, "Packet rejected from %s",
3742++ totemip_sa_print((const struct sockaddr *)&system_from));
3743++
3744++ return (0);
3745++ }
3746++
3747+ iovec->iov_len = bytes_received;
3748+
3749+ /*
3750+diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
3751+index 674179d..953c830 100644
3752+--- a/man/corosync.conf.5
3753++++ b/man/corosync.conf.5
3754+@@ -32,7 +32,7 @@
3755+ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3756+ .\" * THE POSSIBILITY OF SUCH DAMAGE.
3757+ .\" */
3758+-.TH COROSYNC_CONF 5 2019-04-11 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
3759++.TH COROSYNC_CONF 5 2019-05-24 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
3760+ .SH NAME
3761+ corosync.conf - corosync executive configuration file
3762+
3763+@@ -571,6 +571,14 @@ knet_enable_access_lists
3764+ Allow knet to drop packets from IP addresses that are not known to corosync.
3765+ Value is 0 (off) and 1 (on). Default: 0.
3766+
3767++.TP
3768++block_unlisted_ips
3769++Allow UDPU to drop packets from IP addresses that are not known
3770++(nodes which don't exist in the nodelist) to corosync.
3771++Value is yes or no.
3772++
3773++The default value is yes.
3774++
3775+ .PP
3776+ Within the
3777+ .B logging
3778diff --git a/debian/patches/vqsim-Check-length-of-copied-optarg.patch b/debian/patches/vqsim-Check-length-of-copied-optarg.patch
3779new file mode 100644
3780index 00000000..ef2afb67
3781--- /dev/null
3782+++ b/debian/patches/vqsim-Check-length-of-copied-optarg.patch
3783@@ -0,0 +1,37 @@
3784+From: Jan Friesse <jfriesse@redhat.com>
3785+Date: Tue, 11 Jun 2019 15:30:00 +0200
3786+Subject: vqsim: Check length of copied optarg
3787+
3788+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3789+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3790+(cherry picked from commit 0390200dd427d1d3e75bba8584dbfbb794b52b49)
3791+---
3792+ vqsim/vqmain.c | 8 ++++++--
3793+ 1 file changed, 6 insertions(+), 2 deletions(-)
3794+
3795+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
3796+index 16f7714..25d0fad 100644
3797+--- a/vqsim/vqmain.c
3798++++ b/vqsim/vqmain.c
3799+@@ -759,7 +759,11 @@ int main(int argc, char **argv)
3800+ while ((ch = getopt (argc, argv, "c:o:nh")) != EOF) {
3801+ switch (ch) {
3802+ case 'c':
3803+- strncpy(corosync_config_file, optarg, sizeof(corosync_config_file));
3804++ if (strlen(optarg) >= sizeof(sizeof(corosync_config_file) - 1)) {
3805++ fprintf(stderr, "Corosync config file path too long\n");
3806++ exit(1);
3807++ }
3808++ strncpy(corosync_config_file, optarg, sizeof(corosync_config_file) - 1);
3809+ break;
3810+ case 'o':
3811+ output_file_name = optarg;
3812+@@ -777,7 +781,7 @@ int main(int argc, char **argv)
3813+ output_file = fopen(output_file_name, "w");
3814+ if (!output_file) {
3815+ fprintf(stderr, "Unable to open %s for output: %s\n", output_file_name, strerror(errno));
3816+- exit(-1);
3817++ exit(3);
3818+ }
3819+ }
3820+ else {
3821diff --git a/debian/patches/vqsim-Check-length-of-received-message.patch b/debian/patches/vqsim-Check-length-of-received-message.patch
3822new file mode 100644
3823index 00000000..a4d54327
3824--- /dev/null
3825+++ b/debian/patches/vqsim-Check-length-of-received-message.patch
3826@@ -0,0 +1,42 @@
3827+From: Jan Friesse <jfriesse@redhat.com>
3828+Date: Tue, 11 Jun 2019 14:48:41 +0200
3829+Subject: vqsim: Check length of received message
3830+
3831+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3832+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3833+(cherry picked from commit 7267149e050cc8963eb38c7a31bb26c84d1f2338)
3834+---
3835+ vqsim/vqmain.c | 16 +++++++++++++---
3836+ 1 file changed, 13 insertions(+), 3 deletions(-)
3837+
3838+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
3839+index aaba512..98729b9 100644
3840+--- a/vqsim/vqmain.c
3841++++ b/vqsim/vqmain.c
3842+@@ -222,13 +222,23 @@ static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
3843+ msglen = read(fd, msgbuf, sizeof(msgbuf));
3844+ if (msglen < 0) {
3845+ perror("read failed");
3846+- }
3847+-
3848+- if (msglen > 0) {
3849++ } else if (msglen < sizeof(*msg)) {
3850++ fprintf(stderr, "Received message is too short\n");
3851++ } else {
3852+ msg = (void*)msgbuf;
3853+ switch (msg->type) {
3854+ case VQMSG_QUORUM:
3855+ qmsg = (void*)msgbuf;
3856++ /*
3857++ * Check length of message.
3858++ * SOCK_SEQPACKET is used so this check is not strictly needed.
3859++ */
3860++ if (msglen < sizeof(*qmsg) ||
3861++ qmsg->view_list_entries > MAX_NODES ||
3862++ msglen < sizeof(*qmsg) + sizeof(qmsg->view_list[0]) * qmsg->view_list_entries) {
3863++ fprintf(stderr, "Received quorum message is too short or corrupted\n");
3864++ return (0);
3865++ }
3866+ save_quorum_state(vqn, qmsg);
3867+ if (!sync_cmds) {
3868+ print_quorum_state(vqn);
3869diff --git a/debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch b/debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch
3870new file mode 100644
3871index 00000000..25690b75
3872--- /dev/null
3873+++ b/debian/patches/vqsim-Check-result-of-icmap_set_uint32.patch
3874@@ -0,0 +1,31 @@
3875+From: Jan Friesse <jfriesse@redhat.com>
3876+Date: Tue, 11 Jun 2019 15:26:29 +0200
3877+Subject: vqsim: Check result of icmap_set_uint32
3878+
3879+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3880+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3881+(cherry picked from commit 1d8c1a4c9712517b24985941b8fac2d45eef4784)
3882+---
3883+ vqsim/vqsim_vq_engine.c | 2 ++
3884+ 1 file changed, 2 insertions(+)
3885+
3886+diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
3887+index eb35d35..b8460f3 100644
3888+--- a/vqsim/vqsim_vq_engine.c
3889++++ b/vqsim/vqsim_vq_engine.c
3890+@@ -208,6 +208,7 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
3891+ if (nodeid == our_nodeid) {
3892+ found = 1;
3893+ res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
3894++ assert(res == CS_OK);
3895+ }
3896+ }
3897+ }
3898+@@ -217,6 +218,7 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
3899+ * first node in corosync.conf
3900+ */
3901+ res = icmap_set_uint32("nodelist.local_node_pos", 0);
3902++ assert(res == CS_OK);
3903+ }
3904+ }
3905+
3906diff --git a/debian/patches/vqsim-Check-write-result.patch b/debian/patches/vqsim-Check-write-result.patch
3907new file mode 100644
3908index 00000000..303f661c
3909--- /dev/null
3910+++ b/debian/patches/vqsim-Check-write-result.patch
3911@@ -0,0 +1,33 @@
3912+From: Jan Friesse <jfriesse@redhat.com>
3913+Date: Tue, 11 Jun 2019 14:46:34 +0200
3914+Subject: vqsim: Check write result
3915+
3916+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3917+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3918+(cherry picked from commit e953cfeb873f495cd9c59ba999be2b103363718b)
3919+---
3920+ vqsim/vqmain.c | 8 +++++++-
3921+ 1 file changed, 7 insertions(+), 1 deletion(-)
3922+
3923+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
3924+index 0eca43c..aaba512 100644
3925+--- a/vqsim/vqmain.c
3926++++ b/vqsim/vqmain.c
3927+@@ -138,10 +138,16 @@ static void print_quorum_state(struct vq_node *node)
3928+ static void propogate_vq_message(struct vq_node *vqn, const char *msg, int len)
3929+ {
3930+ struct vq_node *other_vqn;
3931++ ssize_t write_res;
3932+
3933+ /* Send it to everyone in that node's partition (including itself) */
3934+ TAILQ_FOREACH(other_vqn, &vqn->partition->nodelist, entries) {
3935+- write(other_vqn->fd, msg, len);
3936++ write_res = write(other_vqn->fd, msg, len);
3937++ /*
3938++ * Read counterpart is not ready for receiving non-complete message so
3939++ * ensure all required information was send.
3940++ */
3941++ assert(write_res == len);
3942+ }
3943+ }
3944+
3945diff --git a/debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch b/debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch
3946new file mode 100644
3947index 00000000..04973dff
3948--- /dev/null
3949+++ b/debian/patches/vqsim-Do-not-access-unitialized-argv-0.patch
3950@@ -0,0 +1,24 @@
3951+From: Jan Friesse <jfriesse@redhat.com>
3952+Date: Tue, 11 Jun 2019 11:04:48 +0200
3953+Subject: vqsim: Do not access unitialized argv[0]
3954+
3955+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
3956+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
3957+(cherry picked from commit 1af23e9c2dd3830beb2cd16277a44ae50ad483db)
3958+---
3959+ vqsim/parser.c | 2 +-
3960+ 1 file changed, 1 insertion(+), 1 deletion(-)
3961+
3962+diff --git a/vqsim/parser.c b/vqsim/parser.c
3963+index d13e678..2857184 100644
3964+--- a/vqsim/parser.c
3965++++ b/vqsim/parser.c
3966+@@ -196,7 +196,7 @@ void parse_input_command(char *rl_cmd)
3967+ }
3968+
3969+ /* Ignore null commands */
3970+- if (strlen(argv[0]) == 0) {
3971++ if (argc < 1 || strlen(argv[0]) == 0) {
3972+ free(cmd);
3973+ resume_kb_input(0);
3974+ return;
3975diff --git a/debian/patches/vqsim-Enhance-vqsim.patch b/debian/patches/vqsim-Enhance-vqsim.patch
3976new file mode 100644
3977index 00000000..7e95761f
3978--- /dev/null
3979+++ b/debian/patches/vqsim-Enhance-vqsim.patch
3980@@ -0,0 +1,1155 @@
3981+From: Christine Caulfield <ccaulfie@redhat.com>
3982+Date: Fri, 26 Apr 2019 10:54:32 +0100
3983+Subject: vqsim: Enhance vqsim
3984+
3985+1. Enable scripting of vqsim and add man page
3986+
3987+I've added a 'sleep' command to help with scripting as well as
3988+documentation on how to do it.
3989+
3990+2. Make 'sync' operation much more robust and useful
3991+
3992+Refactored a lot of code to make sure that in sync mode the
3993+prompt appears at the 'right' time. What we do is wait for all
3994+of the nodes in all partitions to have the same ring_id. If this
3995+doesn't happen then the timeout will fire as before.
3996+
3997+3. Rename binary to corosync-vqsim and add a sub-package for it
3998+
3999+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
4000+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
4001+(cherry picked from commit c3d69712c614deea688b7cfe0975976ecca60a2d)
4002+---
4003+ configure.ac | 1 +
4004+ man/Makefile.am | 4 +
4005+ vqsim/Makefile.am | 22 ++--
4006+ vqsim/vqsim.h | 82 +++++++++++++++
4007+ corosync.spec.in | 26 +++++
4008+ vqsim/parser.c | 141 ++++++++++++++++++++-----
4009+ vqsim/vqmain.c | 274 +++++++++++++++++++++++++++++++++---------------
4010+ vqsim/vqsim_vq_engine.c | 12 ++-
4011+ man/corosync-vqsim.8 | 94 +++++++++++++++++
4012+ 9 files changed, 533 insertions(+), 123 deletions(-)
4013+ create mode 100644 vqsim/vqsim.h
4014+ create mode 100644 man/corosync-vqsim.8
4015+
4016+diff --git a/configure.ac b/configure.ac
4017+index 14c0e17..a27ba95 100644
4018+--- a/configure.ac
4019++++ b/configure.ac
4020+@@ -470,6 +470,7 @@ if test "x${enable_vqsim}" = xyes; then
4021+ [],
4022+ AC_MSG_WARN([vqsim will lack readline support]))
4023+ PACKAGE_FEATURES="$PACKAGE_FEATURES vqsim"
4024++ WITH_LIST="$WITH_LIST --with vqsim"
4025+ fi
4026+ AM_CONDITIONAL(VQSIM_READLINE, [test "x${ac_cv_header_readline_readline_h}" = xyes])
4027+
4028+diff --git a/man/Makefile.am b/man/Makefile.am
4029+index d1b7f94..8e4eda3 100644
4030+--- a/man/Makefile.am
4031++++ b/man/Makefile.am
4032+@@ -139,6 +139,10 @@ dist_man_MANS = corosync.conf.5 \
4033+ cmap_overview.3 \
4034+ cmap_keys.8
4035+
4036++if BUILD_VQSIM
4037++dist_man_MANS += corosync-vqsim.8
4038++endif
4039++
4040+ if INSTALL_XMLCONF
4041+ dist_man_MANS += $(xml_man)
4042+ endif
4043+diff --git a/vqsim/Makefile.am b/vqsim/Makefile.am
4044+index 2a76544..9a7fbf6 100644
4045+--- a/vqsim/Makefile.am
4046++++ b/vqsim/Makefile.am
4047+@@ -30,23 +30,25 @@
4048+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
4049+ # THE POSSIBILITY OF SUCH DAMAGE.
4050+
4051+-MAINTAINERCLEANFILES = Makefile.in
4052++MAINTAINERCLEANFILES = Makefile.in
4053+
4054+ if BUILD_VQSIM
4055+
4056+-noinst_PROGRAMS = vqsim
4057++noinst_HEADERS = vqsim.h
4058+
4059+-vqsim_LDADD = $(top_builddir)/common_lib/libcorosync_common.la \
4060+- ../exec/corosync-votequorum.o ../exec/corosync-icmap.o ../exec/corosync-logsys.o \
4061+- ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
4062+- ../exec/corosync-util.o \
4063+- $(LIBQB_LIBS)
4064++bin_PROGRAMS = corosync-vqsim
4065++
4066++corosync_vqsim_LDADD = $(top_builddir)/common_lib/libcorosync_common.la \
4067++ ../exec/corosync-votequorum.o ../exec/corosync-icmap.o \
4068++ ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
4069++ ../exec/corosync-util.o ../exec/corosync-logsys.o \
4070++ $(LIBQB_LIBS)
4071+ if VQSIM_READLINE
4072+-vqsim_LDADD += -lreadline
4073++corosync_vqsim_LDADD += -lreadline
4074+ endif
4075+
4076+-vqsim_DEPENDENCIES = $(top_builddir)/common_lib/libcorosync_common.la
4077++corosync_vqsim_DEPENDENCIES = $(top_builddir)/common_lib/libcorosync_common.la
4078+
4079+-vqsim_SOURCES = vqmain.c parser.c vq_object.c vqsim_vq_engine.c
4080++corosync_vqsim_SOURCES = vqmain.c parser.c vq_object.c vqsim_vq_engine.c
4081+
4082+ endif
4083+diff --git a/vqsim/vqsim.h b/vqsim/vqsim.h
4084+new file mode 100644
4085+index 0000000..0c4c973
4086+--- /dev/null
4087++++ b/vqsim/vqsim.h
4088+@@ -0,0 +1,82 @@
4089++
4090++typedef enum {VQMSG_QUIT=1,
4091++ VQMSG_SYNC, /* set nodelist */
4092++ VQMSG_QUORUM, /* quorum state of this 'node' */
4093++ VQMSG_EXEC, /* message for exec_handler */
4094++ VQMSG_QDEVICE, /* quorum device enable/disable */
4095++ VQMSG_QUORUMQUIT, /* quit if you don't have quorum */
4096++} vqsim_msg_type_t;
4097++
4098++typedef struct vq_instance *vq_object_t;
4099++
4100++struct vqsim_msg_header
4101++{
4102++ vqsim_msg_type_t type;
4103++ int from_nodeid;
4104++ int param;
4105++};
4106++
4107++/* This is the sync sent from the controller process */
4108++struct vqsim_sync_msg
4109++{
4110++ struct vqsim_msg_header header;
4111++ struct memb_ring_id ring_id;
4112++ size_t view_list_entries;
4113++ unsigned int view_list[];
4114++};
4115++
4116++/* This is just info sent from each VQ instance */
4117++struct vqsim_quorum_msg
4118++{
4119++ struct vqsim_msg_header header;
4120++ int quorate;
4121++ struct memb_ring_id ring_id;
4122++ size_t view_list_entries;
4123++ unsigned int view_list[];
4124++};
4125++
4126++struct vqsim_exec_msg
4127++{
4128++ struct vqsim_msg_header header;
4129++ char execmsg[];
4130++};
4131++
4132++struct vqsim_lib_msg
4133++{
4134++ struct vqsim_msg_header header;
4135++ char libmsg[];
4136++};
4137++
4138++#define MAX_NODES 1024
4139++#define MAX_PARTITIONS 16
4140++
4141++/* In vq_object.c */
4142++vq_object_t vq_create_instance(qb_loop_t *poll_loop, int nodeid);
4143++void vq_quit(vq_object_t instance);
4144++int vq_set_nodelist(vq_object_t instance, struct memb_ring_id *ring_id, int *nodeids, int nodeids_entries);
4145++int vq_get_parent_fd(vq_object_t instance);
4146++int vq_set_qdevice(vq_object_t instance, struct memb_ring_id *ring_id, int onoff);
4147++int vq_quit_if_inquorate(vq_object_t instance);
4148++pid_t vq_get_pid(vq_object_t instance);
4149++
4150++/* in vqsim_vq_engine.c - effectively the constructor */
4151++int fork_new_instance(int nodeid, int *vq_sock, pid_t *child_pid);
4152++
4153++/* In parser.c */
4154++void parse_input_command(char *cmd);
4155++
4156++/* These are in vqmain.c */
4157++int cmd_stop_node(int nodeid);
4158++void cmd_stop_all_nodes(void);
4159++int cmd_start_new_node(int nodeid, int partition);
4160++void cmd_set_autofence(int onoff);
4161++void cmd_set_sync(int onoff);
4162++void cmd_set_assert(int onoff);
4163++void cmd_move_nodes(int partition, int num_nodes, int *nodelist);
4164++void cmd_join_partitions(int part1, int part2);
4165++void cmd_update_all_partitions(int newring);
4166++void cmd_qdevice_poll(int nodeid, int onoff);
4167++void cmd_show_node_states(void);
4168++void cmd_set_timeout(uint64_t seconds);
4169++void cmd_start_sync_command(void);
4170++void resume_kb_input(int show_state);
4171+diff --git a/corosync.spec.in b/corosync.spec.in
4172+index 07c004c..8af686e 100644
4173+--- a/corosync.spec.in
4174++++ b/corosync.spec.in
4175+@@ -12,6 +12,7 @@
4176+ %bcond_with systemd
4177+ %bcond_with xmlconf
4178+ %bcond_with nozzle
4179++%bcond_with vqsim
4180+ %bcond_with runautogen
4181+
4182+ %global gitver %{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}
4183+@@ -70,6 +71,9 @@ Requires(preun): /sbin/chkconfig
4184+ %if %{with xmlconf}
4185+ Requires: libxslt
4186+ %endif
4187++%if %{with vqsim}
4188++BuildRequires: readline-devel
4189++%endif
4190+
4191+ %prep
4192+ %setup -q -n %{name}-%{version}%{?gittarver}
4193+@@ -100,6 +104,9 @@ Requires: libxslt
4194+ %endif
4195+ %if %{with nozzle}
4196+ --enable-nozzle \
4197++%endif
4198++%if %{with vqsim}
4199++ --enable-vqsim \
4200+ %endif
4201+ --with-initddir=%{_initrddir} \
4202+ --with-systemddir=%{_unitdir} \
4203+@@ -266,6 +273,25 @@ The Corosync Cluster Engine APIs.
4204+ %{_mandir}/man3/sam_*3*
4205+ %{_mandir}/man3/cmap_*3*
4206+
4207++%if %{with vqsim}
4208++%package -n corosync-vqsim
4209++Summary: The Corosync Cluster Engine - Votequorum Simulator
4210++Requires: corosynclib%{?_isa} = %{version}-%{release}
4211++Requires: pkgconfig
4212++
4213++%description -n corosync-vqsim
4214++A command-line simulator for the corosync votequorum subsystem.
4215++It uses the same code as the corosync quorum system but forks
4216++them into subprocesses to simulate nodes.
4217++Nodes can be added and removed as well as partitioned (to simulate
4218++network splits)
4219++
4220++%files -n corosync-vqsim
4221++%doc LICENSE
4222++%{_bindir}/corosync-vqsim
4223++%{_mandir}/man8/corosync-vqsim.8*
4224++%endif
4225++
4226+ %changelog
4227+ * @date@ Autotools generated version <nobody@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@dirty@
4228+ - Autotools generated version
4229+diff --git a/vqsim/parser.c b/vqsim/parser.c
4230+index 2fc1043..d13e678 100644
4231+--- a/vqsim/parser.c
4232++++ b/vqsim/parser.c
4233+@@ -30,21 +30,31 @@ static void do_usage(void)
4234+ printf(" Enable quorum device in specified nodes\n");
4235+ printf("autofence on|off\n");
4236+ printf(" automatically 'down' nodes on inquorate side on netsplit\n");
4237++ printf("timeout <n> (default 250)\n");
4238++ printf(" Wait a maximum of <n> milli-seconds for the next command to complete.\n");
4239++ printf("sync on|off (default on)\n");
4240++ printf(" enable/disable synchronous execution of commands (wait for completion)\n");
4241++ printf("assert on|off (default off)\n");
4242++ printf(" Abort the simulation run if a timeout expires\n");
4243+ printf("show Show current nodes status\n");
4244+ printf("exit\n\n");
4245+ }
4246+
4247+
4248+-typedef void (*cmd_routine_t)(int argc, char **argv);
4249++/* Commands return 0 if they return immediately, >1 if we are waiting for replies from nodes */
4250++typedef int (*cmd_routine_t)(int argc, char **argv);
4251+
4252+-static void run_up_cmd(int argc, char **argv);
4253+-static void run_down_cmd(int argc, char **argv);
4254+-static void run_join_cmd(int argc, char **argv);
4255+-static void run_move_cmd(int argc, char **argv);
4256+-static void run_exit_cmd(int argc, char **argv);
4257+-static void run_show_cmd(int argc, char **argv);
4258+-static void run_autofence_cmd(int argc, char **argv);
4259+-static void run_qdevice_cmd(int argc, char **argv);
4260++static int run_up_cmd(int argc, char **argv);
4261++static int run_down_cmd(int argc, char **argv);
4262++static int run_join_cmd(int argc, char **argv);
4263++static int run_move_cmd(int argc, char **argv);
4264++static int run_exit_cmd(int argc, char **argv);
4265++static int run_show_cmd(int argc, char **argv);
4266++static int run_timeout_cmd(int argc, char **argv);
4267++static int run_assert_cmd(int argc, char **argv);
4268++static int run_autofence_cmd(int argc, char **argv);
4269++static int run_qdevice_cmd(int argc, char **argv);
4270++static int run_sync_cmd(int argc, char **argv);
4271+
4272+ static struct cmd_list_struct {
4273+ const char *cmd;
4274+@@ -59,6 +69,9 @@ static struct cmd_list_struct {
4275+ { "autofence", 1, run_autofence_cmd},
4276+ { "qdevice", 1, run_qdevice_cmd},
4277+ { "show", 0, run_show_cmd},
4278++ { "timeout", 1, run_timeout_cmd},
4279++ { "sync", 1, run_sync_cmd},
4280++ { "assert", 1, run_assert_cmd},
4281+ { "exit", 0, run_exit_cmd},
4282+ { "quit", 0, run_exit_cmd},
4283+ { "q", 0, run_exit_cmd},
4284+@@ -135,11 +148,16 @@ void parse_input_command(char *rl_cmd)
4285+ int last_arg_start = 0;
4286+ int last_was_space = 0;
4287+ int len;
4288++ int ret = 0;
4289+ char *cmd;
4290+
4291+ /* ^D quits */
4292+ if (rl_cmd == NULL) {
4293+- run_exit_cmd(0, NULL);
4294++ (void)run_exit_cmd(0, NULL);
4295++ }
4296++ /* '#' starts a comment */
4297++ if (rl_cmd[0] == '#') {
4298++ return;
4299+ }
4300+
4301+ cmd = strdup(rl_cmd);
4302+@@ -180,7 +198,8 @@ void parse_input_command(char *rl_cmd)
4303+ /* Ignore null commands */
4304+ if (strlen(argv[0]) == 0) {
4305+ free(cmd);
4306+- return;
4307++ resume_kb_input(0);
4308++ return;
4309+ }
4310+ #ifdef HAVE_READLINE_HISTORY_H
4311+ add_history(rl_cmd);
4312+@@ -193,7 +212,7 @@ void parse_input_command(char *rl_cmd)
4313+ if (argc < cmd_list[i].min_args) {
4314+ break;
4315+ }
4316+- cmd_list[i].cmd_runner(argc, argv);
4317++ ret = cmd_list[i].cmd_runner(argc, argv);
4318+ valid_cmd = 1;
4319+ }
4320+ }
4321+@@ -201,64 +220,86 @@ void parse_input_command(char *rl_cmd)
4322+ do_usage();
4323+ }
4324+ free(cmd);
4325++
4326++ /* ret==0 means we can return immediately to command-line input */
4327++ if (ret == 0) {
4328++ resume_kb_input(ret);
4329++ }
4330+ }
4331+
4332+
4333+
4334+-static void run_up_cmd(int argc, char **argv)
4335++static int run_up_cmd(int argc, char **argv)
4336+ {
4337+ int partition;
4338+ int num_nodes;
4339+ int *nodelist;
4340+ int i,j;
4341++ int succeeded = 0;
4342+
4343+ if (argc <= 1) {
4344+- return;
4345++ return 0;
4346+ }
4347+
4348++ cmd_start_sync_command();
4349++
4350+ for (i=1; i<argc; i++) {
4351+ if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
4352+ for (j=0; j<num_nodes; j++) {
4353+- cmd_start_new_node(nodelist[j], partition);
4354++ if (!cmd_start_new_node(nodelist[j], partition)) {
4355++ succeeded++;
4356++ }
4357+ }
4358+ free(nodelist);
4359+ }
4360+ }
4361++ return succeeded;
4362+ }
4363+
4364+-static void run_down_cmd(int argc, char **argv)
4365++static int run_down_cmd(int argc, char **argv)
4366+ {
4367+ int nodeid;
4368+ int i;
4369++ int succeeded = 0;
4370++
4371++ cmd_start_sync_command();
4372+
4373+ for (i=1; i<argc; i++) {
4374+ nodeid = atoi(argv[1]);
4375+- cmd_stop_node(nodeid);
4376++ if (!cmd_stop_node(nodeid)) {
4377++ succeeded++;
4378++ }
4379+ }
4380++ return succeeded;
4381+ }
4382+
4383+-static void run_join_cmd(int argc, char **argv)
4384++static int run_join_cmd(int argc, char **argv)
4385+ {
4386+ int i;
4387+
4388+ if (argc < 2) {
4389+ printf("join needs at least two partition numbers\n");
4390+- return;
4391++ return 0;
4392+ }
4393+
4394++ cmd_start_sync_command();
4395++
4396+ for (i=2; i<argc; i++) {
4397+ cmd_join_partitions(atoi(argv[1]), atoi(argv[i]));
4398+ }
4399+ cmd_update_all_partitions(1);
4400++ return 1;
4401+ }
4402+
4403+-static void run_move_cmd(int argc, char **argv)
4404++static int run_move_cmd(int argc, char **argv)
4405+ {
4406+ int i;
4407+ int partition;
4408+ int num_nodes;
4409+ int *nodelist;
4410+
4411++ cmd_start_sync_command();
4412++
4413+ for (i=1; i<argc; i++) {
4414+ if (parse_partition_nodelist(argv[i], &partition, &num_nodes, &nodelist) == 0) {
4415+ cmd_move_nodes(partition, num_nodes, nodelist);
4416+@@ -266,9 +307,10 @@ static void run_move_cmd(int argc, char **argv)
4417+ }
4418+ }
4419+ cmd_update_all_partitions(1);
4420++ return 1;
4421+ }
4422+
4423+-static void run_autofence_cmd(int argc, char **argv)
4424++static int run_autofence_cmd(int argc, char **argv)
4425+ {
4426+ int onoff = -1;
4427+
4428+@@ -284,9 +326,10 @@ static void run_autofence_cmd(int argc, char **argv)
4429+ else {
4430+ cmd_set_autofence(onoff);
4431+ }
4432++ return 0;
4433+ }
4434+
4435+-static void run_qdevice_cmd(int argc, char **argv)
4436++static int run_qdevice_cmd(int argc, char **argv)
4437+ {
4438+ int i,j;
4439+ int partition;
4440+@@ -303,7 +346,7 @@ static void run_qdevice_cmd(int argc, char **argv)
4441+
4442+ if (onoff == -1) {
4443+ fprintf(stderr, "ERR: qdevice should be 'on' or 'off'\n");
4444+- return;
4445++ return 0;
4446+ }
4447+
4448+ for (i=2; i<argc; i++) {
4449+@@ -315,17 +358,61 @@ static void run_qdevice_cmd(int argc, char **argv)
4450+ }
4451+ }
4452+ cmd_update_all_partitions(0);
4453++ return 0;
4454+ }
4455+
4456+-static void run_show_cmd(int argc, char **argv)
4457++static int run_show_cmd(int argc, char **argv)
4458+ {
4459+ cmd_show_node_states();
4460++ return 0;
4461+ }
4462+
4463+-static void run_exit_cmd(int argc, char **argv)
4464++static int run_timeout_cmd(int argc, char **argv)
4465+ {
4466+- cmd_stop_all_nodes();
4467+- exit(0);
4468++ cmd_set_timeout(atol(argv[1]));
4469++ return 0;
4470++}
4471++
4472++static int run_sync_cmd(int argc, char **argv)
4473++{
4474++ int onoff = -1;
4475++
4476++ if (strcasecmp(argv[1], "on") == 0) {
4477++ onoff = 1;
4478++ }
4479++ if (strcasecmp(argv[1], "off") == 0) {
4480++ onoff = 0;
4481++ }
4482++ if (onoff == -1) {
4483++ fprintf(stderr, "ERR: sync value must be 'on' or 'off'\n");
4484++ }
4485++ else {
4486++ cmd_set_sync(onoff);
4487++ }
4488++ return 0;
4489+ }
4490+
4491++static int run_assert_cmd(int argc, char **argv)
4492++{
4493++ int onoff = -1;
4494+
4495++ if (strcasecmp(argv[1], "on") == 0) {
4496++ onoff = 1;
4497++ }
4498++ if (strcasecmp(argv[1], "off") == 0) {
4499++ onoff = 0;
4500++ }
4501++ if (onoff == -1) {
4502++ fprintf(stderr, "ERR: assert value must be 'on' or 'off'\n");
4503++ }
4504++ else {
4505++ cmd_set_assert(onoff);
4506++ }
4507++ return 0;
4508++}
4509++
4510++static int run_exit_cmd(int argc, char **argv)
4511++{
4512++ cmd_stop_all_nodes();
4513++ exit(0);
4514++}
4515+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
4516+index c3a1327..0eca43c 100644
4517+--- a/vqsim/vqmain.c
4518++++ b/vqsim/vqmain.c
4519+@@ -25,6 +25,7 @@
4520+ /* Easier than including the config file with a ton of conflicting dependencies */
4521+ extern int coroparse_configparse (icmap_map_t config_map, const char **error_string);
4522+ extern int corosync_log_config_read (const char **error_string);
4523++static int stdin_read_fn(int32_t fd, int32_t revents, void *data);
4524+
4525+ /* 'Keep the compiler happy' time */
4526+ const char *corosync_get_config_file(void);
4527+@@ -56,21 +57,22 @@ static qb_loop_t *poll_loop;
4528+ static int autofence;
4529+ static int check_for_quorum;
4530+ static FILE *output_file;
4531+-static int nosync;
4532++static int sync_cmds = 1;
4533+ static qb_loop_timer_handle kb_timer;
4534+-static ssize_t wait_count;
4535+-static ssize_t wait_count_to_unblock;
4536++static int waiting_for_sync = 0;
4537++static int is_tty;
4538++static int assert_on_timeout;
4539++static uint64_t command_timeout = 250000000L;
4540+
4541+ static struct vq_node *find_by_pid(pid_t pid);
4542+ static void send_partition_to_nodes(struct vq_partition *partition, int newring);
4543+-static void start_kb_input(void);
4544+ static void start_kb_input_timeout(void *data);
4545++static void finish_wait_timeout(void *data);
4546+
4547+ #ifndef HAVE_READLINE_READLINE_H
4548+ #define INPUT_BUF_SIZE 1024
4549+ static char input_buf[INPUT_BUF_SIZE];
4550+ static size_t input_buf_term = 0;
4551+-static int is_tty;
4552+ #endif
4553+
4554+ /* 'Keep the compiler happy' time */
4555+@@ -78,7 +80,6 @@ static char corosync_config_file[PATH_MAX + 1] = COROSYSCONFDIR "/corosync.conf"
4556+
4557+ const char *corosync_get_config_file(void)
4558+ {
4559+-
4560+ return (corosync_config_file);
4561+ }
4562+
4563+@@ -144,6 +145,65 @@ static void propogate_vq_message(struct vq_node *vqn, const char *msg, int len)
4564+ }
4565+ }
4566+
4567++
4568++static void cmd_show_prompt_if_needed(void)
4569++{
4570++ qb_loop_timer_del(poll_loop, kb_timer);
4571++ if (is_tty) {
4572++ printf("vqsim> ");
4573++ fflush(stdout);
4574++ } else {
4575++ printf("#vqsim> ");
4576++ fflush(stdout);
4577++ }
4578++
4579++}
4580++
4581++void resume_kb_input(int show_status)
4582++{
4583++ /* If running synchronously, we don't display
4584++ the quorum messages as they come in. So run 'show' commamnd
4585++ */
4586++ if (show_status && waiting_for_sync) {
4587++ cmd_show_node_states();
4588++ }
4589++
4590++ waiting_for_sync = 0;
4591++
4592++ if (qb_loop_poll_add(poll_loop,
4593++ QB_LOOP_MED,
4594++ STDIN_FILENO,
4595++ POLLIN | POLLERR,
4596++ NULL,
4597++ stdin_read_fn)) {
4598++ if (errno != EEXIST) {
4599++ perror("qb_loop_poll_add1 returned error");
4600++ }
4601++ }
4602++ /* Always shows the prompt here, cos we cleared waiting_for_sync */
4603++ cmd_show_prompt_if_needed();
4604++}
4605++
4606++/* Return true (1) if all nodes in each partition have the same ring id, false(0) otherwise */
4607++static int all_nodes_consistent(void)
4608++{
4609++ int i;
4610++ struct vq_node *vqn;
4611++ struct memb_ring_id last_ring_id;
4612++
4613++ for (i=0; i<MAX_PARTITIONS; i++) {
4614++ memset(&last_ring_id, 0, sizeof(last_ring_id));
4615++ TAILQ_FOREACH(vqn, &partitions[i].nodelist, entries) {
4616++ if (last_ring_id.seq &&
4617++ last_ring_id.seq != vqn->last_ring_id.seq) {
4618++ return 0;
4619++ }
4620++ last_ring_id.seq = vqn->last_ring_id.seq;
4621++ }
4622++ }
4623++ return 1;
4624++}
4625++
4626+ static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
4627+ {
4628+ char msgbuf[8192];
4629+@@ -162,13 +222,18 @@ static int vq_parent_read_fn(int32_t fd, int32_t revents, void *data)
4630+ msg = (void*)msgbuf;
4631+ switch (msg->type) {
4632+ case VQMSG_QUORUM:
4633+- if (!nosync && --wait_count_to_unblock <= 0)
4634+- qb_loop_timer_del(poll_loop, kb_timer);
4635+ qmsg = (void*)msgbuf;
4636+ save_quorum_state(vqn, qmsg);
4637+- print_quorum_state(vqn);
4638+- if (!nosync && wait_count_to_unblock <= 0)
4639+- start_kb_input();
4640++ if (!sync_cmds) {
4641++ print_quorum_state(vqn);
4642++ }
4643++
4644++ /* Have the partitions stabilised? */
4645++ if (sync_cmds && waiting_for_sync &&
4646++ all_nodes_consistent()) {
4647++ qb_loop_timer_del(poll_loop, kb_timer);
4648++ resume_kb_input(sync_cmds);
4649++ }
4650+ break;
4651+ case VQMSG_EXEC:
4652+ /* Message from votequorum, pass around the partition */
4653+@@ -204,7 +269,7 @@ static int read_corosync_conf(void)
4654+ logsys_format_set(NULL);
4655+ res = coroparse_configparse(icmap_get_global_map(), &error_string);
4656+ if (res == -1) {
4657+- log_printf (LOGSYS_LEVEL_INFO, "Error loading corosyc.conf %s", error_string);
4658++ log_printf (LOGSYS_LEVEL_INFO, "Error loading corosync.conf %s", error_string);
4659+ return -1;
4660+ }
4661+ else {
4662+@@ -234,8 +299,6 @@ static void remove_node(struct vq_node *node)
4663+ TAILQ_REMOVE(&part->nodelist, node, entries);
4664+ free(node);
4665+
4666+- wait_count--;
4667+-
4668+ /* Rebuild quorum */
4669+ send_partition_to_nodes(part, 1);
4670+ }
4671+@@ -263,7 +326,7 @@ static int32_t sigchld_handler(int32_t sig, void *data)
4672+ sprintf(text, "(exit code %d)", WEXITSTATUS(status));
4673+ break;
4674+ }
4675+- printf("%d:%02d Quit %s\n", vqn->partition->num, vqn->nodeid, exit_status);
4676++ printf("%d:%02d: Quit %s\n", vqn->partition->num, vqn->nodeid, exit_status);
4677+
4678+ remove_node(vqn);
4679+ }
4680+@@ -322,20 +385,24 @@ static void init_partitions(void)
4681+ }
4682+ }
4683+
4684++static int nodes_in_partition(int part)
4685++{
4686++ struct vq_node *vqn;
4687++ int partnodes = 0;
4688++
4689++ TAILQ_FOREACH(vqn, &partitions[part].nodelist, entries) {
4690++ partnodes++;
4691++ }
4692++ return partnodes;
4693++}
4694++
4695++
4696+ static pid_t create_node(int nodeid, int partno)
4697+ {
4698+ struct vq_node *newvq;
4699+
4700+ newvq = malloc(sizeof(struct vq_node));
4701+ if (newvq) {
4702+- if (!nosync) {
4703+- /* Number of expected "quorum" vq messages is a square
4704+- of the total nodes count, so increment the node
4705+- counter and set new square of this value as
4706+- a "to observe" counter */
4707+- wait_count++;
4708+- wait_count_to_unblock = wait_count * wait_count;
4709+- }
4710+ newvq->last_quorate = -1; /* mark "uninitialized" */
4711+ newvq->instance = vq_create_instance(poll_loop, nodeid);
4712+ if (!newvq->instance) {
4713+@@ -439,29 +506,39 @@ static struct vq_node *find_by_pid(pid_t pid)
4714+ }
4715+
4716+ /* Routines called from the parser */
4717+-void cmd_start_new_node(int nodeid, int partition)
4718++
4719++
4720++/*
4721++ * The parser calls this before running a command where
4722++ * we might have to wait for a result to come back.
4723++ */
4724++void cmd_start_sync_command()
4725++{
4726++ if (sync_cmds) {
4727++ qb_loop_poll_del(poll_loop, STDIN_FILENO);
4728++ qb_loop_timer_add(poll_loop,
4729++ QB_LOOP_MED,
4730++ command_timeout,
4731++ NULL,
4732++ finish_wait_timeout,
4733++ &kb_timer);
4734++ waiting_for_sync = 1;
4735++ }
4736++}
4737++
4738++int cmd_start_new_node(int nodeid, int partition)
4739+ {
4740+ struct vq_node *node;
4741+
4742+ node = find_node(nodeid);
4743+ if (node) {
4744+ fprintf(stderr, "ERR: nodeid %d already exists in partition %d\n", nodeid, node->partition->num);
4745+- return;
4746++ return -1;
4747+ }
4748+- qb_loop_poll_del(poll_loop, STDIN_FILENO);
4749+- create_node(nodeid, partition);
4750+- if (!nosync) {
4751+- /* Delay kb input handling by 0.25 second when we've just
4752+- added a node; expect that the delay will be cancelled
4753+- substantially earlier once it has reported its quorum info
4754+- (the delay is in fact a failsafe input enabler here) */
4755+- qb_loop_timer_add(poll_loop,
4756+- QB_LOOP_MED,
4757+- 250000000,
4758+- NULL,
4759+- start_kb_input_timeout,
4760+- &kb_timer);
4761++ if (create_node(nodeid, partition) == -1) {
4762++ return -1;
4763+ }
4764++ return 0;
4765+ }
4766+
4767+ void cmd_stop_all_nodes()
4768+@@ -489,20 +566,21 @@ void cmd_show_node_states()
4769+ fprintf(output_file, "#autofence: %s\n", autofence?"on":"off");
4770+ }
4771+
4772+-void cmd_stop_node(int nodeid)
4773++int cmd_stop_node(int nodeid)
4774+ {
4775+ struct vq_node *node;
4776+
4777+ node = find_node(nodeid);
4778+ if (!node) {
4779+ fprintf(stderr, "ERR: nodeid %d is not up\n", nodeid);
4780+- return;
4781++ return -1;
4782+ }
4783+
4784+ /* Remove processor */
4785+ vq_quit(node->instance);
4786+
4787+ /* Node will be removed when the child process exits */
4788++ return 0;
4789+ }
4790+
4791+ /* Move all nodes in 'nodelist' into partition 'partition' */
4792+@@ -510,6 +588,13 @@ void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
4793+ {
4794+ int i;
4795+ struct vq_node *node;
4796++ struct vq_node *vqn;
4797++ int total_nodes = num_nodes;
4798++
4799++ /* Work out the number of nodes affected */
4800++ TAILQ_FOREACH(vqn, &partitions[partition].nodelist, entries) {
4801++ total_nodes++;
4802++ }
4803+
4804+ for (i=0; i<num_nodes; i++) {
4805+ node = find_node(nodelist[i]);
4806+@@ -532,6 +617,11 @@ void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
4807+ void cmd_join_partitions(int part1, int part2)
4808+ {
4809+ struct vq_node *vqn;
4810++ int total_nodes=0;
4811++
4812++ /* Work out the number of nodes affected */
4813++ total_nodes += nodes_in_partition(part1);
4814++ total_nodes += nodes_in_partition(part2);
4815+
4816+ /* TAILQ_FOREACH is not delete safe *sigh* */
4817+ retry:
4818+@@ -551,6 +641,18 @@ void cmd_set_autofence(int onoff)
4819+ fprintf(output_file, "#autofence: %s\n", onoff?"on":"off");
4820+ }
4821+
4822++void cmd_set_sync(int onoff)
4823++{
4824++ autofence = onoff;
4825++ fprintf(output_file, "#sync: %s\n", onoff?"on":"off");
4826++ sync_cmds = onoff;
4827++}
4828++
4829++void cmd_set_assert(int onoff)
4830++{
4831++ assert_on_timeout = onoff;
4832++}
4833++
4834+ void cmd_update_all_partitions(int newring)
4835+ {
4836+ int i;
4837+@@ -571,6 +673,24 @@ void cmd_qdevice_poll(int nodeid, int onoff)
4838+ }
4839+ }
4840+
4841++/* If we get called then a command has timed-out */
4842++static void finish_wait_timeout(void *data)
4843++{
4844++ if (command_timeout) {
4845++ fprintf(stderr, "ERR: Partition(s) not stable within timeout\n");
4846++ if (assert_on_timeout) {
4847++ exit(2);
4848++ }
4849++ }
4850++
4851++ resume_kb_input(sync_cmds);
4852++}
4853++
4854++void cmd_set_timeout(uint64_t seconds)
4855++{
4856++ command_timeout = seconds * QB_TIME_NS_IN_MSEC;
4857++}
4858++
4859+ /* ---------------------------------- */
4860+
4861+ #ifndef HAVE_READLINE_READLINE_H
4862+@@ -598,11 +718,6 @@ static void dummy_read_char()
4863+
4864+ parse_input_command((c == EOF) ? NULL : input_buf);
4865+ input_buf_term = 0;
4866+-
4867+- if (is_tty) {
4868+- printf("vqsim> ");
4869+- fflush(stdout);
4870+- }
4871+ }
4872+ #endif
4873+
4874+@@ -617,50 +732,26 @@ static int stdin_read_fn(int32_t fd, int32_t revents, void *data)
4875+ return 0;
4876+ }
4877+
4878+-static void start_kb_input(void)
4879+-{
4880+- wait_count_to_unblock = 0;
4881+-
4882+-#ifdef HAVE_READLINE_READLINE_H
4883+- /* Readline will deal with completed lines when they arrive */
4884+- rl_callback_handler_install("vqsim> ", parse_input_command);
4885+-#else
4886+- if (is_tty) {
4887+- printf("vqsim> ");
4888+- fflush(stdout);
4889+- }
4890+-#endif
4891+-
4892+- /* Send stdin to readline */
4893+- if (qb_loop_poll_add(poll_loop,
4894+- QB_LOOP_MED,
4895+- STDIN_FILENO,
4896+- POLLIN | POLLERR,
4897+- NULL,
4898+- stdin_read_fn)) {
4899+- if (errno != EEXIST) {
4900+- perror("qb_loop_poll_add1 returned error");
4901+- }
4902+- }
4903+-}
4904+
4905+ static void start_kb_input_timeout(void *data)
4906+ {
4907+-// fprintf(stderr, "Waiting for nodes to report status timed out\n");
4908+- start_kb_input();
4909++ resume_kb_input(1);
4910+ }
4911+
4912+ static void usage(char *program)
4913+ {
4914+ printf("Usage:\n");
4915+ printf("\n");
4916+- printf("%s [-f <config-file>] [-o <output-file>]\n", program);
4917++ printf("%s [-c <config-file>] [-o <output-file>]\n", program);
4918+ printf("\n");
4919+- printf(" -f config file. defaults to /etc/corosync/corosync.conf\n");
4920++ printf(" -c config file. defaults to /etc/corosync/corosync.conf\n");
4921+ printf(" -o output file. defaults to stdout\n");
4922+ printf(" -n no synchronization (on adding a node)\n");
4923+ printf(" -h display this help text\n");
4924+ printf("\n");
4925++ printf("%s always takes input from STDIN, but cannot use a file.\n", program);
4926++ printf("If you want to script it then use\n cat | %s\n", program);
4927++ printf("\n");
4928+ }
4929+
4930+ int main(int argc, char **argv)
4931+@@ -669,16 +760,16 @@ int main(int argc, char **argv)
4932+ int ch;
4933+ char *output_file_name = NULL;
4934+
4935+- while ((ch = getopt (argc, argv, "f:o:nh")) != EOF) {
4936++ while ((ch = getopt (argc, argv, "c:o:nh")) != EOF) {
4937+ switch (ch) {
4938+- case 'f':
4939++ case 'c':
4940+ strncpy(corosync_config_file, optarg, sizeof(corosync_config_file));
4941+ break;
4942+ case 'o':
4943+ output_file_name = optarg;
4944+ break;
4945+ case 'n':
4946+- nosync = 1;
4947++ sync_cmds = 0;
4948+ break;
4949+ default:
4950+ usage(argv[0]);
4951+@@ -696,9 +787,8 @@ int main(int argc, char **argv)
4952+ else {
4953+ output_file = stdout;
4954+ }
4955+-#ifndef HAVE_READLINE_READLINE_H
4956++
4957+ is_tty = isatty(STDIN_FILENO);
4958+-#endif
4959+
4960+ qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD,
4961+ QB_LOG_FILTER_FUNCTION, "*", LOG_DEBUG);
4962+@@ -717,9 +807,26 @@ int main(int argc, char **argv)
4963+ sigchld_handler,
4964+ &sigchld_qb_handle);
4965+
4966+- /* Create a full cluster of nodes from corosync.conf */
4967++
4968++#ifdef HAVE_READLINE_READLINE_H
4969++ /* Readline will deal with completed lines when they arrive */
4970++ /*
4971++ * For scripting add '#' to the start of the prompt so that
4972++ * parsers can ignore input lines
4973++ */
4974++ rl_already_prompted = 1;
4975++ if (is_tty) {
4976++ rl_callback_handler_install("vqsim> ", parse_input_command);
4977++ } else {
4978++ rl_callback_handler_install("#vqsim> ", parse_input_command);
4979++ }
4980++#endif
4981++
4982++
4983++
4984++/* Create a full cluster of nodes from corosync.conf */
4985+ read_corosync_conf();
4986+- if (create_nodes_from_config() && !nosync) {
4987++ if (create_nodes_from_config() && sync_cmds) {
4988+ /* Delay kb input handling by 1 second when we've just
4989+ added the nodes from corosync.conf; expect that
4990+ the delay will be cancelled substantially earlier
4991+@@ -731,8 +838,9 @@ int main(int argc, char **argv)
4992+ NULL,
4993+ start_kb_input_timeout,
4994+ &kb_timer);
4995++ waiting_for_sync = 1;
4996+ } else {
4997+- start_kb_input();
4998++ resume_kb_input(0);
4999+ }
5000+
5001+ qb_loop_run(poll_loop);
5002+diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
5003+index cbe1d47..eb35d35 100644
5004+--- a/vqsim/vqsim_vq_engine.c
5005++++ b/vqsim/vqsim_vq_engine.c
5006+@@ -191,6 +191,7 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
5007+ uint32_t nodeid;
5008+ const char *iter_key;
5009+ int res;
5010++ int found = 0;
5011+
5012+ iter = icmap_iter_init("nodelist.node.");
5013+ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
5014+@@ -205,13 +206,18 @@ static void set_local_node_pos(struct corosync_api_v1 *api)
5015+ res = icmap_get_uint32(iter_key, &nodeid);
5016+ if (res == CS_OK) {
5017+ if (nodeid == our_nodeid) {
5018++ found = 1;
5019+ res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
5020+- if (res != CS_OK) {
5021+- fprintf(stderr, "Failed to find node %d in corosync.conf. Quorum calculations may not be correct:\n", our_nodeid);
5022+- }
5023+ }
5024+ }
5025+ }
5026++ if (!found) {
5027++ /* This probably indicates a dynamically-added node
5028++ * set the pos to zero and use the votes of the
5029++ * first node in corosync.conf
5030++ */
5031++ res = icmap_set_uint32("nodelist.local_node_pos", 0);
5032++ }
5033+ }
5034+
5035+ static int load_quorum_instance(struct corosync_api_v1 *api)
5036+diff --git a/man/corosync-vqsim.8 b/man/corosync-vqsim.8
5037+new file mode 100644
5038+index 0000000..26a6468
5039+--- /dev/null
5040++++ b/man/corosync-vqsim.8
5041+@@ -0,0 +1,94 @@
5042++.\"/*
5043++.\" * Copyright (C) 2019 Red Hat, Inc.
5044++.\" *
5045++.\" * All rights reserved.
5046++.\" *
5047++.\" * Author: Christine Caulfield <ccaulfie@redhat.com>
5048++.\" *
5049++.\" * This software licensed under BSD license, the text of which follows:
5050++.\" *
5051++.\" * Redistribution and use in source and binary forms, with or without
5052++.\" * modification, are permitted provided that the following conditions are met:
5053++.\" *
5054++.\" * - Redistributions of source code must retain the above copyright notice,
5055++.\" * this list of conditions and the following disclaimer.
5056++.\" * - Redistributions in binary form must reproduce the above copyright notice,
5057++.\" * this list of conditions and the following disclaimer in the documentation
5058++.\" * and/or other materials provided with the distribution.
5059++.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
5060++.\" * contributors may be used to endorse or promote products derived from this
5061++.\" * software without specific prior written permission.
5062++.\" *
5063++.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
5064++.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5065++.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5066++.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
5067++.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
5068++.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
5069++.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
5070++.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
5071++.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5072++.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
5073++.\" * THE POSSIBILITY OF SUCH DAMAGE.
5074++.\" */
5075++.TH COROSYNC-VQSIM 8 2019-05-10
5076++.SH NAME
5077++corosync-vqsim \- The votequorum simulator
5078++.SH SYNOPSIS
5079++.B "corosync-vqsim [\-c config_file] [\-o output file] [\-n] [\-h]"
5080++.SH DESCRIPTION
5081++.B corosync-vqsim
5082++simulates the quorum functions of corosync in a single program. it can simulate
5083++multiple nodes, network splits and a basic quorum device.
5084++
5085++By default vqsim will build a virtual cluster of all the nodes in the corosync.conf file,
5086++each 'node' running in a forked subprocess (and thus asynchronously). It then provides a
5087++command-line interface to add (up) or remove (down) nodes, and cause network splits and
5088++rejoins. After each event it shows the new quorum status for all nodes.
5089++
5090++Nodes in vqsim are always referred to by their nodeid (the IP address is meaningless) and
5091++optionally by a 'partition' which precedes the nodeid with a colon. By default all nodes
5092++are in partition 0. Nodes can be moved between partitions using the split and join commands.
5093++Multiple nodes can be split and joined at the same time.
5094++
5095++To script vqsim you must send input to it via a pipe rather than just redirecting STDIN. This
5096++is because it runs asynchronously to enable the virtual 'nodes' to report status when needed.
5097++(eg if you kill a subprocess using the 'kill(1)' command it gets removed from the cluster).
5098++
5099++By default vqsim will wait for all nodes in all partitions to reach the same
5100++ring sequence number before returning a prompt,
5101++there is a timeout associated with this in case of a 'node' failure and exceeding this timeout
5102++can (optionally) quit the program signalling an error.
5103++
5104++You can disable waiting using the 'sync off' command or the -n command-line option. This can easily
5105++cause unexpected behaviour so use it with care.
5106++
5107++The number of votes per node is read from corosync.conf. New nodes added using the 'up' command
5108++will copy their number of votes from the first node in corosync.conf. This may not be what you
5109++expect and I might fix it in future. As most clusters have only 1 vote per node (and this is
5110++strongly recommended) then this should rarely be a problem.
5111++
5112++Once you have the 'vqsim> ' prompt you can type 'help' and get a list of sub-commands.
5113++
5114++.SH OPTIONS
5115++.TP
5116++.B -c
5117++This specifies the fully qualified path to the corosync configuration file.
5118++
5119++The default is /etc/corosync/corosync.conf.
5120++.TP
5121++.B -o
5122++Specifies the output destination. STDOUT by default.
5123++.TP
5124++.B -n
5125++Don't pause after each command, come straight back to a prompt. Use with care!
5126++
5127++.TP
5128++.B -h
5129++Display a brief help message
5130++.SH SEE ALSO
5131++.BR corosync (9),
5132++.BR corosync.conf (5),
5133++.SH AUTHOR
5134++Christine Caulfield
5135++.PP
5136diff --git a/debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch b/debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch
5137new file mode 100644
5138index 00000000..36f686c9
5139--- /dev/null
5140+++ b/debian/patches/vqsim-Fix-vqsim-for-corosync-3.0.patch
5141@@ -0,0 +1,102 @@
5142+From: Christine Caulfield <ccaulfie@redhat.com>
5143+Date: Thu, 25 Apr 2019 14:38:52 +0100
5144+Subject: vqsim: Fix vqsim for corosync 3.0
5145+
5146+A couple of small internal changes in corosync 3.0 broke vqsim.
5147+1) The way the custom config file is specified (no long an env variable)
5148+2) votequorum now needs to know ouZ_node_pos
5149+
5150+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
5151+Reviewed-by: Jan Friesse <jfriesse@redhat.com>
5152+(cherry picked from commit e65d7b5d9800df96dcc8b5d6216a85800113924c)
5153+---
5154+ vqsim/vqmain.c | 8 +-------
5155+ vqsim/vqsim_vq_engine.c | 37 +++++++++++++++++++++++++++++++++++++
5156+ 2 files changed, 38 insertions(+), 7 deletions(-)
5157+
5158+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
5159+index 683cc22..c3a1327 100644
5160+--- a/vqsim/vqmain.c
5161++++ b/vqsim/vqmain.c
5162+@@ -667,14 +667,12 @@ int main(int argc, char **argv)
5163+ {
5164+ qb_loop_signal_handle sigchld_qb_handle;
5165+ int ch;
5166+- char *config_file_name = NULL;
5167+ char *output_file_name = NULL;
5168+- char envstring[PATH_MAX];
5169+
5170+ while ((ch = getopt (argc, argv, "f:o:nh")) != EOF) {
5171+ switch (ch) {
5172+ case 'f':
5173+- config_file_name = optarg;
5174++ strncpy(corosync_config_file, optarg, sizeof(corosync_config_file));
5175+ break;
5176+ case 'o':
5177+ output_file_name = optarg;
5178+@@ -688,10 +686,6 @@ int main(int argc, char **argv)
5179+ }
5180+ }
5181+
5182+- if (config_file_name) {
5183+- sprintf(envstring, "COROSYNC_MAIN_CONFIG_FILE=%s", config_file_name);
5184+- putenv(envstring);
5185+- }
5186+ if (output_file_name) {
5187+ output_file = fopen(output_file_name, "w");
5188+ if (!output_file) {
5189+diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
5190+index 9d8b4ee..cbe1d47 100644
5191+--- a/vqsim/vqsim_vq_engine.c
5192++++ b/vqsim/vqsim_vq_engine.c
5193+@@ -178,6 +178,42 @@ char *get_run_dir()
5194+ return getcwd(cwd_buffer, PATH_MAX);
5195+ }
5196+
5197++/* This is different to the one in totemconfig.c in that we already
5198++ * know the 'local' node ID, so we can just search for that.
5199++ * It needs to be here rather than at main config read time as it's
5200++ * (obviously) going to be different for each instance.
5201++ */
5202++static void set_local_node_pos(struct corosync_api_v1 *api)
5203++{
5204++ icmap_iter_t iter;
5205++ uint32_t node_pos;
5206++ char name_str[ICMAP_KEYNAME_MAXLEN];
5207++ uint32_t nodeid;
5208++ const char *iter_key;
5209++ int res;
5210++
5211++ iter = icmap_iter_init("nodelist.node.");
5212++ while ((iter_key = icmap_iter_next(iter, NULL, NULL)) != NULL) {
5213++ res = sscanf(iter_key, "nodelist.node.%u.%s", &node_pos, name_str);
5214++ if (res != 2) {
5215++ continue;
5216++ }
5217++ if (strcmp(name_str, "nodeid")) {
5218++ continue;
5219++ }
5220++
5221++ res = icmap_get_uint32(iter_key, &nodeid);
5222++ if (res == CS_OK) {
5223++ if (nodeid == our_nodeid) {
5224++ res = icmap_set_uint32("nodelist.local_node_pos", node_pos);
5225++ if (res != CS_OK) {
5226++ fprintf(stderr, "Failed to find node %d in corosync.conf. Quorum calculations may not be correct:\n", our_nodeid);
5227++ }
5228++ }
5229++ }
5230++ }
5231++}
5232++
5233+ static int load_quorum_instance(struct corosync_api_v1 *api)
5234+ {
5235+ const char *error_string;
5236+@@ -417,6 +453,7 @@ int fork_new_instance(int nodeid, int *vq_sock, pid_t *childpid)
5237+ qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
5238+ }
5239+
5240++ set_local_node_pos(&corosync_api);
5241+ load_quorum_instance(&corosync_api);
5242+
5243+ qb_loop_poll_add(poll_loop,
5244diff --git a/debian/patches/vqsim-Free-allocated-newvq-on-error.patch b/debian/patches/vqsim-Free-allocated-newvq-on-error.patch
5245new file mode 100644
5246index 00000000..cfa9a763
5247--- /dev/null
5248+++ b/debian/patches/vqsim-Free-allocated-newvq-on-error.patch
5249@@ -0,0 +1,23 @@
5250+From: Jan Friesse <jfriesse@redhat.com>
5251+Date: Tue, 11 Jun 2019 14:50:03 +0200
5252+Subject: vqsim: Free allocated newvq on error
5253+
5254+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
5255+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
5256+(cherry picked from commit 215d2e30b20d5167161a2d803284f2b0ecf67c29)
5257+---
5258+ vqsim/vqmain.c | 1 +
5259+ 1 file changed, 1 insertion(+)
5260+
5261+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
5262+index 98729b9..d45a24d 100644
5263+--- a/vqsim/vqmain.c
5264++++ b/vqsim/vqmain.c
5265+@@ -425,6 +425,7 @@ static pid_t create_node(int nodeid, int partno)
5266+ fprintf(stderr,
5267+ "ERR: could not create vq instance nodeid %d\n",
5268+ nodeid);
5269++ free(newvq);
5270+ return (pid_t) -1;
5271+ }
5272+ newvq->partition = &partitions[partno];
5273diff --git a/debian/patches/vqsim-Make-vqsim-compile.patch b/debian/patches/vqsim-Make-vqsim-compile.patch
5274new file mode 100644
5275index 00000000..766ab88b
5276--- /dev/null
5277+++ b/debian/patches/vqsim-Make-vqsim-compile.patch
5278@@ -0,0 +1,131 @@
5279+From: Jan Friesse <jfriesse@redhat.com>
5280+Date: Tue, 23 Apr 2019 16:48:30 +0200
5281+Subject: vqsim: Make vqsim compile
5282+
5283+Also add vqsim binary to .gitignore.
5284+
5285+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
5286+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
5287+(cherry picked from commit e287a7c1efd37732d2bd3309a1d7d23a303f8640)
5288+---
5289+ vqsim/Makefile.am | 1 +
5290+ vqsim/vqmain.c | 19 ++++++++++++++++---
5291+ vqsim/vqsim_vq_engine.c | 5 +++--
5292+ vqsim/.gitignore | 1 +
5293+ 4 files changed, 21 insertions(+), 5 deletions(-)
5294+ create mode 100644 vqsim/.gitignore
5295+
5296+diff --git a/vqsim/Makefile.am b/vqsim/Makefile.am
5297+index b74826b..2a76544 100644
5298+--- a/vqsim/Makefile.am
5299++++ b/vqsim/Makefile.am
5300+@@ -39,6 +39,7 @@ noinst_PROGRAMS = vqsim
5301+ vqsim_LDADD = $(top_builddir)/common_lib/libcorosync_common.la \
5302+ ../exec/corosync-votequorum.o ../exec/corosync-icmap.o ../exec/corosync-logsys.o \
5303+ ../exec/corosync-coroparse.o ../exec/corosync-logconfig.o \
5304++ ../exec/corosync-util.o \
5305+ $(LIBQB_LIBS)
5306+ if VQSIM_READLINE
5307+ vqsim_LDADD += -lreadline
5308+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
5309+index e7917d7..683cc22 100644
5310+--- a/vqsim/vqmain.c
5311++++ b/vqsim/vqmain.c
5312+@@ -26,6 +26,9 @@
5313+ extern int coroparse_configparse (icmap_map_t config_map, const char **error_string);
5314+ extern int corosync_log_config_read (const char **error_string);
5315+
5316++/* 'Keep the compiler happy' time */
5317++const char *corosync_get_config_file(void);
5318++
5319+ /* One of these per partition */
5320+ struct vq_partition {
5321+ TAILQ_HEAD(, vq_node) nodelist;
5322+@@ -70,6 +73,15 @@ static size_t input_buf_term = 0;
5323+ static int is_tty;
5324+ #endif
5325+
5326++/* 'Keep the compiler happy' time */
5327++static char corosync_config_file[PATH_MAX + 1] = COROSYSCONFDIR "/corosync.conf";
5328++
5329++const char *corosync_get_config_file(void)
5330++{
5331++
5332++ return (corosync_config_file);
5333++}
5334++
5335+ /* Tell all non-quorate nodes to quit */
5336+ static void force_fence(void)
5337+ {
5338+@@ -110,7 +122,7 @@ static void print_quorum_state(struct vq_node *node)
5339+ }
5340+
5341+ fprintf(output_file, "%d:%02d: q=%d ring=[%d/%lld] ", node->partition->num, node->nodeid, node->last_quorate,
5342+- node->last_ring_id.rep.nodeid, node->last_ring_id.seq);
5343++ node->last_ring_id.nodeid, node->last_ring_id.seq);
5344+ fprintf(output_file, "nodes=[");
5345+ for (i = 0; i < node->last_view_list_entries; i++) {
5346+ if (i) {
5347+@@ -209,6 +221,7 @@ static int read_corosync_conf(void)
5348+ log_printf (LOGSYS_LEVEL_ERROR, "Can't initialize log thread");
5349+ return -1;
5350+ }
5351++
5352+ return 0;
5353+ }
5354+
5355+@@ -287,7 +300,7 @@ static void send_partition_to_nodes(struct vq_partition *partition, int newring)
5356+ TAILQ_FOREACH(vqn, &partition->nodelist, entries) {
5357+ nodelist[nodes++] = vqn->nodeid;
5358+ if (first) {
5359+- partition->ring_id.rep.nodeid = vqn->nodeid;
5360++ partition->ring_id.nodeid = vqn->nodeid;
5361+ first = 0;
5362+ }
5363+ }
5364+@@ -303,7 +316,7 @@ static void init_partitions(void)
5365+
5366+ for (i=0; i<MAX_PARTITIONS; i++) {
5367+ TAILQ_INIT(&partitions[i].nodelist);
5368+- partitions[i].ring_id.rep.nodeid = 1000+i;
5369++ partitions[i].ring_id.nodeid = 1000+i;
5370+ partitions[i].ring_id.seq = 0;
5371+ partitions[i].num = i;
5372+ }
5373+diff --git a/vqsim/vqsim_vq_engine.c b/vqsim/vqsim_vq_engine.c
5374+index ee139d4..9d8b4ee 100644
5375+--- a/vqsim/vqsim_vq_engine.c
5376++++ b/vqsim/vqsim_vq_engine.c
5377+@@ -44,6 +44,7 @@ static unsigned int qdevice_timeout = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT;
5378+
5379+ /* 'Keep the compiler happy' time */
5380+ char *get_run_dir(void);
5381++
5382+ int api_timer_add_duration (
5383+ unsigned long long nanosec_duration,
5384+ void *data,
5385+@@ -262,7 +263,7 @@ static int poll_qdevice(int onoff)
5386+ int res;
5387+
5388+ pollmsg.cast_vote = onoff;
5389+- pollmsg.ring_id.nodeid = current_ring_id.rep.nodeid;
5390++ pollmsg.ring_id.nodeid = current_ring_id.nodeid;
5391+ pollmsg.ring_id.seq = current_ring_id.seq;
5392+ strcpy(pollmsg.name, QDEVICE_NAME);
5393+
5394+@@ -374,7 +375,7 @@ static void initial_sync(int nodeid)
5395+ unsigned int member_list[1] = {nodeid};
5396+ struct memb_ring_id ring_id;
5397+
5398+- ring_id.rep.nodeid = our_nodeid;
5399++ ring_id.nodeid = our_nodeid;
5400+ ring_id.seq = 1;
5401+
5402+ /* cluster with just us in it */
5403+diff --git a/vqsim/.gitignore b/vqsim/.gitignore
5404+new file mode 100644
5405+index 0000000..85d30f9
5406+--- /dev/null
5407++++ b/vqsim/.gitignore
5408+@@ -0,0 +1 @@
5409++vqsim
5410diff --git a/debian/patches/vqsim-Remove-unused-total_nodes.patch b/debian/patches/vqsim-Remove-unused-total_nodes.patch
5411new file mode 100644
5412index 00000000..a50c6d58
5413--- /dev/null
5414+++ b/debian/patches/vqsim-Remove-unused-total_nodes.patch
5415@@ -0,0 +1,62 @@
5416+From: Jan Friesse <jfriesse@redhat.com>
5417+Date: Tue, 11 Jun 2019 15:11:13 +0200
5418+Subject: vqsim: Remove unused total_nodes
5419+
5420+... and remove unused nodes_in_partition function.
5421+
5422+Also replace TAILQ_FOREACH with goto to while cycle.
5423+
5424+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
5425+Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
5426+(cherry picked from commit ef9b931b7e2585ef87198693760df39d60e9f542)
5427+---
5428+ vqsim/vqmain.c | 25 ++-----------------------
5429+ 1 file changed, 2 insertions(+), 23 deletions(-)
5430+
5431+diff --git a/vqsim/vqmain.c b/vqsim/vqmain.c
5432+index d45a24d..16f7714 100644
5433+--- a/vqsim/vqmain.c
5434++++ b/vqsim/vqmain.c
5435+@@ -401,18 +401,6 @@ static void init_partitions(void)
5436+ }
5437+ }
5438+
5439+-static int nodes_in_partition(int part)
5440+-{
5441+- struct vq_node *vqn;
5442+- int partnodes = 0;
5443+-
5444+- TAILQ_FOREACH(vqn, &partitions[part].nodelist, entries) {
5445+- partnodes++;
5446+- }
5447+- return partnodes;
5448+-}
5449+-
5450+-
5451+ static pid_t create_node(int nodeid, int partno)
5452+ {
5453+ struct vq_node *newvq;
5454+@@ -634,21 +622,12 @@ void cmd_move_nodes(int partition, int num_nodes, int *nodelist)
5455+ void cmd_join_partitions(int part1, int part2)
5456+ {
5457+ struct vq_node *vqn;
5458+- int total_nodes=0;
5459+-
5460+- /* Work out the number of nodes affected */
5461+- total_nodes += nodes_in_partition(part1);
5462+- total_nodes += nodes_in_partition(part2);
5463+-
5464+- /* TAILQ_FOREACH is not delete safe *sigh* */
5465+-retry:
5466+- TAILQ_FOREACH(vqn, &partitions[part2].nodelist, entries) {
5467+
5468++ while (!TAILQ_EMPTY(&partitions[part2].nodelist)) {
5469++ vqn = TAILQ_FIRST(&partitions[part2].nodelist);
5470+ TAILQ_REMOVE(&vqn->partition->nodelist, vqn, entries);
5471+ TAILQ_INSERT_TAIL(&partitions[part1].nodelist, vqn, entries);
5472+ vqn->partition = &partitions[part1];
5473+-
5474+- goto retry;
5475+ }
5476+ }
5477+
5478diff --git a/debian/patches/series b/debian/patches/series
5479index 6b552ce1..ea6e04ea 100644
5480--- a/debian/patches/series
5481+++ b/debian/patches/series
5482@@ -1,8 +1,53 @@
5483-Fix-various-typos-in-ChangeLog.patch
5484-Enable-PrivateTmp-in-the-systemd-service-files.patch
5485-Make-the-example-config-valid.patch
5486+doc-Update-INSTALL-file.patch
5487+cfgtool-Improve-link-status-display.patch
5488 corosync.conf.5-fix-grammar.patch
5489 corosync.conf.5-typography-fixes.patch
5490-AC_PROG_SED-is-already-present.patch
5491-Use-the-SED-variable-provided-by-configure.patch
5492-Use-the-AWK-variable-provided-by-configure.patch
5493+configure.ac-AC_PROG_SED-is-already-present.patch
5494+build-Use-the-SED-variable-provided-by-configure.patch
5495+build-Use-the-AWK-variable-provided-by-configure.patch
5496+corosync-cfgtool-Fix-i-matching.patch
5497+quorumtool-Fix-exit-status-codes.patch
5498+nozzle-Add-support-for-libnozzle-devices.patch
5499+configure-Do-not-autodetect-nozzle.patch
5500+coroparse-Fix-compiler-warning.patch
5501+totemsrp-Word-spelling-mistake.patch
5502+Revert-init-Enable-StopWhenUnneeded.patch
5503+set-totem.keyfile-and-totem.key-to-RO.patch
5504+keygen-Reflect-change-in-knet.patch
5505+totemconfig-Remove-support-for-3des.patch
5506+crypto-re-introduce-secauth-parameter.patch
5507+cpg-Add-CPG_REASON_UNDEFINED.patch
5508+totemconfig-ipaddr_equal-check-just-addr-part.patch
5509+vqsim-Make-vqsim-compile.patch
5510+vqsim-Fix-vqsim-for-corosync-3.0.patch
5511+totemconfig-Ensure-nodeid-is-specified-for-IPv6.patch
5512+totemconfig-fix-autogen-mcastaddr-for-ipv6-4.patch
5513+knet-Fix-a-couple-of-errors-when-adding-a-new-link.patch
5514+vqsim-Enhance-vqsim.patch
5515+totemconfig-Fix-minimum-limit-for-hold-timeout.patch
5516+man-Enhance-token_retransmit-description.patch
5517+knet-allow-corosync-to-use-knet-access-lists.patch
5518+knet-Fix-initialising-of-knet-access-lists.patch
5519+udpu-Drop-packets-from-unlisted-IPs.patch
5520+knet-Use-block_unlisted_ips.patch
5521+cfgtool-Fix-link-status-display.patch
5522+man-Enhance-corosync.conf-mp-a-bit.patch
5523+man-Enahnce-block_unlisted_ips-description.patch
5524+spec-Add-support-for-user-flags-configure-option.patch
5525+man-Add-vqsim-man-page-into-distributed-tarball.patch
5526+configure-Fix-GDB_CFLAGS-typo.patch
5527+totemconfig-ipaddr_equal-use-switch.patch
5528+totemip-Use-res-in-totemip_sa_equal.patch
5529+totemknet-create_nozzle_device-simplify-check.patch
5530+totemknet-Ignore-icmap_get_string-result.patch
5531+totemknet-macaddr_str-is-always-set.patch
5532+totemknet-Initialize-return-value-in-setup_nozzle.patch
5533+vqsim-Do-not-access-unitialized-argv-0.patch
5534+vqsim-Check-write-result.patch
5535+vqsim-Check-length-of-received-message.patch
5536+vqsim-Free-allocated-newvq-on-error.patch
5537+vqsim-Remove-unused-total_nodes.patch
5538+vqsim-Check-result-of-icmap_set_uint32.patch
5539+vqsim-Check-length-of-copied-optarg.patch
5540+Fix-various-typos-in-ChangeLog.patch
5541+Enable-PrivateTmp-in-the-systemd-service-files.patch