mirror of
https://git.proxmox.com/git/mirror_corosync
synced 2025-07-25 07:17:11 +00:00
Implementation of cpg_iteration functions
This functions allows iterate available cpg groups and their members. API is modelled like ckpt iteration functions. git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2399 fd59a12c-fef9-0310-b244-a6a79926bd2f
This commit is contained in:
parent
519616de0c
commit
db87fb8f56
@ -164,6 +164,9 @@ SOMAJOR="4"
|
||||
SOMINOR="0"
|
||||
SOMICRO="0"
|
||||
SONAME="${SOMAJOR}.${SOMINOR}.${SOMICRO}"
|
||||
# Special for libcpg
|
||||
CPG_SOMICRO="1"
|
||||
CPG_SONAME="${SOMAJOR}.${SOMINOR}.${CPG_SOMICRO}"
|
||||
|
||||
# local options
|
||||
AC_ARG_ENABLE([ansi],
|
||||
@ -375,6 +378,7 @@ AC_SUBST([SOMAJOR])
|
||||
AC_SUBST([SOMINOR])
|
||||
AC_SUBST([SOMICRO])
|
||||
AC_SUBST([SONAME])
|
||||
AC_SUBST([CPG_SONAME])
|
||||
|
||||
AC_SUBST([OS_DYFLAGS])
|
||||
|
||||
@ -420,6 +424,7 @@ AC_MSG_RESULT([ Features =${PACKAGE_FEATURES}])
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_RESULT([$PACKAGE build info:])
|
||||
AC_MSG_RESULT([ Library SONAME = ${SONAME}])
|
||||
AC_MSG_RESULT([ CPG Library SONAME = ${CPG_SONAME}])
|
||||
AC_MSG_RESULT([ Default optimization = ${OPT_CFLAGS}])
|
||||
AC_MSG_RESULT([ Default debug options = ${GDB_CFLAGS}])
|
||||
AC_MSG_RESULT([ Extra compiler warnings = ${EXTRA_WARNING}])
|
||||
|
@ -4,6 +4,7 @@
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Christine Caulfield (ccaulfi@redhat.com)
|
||||
* Author: Jan Friesse (jfriesse@redhat.com)
|
||||
*
|
||||
* 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
|
||||
|
@ -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 */
|
||||
|
@ -40,7 +40,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
|
||||
lib_LIBRARIES = libcpg.a libconfdb.a libevs.a libcfg.a libquorum.a \
|
||||
libvotequorum.a libpload.a libcoroipcc.a
|
||||
SHARED_LIBS = $(lib_LIBRARIES:%.a=%.so.$(SONAME))
|
||||
SHARED_LIBS = $(filter-out libcpg.so.$(SONAME), $(lib_LIBRARIES:%.a=%.so.$(SONAME))) libcpg.so.$(CPG_SONAME)
|
||||
SHARED_LIBS_SO = $(lib_LIBRARIES:%.a=%.so)
|
||||
SHARED_LIBS_SO_TWO = $(lib_LIBRARIES:%.a=%.so.$(SOMAJOR))
|
||||
|
||||
@ -75,6 +75,11 @@ libconfdb.so.$(SONAME): confdb.o sa-confdb.o libcoroipcc.so.$(SONAME)
|
||||
ln -sf libconfdb.so.$(SONAME) libconfdb.so
|
||||
ln -sf libconfdb.so.$(SONAME) libconfdb.so.$(SOMAJOR)
|
||||
|
||||
libcpg.so.$(CPG_SONAME): cpg.o libcoroipcc.so.$(SONAME)
|
||||
$(CC) $(DARWIN_OPTS) $^ -o $@
|
||||
ln -sf $@ libcpg.so
|
||||
ln -sf $@ libcpg.so.$(SOMAJOR)
|
||||
|
||||
lib%.so.$(SONAME): %.o libcoroipcc.so.$(SONAME)
|
||||
$(CC) $(DARWIN_OPTS) $^ -o $@
|
||||
ln -sf lib$*.so.$(SONAME) lib$*.so
|
||||
@ -95,6 +100,11 @@ libconfdb.so.$(SONAME): confdb.o sa-confdb.o libcoroipcc.so.$(SONAME)
|
||||
ln -sf libconfdb.so.$(SONAME) libconfdb.so
|
||||
ln -sf libconfdb.so.$(SONAME) libconfdb.so.$(SOMAJOR)
|
||||
|
||||
libcpg.so.$(CPG_SONAME): cpg.o libcoroipcc.so.$(SONAME)
|
||||
$(LD) $(SOLARIS_OPTS) -G $^ -o $@
|
||||
ln -sf $@ libcpg.so
|
||||
ln -sf $@ libcpg.so.$(SOMAJOR)
|
||||
|
||||
lib%.so.$(SONAME): %.o libcoroipcc.so.$(SONAME)
|
||||
$(LD) $(SOLARIS_OPTS) -G $^ -o $@
|
||||
ln -sf lib$*.so.$(SONAME) lib$*.so
|
||||
@ -118,6 +128,14 @@ libconfdb.so.$(SONAME): confdb.o sa-confdb.o ../lcr/lcr_ifact.o libcoroipcc.so.$
|
||||
ln -sf libconfdb.so.$(SONAME) libconfdb.so
|
||||
ln -sf libconfdb.so.$(SONAME) libconfdb.so.$(SOMAJOR)
|
||||
|
||||
libcpg.so.$(CPG_SONAME): cpg.o libcoroipcc.so.$(SONAME)
|
||||
$(CC) -shared -o $@ \
|
||||
-Wl,-soname=libcpg.so.$(SOMAJOR) \
|
||||
-Wl,-version-script=$(srcdir)/libcpg.versions \
|
||||
$^ $(LDFLAGS) $(AM_LDFLAGS)
|
||||
ln -sf $@ libcpg.so
|
||||
ln -sf $@ libcpg.so.$(SOMAJOR)
|
||||
|
||||
lib%.so.$(SONAME): %.o libcoroipcc.so.$(SONAME)
|
||||
$(CC) -shared -o $@ \
|
||||
-Wl,-soname=lib$*.so.$(SOMAJOR) \
|
||||
|
236
lib/cpg.c
236
lib/cpg.c
@ -5,7 +5,8 @@
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Patrick Caulfield (pcaulfie@redhat.com)
|
||||
* Author: Christine Caulfield (ccaulfi@redhat.com)
|
||||
* Author: Jan Friesse (jfriesse@redhat.com)
|
||||
*
|
||||
* 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 res_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);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
315
services/cpg.c
315
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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user