On Thu, 2009-08-20 at 06:39 +0200, Fabio M. Di Nitto wrote:
> This change the API and ABI for cpg.
> 
> Before this change can go anywhere, it needs proper Makefile.am love or
> even easier queue it after libtool changes that makes slightly easier to
> have per library API and ABI versioning.
> 
> Let's try, as a general rule, to avoid the same nightmare we had between
> whitetank and current status with hidden API/ABI changes.
> 
> Fabio
> 

The addition of API calls are allowed in Y releases, and those additions
don't result in a soname bump.

I don't see any problem with this change.

Regards
-steve

> On Wed, 2009-08-19 at 13:16 -0700, Steven Dake wrote:
> > comments inline.  Looks pretty good though.
> > 
> > Regards
> > -steve
> > 
> > On Wed, 2009-08-19 at 16:31 +0200, Jan Friesse wrote:
> > > Implementation of DRAFT API. Look like there are no leaks, valgrind
> > > problems, ...
> > > 
> > > Regards,
> > >   Honza
> > > plain text document attachment
> > > (0001-Implementation-of-cpg_iteration-functions.patch)
> > > From 02a9fbad2db3ee019c735422dc064fed0179e103 Mon Sep 17 00:00:00 2001
> > > From: Jan Friesse <[email protected]>
> > > Date: Wed, 19 Aug 2009 15:17:27 +0200
> > > Subject: [PATCH] Implementation of cpg_iteration functions
> > > 
> > > ---
> > >  trunk/include/corosync/cpg.h     |   31 ++++
> > >  trunk/include/corosync/ipc_cpg.h |   53 +++++++-
> > >  trunk/lib/cpg.c                  |  236 ++++++++++++++++++++++++++++-
> > >  trunk/services/cpg.c             |  313 
> > > +++++++++++++++++++++++++++++++++++++-
> > >  4 files changed, 627 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/trunk/include/corosync/cpg.h b/trunk/include/corosync/cpg.h
> > > index 242cbbe..b5609df 100644
> > > --- a/trunk/include/corosync/cpg.h
> > > +++ b/trunk/include/corosync/cpg.h
> > > @@ -4,6 +4,7 @@
> > >   * All rights reserved.
> > >   *
> > >   * Author: Christine Caulfield ([email protected])
> > > + * Author: Jan Friesse ([email protected])
> > >   *
> > >   * This software licensed under BSD license, the text of which follows:
> > >   *
> > > @@ -48,6 +49,8 @@ extern "C" {
> > >   */
> > >  typedef uint64_t cpg_handle_t;
> > >  
> > > +typedef uint64_t cpg_iteration_handle_t;
> > > +
> > >  typedef enum {
> > >   CPG_TYPE_UNORDERED, /* not implemented */
> > >   CPG_TYPE_FIFO,          /* same as agreed */
> > > @@ -69,6 +72,12 @@ typedef enum {
> > >   CPG_REASON_PROCDOWN = 5
> > >  } cpg_reason_t;
> > >  
> > > +typedef enum {
> > > + CPG_ITERATION_NAME_ONLY = 1,
> > > + CPG_ITERATION_ONE_GROUP = 2,
> > > + CPG_ITERATION_ALL = 3,
> > > +} cpg_iteration_type_t;
> > > +
> > >  struct cpg_address {
> > >   uint32_t nodeid;
> > >   uint32_t pid;
> > > @@ -83,6 +92,12 @@ struct cpg_name {
> > >  
> > >  #define CPG_MEMBERS_MAX 128
> > >  
> > > +struct cpg_iteration_description_t {
> > > + struct cpg_name group;
> > > + uint32_t nodeid;
> > > + uint32_t pid;
> > > +};
> > > +
> > >  typedef void (*cpg_deliver_fn_t) (
> > >   cpg_handle_t handle,
> > >   const struct cpg_name *group_name,
> > > @@ -209,6 +224,22 @@ cs_error_t cpg_zcb_mcast_joined (
> > >   void *msg,
> > >   size_t msg_len);
> > >  
> > > +/*
> > > + * Iteration
> > > + */
> > > +cs_error_t cpg_iteration_initialize(
> > > + cpg_handle_t handle,
> > > + cpg_iteration_type_t iteration_type,
> > > + const struct cpg_name *group,
> > > + cpg_iteration_handle_t *cpg_iteration_handle);
> > > +
> > > +cs_error_t cpg_iteration_next(
> > > + cpg_iteration_handle_t handle,
> > > + struct cpg_iteration_description_t *description);
> > > +
> > > +cs_error_t cpg_iteration_finalize (
> > > + cpg_iteration_handle_t handle);
> > > +
> > >  #ifdef __cplusplus
> > >  }
> > >  #endif
> > > diff --git a/trunk/include/corosync/ipc_cpg.h 
> > > b/trunk/include/corosync/ipc_cpg.h
> > > index 1d240d4..7df1891 100644
> > > --- a/trunk/include/corosync/ipc_cpg.h
> > > +++ b/trunk/include/corosync/ipc_cpg.h
> > > @@ -45,6 +45,9 @@ enum req_cpg_types {
> > >   MESSAGE_REQ_CPG_MCAST = 2,
> > >   MESSAGE_REQ_CPG_MEMBERSHIP = 3,
> > >   MESSAGE_REQ_CPG_LOCAL_GET = 4,
> > > + MESSAGE_REQ_CPG_ITERATIONINITIALIZE = 5,
> > > + MESSAGE_REQ_CPG_ITERATIONNEXT = 6,
> > > + MESSAGE_REQ_CPG_ITERATIONFINALIZE = 7
> > >  };
> > >  
> > >  enum res_cpg_types {
> > > @@ -56,7 +59,10 @@ enum res_cpg_types {
> > >   MESSAGE_RES_CPG_DELIVER_CALLBACK = 5,
> > >   MESSAGE_RES_CPG_FLOW_CONTROL_STATE_SET = 6,
> > >   MESSAGE_RES_CPG_LOCAL_GET = 7,
> > > - MESSAGE_RES_CPG_FLOWCONTROL_CALLBACK = 8
> > > + MESSAGE_RES_CPG_FLOWCONTROL_CALLBACK = 8,
> > > + MESSAGE_RES_CPG_ITERATIONINITIALIZE = 9,
> > > + MESSAGE_RES_CPG_ITERATIONNEXT = 10,
> > > + MESSAGE_RES_CPG_ITERATIONFINALIZE = 11,
> > >  };
> > >  
> > >  enum lib_cpg_confchg_reason {
> > > @@ -126,6 +132,21 @@ static inline int mar_name_compare (
> > >           g1->length - g2->length);
> > >  }
> > >  
> > > +typedef struct {
> > > + mar_cpg_name_t group;
> > > + mar_uint32_t nodeid;
> > > + mar_uint32_t pid;
> > > +} mar_cpg_iteration_description_t;
> > > +
> > > +static inline void marshall_from_mar_cpg_iteration_description_t(
> > > + struct cpg_iteration_description_t *dest,
> > > + const mar_cpg_iteration_description_t *src)
> > > +{
> > > + dest->nodeid = src->nodeid;
> > > + dest->pid = src->pid;
> > > + marshall_from_mar_cpg_name_t (&dest->group, &src->group);
> > > +};
> > > +
> > >  struct req_lib_cpg_join {
> > >   coroipc_request_header_t header __attribute__((aligned(8)));
> > >   mar_cpg_name_t group_name __attribute__((aligned(8)));
> > > @@ -217,4 +238,34 @@ struct res_lib_cpg_leave {
> > >   coroipc_response_header_t header __attribute__((aligned(8)));
> > >  };
> > >  
> > > +struct req_lib_cpg_iterationinitialize {
> > > + coroipc_request_header_t header __attribute__((aligned(8)));
> > > + mar_cpg_name_t group_name __attribute__((aligned(8)));
> > > + mar_uint32_t iteration_type __attribute__((aligned(8)));
> > > +};
> > > +
> > > +struct res_lib_cpg_iterationinitialize {
> > > + coroipc_response_header_t header __attribute__((aligned(8)));
> > > + hdb_handle_t iteration_handle __attribute__((aligned(8)));
> > > +};
> > > +
> > > +struct req_lib_cpg_iterationnext {
> > > + coroipc_request_header_t header __attribute__((aligned(8)));
> > > + hdb_handle_t iteration_handle __attribute__((aligned(8)));
> > > +};
> > > +
> > > +struct res_lib_cpg_iterationnext {
> > > + coroipc_response_header_t header __attribute__((aligned(8)));
> > > + mar_cpg_iteration_description_t description __attribute__((aligned(8)));
> > > +};
> > > +
> > > +struct req_lib_cpg_iterationfinalize {
> > > + coroipc_request_header_t header __attribute__((aligned(8)));
> > > + hdb_handle_t iteration_handle __attribute__((aligned(8)));
> > > +};
> > > +
> > > +struct res_lib_cpg_iterationfinalize {
> > > + coroipc_response_header_t header __attribute__((aligned(8)));
> > > +};
> > > +
> > >  #endif /* IPC_CPG_H_DEFINED */
> > > diff --git a/trunk/lib/cpg.c b/trunk/lib/cpg.c
> > > index 3f8df6c..e3ab8e6 100644
> > > --- a/trunk/lib/cpg.c
> > > +++ b/trunk/lib/cpg.c
> > > @@ -5,7 +5,8 @@
> > >   *
> > >   * All rights reserved.
> > >   *
> > > - * Author: Patrick Caulfield ([email protected])
> > > + * Author: Christine Caulfield ([email protected])
> > > + * Author: Jan Friesse ([email protected])
> > >   *
> > >   * This software licensed under BSD license, the text of which follows:
> > >   *
> > > @@ -51,6 +52,7 @@
> > >  #include <corosync/coroipcc.h>
> > >  #include <corosync/corodefs.h>
> > >  #include <corosync/hdb.h>
> > > +#include <corosync/list.h>
> > >  
> > >  #include <corosync/cpg.h>
> > >  #include <corosync/ipc_cpg.h>
> > > @@ -62,10 +64,49 @@ struct cpg_inst {
> > >   int finalize;
> > >   cpg_callbacks_t callbacks;
> > >   void *context;
> > > + struct list_head iteration_list_head;
> > >  };
> > >  
> > >  DECLARE_HDB_DATABASE(cpg_handle_t_db,NULL);
> > >  
> > > +struct cpg_iteration_instance_t {
> > > + cpg_iteration_handle_t cpg_iteration_handle;
> > > + hdb_handle_t conn_handle;
> > > + hdb_handle_t executive_iteration_handle;
> > > + struct list_head list;
> > > +};
> > > +
> > > +DECLARE_HDB_DATABASE(cpg_iteration_handle_t_db,NULL);
> > > +
> > > +
> > > +/*
> > > + * Internal (not visible by API) functions
> > > + */
> > > +
> > > +static void cpg_iteration_instance_finalize (struct 
> > > cpg_iteration_instance_t *cpg_iteration_instance)
> > > +{
> > > + list_del (&cpg_iteration_instance->list);
> > > + hdb_handle_destroy (&cpg_iteration_handle_t_db, 
> > > cpg_iteration_instance->cpg_iteration_handle);
> > > +}
> > > +
> > > +static void cpg_inst_finalize (struct cpg_inst *cpg_inst, hdb_handle_t 
> > > handle)
> > > +{
> > > + struct list_head *iter, *iter_next;
> > > + struct cpg_iteration_instance_t *cpg_iteration_instance;
> > > +
> > > + /*
> > > +  * Traverse thru iteration instances and delete them
> > > +  */
> > > + for (iter = cpg_inst->iteration_list_head.next; iter != 
> > > &cpg_inst->iteration_list_head;iter = iter_next) {
> > > +         iter_next = iter->next;
> > > +
> > > +         cpg_iteration_instance = list_entry (iter, struct 
> > > cpg_iteration_instance_t, list);
> > > +
> > > +         cpg_iteration_instance_finalize (cpg_iteration_instance);
> > > + }
> > > + hdb_handle_destroy (&cpg_handle_t_db, handle);
> > > +}
> > > +
> > 
> > this handle destroy doesn't make any sense since cpg_finalize should be
> > doing the hdb_handle_destroy.  This will result in wrong ref counting.
> > 
> > >  /**
> > >   * @defgroup cpg_coroipcc The closed process group API
> > >   * @ingroup coroipcc
> > > @@ -103,6 +144,8 @@ cs_error_t cpg_initialize (
> > >  
> > >   memcpy (&cpg_inst->callbacks, callbacks, sizeof (cpg_callbacks_t));
> > >  
> > > + list_init(&cpg_inst->iteration_list_head);
> > > +
> > >   hdb_handle_put (&cpg_handle_t_db, *handle);
> > >  
> > >   return (CS_OK);
> > > @@ -138,8 +181,7 @@ cs_error_t cpg_finalize (
> > >  
> > >   coroipcc_service_disconnect (cpg_inst->handle);
> > >  
> > > - hdb_handle_destroy (&cpg_handle_t_db, handle);
> > > -
> > > + cpg_inst_finalize (cpg_inst, handle);
> > >   hdb_handle_put (&cpg_handle_t_db, handle);
> > >  
> > >   return (CPG_OK);
> > > @@ -675,4 +717,192 @@ error_exit:
> > >  
> > >   return (error);
> > >  }
> > > +
> > > +cs_error_t cpg_iteration_initialize(
> > > + cpg_handle_t handle,
> > > + cpg_iteration_type_t iteration_type,
> > > + const struct cpg_name *group,
> > > + cpg_iteration_handle_t *cpg_iteration_handle)
> > > +{
> > > + cs_error_t error;
> > > + struct iovec iov;
> > > + struct cpg_inst *cpg_inst;
> > > + struct cpg_iteration_instance_t *cpg_iteration_instance;
> > > + struct req_lib_cpg_iterationinitialize req_lib_cpg_iterationinitialize;
> > > + struct res_lib_cpg_iterationinitialize res_lib_cpg_iterationinitialize;
> > > +
> > > + if (cpg_iteration_handle == NULL) {
> > > +         return (CS_ERR_INVALID_PARAM);
> > > + }
> > > +
> > > + if ((iteration_type == CPG_ITERATION_ONE_GROUP && group == NULL) ||
> > > +         (iteration_type != CPG_ITERATION_ONE_GROUP && group != NULL)) {
> > > +         return (CS_ERR_INVALID_PARAM);
> > > + }
> > > +
> > > + if (iteration_type != CPG_ITERATION_NAME_ONLY && iteration_type != 
> > > CPG_ITERATION_ONE_GROUP &&
> > > +     iteration_type != CPG_ITERATION_ALL) {
> > > +
> > > +         return (CS_ERR_INVALID_PARAM);
> > > + }
> > > +
> > > + error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, 
> > > (void *)&cpg_inst));
> > > +
> > 
> > why the void cast?
> > 
> > 
> > >   if (error != CS_OK) {
> > > +         return (error);
> > > + }
> > > +
> > > + error = hdb_error_to_cs (hdb_handle_create (&cpg_iteration_handle_t_db,
> > > +         sizeof (struct cpg_iteration_instance_t), 
> > > cpg_iteration_handle));
> > > + if (error != CS_OK) {
> > > +         goto error_put_cpg_db;
> > > + }
> > > +
> > > + error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, 
> > > *cpg_iteration_handle,
> > > +         (void *)&cpg_iteration_instance));
> > > + if (error != CS_OK) {
> > > +         goto error_destroy;
> > > + }
> > > +
> > > + cpg_iteration_instance->conn_handle = cpg_inst->handle;
> > > +
> > > + list_init (&cpg_iteration_instance->list);
> > > +
> > > + req_lib_cpg_iterationinitialize.header.size = sizeof (struct 
> > > req_lib_cpg_iterationinitialize);
> > > + req_lib_cpg_iterationinitialize.header.id = 
> > > MESSAGE_REQ_CPG_ITERATIONINITIALIZE;
> > > + req_lib_cpg_iterationinitialize.iteration_type = iteration_type;
> > > + if (group) {
> > > +         marshall_to_mar_cpg_name_t 
> > > (&req_lib_cpg_iterationinitialize.group_name, group);
> > > + }
> > > +
> > > + iov.iov_base = (void *)&req_lib_cpg_iterationinitialize;
> > > + iov.iov_len = sizeof (struct req_lib_cpg_iterationinitialize);
> > > +
> > > + error = coroipcc_msg_send_reply_receive (cpg_inst->handle,
> > > +         &iov,
> > > +         1,
> > > +         &res_lib_cpg_iterationinitialize,
> > > +         sizeof (struct req_lib_cpg_iterationinitialize));
> > > +
> > > + if (error != CS_OK) {
> > > +         goto error_put_destroy;
> > > + }
> > > +
> > > + cpg_iteration_instance->executive_iteration_handle =
> > > +         res_lib_cpg_iterationinitialize.iteration_handle;
> > > + cpg_iteration_instance->cpg_iteration_handle = *cpg_iteration_handle;
> > > +
> > > + list_add (&cpg_iteration_instance->list, 
> > > &cpg_inst->iteration_list_head);
> > > +
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
> > > + hdb_handle_put (&cpg_handle_t_db, handle);
> > > +
> > > + return (res_lib_cpg_iterationinitialize.header.error);
> > > +
> > > +error_put_destroy:
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
> > > +error_destroy:
> > > + hdb_handle_destroy (&cpg_iteration_handle_t_db, *cpg_iteration_handle);
> > > +error_put_cpg_db:
> > > + hdb_handle_put (&cpg_handle_t_db, handle);
> > > +
> > > + return (error);
> > > +}
> > > +
> > > +cs_error_t cpg_iteration_next(
> > > + cpg_iteration_handle_t handle,
> > > + struct cpg_iteration_description_t *description)
> > > +{
> > > + cs_error_t error;
> > > + struct cpg_iteration_instance_t *cpg_iteration_instance;
> > > + struct req_lib_cpg_iterationnext req_lib_cpg_iterationnext;
> > > + struct res_lib_cpg_iterationnext *res_lib_cpg_iterationnext;
> > > + struct iovec iov;
> > > + void *return_address;
> > > +
> > > + if (description == NULL) {
> > > +         return CS_ERR_INVALID_PARAM;
> > > + }
> > > +
> > > + error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, 
> > > handle,
> > > +         (void *)&cpg_iteration_instance));
> > > + if (error != CS_OK) {
> > > +         goto error_exit;
> > > + }
> > > +
> > > + req_lib_cpg_iterationnext.header.size = sizeof (struct 
> > > req_lib_cpg_iterationnext);
> > > + req_lib_cpg_iterationnext.header.id = MESSAGE_REQ_CPG_ITERATIONNEXT;
> > > + req_lib_cpg_iterationnext.iteration_handle = 
> > > cpg_iteration_instance->executive_iteration_handle;
> > > +
> > > + iov.iov_base = (void *)&req_lib_cpg_iterationnext;
> > > + iov.iov_len = sizeof (struct req_lib_cpg_iterationnext);
> > > +
> > > + error = coroipcc_msg_send_reply_receive_in_buf_get 
> > > (cpg_iteration_instance->conn_handle,
> > > +         &iov,
> > > +         1,
> > > +         &return_address);
> > > + res_lib_cpg_iterationnext = return_address;
> > > +
> > > + if (error != CS_OK) {
> > > +         goto error_put;
> > > + }
> > > +
> > > + marshall_from_mar_cpg_iteration_description_t(
> > > +                 description,
> > > +                 &res_lib_cpg_iterationnext->description);
> > > +
> > > + error = (error == CS_OK ? res_lib_cpg_iterationnext->header.error : 
> > > error);
> > > +
> > > + coroipcc_msg_send_reply_receive_in_buf_put(
> > > +                 cpg_iteration_instance->conn_handle);
> > > +
> > > +error_put:
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, handle);
> > > +
> > > +error_exit:
> > > + return (error);
> > > +}
> > > +
> > > +cs_error_t cpg_iteration_finalize (
> > > + cpg_iteration_handle_t handle)
> > > +{
> > > + cs_error_t error;
> > > + struct iovec iov;
> > > + struct cpg_iteration_instance_t *cpg_iteration_instance;
> > > + struct req_lib_cpg_iterationfinalize req_lib_cpg_iterationfinalize;
> > > + struct res_lib_cpg_iterationfinalize res_lib_cpg_iterationfinalize;
> > > +
> > > + error = hdb_error_to_cs (hdb_handle_get (&cpg_iteration_handle_t_db, 
> > > handle,
> > > +         (void *)&cpg_iteration_instance));
> > > + if (error != CS_OK) {
> > > +         goto error_exit;
> > > + }
> > > +
> > > + req_lib_cpg_iterationfinalize.header.size = sizeof (struct 
> > > req_lib_cpg_iterationfinalize);
> > > + req_lib_cpg_iterationfinalize.header.id = 
> > > MESSAGE_REQ_CPG_ITERATIONFINALIZE;
> > > + req_lib_cpg_iterationfinalize.iteration_handle = 
> > > cpg_iteration_instance->executive_iteration_handle;
> > > +
> > > + iov.iov_base = (void *)&req_lib_cpg_iterationfinalize;
> > > + iov.iov_len = sizeof (struct req_lib_cpg_iterationfinalize);
> > > +
> > > + error = coroipcc_msg_send_reply_receive 
> > > (cpg_iteration_instance->conn_handle,
> > > +         &iov,
> > > +         1,
> > > +         &res_lib_cpg_iterationfinalize,
> > > +         sizeof (struct req_lib_cpg_iterationfinalize));
> > > +
> > > + if (error != CS_OK) {
> > > +         goto error_put;
> > > + }
> > > +
> > > + cpg_iteration_instance_finalize (cpg_iteration_instance);
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, 
> > > cpg_iteration_instance->cpg_iteration_handle);
> > > +
> > > + return (res_lib_cpg_iterationfinalize.header.error);
> > > +
> > > +error_put:
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, handle);
> > > +error_exit:
> > > + return (error);
> > > +}
> > > +
> > >  /** @} */
> > > diff --git a/trunk/services/cpg.c b/trunk/services/cpg.c
> > > index cac623d..507af7c 100644
> > > --- a/trunk/services/cpg.c
> > > +++ b/trunk/services/cpg.c
> > > @@ -134,8 +134,18 @@ struct cpg_pd {
> > >   uint32_t pid;
> > >   enum cpd_state cpd_state;
> > >   struct list_head list;
> > > + struct list_head iteration_instance_list_head;
> > >  };
> > >  
> > > +struct cpg_iteration_instance {
> > > + hdb_handle_t handle;
> > > + struct list_head list;
> > > + struct list_head items_list_head; /* List of process_info */
> > > + struct list_head *current_pointer;
> > > +};
> > > +
> > > +DECLARE_HDB_DATABASE(cpg_iteration_handle_t_db,NULL);
> > > +
> > >  DECLARE_LIST_INIT(cpg_pd_list_head);
> > >  
> > >  static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
> > > @@ -212,6 +222,15 @@ static void message_handler_req_lib_cpg_membership 
> > > (void *conn,
> > >  static void message_handler_req_lib_cpg_local_get (void *conn,
> > >                                              const void *message);
> > >  
> > > +static void message_handler_req_lib_cpg_iteration_initialize (void *conn,
> > > +                                                       const void 
> > > *message);
> > > +
> > > +static void message_handler_req_lib_cpg_iteration_next (void *conn,
> > > +                                                 const void *message);
> > > +
> > > +static void message_handler_req_lib_cpg_iteration_finalize (void *conn,
> > > +                                                     const void 
> > > *message);
> > > +
> > >  static int cpg_node_joinleave_send (unsigned int pid, const 
> > > mar_cpg_name_t *group_name, int fn, int reason);
> > >  
> > >  static int cpg_exec_send_downlist(void);
> > > @@ -253,7 +272,19 @@ static struct corosync_lib_handler cpg_lib_engine[] =
> > >   { /* 4 */
> > >           .lib_handler_fn                         = 
> > > message_handler_req_lib_cpg_local_get,
> > >           .flow_control                           = 
> > > CS_LIB_FLOW_CONTROL_NOT_REQUIRED
> > > - }
> > > + },
> > > + { /* 5 */
> > > +         .lib_handler_fn                         = 
> > > message_handler_req_lib_cpg_iteration_initialize,
> > > +         .flow_control                           = 
> > > CS_LIB_FLOW_CONTROL_NOT_REQUIRED
> > > + },
> > > + { /* 6 */
> > > +         .lib_handler_fn                         = 
> > > message_handler_req_lib_cpg_iteration_next,
> > > +         .flow_control                           = 
> > > CS_LIB_FLOW_CONTROL_NOT_REQUIRED
> > > + },
> > > + { /* 7 */
> > > +         .lib_handler_fn                         = 
> > > message_handler_req_lib_cpg_iteration_finalize,
> > > +         .flow_control                           = 
> > > CS_LIB_FLOW_CONTROL_NOT_REQUIRED
> > > + },
> > >  };
> > >  
> > >  static struct corosync_exec_handler cpg_exec_engine[] =
> > > @@ -572,6 +603,45 @@ static int cpg_exec_init_fn (struct corosync_api_v1 
> > > *corosync_api)
> > >   return (0);
> > >  }
> > >  
> > > +static void cpg_iteration_instance_finalize (struct 
> > > cpg_iteration_instance *cpg_iteration_instance)
> > > +{
> > > + struct list_head *iter, *iter_next;
> > > + struct process_info *pi;
> > > +
> > > + for (iter = cpg_iteration_instance->items_list_head.next;
> > > +         iter != &cpg_iteration_instance->items_list_head;
> > > +         iter = iter_next) {
> > > +
> > > +         iter_next = iter->next;
> > > +
> > > +         pi = list_entry (iter, struct process_info, list);
> > > +         list_del (&pi->list);
> > > +         free (pi);
> > > + }
> > > +
> > > + list_del (&cpg_iteration_instance->list);
> > > + hdb_handle_destroy (&cpg_iteration_handle_t_db, 
> > > cpg_iteration_instance->handle);
> > > +}
> > > +
> > > +static void cpg_pd_finalize (struct cpg_pd *cpd)
> > > +{
> > > + struct list_head *iter, *iter_next;
> > > + struct cpg_iteration_instance *cpii;
> > > +
> > > + for (iter = cpd->iteration_instance_list_head.next;
> > > +         iter != &cpd->iteration_instance_list_head;
> > > +         iter = iter_next) {
> > > +
> > > +         iter_next = iter->next;
> > > +
> > > +         cpii = list_entry (iter, struct cpg_iteration_instance, list);
> > > +
> > > +         cpg_iteration_instance_finalize (cpii);
> > > + }
> > > +
> > > + list_del (&cpd->list);
> > > +}
> > > +
> > >  static int cpg_lib_exit_fn (void *conn)
> > >  {
> > >   struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
> > > @@ -582,7 +652,9 @@ static int cpg_lib_exit_fn (void *conn)
> > >           cpg_node_joinleave_send (cpd->pid, &cpd->group_name,
> > >                           MESSAGE_REQ_EXEC_CPG_PROCLEAVE, 
> > > CONFCHG_CPG_REASON_LEAVE);
> > >   }
> > > - list_del (&cpd->list);
> > > +
> > > + cpg_pd_finalize (cpd);
> > > +
> > >   api->ipc_refcnt_dec (conn);
> > >   return (0);
> > >  }
> > > @@ -958,6 +1030,8 @@ static int cpg_lib_init_fn (void *conn)
> > >   cpd->conn = conn;
> > >   list_add (&cpd->list, &cpg_pd_list_head);
> > >  
> > > + list_init (&cpd->iteration_instance_list_head);
> > > +
> > >   api->ipc_refcnt_inc (conn);
> > >   log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p, cpd=%p\n", conn, 
> > > cpd);
> > >   return (0);
> > > @@ -1157,3 +1231,238 @@ static void message_handler_req_lib_cpg_local_get 
> > > (void *conn,
> > >   api->ipc_response_send (conn, &res_lib_cpg_local_get,
> > >           sizeof (res_lib_cpg_local_get));
> > >  }
> > > +
> > > +static void message_handler_req_lib_cpg_iteration_initialize (void *conn,
> > > +                                                       const void 
> > > *message)
> > > +{
> > > + const struct req_lib_cpg_iterationinitialize 
> > > *req_lib_cpg_iterationinitialize = message;
> > > + struct cpg_pd *cpd = (struct cpg_pd *)api->ipc_private_data_get (conn);
> > > + hdb_handle_t cpg_iteration_handle;
> > > +
> > > + struct res_lib_cpg_iterationinitialize res_lib_cpg_iterationinitialize;
> > > + struct list_head *iter, *iter2;
> > > + struct cpg_iteration_instance *cpg_iteration_instance;
> > > + cs_error_t error = CS_OK;
> > > + int res;
> > > +
> > > + log_printf (LOGSYS_LEVEL_DEBUG, "cpg iteration initialize\n");
> > > +
> > > + /* Because between calling this function and *next can be some 
> > > operations which will
> > > +  * change list, we must do full copy.
> > > +  */
> > > +
> > > + /*
> > > +  * Create new iteration instance
> > > +  */
> > > + res = hdb_handle_create (&cpg_iteration_handle_t_db, sizeof (struct 
> > > cpg_iteration_instance),
> > > +                 &cpg_iteration_handle);
> > > +
> > > + if (res != 0) {
> > > +         error = CS_ERR_NO_MEMORY;
> > > +         goto response_send;
> > > + }
> > > +
> > > + res = hdb_handle_get (&cpg_iteration_handle_t_db, cpg_iteration_handle, 
> > > (void *)&cpg_iteration_instance);
> > > +
> > > + if (res != 0) {
> > > +         error = CS_ERR_BAD_HANDLE;
> > > +         goto error_destroy;
> > > + }
> > > +
> > > + list_init (&cpg_iteration_instance->items_list_head);
> > > + cpg_iteration_instance->handle = cpg_iteration_handle;
> > > +
> > > + /*
> > > +  * Create copy of process_info list "grouped by" group name
> > > +  */
> > > + for (iter = process_info_list_head.next; iter != 
> > > &process_info_list_head; iter = iter->next) {
> > > +         struct process_info *pi = list_entry (iter, struct 
> > > process_info, list);
> > > +         struct process_info *new_pi;
> > > +
> > > +         if (req_lib_cpg_iterationinitialize->iteration_type == 
> > > CPG_ITERATION_NAME_ONLY) {
> > > +                 /*
> > > +                  * Try to find processed group name in our list new list
> > > +                  */
> > > +                 int found = 0;
> > > +
> > > +                 for (iter2 = 
> > > cpg_iteration_instance->items_list_head.next;
> > > +                      iter2 != &cpg_iteration_instance->items_list_head;
> > > +                      iter2 = iter2->next) {
> > > +                          struct process_info *pi2 = list_entry (iter2, 
> > > struct process_info, list);
> > > +
> > > +                          if (mar_name_compare (&pi2->group, &pi->group) 
> > > == 0) {
> > > +                                 found = 1;
> > > +                                 break;
> > > +                          }
> > > +                 }
> > > +
> > > +                 if (found) {
> > > +                         /*
> > > +                          * We have this name in list -> don't add
> > > +                          */
> > > +                         continue ;
> > > +                 }
> > > +         } else if (req_lib_cpg_iterationinitialize->iteration_type == 
> > > CPG_ITERATION_ONE_GROUP) {
> > > +                 /*
> > > +                  * Test pi group name with request
> > > +                  */
> > > +                 if (mar_name_compare (&pi->group, 
> > > &req_lib_cpg_iterationinitialize->group_name) != 0)
> > > +                         /*
> > > +                          * Not same -> don't add
> > > +                          */
> > > +                         continue ;
> > > +         } else {
> > 
> > why an else with no code?  Maybe should remove this stanza entirely.
> > 
> > > +                 /*
> > > +                  * We will add new item for sure
> > > +                  */
> > > +         }
> > > +
> > > +         new_pi = malloc (sizeof (struct process_info));
> > > +         if (!new_pi) {
> > > +                 log_printf(LOGSYS_LEVEL_WARNING, "Unable to allocate 
> > > process_info struct");
> > > +
> > > +                 error = CS_ERR_NO_MEMORY;
> > > +
> > > +                 goto error_put_destroy;
> > > +         }
> > > +
> > > +         memcpy (new_pi, pi, sizeof (struct process_info));
> > > +         list_init (&new_pi->list);
> > > +
> > > +         if (req_lib_cpg_iterationinitialize->iteration_type == 
> > > CPG_ITERATION_NAME_ONLY) {
> > > +                 /*
> > > +                  * pid and nodeid -> undefined
> > > +                  */
> > > +                 new_pi->pid = new_pi->nodeid = 0;
> > > +         }
> > > +
> > > +         /*
> > > +          * We will return list "grouped" by "group name", so try to 
> > > find right place to add
> > > +          */
> > > +         for (iter2 = cpg_iteration_instance->items_list_head.next;
> > > +              iter2 != &cpg_iteration_instance->items_list_head;
> > > +              iter2 = iter2->next) {
> > > +                  struct process_info *pi2 = list_entry (iter2, struct 
> > > process_info, list);
> > > +
> > > +                  if (mar_name_compare (&pi2->group, &pi->group) == 0) {
> > > +                         break;
> > > +                  }
> > > +         }
> > > +
> > > +         list_add (&new_pi->list, iter2);
> > > + }
> > > +
> > > + /*
> > > +  * Now we have a full "grouped by" copy of process_info list
> > > +  */
> > > +
> > > + /*
> > > +  * Add instance to current cpd list
> > > +  */
> > > + list_init (&cpg_iteration_instance->list);
> > > + list_add (&cpg_iteration_instance->list, 
> > > &cpd->iteration_instance_list_head);
> > > +
> > > + cpg_iteration_instance->current_pointer = 
> > > &cpg_iteration_instance->items_list_head;
> > > +
> > > +error_put_destroy:
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, cpg_iteration_handle);
> > > +error_destroy:
> > > + if (error != CS_OK) {
> > > +         hdb_handle_destroy (&cpg_iteration_handle_t_db, 
> > > cpg_iteration_handle);
> > > + }
> > > +
> > > +response_send:
> > > + res_lib_cpg_iterationinitialize.header.size = sizeof 
> > > (res_lib_cpg_iterationinitialize);
> > > + res_lib_cpg_iterationinitialize.header.id = 
> > > MESSAGE_RES_CPG_ITERATIONINITIALIZE;
> > > + res_lib_cpg_iterationinitialize.header.error = error;
> > > + res_lib_cpg_iterationinitialize.iteration_handle = cpg_iteration_handle;
> > > +
> > > + api->ipc_response_send (conn, &res_lib_cpg_iterationinitialize,
> > > +         sizeof (res_lib_cpg_iterationinitialize));
> > > +}
> > > +
> > > +static void message_handler_req_lib_cpg_iteration_next (void *conn,
> > > +                                                 const void *message)
> > > +{
> > > + const struct req_lib_cpg_iterationnext *req_lib_cpg_iterationnext = 
> > > message;
> > > + struct res_lib_cpg_iterationnext res_lib_cpg_iterationnext;
> > > + struct cpg_iteration_instance *cpg_iteration_instance;
> > > + cs_error_t error = CS_OK;
> > > + int res;
> > > + struct process_info *pi;
> > > +
> > > + log_printf (LOGSYS_LEVEL_DEBUG, "cpg iteration next\n");
> > > +
> > > + res = hdb_handle_get (&cpg_iteration_handle_t_db,
> > > +                 req_lib_cpg_iterationnext->iteration_handle,
> > > +                 (void *)&cpg_iteration_instance);
> > > +
> > > + if (res != 0) {
> > > +         error = CS_ERR_LIBRARY;
> > > +         goto error_exit;
> > > + }
> > > +
> > > + assert (cpg_iteration_instance);
> > > +
> > > + cpg_iteration_instance->current_pointer = 
> > > cpg_iteration_instance->current_pointer->next;
> > > +
> > > + if (cpg_iteration_instance->current_pointer == 
> > > &cpg_iteration_instance->items_list_head) {
> > > +         error = CS_ERR_NO_SECTIONS;
> > > +         goto error_put;
> > > + }
> > > +
> > > + pi = list_entry (cpg_iteration_instance->current_pointer, struct 
> > > process_info, list);
> > > +
> > > + /*
> > > +  * Copy iteration data
> > > +  */
> > > + res_lib_cpg_iterationnext.description.nodeid = pi->nodeid;
> > > + res_lib_cpg_iterationnext.description.pid = pi->pid;
> > > + memcpy (&res_lib_cpg_iterationnext.description.group,
> > > +                 &pi->group,
> > > +                 sizeof (mar_cpg_name_t));
> > > +
> > > +error_put:
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, 
> > > req_lib_cpg_iterationnext->iteration_handle);
> > > +error_exit:
> > > + res_lib_cpg_iterationnext.header.size = sizeof 
> > > (res_lib_cpg_iterationnext);
> > > + res_lib_cpg_iterationnext.header.id = MESSAGE_RES_CPG_ITERATIONNEXT;
> > > + res_lib_cpg_iterationnext.header.error = error;
> > > +
> > > + api->ipc_response_send (conn, &res_lib_cpg_iterationnext,
> > > +         sizeof (res_lib_cpg_iterationnext));
> > > +}
> > > +
> > > +static void message_handler_req_lib_cpg_iteration_finalize (void *conn,
> > > +                                                     const void *message)
> > > +
> > 
> > const void *message should be at 1 tabtop not tabbed to align.
> > 
> > > {
> > > + const struct req_lib_cpg_iterationfinalize 
> > > *req_lib_cpg_iterationfinalize = message;
> > > + struct res_lib_cpg_iterationfinalize res_lib_cpg_iterationfinalize;
> > > + struct cpg_iteration_instance *cpg_iteration_instance;
> > > + cs_error_t error = CS_OK;
> > > + int res;
> > > +
> > > + log_printf (LOGSYS_LEVEL_DEBUG, "cpg iteration finalize\n");
> > > +
> > > + res = hdb_handle_get (&cpg_iteration_handle_t_db,
> > > +                 req_lib_cpg_iterationfinalize->iteration_handle,
> > > +                 (void *)&cpg_iteration_instance);
> > > +
> > > + if (res != 0) {
> > > +         error = CS_ERR_LIBRARY;
> > > +         goto error_exit;
> > > + }
> > > +
> > > + assert (cpg_iteration_instance);
> > > +
> > > + cpg_iteration_instance_finalize (cpg_iteration_instance);
> > > + hdb_handle_put (&cpg_iteration_handle_t_db, 
> > > cpg_iteration_instance->handle);
> > > +
> > > +error_exit:
> > > + res_lib_cpg_iterationfinalize.header.size = sizeof 
> > > (res_lib_cpg_iterationfinalize);
> > > + res_lib_cpg_iterationfinalize.header.id = 
> > > MESSAGE_RES_CPG_ITERATIONFINALIZE;
> > > + res_lib_cpg_iterationfinalize.header.error = error;
> > > +
> > > + api->ipc_response_send (conn, &res_lib_cpg_iterationfinalize,
> > > +         sizeof (res_lib_cpg_iterationfinalize));
> > > +}
> > > _______________________________________________
> > > Openais mailing list
> > > [email protected]
> > > https://lists.linux-foundation.org/mailman/listinfo/openais
> > 
> > _______________________________________________
> > Openais mailing list
> > [email protected]
> > https://lists.linux-foundation.org/mailman/listinfo/openais
> 

_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to