Steve,
take2 patch included.
+ 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.
IRC discussed
+
+ error = hdb_error_to_cs (hdb_handle_get (&cpg_handle_t_db, handle, (void
*)&cpg_inst));
+
why the void cast?
It doesn't make much sense, but it's everywhere and it's only because
compiler warnings.
+ continue ;
+ } else {
why an else with no code? Maybe should remove this stanza entirely.
Remainder from development (just note). Removed completely
+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.
It is copying neighboring code. But yes, lib style looks nicer, so
changed now.
Regards,
Honza
commit 6e9292f426aaf32da5a12e0f7df9724c2edfd83d
Author: Jan Friesse <[email protected]>
Date: Thu Aug 20 15:06:11 2009 +0200
Implementation of cpg_iteration functions
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 f78ad91..d00f7c8 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);
+}
+
/**
* @defgroup cpg_coroipcc The closed process group API
* @ingroup coroipcc
@@ -105,6 +146,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);
@@ -140,8 +183,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);
@@ -685,4 +727,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));
+ 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..ed3128c 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,18 @@ 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 +275,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 +606,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 +655,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 +1033,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 +1234,237 @@ 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 ;
+ }
+
+ 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 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