Re: [PATCH] Send one confchg event per CPG group to CPG client

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I defined a macro CPG_GROUPS_MAX in cpg.h, so that I can give a
significant argument when I call qb_hashtable_create function to
create hashtable to hold cgp groups.

Now I set the CPG_GROUPS_MAX's value to 64, I think it will be enough
in most cases. If anyone suggest more reasonable value, I can change
it.

Should we update the Man page about CPG API to introduce this macro to
prevent client programmers exceeding this limit when they add new cpg
group by calling cpg_join ?

On Fri, Oct 28, 2011 at 12:22 AM, Yunkai Zhang <qiushu.zyk@xxxxxxxxxx> wrote:
> We found that sheepdog will receive more than one confchg msg when
> network partition occur.  For example, suppose the cluster has 4
> nodes: N1, N2, N3, N4,  and they form a single-ring initially. After a
> while, network partition occur, the single-ring divide into two
> sub-ring: ring(N1, N2, N3) and ring(N4). The sheepdog in the ring(N4)
> will receive the following confchg messages in turn:
> Memb: N2,N3,N4  Left:N1         Joined:null
> memb: N3,N4     Left:N2         Joined:null
> memb: N4        Left:N3         Joined:null
>
> This patch will fixed this bug, and the client will only receive one
> confchg event in this case:
> memb: N4        Left:N2,N3,N4   Joined:null
>
> Signed-off-by: Yunkai Zhang <qiushu.zyk@xxxxxxxxxx>
> ---
>  configure.ac           |    2 +-
>  include/corosync/cpg.h |    1 +
>  services/cpg.c         |   97 +++++++++++++++++++++++++++++++++++++++++-------
>  3 files changed, 85 insertions(+), 15 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 563f799..aaed478 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -88,7 +88,7 @@ AC_HEADER_SYS_WAIT
>  AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h \
>                  stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \
>                  sys/time.h syslog.h unistd.h sys/types.h getopt.h malloc.h \
> -                 sys/sockio.h utmpx.h])
> +                 sys/sockio.h utmpx.h search.h])
>
>  # Checks for typedefs, structures, and compiler characteristics.
>  AC_C_CONST
> diff --git a/include/corosync/cpg.h b/include/corosync/cpg.h
> index f7956fa..9861c5a 100644
> --- a/include/corosync/cpg.h
> +++ b/include/corosync/cpg.h
> @@ -95,6 +95,7 @@ struct cpg_name {
>  };
>
>  #define CPG_MEMBERS_MAX 128
> +#define CPG_GROUPS_MAX 64
>
>  struct cpg_iteration_description_t {
>        struct cpg_name group;
> diff --git a/services/cpg.c b/services/cpg.c
> index caec097..dc72c84 100644
> --- a/services/cpg.c
> +++ b/services/cpg.c
> @@ -55,6 +55,7 @@
>  #include <netinet/in.h>
>  #include <arpa/inet.h>
>  #include <sys/mman.h>
> +#include <qb/qbmap.h>
>
>  #include <corosync/corotypes.h>
>  #include <qb/qbipc_common.h>
> @@ -705,7 +706,6 @@ static int notify_lib_joinlist(
>                for (iter = cpg_pd_list_head.next; iter != &cpg_pd_list_head; iter = iter->next) {
>                        struct cpg_pd *cpd = list_entry (iter, struct cpg_pd, list);
>                        if (mar_name_compare (&cpd->group_name, group_name) == 0) {
> -                               assert (left_list_entries <= 1);
>                                assert (joined_list_entries <= 1);
>                                if (joined_list_entries) {
>                                        if (joined_list[0].pid == cpd->pid &&
> @@ -798,8 +798,18 @@ static void downlist_master_choose_and_send (void)
>  {
>        struct downlist_msg *stored_msg;
>        struct list_head *iter;
> -       mar_cpg_address_t left_list;
> -       int i;
> +       struct process_info *left_pi;
> +       struct qb_map_t *group_htab;
> +       struct cpg_name cpg_group;
> +       mar_cpg_name_t group;
> +       struct confchg_data{
> +               struct cpg_name cpg_group;
> +               mar_cpg_address_t left_list[CPG_MEMBERS_MAX];
> +               int left_list_entries;
> +               struct list_head  list;
> +       } *pcd;
> +       DECLARE_LIST_INIT(confchg_data_list_head);
> +       int i, size;
>
>        downlist_state = CPG_DOWNLIST_APPLYING;
>
> @@ -810,27 +820,86 @@ static void downlist_master_choose_and_send (void)
>        }
>        downlist_log("chosen downlist", stored_msg);
>
> -       /* send events */
> +       group_htab = qb_hashtable_create(CPG_GROUPS_MAX);
> +
> +        /*
> +        * only the cpg groups included in left nodes should receive
> +        * confchg event, so we will collect these cpg groups and
> +        * relative left_lists here
> +        */
>        for (iter = process_info_list_head.next; iter != &process_info_list_head; ) {
>                struct process_info *pi = list_entry(iter, struct process_info, list);
>                iter = iter->next;
>
> +               left_pi = NULL;
>                for (i = 0; i < stored_msg->left_nodes; i++) {
> +
>                        if (pi->nodeid == stored_msg->nodeids[i]) {
> -                               left_list.nodeid = pi->nodeid;
> -                               left_list.pid = pi->pid;
> -                               left_list.reason = CONFCHG_CPG_REASON_NODEDOWN;
> -
> -                               notify_lib_joinlist(&pi->group, NULL,
> -                                       0, NULL,
> -                                       1, &left_list,
> -                                       MESSAGE_RES_CPG_CONFCHG_CALLBACK);
> -                               list_del (&pi->list);
> -                               free (pi);
> +                               left_pi = pi;
>                                break;
>                        }
>                }
> +
> +               if (left_pi) {
> +                       marshall_from_mar_cpg_name_t(&cpg_group, &left_pi->group);
> +                       log_printf (LOG_DEBUG, "cpg group name:%s", cpg_group.value);
> +                       cpg_group.value[cpg_group.length] = 0;
> +
> +                       pcd = (struct confchg_data *)qb_map_get(group_htab,
> +                                       cpg_group.value);
> +                       if (pcd != NULL) {
> +                               size = pcd->left_list_entries;
> +                               pcd->left_list[size].nodeid = left_pi->nodeid;
> +                               pcd->left_list[size].pid = left_pi->pid;
> +                               pcd->left_list[size].reason = CONFCHG_CPG_REASON_NODEDOWN;
> +                               pcd->left_list_entries++;
> +                       }else {
> +                               pcd = (struct confchg_data *)malloc(sizeof(struct confchg_data));
> +                               memset(pcd, 0, sizeof(struct confchg_data));
> +
> +                               memcpy(&pcd->cpg_group, &cpg_group, sizeof(struct cpg_name));
> +                               pcd->left_list[0].nodeid = left_pi->nodeid;
> +                               pcd->left_list[0].pid = left_pi->pid;
> +                               pcd->left_list[0].reason = CONFCHG_CPG_REASON_NODEDOWN;
> +                               pcd->left_list_entries = 1;
> +
> +                               qb_map_put(group_htab, pcd->cpg_group.value, pcd);
> +
> +                               list_init(&pcd->list);
> +                               list_add(&pcd->list, &confchg_data_list_head);
> +                       }
> +
> +                       list_del (&left_pi->list);
> +                       free (left_pi);
> +               }
> +       }
> +
> +       /* send only one confchg event per cpg group */
> +       for (iter = confchg_data_list_head.next; iter != &confchg_data_list_head; ) {
> +               pcd = list_entry(iter, struct confchg_data, list);
> +               iter = iter->next;
> +
> +               marshall_to_mar_cpg_name_t(&group, &pcd->cpg_group);
> +
> +               log_printf (LOG_DEBUG, "left_list_entries:%d", pcd->left_list_entries);
> +               for (i=0; i<pcd->left_list_entries; i++) {
> +                       log_printf (LOG_DEBUG, "left_list[%d] group:%d, ip:%s, pid:%d",
> +                               i, pcd->cpg_group.value,
> +                               (char*)api->totem_ifaces_print(pcd->left_list[i].nodeid),
> +                               pcd->left_list[i].pid);
> +               }
> +
> +               /* send confchg event */
> +               notify_lib_joinlist(&group, NULL,
> +                       0, NULL,
> +                       pcd->left_list_entries,
> +                       pcd->left_list,
> +                       MESSAGE_RES_CPG_CONFCHG_CALLBACK);
> +
> +               free(pcd);
>        }
> +
> +       qb_map_destroy(group_htab);
>  }
>
>  static void downlist_messages_delete (void)
> --
> 1.7.6.4
>
>



-- 
Yunkai Zhang
Work at Taobao
_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss



[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux