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
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 cherry-picked from upstream PR 468.
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.
15 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
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
30 diff --git a/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
32 index 00000000..a69b53ac
34 +++ b/debian/patches/cpg-Add-CPG_REASON_UNDEFINED.patch
36 +From: Jan Friesse <jfriesse@redhat.com>
37 +Date: Tue, 16 Apr 2019 12:52:31 +0200
38 +Subject: cpg: Add CPG_REASON_UNDEFINED
40 +Previously the reason field for the member_list items
41 +in cpg_totem_confchg_fn was unset what may be little confusing.
43 +Solution is to add a special value CPG_REASON_UNDEFINED and use it for
44 +the member_list items.
46 +Signed-off-by: Jan Friesse <jfriesse@redhat.com>
47 +Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
48 +(cherry picked from commit 41f9e966bb1cfa70d0f6ec1ce46d9c845845b599)
50 + include/corosync/cpg.h | 3 ++-
51 + man/cpg_initialize.3.in | 18 ++++++++++--------
52 + man/cpg_model_initialize.3.in | 18 ++++++++++--------
54 + 4 files changed, 24 insertions(+), 18 deletions(-)
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
62 +- * Copyright (c) 2006-2011 Red Hat, Inc.
63 ++ * Copyright (c) 2006-2019 Red Hat, Inc.
65 + * All rights reserved.
67 +@@ -80,6 +80,7 @@ typedef enum {
68 + * @brief The cpg_reason_t 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
81 +-.\" * Copyright (c) 2006-2009 Red Hat, Inc.
82 ++.\" * Copyright (c) 2006-2019 Red Hat, Inc.
84 + .\" * All rights reserved.
87 + .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
88 + .\" * THE POSSIBILITY OF SUCH DAMAGE.
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"
93 + cpg_initialize \- Create a new connection to the CPG service
95 +@@ -132,18 +132,20 @@ struct cpg_address {
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).
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
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
128 +-.\" * Copyright (c) 2010 Red Hat, Inc.
129 ++.\" * Copyright (c) 2010-2019 Red Hat, Inc.
131 + .\" * All rights reserved.
134 + .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
135 + .\" * THE POSSIBILITY OF SUCH DAMAGE.
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"
140 + cpg_model_initialize \- Create a new connection to the CPG service
142 +@@ -166,18 +166,20 @@ struct cpg_address {
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).
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
169 +diff --git a/exec/cpg.c b/exec/cpg.c
170 +index b7ac579..e39ca34 100644
175 +- * Copyright (c) 2006-2015 Red Hat, Inc.
176 ++ * Copyright (c) 2006-2019 Red Hat, Inc.
178 + * All rights reserved.
180 +@@ -712,6 +712,7 @@ static int notify_lib_joinlist(
182 + retgi->nodeid = pi->nodeid;
183 + retgi->pid = pi->pid;
184 ++ retgi->reason = CPG_REASON_UNDEFINED;
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
190 index 00000000..e32102fa
192 +++ b/debian/patches/cpg-Add-more-comments-to-notify_lib_joinlist.patch
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
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").
202 +Signed-off-by: Jan Friesse <jfriesse@redhat.com>
203 +(cherry picked from commit 10702c7e6c0cf8164ad8f05acb4e334461555973)
205 + exec/cpg.c | 91 +++++++++++++++++++++++++++++++++++++++++---------------------
206 + 1 file changed, 60 insertions(+), 31 deletions(-)
208 +diff --git a/exec/cpg.c b/exec/cpg.c
209 +index e04ba57..2ecdc6b 100644
212 +@@ -663,31 +663,37 @@ static int notify_lib_joinlist(
215 + struct qb_list_head *iter;
217 ++ int member_list_entries;
218 + struct res_lib_cpg_confchg_callback *res;
219 + mar_cpg_address_t *retgi;
224 ++ * Find size of member_list (use process_info_list but remove items in left_list)
226 ++ member_list_entries = 0;
228 + qb_list_for_each(iter, &process_info_list_head) {
229 + struct process_info *pi = qb_list_entry (iter, struct process_info, list);
231 + if (mar_name_compare (&pi->group, group_name) == 0) {
234 ++ int in_left_list = 0;
236 + for (i = 0; i < left_list_entries; i++) {
237 + if (left_list[i].nodeid == pi->nodeid && left_list[i].pid == pi->pid) {
246 ++ if (!in_left_list) {
247 ++ member_list_entries++;
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);
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));
271 ++ * Fill res->memberlist. Use process_info_list but remove items in left_list.
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);
277 + if (mar_name_compare (&pi->group, group_name) == 0) {
280 ++ int in_left_list = 0;
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) {
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(
301 ++ * Fill res->left_list
303 + if (left_list_entries) {
304 + memcpy (retgi, left_list, left_list_entries * sizeof(mar_cpg_address_t));
305 + retgi += left_list_entries;
308 + if (joined_list_entries) {
312 ++ * Fill res->joined_list
314 + memcpy (retgi, joined_list, joined_list_entries * sizeof(mar_cpg_address_t));
315 + retgi += joined_list_entries;
317 +- for (i=0; i < joined_list_entries; i++) {
319 ++ * Update cpd_state for all local joined processes in group
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;
333 +@@ -748,6 +764,9 @@ static int notify_lib_joinlist(
338 ++ * Send notification to all ipc clients joined in group_name
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(
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) {
355 +- memset (&cpd->group_name, 0, sizeof(cpd->group_name));
356 +- cpd->cpd_state = CPD_STATE_UNJOINED;
357 ++ if (left_list_entries) {
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)
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) {
372 ++ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
373 ++ cpd->cpd_state = CPD_STATE_UNJOINED;
379 +@@ -966,6 +994,7 @@ static void joinlist_inform_clients (void)
382 + qb_map_iter_free(miter);
383 ++ qb_map_destroy(group_notify_map);
385 + joinlist_remove_zombie_pi_entries ();
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
389 index 00000000..9ec65353
391 +++ b/debian/patches/cpg-Move-filling-of-member_list-to-subfunction.patch
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
397 +Signed-off-by: Jan Friesse <jfriesse@redhat.com>
398 +(cherry picked from commit 0c1de94461368b4a924b516b77691e6ec471dcb0)
400 + exec/cpg.c | 86 ++++++++++++++++++++++++++++++++++++--------------------------
401 + 1 file changed, 50 insertions(+), 36 deletions(-)
403 +diff --git a/exec/cpg.c b/exec/cpg.c
404 +index 2ecdc6b..98a16a6 100644
407 +@@ -652,26 +652,27 @@ static int notify_lib_totem_membership (
411 +-static int notify_lib_joinlist(
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
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,
427 ++ const mar_cpg_address_t *left_list,
428 ++ int *member_list_entries,
429 ++ mar_cpg_address_t **member_list)
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;
440 +- * Find size of member_list (use process_info_list but remove items in left_list)
442 +- member_list_entries = 0;
443 ++ if (member_list_entries != NULL) {
444 ++ *member_list_entries = 0;
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(
452 + if (!in_left_list) {
453 +- member_list_entries++;
454 ++ if (member_list_entries != NULL) {
455 ++ (*member_list_entries)++;
458 ++ if (member_list != NULL) {
459 ++ (*member_list)->nodeid = pi->nodeid;
460 ++ (*member_list)->pid = pi->pid;
461 ++ (*member_list)->reason = CPG_REASON_UNDEFINED;
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,
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;
486 ++ * Find size of member_list (use process_info_list but remove items in left_list)
488 ++ notify_lib_joinlist_fill_member_list(group_name, left_list_entries, left_list,
489 ++ &member_list_entries, NULL);
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(
495 + * Fill res->memberlist. Use process_info_list but remove items in left_list.
497 +- qb_list_for_each(iter, &process_info_list_head) {
498 +- struct process_info *pi = qb_list_entry (iter, struct process_info, list);
500 +- if (mar_name_compare (&pi->group, group_name) == 0) {
501 +- int in_left_list = 0;
503 +- for (i = 0; i < left_list_entries; i++) {
504 +- if (left_list[i].nodeid == pi->nodeid && left_list[i].pid == pi->pid) {
510 +- if (!in_left_list) {
511 +- retgi->nodeid = pi->nodeid;
512 +- retgi->pid = pi->pid;
513 +- retgi->reason = CPG_REASON_UNDEFINED;
518 ++ notify_lib_joinlist_fill_member_list(group_name, left_list_entries, left_list,
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
525 index 00000000..e1742bf9
527 +++ b/debian/patches/cpg-notify_lib_joinlist-drop-conn-parameter.patch
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
533 +since it is always set to NULL.
535 +(cherry picked from commit d5e9723695b2ae63162b238300013d785e875ea7)
537 + exec/cpg.c | 54 ++++++++++++++++++++++++------------------------------
538 + 1 file changed, 24 insertions(+), 30 deletions(-)
540 +diff --git a/exec/cpg.c b/exec/cpg.c
541 +index e39ca34..b752cc1 100644
544 +@@ -647,7 +647,6 @@ static int notify_lib_totem_membership (
546 + static int notify_lib_joinlist(
547 + const mar_cpg_name_t *group_name,
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;
557 +- api->ipc_dispatch_send (conn, buf, size);
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;
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;
576 +- if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
577 +- cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
579 ++ if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
580 ++ cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
582 +- api->ipc_dispatch_send (cpd->conn, buf, size);
583 +- cpd->transition_counter++;
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) {
591 +- memset (&cpd->group_name, 0, sizeof(cpd->group_name));
592 +- cpd->cpd_state = CPD_STATE_UNJOINED;
594 ++ api->ipc_dispatch_send (cpd->conn, buf, size);
595 ++ cpd->transition_counter++;
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) {
603 ++ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
604 ++ cpd->cpd_state = CPD_STATE_UNJOINED;
612 + * Traverse thru cpds and send totem membership for cpd, where it is not send yet
614 +@@ -858,7 +852,7 @@ static void downlist_inform_clients (void)
617 + /* send confchg event */
618 +- notify_lib_joinlist(&group, NULL,
619 ++ notify_lib_joinlist(&group,
621 + pcd->left_list_entries,
623 +@@ -1157,7 +1151,7 @@ static void do_proc_join(
624 + notify_info.nodeid = nodeid;
625 + notify_info.reason = reason;
627 +- notify_lib_joinlist(&pi->group, NULL,
628 ++ notify_lib_joinlist(&pi->group,
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;
636 +- notify_lib_joinlist(name, NULL,
637 ++ notify_lib_joinlist(name,
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
643 index 00000000..013baaa0
645 +++ b/debian/patches/cpg-send-single-confchg-event-per-group-on-joinlist.patch
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
651 +Content-Type: text/plain; charset="utf-8"
652 +Content-Transfer-Encoding: 8bit
654 +using a similar approach to
656 +43bead364514e8ae2ba00bcf07c460e31d0b1765 "Send one confchg event per CPG group to CPG client"
658 +which did the same for leave events on a network partition.
662 +Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
663 +(cherry picked from commit 9c60289b831ef0b138142c3fc39c9a9da8a2ada2)
665 + exec/cpg.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++----------------
666 + 1 file changed, 73 insertions(+), 24 deletions(-)
668 +diff --git a/exec/cpg.c b/exec/cpg.c
669 +index b752cc1..e04ba57 100644
672 +@@ -194,6 +194,12 @@ struct join_list_entry {
673 + mar_cpg_name_t group_name;
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;
683 + * Service Interfaces required by service_message_handler struct
685 +@@ -312,7 +318,8 @@ static void do_proc_join(
686 + const mar_cpg_name_t *name,
688 + unsigned int nodeid,
691 ++ qb_map_t *group_notify_map);
693 + static void do_proc_leave(
694 + const mar_cpg_name_t *name,
695 +@@ -723,35 +730,46 @@ static int notify_lib_joinlist(
698 + if (joined_list_entries) {
701 + memcpy (retgi, joined_list, joined_list_entries * sizeof(mar_cpg_address_t));
702 + retgi += joined_list_entries;
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;
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;
727 + if (cpd->cpd_state == CPD_STATE_JOIN_COMPLETED ||
728 + cpd->cpd_state == CPD_STATE_LEAVE_STARTED) {
730 + api->ipc_dispatch_send (cpd->conn, buf, size);
731 + cpd->transition_counter++;
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) {
739 +- memset (&cpd->group_name, 0, sizeof(cpd->group_name));
740 +- cpd->cpd_state = CPD_STATE_UNJOINED;
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) {
753 ++ memset (&cpd->group_name, 0, sizeof(cpd->group_name));
754 ++ cpd->cpd_state = CPD_STATE_UNJOINED;
758 +@@ -915,6 +933,11 @@ static void joinlist_inform_clients (void)
759 + struct joinlist_msg *stored_msg;
760 + struct qb_list_head *iter;
762 ++ qb_map_t *group_notify_map;
763 ++ qb_map_iter_t *miter;
764 ++ struct join_list_confchg_data *jld;
766 ++ group_notify_map = qb_skiplist_create();
769 + qb_list_for_each(iter, &joinlist_messages_head) {
770 +@@ -931,9 +954,19 @@ static void joinlist_inform_clients (void)
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);
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,
783 ++ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
786 ++ qb_map_iter_free(miter);
788 + joinlist_remove_zombie_pi_entries ();
791 +@@ -1111,13 +1144,15 @@ static void do_proc_join(
792 + const mar_cpg_name_t *name,
794 + unsigned int nodeid,
797 ++ qb_map_t *group_notify_map)
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;
806 + if (process_info_find (name, pid, nodeid) != NULL) {
808 +@@ -1151,10 +1186,24 @@ static void do_proc_join(
809 + notify_info.nodeid = nodeid;
810 + notify_info.reason = reason;
812 +- notify_lib_joinlist(&pi->group,
815 +- MESSAGE_RES_CPG_CONFCHG_CALLBACK);
816 ++ if (group_notify_map == NULL) {
817 ++ notify_lib_joinlist(&pi->group,
820 ++ MESSAGE_RES_CPG_CONFCHG_CALLBACK);
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);
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++;
836 + static void do_proc_leave(
837 +@@ -1219,7 +1268,7 @@ static void message_handler_req_exec_cpg_procjoin (
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);
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