]> git.proxmox.com Git - corosync-pve.git/blob - patches/0008-CPG-callback-merging.patch
2b8d9466c37569a1b2fbd625d0f1bda39193927c
[corosync-pve.git] / patches / 0008-CPG-callback-merging.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
3 Date: Wed, 22 May 2019 12:27:19 +0200
4 Subject: [PATCH] CPG callback merging
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 cherry-picked from upstream PR 468.
10
11 this series aims to minimize callback calls in case of cluster cold
12 starts or re-joining after network partitions, which cause a huge spike
13 in network load on bigger clusters running pmxcfs.
14
15 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
16 ---
17 .../cpg-Add-CPG_REASON_UNDEFINED.patch | 152 +++++++++++++
18 ...more-comments-to-notify_lib_joinlist.patch | 193 +++++++++++++++++
19 ...illing-of-member_list-to-subfunction.patch | 130 ++++++++++++
20 ...ify_lib_joinlist-drop-conn-parameter.patch | 112 ++++++++++
21 ...-confchg-event-per-group-on-joinlist.patch | 199 ++++++++++++++++++
22 debian/patches/series | 5 +
23 6 files changed, 791 insertions(+)
24 create mode 100644 debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
25 create mode 100644 debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch
26 create mode 100644 debian/patches/cpg-Move-filling-of-member_list-to-subfunction.patch
27 create mode 100644 debian/patches/cpg-notify_lib_joinlist-drop-conn-parameter.patch
28 create mode 100644 debian/patches/cpg-send-single-confchg-event-per-group-on-joinlist.patch
29
30 diff --git a/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
31 new file mode 100644
32 index 00000000..a69b53ac
33 --- /dev/null
34 +++ b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
35 @@ -0,0 +1,152 @@
36 +From: Jan Friesse <jfriesse@redhat.com>
37 +Date: Tue, 16 Apr 2019 12:52:31 +0200
38 +Subject: cpg: Add CPG_REASON_UNDEFINED
39 +
40 +Previously the reason field for the member_list items
41 +in cpg_totem_confchg_fn was unset what may be little confusing.
42 +
43 +Solution is to add a special value CPG_REASON_UNDEFINED and use it for
44 +the member_list items.
45 +
46 +Signed-off-by: Jan Friesse <jfriesse@redhat.com>
47 +Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
48 +(cherry picked from commit 41f9e966bb1cfa70d0f6ec1ce46d9c845845b599)
49 +---
50 + include/corosync/cpg.h | 3 ++-
51 + man/cpg_initialize.3.in | 18 ++++++++++--------
52 + man/cpg_model_initialize.3.in | 18 ++++++++++--------
53 + exec/cpg.c | 3 ++-
54 + 4 files changed, 24 insertions(+), 18 deletions(-)
55 +
56 +diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h
57 +index 5ebd478..600bbf7 100644
58 +--- a/include/corosync/cpg.h
59 ++++ b/include/corosync/cpg.h
60 +@@ -1,5 +1,5 @@
61 + /*
62 +- * Copyright (c) 2006-2011 Red Hat, Inc.
63 ++ * Copyright (c) 2006-2019 Red Hat, Inc.
64 + *
65 + * All rights reserved.
66 + *
67 +@@ -80,6 +80,7 @@ typedef enum {
68 + * @brief The cpg_reason_t enum
69 + */
70 + typedef enum {
71 ++ CPG_REASON_UNDEFINED = 0,
72 + CPG_REASON_JOIN = 1,
73 + CPG_REASON_LEAVE = 2,
74 + CPG_REASON_NODEDOWN = 3,
75 +diff --git a/man/cpg_initialize.3.in b/man/cpg_initialize.3.in
76 +index bdecc1e..38c7de5 100644
77 +--- a/man/cpg_initialize.3.in
78 ++++ b/man/cpg_initialize.3.in
79 +@@ -1,5 +1,5 @@
80 + .\"/*
81 +-.\" * Copyright (c) 2006-2009 Red Hat, Inc.
82 ++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
83 + .\" *
84 + .\" * All rights reserved.
85 + .\" *
86 +@@ -31,7 +31,7 @@
87 + .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
88 + .\" * THE POSSIBILITY OF SUCH DAMAGE.
89 + .\" */
90 +-.TH CPG_INITIALIZE 3 2004-08-31 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
91 ++.TH CPG_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
92 + .SH NAME
93 + cpg_initialize \- Create a new connection to the CPG service
94 + .SH SYNOPSIS
95 +@@ -132,18 +132,20 @@ struct cpg_address {
96 + .IP
97 + .PP
98 + where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
99 +-or sent the message, and reason is an integer code indicating why the node joined/left the group.
100 ++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
101 ++set for the member_list items).
102 + .PP
103 + .IP
104 + .RS
105 + .ne 18
106 + .nf
107 + .PP
108 +-CPG_REASON_JOIN - the process joined a group using cpg_join().
109 +-CPG_REASON_LEAVE - the process left a group using cpg_leave()
110 +-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
111 +-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
112 +-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
113 ++CPG_REASON_JOIN - the process joined a group using cpg_join().
114 ++CPG_REASON_LEAVE - the process left a group using cpg_leave()
115 ++CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
116 ++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
117 ++CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
118 ++CPG_REASON_UNDEFINED - a special value used for the member_list items
119 + .ta
120 + .fi
121 + .RE
122 +diff --git a/man/cpg_model_initialize.3.in b/man/cpg_model_initialize.3.in
123 +index e06325d..17ca16a 100644
124 +--- a/man/cpg_model_initialize.3.in
125 ++++ b/man/cpg_model_initialize.3.in
126 +@@ -1,5 +1,5 @@
127 + .\"/*
128 +-.\" * Copyright (c) 2010 Red Hat, Inc.
129 ++.\" * Copyright (c) 2010-2019 Red Hat, Inc.
130 + .\" *
131 + .\" * All rights reserved.
132 + .\" *
133 +@@ -32,7 +32,7 @@
134 + .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
135 + .\" * THE POSSIBILITY OF SUCH DAMAGE.
136 + .\" */
137 +-.TH CPG_MODEL_INITIALIZE 3 2010-04-07 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
138 ++.TH CPG_MODEL_INITIALIZE 3 2019-04-16 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
139 + .SH NAME
140 + cpg_model_initialize \- Create a new connection to the CPG service
141 + .SH SYNOPSIS
142 +@@ -166,18 +166,20 @@ struct cpg_address {
143 + .IP
144 + .PP
145 + where nodeid is a 32 bit unique node identifier, pid is the process ID of the process that has joined/left the group
146 +-or sent the message, and reason is an integer code indicating why the node joined/left the group.
147 ++or sent the message, and reason is an integer code indicating why the node joined/left the group (this value is not
148 ++set for the member_list items).
149 + .PP
150 + .IP
151 + .RS
152 + .ne 18
153 + .nf
154 + .PP
155 +-CPG_REASON_JOIN - the process joined a group using cpg_join().
156 +-CPG_REASON_LEAVE - the process left a group using cpg_leave()
157 +-CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
158 +-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
159 +-CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
160 ++CPG_REASON_JOIN - the process joined a group using cpg_join().
161 ++CPG_REASON_LEAVE - the process left a group using cpg_leave()
162 ++CPG_REASON_NODEDOWN - the process left a group because the node left the cluster.
163 ++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
164 ++CPG_REASON_PROCDOWN - the process left a group without calling cpg_leave()
165 ++CPG_REASON_UNDEFINED - a special value used for the member_list items
166 + .ta
167 + .fi
168 + .RE
169 +diff --git a/exec/cpg.c b/exec/cpg.c
170 +index b7ac579..e39ca34 100644
171 +--- a/exec/cpg.c
172 ++++ b/exec/cpg.c
173 +@@ -1,5 +1,5 @@
174 + /*
175 +- * Copyright (c) 2006-2015 Red Hat, Inc.
176 ++ * Copyright (c) 2006-2019 Red Hat, Inc.
177 + *
178 + * All rights reserved.
179 + *
180 +@@ -712,6 +712,7 @@ static int notify_lib_joinlist(
181 + if (!founded) {
182 + retgi->nodeid = pi->nodeid;
183 + retgi->pid = pi->pid;
184 ++ retgi->reason = CPG_REASON_UNDEFINED;
185 + retgi++;
186 + }
187 + }
188 diff --git a/debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch b/debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch
189 new file mode 100644
190 index 00000000..e32102fa
191 --- /dev/null
192 +++ b/debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch
193 @@ -0,0 +1,193 @@
194 +From: Jan Friesse <jfriesse@redhat.com>
195 +Date: Wed, 15 May 2019 17:39:13 +0200
196 +Subject: cpg: Add more comments to notify_lib_joinlist
197 +
198 +And make handling of left_list more generic. Also free skiplist
199 +allocated by joinlist_inform_clients function. Last (but not least)
200 +remove czechlish founded (should have been pp of "find").
201 +
202 +Signed-off-by: Jan Friesse <jfriesse@redhat.com>
203 +(cherry picked from commit 10702c7e6c0cf8164ad8f05acb4e334461555973)
204 +---
205 + exec/cpg.c | 91 +++++++++++++++++++++++++++++++++++++++++---------------------
206 + 1 file changed, 60 insertions(+), 31 deletions(-)
207 +
208 +diff --git a/exec/cpg.c b/exec/cpg.c
209 +index e04ba57..2ecdc6b 100644
210 +--- a/exec/cpg.c
211 ++++ b/exec/cpg.c
212 +@@ -663,31 +663,37 @@ static int notify_lib_joinlist(
213 + int size;
214 + char *buf;
215 + struct qb_list_head *iter;
216 +- int count;
217 ++ int member_list_entries;
218 + struct res_lib_cpg_confchg_callback *res;
219 + mar_cpg_address_t *retgi;
220 ++ int i;
221 +
222 +- count = 0;
223 ++ /*
224 ++ * Find size of member_list (use process_info_list but remove items in left_list)
225 ++ */
226 ++ member_list_entries = 0;
227 +
228 + qb_list_for_each(iter, &process_info_list_head) {
229 + struct process_info *pi = qb_list_entry (iter, struct process_info, list);
230 ++
231 + if (mar_name_compare (&pi->group, group_name) == 0) {
232 +- int i;
233 +- int founded = 0;
234 ++ int in_left_list = 0;
235 +
236 + for (i = 0; i < left_list_entries; i++) {
237 + if (left_list[i].nodeid == pi->nodeid && left_list[i].pid == pi->pid) {
238 +- founded++;
239 ++ in_left_list = 1;
240 ++ break ;
241 + }
242 + }
243 +
244 +- if (!founded)
245 +- count++;
246 ++ if (!in_left_list) {
247 ++ member_list_entries++;
248 ++ }
249 + }
250 + }
251 +
252 + size = sizeof(struct res_lib_cpg_confchg_callback) +
253 +- sizeof(mar_cpg_address_t) * (count + left_list_entries + joined_list_entries);
254 ++ sizeof(mar_cpg_address_t) * (member_list_entries + left_list_entries + joined_list_entries);
255 + buf = alloca(size);
256 + if (!buf)
257 + return CS_ERR_LIBRARY;
258 +@@ -695,27 +701,30 @@ static int notify_lib_joinlist(
259 + res = (struct res_lib_cpg_confchg_callback *)buf;
260 + res->joined_list_entries = joined_list_entries;
261 + res->left_list_entries = left_list_entries;
262 +- res->member_list_entries = count;
263 ++ res->member_list_entries = member_list_entries;
264 + retgi = res->member_list;
265 + res->header.size = size;
266 + res->header.id = id;
267 + res->header.error = CS_OK;
268 + memcpy(&res->group_name, group_name, sizeof(mar_cpg_name_t));
269 +
270 ++ /*
271 ++ * Fill res->memberlist. Use process_info_list but remove items in left_list.
272 ++ */
273 + qb_list_for_each(iter, &process_info_list_head) {
274 +- struct process_info *pi=qb_list_entry (iter, struct process_info, list);
275 ++ struct process_info *pi = qb_list_entry (iter, struct process_info, list);
276 +
277 + if (mar_name_compare (&pi->group, group_name) == 0) {
278 +- int i;
279 +- int founded = 0;
280 ++ int in_left_list = 0;
281 +
282 +- for (i = 0;i < left_list_entries; i++) {
283 ++ for (i = 0; i < left_list_entries; i++) {
284 + if (left_list[i].nodeid == pi->nodeid && left_list[i].pid == pi->pid) {
285 +- founded++;
286 ++ in_left_list = 1;
287 ++ break ;
288 + }
289 + }
290 +
291 +- if (!founded) {
292 ++ if (!in_left_list) {
293 + retgi->nodeid = pi->nodeid;
294 + retgi->pid = pi->pid;
295 + retgi->reason = CPG_REASON_UNDEFINED;
296 +@@ -724,23 +733,30 @@ static int notify_lib_joinlist(
297 + }
298 + }
299 +
300 ++ /*
301 ++ * Fill res->left_list
302 ++ */
303 + if (left_list_entries) {
304 + memcpy (retgi, left_list, left_list_entries * sizeof(mar_cpg_address_t));
305 + retgi += left_list_entries;
306 + }
307 +
308 + if (joined_list_entries) {
309 +- int i;
310 +-
311 ++ /*
312 ++ * Fill res->joined_list
313 ++ */
314 + memcpy (retgi, joined_list, joined_list_entries * sizeof(mar_cpg_address_t));
315 + retgi += joined_list_entries;
316 +
317 +- for (i=0; i < joined_list_entries; i++) {
318 ++ /*
319 ++ * Update cpd_state for all local joined processes in group
320 ++ */
321 ++ for (i = 0; i < joined_list_entries; i++) {
322 + if (joined_list[i].nodeid == api->totem_nodeid_get()) {
323 +- qb_list_for_each(iter, &cpg_pd_list_head) {
324 ++ qb_list_for_each(iter, &cpg_pd_list_head) {
325 + struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
326 +- if (mar_name_compare (&cpd->group_name, group_name) == 0 &&
327 +- joined_list[i].pid == cpd->pid) {
328 ++ if (joined_list[i].pid == cpd->pid &&
329 ++ mar_name_compare (&cpd->group_name, group_name) == 0) {
330 + cpd->cpd_state = CPD_STATE_JOIN_COMPLETED;
331 + }
332 + }
333 +@@ -748,6 +764,9 @@ static int notify_lib_joinlist(
334 + }
335 + }
336 +
337 ++ /*
338 ++ * Send notification to all ipc clients joined in group_name
339 ++ */
340 + qb_list_for_each(iter, &cpg_pd_list_head) {
341 + struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
342 + if (mar_name_compare (&cpd->group_name, group_name) == 0) {
343 +@@ -760,16 +779,25 @@ static int notify_lib_joinlist(
344 + }
345 + }
346 +
347 +- if (left_list_entries &&
348 +- left_list[0].nodeid == api->totem_nodeid_get() &&
349 +- left_list[0].reason == CONFCHG_CPG_REASON_LEAVE) {
350 +- qb_list_for_each(iter, &cpg_pd_list_head) {
351 +- struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
352 +- if (mar_name_compare (&cpd->group_name, group_name) == 0 &&
353 +- left_list[0].pid == cpd->pid) {
354 +- cpd->pid = 0;
355 +- memset (&cpd->group_name, 0, sizeof(cpd->group_name));
356 +- cpd->cpd_state = CPD_STATE_UNJOINED;
357 ++ if (left_list_entries) {
358 ++ /*
359 ++ * Zero internal cpd state for all local processes leaving group
360 ++ * (this loop is not strictly needed because left_list always either
361 ++ * contains exactly one process running on local node or more items
362 ++ * but none of them is running on local node)
363 ++ */
364 ++ for (i = 0; i < joined_list_entries; i++) {
365 ++ if (left_list[i].nodeid == api->totem_nodeid_get() &&
366 ++ left_list[i].reason == CONFCHG_CPG_REASON_LEAVE) {
367 ++ qb_list_for_each(iter, &cpg_pd_list_head) {
368 ++ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
369 ++ if (left_list[i].pid == cpd->pid &&
370 ++ mar_name_compare (&cpd->group_name, group_name) == 0) {
371 ++ cpd->pid = 0;
372 ++ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
373 ++ cpd->cpd_state = CPD_STATE_UNJOINED;
374 ++ }
375 ++ }
376 + }
377 + }
378 + }
379 +@@ -966,6 +994,7 @@ static void joinlist_inform_clients (void)
380 + free(jld);
381 + }
382 + qb_map_iter_free(miter);
383 ++ qb_map_destroy(group_notify_map);
384 +
385 + joinlist_remove_zombie_pi_entries ();
386 + }
387 diff --git a/debian/patches/cpg-Move-filling-of-member_list-to-subfunction.patch b/debian/patches/cpg-Move-filling-of-member_list-to-subfunction.patch
388 new file mode 100644
389 index 00000000..9ec65353
390 --- /dev/null
391 +++ b/debian/patches/cpg-Move-filling-of-member_list-to-subfunction.patch
392 @@ -0,0 +1,130 @@
393 +From: Jan Friesse <jfriesse@redhat.com>
394 +Date: Thu, 16 May 2019 14:08:25 +0200
395 +Subject: cpg: Move filling of member_list to subfunction
396 +
397 +Signed-off-by: Jan Friesse <jfriesse@redhat.com>
398 +(cherry picked from commit 0c1de94461368b4a924b516b77691e6ec471dcb0)
399 +---
400 + exec/cpg.c | 86 ++++++++++++++++++++++++++++++++++++--------------------------
401 + 1 file changed, 50 insertions(+), 36 deletions(-)
402 +
403 +diff --git a/exec/cpg.c b/exec/cpg.c
404 +index 2ecdc6b..98a16a6 100644
405 +--- a/exec/cpg.c
406 ++++ b/exec/cpg.c
407 +@@ -652,26 +652,27 @@ static int notify_lib_totem_membership (
408 + return CS_OK;
409 + }
410 +
411 +-static int notify_lib_joinlist(
412 ++/*
413 ++ * Helper function for notify_lib_joinlist which prepares member_list using
414 ++ * process_info_list with removed left_list items.
415 ++ * member_list_entries - When not NULL it contains number of member_list entries
416 ++ * member_list - When not NULL it is used as pointer to start of preallocated
417 ++ * array of members. Pointer is adjusted to the end of array on
418 ++ * exit.
419 ++ */
420 ++static void notify_lib_joinlist_fill_member_list(
421 + const mar_cpg_name_t *group_name,
422 +- int joined_list_entries,
423 +- mar_cpg_address_t *joined_list,
424 + int left_list_entries,
425 +- mar_cpg_address_t *left_list,
426 +- int id)
427 ++ const mar_cpg_address_t *left_list,
428 ++ int *member_list_entries,
429 ++ mar_cpg_address_t **member_list)
430 + {
431 +- int size;
432 +- char *buf;
433 + struct qb_list_head *iter;
434 +- int member_list_entries;
435 +- struct res_lib_cpg_confchg_callback *res;
436 +- mar_cpg_address_t *retgi;
437 + int i;
438 +
439 +- /*
440 +- * Find size of member_list (use process_info_list but remove items in left_list)
441 +- */
442 +- member_list_entries = 0;
443 ++ if (member_list_entries != NULL) {
444 ++ *member_list_entries = 0;
445 ++ }
446 +
447 + qb_list_for_each(iter, &process_info_list_head) {
448 + struct process_info *pi = qb_list_entry (iter, struct process_info, list);
449 +@@ -687,10 +688,42 @@ static int notify_lib_joinlist(
450 + }
451 +
452 + if (!in_left_list) {
453 +- member_list_entries++;
454 ++ if (member_list_entries != NULL) {
455 ++ (*member_list_entries)++;
456 ++ }
457 ++
458 ++ if (member_list != NULL) {
459 ++ (*member_list)->nodeid = pi->nodeid;
460 ++ (*member_list)->pid = pi->pid;
461 ++ (*member_list)->reason = CPG_REASON_UNDEFINED;
462 ++ (*member_list)++;
463 ++ }
464 + }
465 + }
466 + }
467 ++}
468 ++
469 ++static int notify_lib_joinlist(
470 ++ const mar_cpg_name_t *group_name,
471 ++ int joined_list_entries,
472 ++ mar_cpg_address_t *joined_list,
473 ++ int left_list_entries,
474 ++ mar_cpg_address_t *left_list,
475 ++ int id)
476 ++{
477 ++ int size;
478 ++ char *buf;
479 ++ struct qb_list_head *iter;
480 ++ int member_list_entries;
481 ++ struct res_lib_cpg_confchg_callback *res;
482 ++ mar_cpg_address_t *retgi;
483 ++ int i;
484 ++
485 ++ /*
486 ++ * Find size of member_list (use process_info_list but remove items in left_list)
487 ++ */
488 ++ notify_lib_joinlist_fill_member_list(group_name, left_list_entries, left_list,
489 ++ &member_list_entries, NULL);
490 +
491 + size = sizeof(struct res_lib_cpg_confchg_callback) +
492 + sizeof(mar_cpg_address_t) * (member_list_entries + left_list_entries + joined_list_entries);
493 +@@ -711,27 +744,8 @@ static int notify_lib_joinlist(
494 + /*
495 + * Fill res->memberlist. Use process_info_list but remove items in left_list.
496 + */
497 +- qb_list_for_each(iter, &process_info_list_head) {
498 +- struct process_info *pi = qb_list_entry (iter, struct process_info, list);
499 +-
500 +- if (mar_name_compare (&pi->group, group_name) == 0) {
501 +- int in_left_list = 0;
502 +-
503 +- for (i = 0; i < left_list_entries; i++) {
504 +- if (left_list[i].nodeid == pi->nodeid && left_list[i].pid == pi->pid) {
505 +- in_left_list = 1;
506 +- break ;
507 +- }
508 +- }
509 +-
510 +- if (!in_left_list) {
511 +- retgi->nodeid = pi->nodeid;
512 +- retgi->pid = pi->pid;
513 +- retgi->reason = CPG_REASON_UNDEFINED;
514 +- retgi++;
515 +- }
516 +- }
517 +- }
518 ++ notify_lib_joinlist_fill_member_list(group_name, left_list_entries, left_list,
519 ++ NULL, &retgi);
520 +
521 + /*
522 + * Fill res->left_list
523 diff --git a/debian/patches/cpg-notify_lib_joinlist-drop-conn-parameter.patch b/debian/patches/cpg-notify_lib_joinlist-drop-conn-parameter.patch
524 new file mode 100644
525 index 00000000..e1742bf9
526 --- /dev/null
527 +++ b/debian/patches/cpg-notify_lib_joinlist-drop-conn-parameter.patch
528 @@ -0,0 +1,112 @@
529 +From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
530 +Date: Wed, 15 May 2019 13:45:13 +0200
531 +Subject: cpg: notify_lib_joinlist: drop conn parameter
532 +
533 +since it is always set to NULL.
534 +
535 +(cherry picked from commit d5e9723695b2ae63162b238300013d785e875ea7)
536 +---
537 + exec/cpg.c | 54 ++++++++++++++++++++++++------------------------------
538 + 1 file changed, 24 insertions(+), 30 deletions(-)
539 +
540 +diff --git a/exec/cpg.c b/exec/cpg.c
541 +index e39ca34..b752cc1 100644
542 +--- a/exec/cpg.c
543 ++++ b/exec/cpg.c
544 +@@ -647,7 +647,6 @@ static int notify_lib_totem_membership (
545 +
546 + static int notify_lib_joinlist(
547 + const mar_cpg_name_t *group_name,
548 +- void *conn,
549 + int joined_list_entries,
550 + mar_cpg_address_t *joined_list,
551 + int left_list_entries,
552 +@@ -728,40 +727,35 @@ static int notify_lib_joinlist(
553 + retgi += joined_list_entries;
554 + }
555 +
556 +- if (conn) {
557 +- api->ipc_dispatch_send (conn, buf, size);
558 +- } else {
559 + qb_list_for_each(iter, &cpg_pd_list_head) {
560 +- struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
561 +- if (mar_name_compare (&cpd->group_name, group_name) == 0) {
562 +- assert (joined_list_entries <= 1);
563 +- if (joined_list_entries) {
564 +- if (joined_list[0].pid == cpd->pid &&
565 +- joined_list[0].nodeid == api->totem_nodeid_get()) {
566 +- cpd->cpd_state = CPD_STATE_JOIN_COMPLETED;
567 +- }
568 ++ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
569 ++ if (mar_name_compare (&cpd->group_name, group_name) == 0) {
570 ++ assert (joined_list_entries <= 1);
571 ++ if (joined_list_entries) {
572 ++ if (joined_list[0].pid == cpd->pid &&
573 ++ joined_list[0].nodeid == api->totem_nodeid_get()) {
574 ++ cpd->cpd_state = CPD_STATE_JOIN_COMPLETED;
575 + }
576 +- if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
577 +- cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
578 ++ }
579 ++ if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
580 ++ cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
581 +
582 +- api->ipc_dispatch_send (cpd->conn, buf, size);
583 +- cpd->transition_counter++;
584 +- }
585 +- if (left_list_entries) {
586 +- if (left_list[0].pid == cpd->pid &&
587 +- left_list[0].nodeid == api->totem_nodeid_get() &&
588 +- left_list[0].reason == CONFCHG_CPG_REASON_LEAVE) {
589 +-
590 +- cpd->pid = 0;
591 +- memset (&cpd->group_name, 0, sizeof(cpd->group_name));
592 +- cpd->cpd_state = CPD_STATE_UNJOINED;
593 +- }
594 ++ api->ipc_dispatch_send (cpd->conn, buf, size);
595 ++ cpd->transition_counter++;
596 ++ }
597 ++ if (left_list_entries) {
598 ++ if (left_list[0].pid == cpd->pid &&
599 ++ left_list[0].nodeid == api->totem_nodeid_get() &&
600 ++ left_list[0].reason == CONFCHG_CPG_REASON_LEAVE) {
601 ++
602 ++ cpd->pid = 0;
603 ++ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
604 ++ cpd->cpd_state = CPD_STATE_UNJOINED;
605 + }
606 + }
607 + }
608 + }
609 +
610 +-
611 + /*
612 + * Traverse thru cpds and send totem membership for cpd, where it is not send yet
613 + */
614 +@@ -858,7 +852,7 @@ static void downlist_inform_clients (void)
615 + }
616 +
617 + /* send confchg event */
618 +- notify_lib_joinlist(&group, NULL,
619 ++ notify_lib_joinlist(&group,
620 + 0, NULL,
621 + pcd->left_list_entries,
622 + pcd->left_list,
623 +@@ -1157,7 +1151,7 @@ static void do_proc_join(
624 + notify_info.nodeid = nodeid;
625 + notify_info.reason = reason;
626 +
627 +- notify_lib_joinlist(&pi->group, NULL,
628 ++ notify_lib_joinlist(&pi->group,
629 + 1, &notify_info,
630 + 0, NULL,
631 + MESSAGE_RES_CPG_CONFCHG_CALLBACK);
632 +@@ -1177,7 +1171,7 @@ static void do_proc_leave(
633 + notify_info.nodeid = nodeid;
634 + notify_info.reason = reason;
635 +
636 +- notify_lib_joinlist(name, NULL,
637 ++ notify_lib_joinlist(name,
638 + 0, NULL,
639 + 1, &notify_info,
640 + MESSAGE_RES_CPG_CONFCHG_CALLBACK);
641 diff --git a/debian/patches/cpg-send-single-confchg-event-per-group-on-joinlist.patch b/debian/patches/cpg-send-single-confchg-event-per-group-on-joinlist.patch
642 new file mode 100644
643 index 00000000..013baaa0
644 --- /dev/null
645 +++ b/debian/patches/cpg-send-single-confchg-event-per-group-on-joinlist.patch
646 @@ -0,0 +1,199 @@
647 +From: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
648 +Date: Wed, 8 May 2019 16:31:15 +0200
649 +Subject: cpg: send single confchg event per group on joinlist
650 +MIME-Version: 1.0
651 +Content-Type: text/plain; charset="utf-8"
652 +Content-Transfer-Encoding: 8bit
653 +
654 +using a similar approach to
655 +
656 +43bead364514e8ae2ba00bcf07c460e31d0b1765 "Send one confchg event per CPG group to CPG client"
657 +
658 +which did the same for leave events on a network partition.
659 +
660 +Fixes: #351
661 +
662 +Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
663 +(cherry picked from commit 9c60289b831ef0b138142c3fc39c9a9da8a2ada2)
664 +---
665 + exec/cpg.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++----------------
666 + 1 file changed, 73 insertions(+), 24 deletions(-)
667 +
668 +diff --git a/exec/cpg.c b/exec/cpg.c
669 +index b752cc1..e04ba57 100644
670 +--- a/exec/cpg.c
671 ++++ b/exec/cpg.c
672 +@@ -194,6 +194,12 @@ struct join_list_entry {
673 + mar_cpg_name_t group_name;
674 + };
675 +
676 ++struct join_list_confchg_data {
677 ++ mar_cpg_name_t cpg_group;
678 ++ mar_cpg_address_t join_list[CPG_MEMBERS_MAX];
679 ++ int join_list_entries;
680 ++};
681 ++
682 + /*
683 + * Service Interfaces required by service_message_handler struct
684 + */
685 +@@ -312,7 +318,8 @@ static void do_proc_join(
686 + const mar_cpg_name_t *name,
687 + uint32_t pid,
688 + unsigned int nodeid,
689 +- int reason);
690 ++ int reason,
691 ++ qb_map_t *group_notify_map);
692 +
693 + static void do_proc_leave(
694 + const mar_cpg_name_t *name,
695 +@@ -723,35 +730,46 @@ static int notify_lib_joinlist(
696 + }
697 +
698 + if (joined_list_entries) {
699 ++ int i;
700 ++
701 + memcpy (retgi, joined_list, joined_list_entries * sizeof(mar_cpg_address_t));
702 + retgi += joined_list_entries;
703 ++
704 ++ for (i=0; i < joined_list_entries; i++) {
705 ++ if (joined_list[i].nodeid == api->totem_nodeid_get()) {
706 ++ qb_list_for_each(iter, &cpg_pd_list_head) {
707 ++ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
708 ++ if (mar_name_compare (&cpd->group_name, group_name) == 0 &&
709 ++ joined_list[i].pid == cpd->pid) {
710 ++ cpd->cpd_state = CPD_STATE_JOIN_COMPLETED;
711 ++ }
712 ++ }
713 ++ }
714 ++ }
715 + }
716 +
717 + qb_list_for_each(iter, &cpg_pd_list_head) {
718 + struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
719 + if (mar_name_compare (&cpd->group_name, group_name) == 0) {
720 +- assert (joined_list_entries <= 1);
721 +- if (joined_list_entries) {
722 +- if (joined_list[0].pid == cpd->pid &&
723 +- joined_list[0].nodeid == api->totem_nodeid_get()) {
724 +- cpd->cpd_state = CPD_STATE_JOIN_COMPLETED;
725 +- }
726 +- }
727 + if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
728 + cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
729 +
730 + api->ipc_dispatch_send (cpd->conn, buf, size);
731 + cpd->transition_counter++;
732 + }
733 +- if (left_list_entries) {
734 +- if (left_list[0].pid == cpd->pid &&
735 +- left_list[0].nodeid == api->totem_nodeid_get() &&
736 +- left_list[0].reason == CONFCHG_CPG_REASON_LEAVE) {
737 +-
738 +- cpd->pid = 0;
739 +- memset (&cpd->group_name, 0, sizeof(cpd->group_name));
740 +- cpd->cpd_state = CPD_STATE_UNJOINED;
741 +- }
742 ++ }
743 ++ }
744 ++
745 ++ if (left_list_entries &&
746 ++ left_list[0].nodeid == api->totem_nodeid_get() &&
747 ++ left_list[0].reason == CONFCHG_CPG_REASON_LEAVE) {
748 ++ qb_list_for_each(iter, &cpg_pd_list_head) {
749 ++ struct cpg_pd *cpd = qb_list_entry (iter, struct cpg_pd, list);
750 ++ if (mar_name_compare (&cpd->group_name, group_name) == 0 &&
751 ++ left_list[0].pid == cpd->pid) {
752 ++ cpd->pid = 0;
753 ++ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
754 ++ cpd->cpd_state = CPD_STATE_UNJOINED;
755 + }
756 + }
757 + }
758 +@@ -915,6 +933,11 @@ static void joinlist_inform_clients (void)
759 + struct joinlist_msg *stored_msg;
760 + struct qb_list_head *iter;
761 + unsigned int i;
762 ++ qb_map_t *group_notify_map;
763 ++ qb_map_iter_t *miter;
764 ++ struct join_list_confchg_data *jld;
765 ++
766 ++ group_notify_map = qb_skiplist_create();
767 +
768 + i = 0;
769 + qb_list_for_each(iter, &joinlist_messages_head) {
770 +@@ -931,9 +954,19 @@ static void joinlist_inform_clients (void)
771 + }
772 +
773 + do_proc_join (&stored_msg->group_name, stored_msg->pid, stored_msg->sender_nodeid,
774 +- CONFCHG_CPG_REASON_NODEUP);
775 ++ CONFCHG_CPG_REASON_NODEUP, group_notify_map);
776 + }
777 +
778 ++ miter = qb_map_iter_create(group_notify_map);
779 ++ while (qb_map_iter_next(miter, (void **)&jld)) {
780 ++ notify_lib_joinlist(&jld->cpg_group,
781 ++ jld->join_list_entries, jld->join_list,
782 ++ 0, NULL,
783 ++ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
784 ++ free(jld);
785 ++ }
786 ++ qb_map_iter_free(miter);
787 ++
788 + joinlist_remove_zombie_pi_entries ();
789 + }
790 +
791 +@@ -1111,13 +1144,15 @@ static void do_proc_join(
792 + const mar_cpg_name_t *name,
793 + uint32_t pid,
794 + unsigned int nodeid,
795 +- int reason)
796 ++ int reason,
797 ++ qb_map_t *group_notify_map)
798 + {
799 + struct process_info *pi;
800 + struct process_info *pi_entry;
801 + mar_cpg_address_t notify_info;
802 + struct qb_list_head *list;
803 + struct qb_list_head *list_to_add = NULL;
804 ++ int size;
805 +
806 + if (process_info_find (name, pid, nodeid) != NULL) {
807 + return ;
808 +@@ -1151,10 +1186,24 @@ static void do_proc_join(
809 + notify_info.nodeid = nodeid;
810 + notify_info.reason = reason;
811 +
812 +- notify_lib_joinlist(&pi->group,
813 +- 1, &notify_info,
814 +- 0, NULL,
815 +- MESSAGE_RES_CPG_CONFCHG_CALLBACK);
816 ++ if (group_notify_map == NULL) {
817 ++ notify_lib_joinlist(&pi->group,
818 ++ 1, &notify_info,
819 ++ 0, NULL,
820 ++ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
821 ++ } else {
822 ++ struct join_list_confchg_data *jld = qb_map_get(group_notify_map, pi->group.value);
823 ++ if (jld == NULL) {
824 ++ jld = (struct join_list_confchg_data *)calloc(1, sizeof(struct join_list_confchg_data));
825 ++ memcpy(&jld->cpg_group, &pi->group, sizeof(mar_cpg_name_t));
826 ++ qb_map_put(group_notify_map, jld->cpg_group.value, jld);
827 ++ }
828 ++ size = jld->join_list_entries;
829 ++ jld->join_list[size].nodeid = notify_info.nodeid;
830 ++ jld->join_list[size].pid = notify_info.pid;
831 ++ jld->join_list[size].reason = notify_info.reason;
832 ++ jld->join_list_entries++;
833 ++ }
834 + }
835 +
836 + static void do_proc_leave(
837 +@@ -1219,7 +1268,7 @@ static void message_handler_req_exec_cpg_procjoin (
838 +
839 + do_proc_join (&req_exec_cpg_procjoin->group_name,
840 + req_exec_cpg_procjoin->pid, nodeid,
841 +- CONFCHG_CPG_REASON_JOIN);
842 ++ CONFCHG_CPG_REASON_JOIN, NULL);
843 + }
844 +
845 + static void message_handler_req_exec_cpg_procleave (
846 diff --git a/debian/patches/series b/debian/patches/series
847 index 6f18c886..324cc365 100644
848 --- a/debian/patches/series
849 +++ b/debian/patches/series
850 @@ -12,3 +12,8 @@ set-totem.keyfile-and-totem.key-to-RO.patch
851 keygen-Reflect-change-in-knet.patch
852 totemconfig-Remove-support-for-3des.patch
853 crypto-re-introduce-secauth-parameter.patch
854 +cpg-Add-CPG_REASON_UNDEFINED.patch
855 +cpg-notify_lib_joinlist-drop-conn-parameter.patch
856 +cpg-send-single-confchg-event-per-group-on-joinlist.patch
857 +cpg-Add-more-comments-to-notify_lib_joinlist.patch
858 +cpg-Move-filling-of-member_list-to-subfunction.patch