ACK On 10/1/2012 4:21 PM, Jan Friesse wrote: > Function is little more complex, but it is designed to be used in future > without big changes. > > Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx> > --- > exec/cmap.c | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 247 insertions(+), 0 deletions(-) > > diff --git a/exec/cmap.c b/exec/cmap.c > index f4b688d..4b6efb4 100644 > --- a/exec/cmap.c > +++ b/exec/cmap.c > @@ -59,6 +59,9 @@ > > LOGSYS_DECLARE_SUBSYS ("CMAP"); > > +#define MAX_REQ_EXEC_CMAP_MCAST_ITEMS 32 > +#define ICMAP_VALUETYPE_NOT_EXIST 0 > + > struct cmap_conn_info { > struct hdb_handle_database iter_db; > struct hdb_handle_database track_db; > @@ -73,6 +76,14 @@ struct cmap_track_user_data { > uint64_t track_inst_handle; > }; > > +enum cmap_message_req_types { > + MESSAGE_REQ_EXEC_CMAP_MCAST = 0, > +}; > + > +enum cmap_mcast_reason { > + CMAP_MCAST_REASON_SYNC = 0, > +}; > + > static struct corosync_api_v1 *api; > > static char *cmap_exec_init_fn (struct corosync_api_v1 *corosync_api); > @@ -97,6 +108,14 @@ static void cmap_notify_fn(int32_t event, > struct icmap_notify_value old_val, > void *user_data); > > +static void message_handler_req_exec_cmap_mcast( > + const void *message, > + unsigned int nodeid); > + > +static void exec_cmap_mcast_endian_convert(void *message); > + > +static int cmap_mcast_send(enum cmap_mcast_reason reason, int argc, char *argv[]); > + > /* > * Library Handler Definition > */ > @@ -140,6 +159,13 @@ static struct corosync_lib_handler cmap_lib_engine[] = > }, > }; > > +static struct corosync_exec_handler cmap_exec_engine[] = > +{ > + { /* 0 - MESSAGE_REQ_EXEC_CMAP_MCAST */ > + .exec_handler_fn = message_handler_req_exec_cmap_mcast, > + .exec_endian_convert_fn = exec_cmap_mcast_endian_convert > + }, > +}; > > struct corosync_service_engine cmap_service_engine = { > .name = "corosync configuration map access", > @@ -154,6 +180,8 @@ struct corosync_service_engine cmap_service_engine = { > .lib_engine_count = sizeof (cmap_lib_engine) / sizeof (struct corosync_lib_handler), > .exec_init_fn = cmap_exec_init_fn, > .exec_exit_fn = cmap_exec_exit_fn, > + .exec_engine = cmap_exec_engine, > + .exec_engine_count = sizeof (cmap_exec_engine) / sizeof (struct corosync_exec_handler), > }; > > struct corosync_service_engine *cmap_get_service_engine_ver0 (void) > @@ -161,6 +189,24 @@ struct corosync_service_engine *cmap_get_service_engine_ver0 (void) > return (&cmap_service_engine); > } > > +struct req_exec_cmap_mcast_item { > + mar_name_t key_name __attribute__((aligned(8))); > + mar_uint8_t value_type __attribute__((aligned(8))); > + mar_size_t value_len __attribute__((aligned(8))); > + uint8_t value[] __attribute__((aligned(8))); > +}; > + > +struct req_exec_cmap_mcast { > + struct qb_ipc_request_header header __attribute__((aligned(8))); > + mar_uint8_t reason __attribute__((aligned(8))); > + mar_uint8_t no_items __attribute__((aligned(8))); > + mar_uint8_t reserved1 __attribute__((aligned(8))); > + mar_uint8_t reserver2 __attribute__((aligned(8))); > + /* > + * Following are array of req_exec_cmap_mcast_item > + */ > +}; > + > static int cmap_exec_exit_fn(void) > { > return 0; > @@ -602,3 +648,204 @@ reply_send: > > api->ipc_response_send(conn, &res_lib_cmap_track_delete, sizeof(res_lib_cmap_track_delete)); > } > + > +static int cmap_mcast_send(enum cmap_mcast_reason reason, int argc, char *argv[]) > +{ > + int i; > + size_t value_len; > + icmap_value_types_t value_type; > + cs_error_t err; > + size_t item_len; > + size_t msg_len = 0; > + struct req_exec_cmap_mcast req_exec_cmap_mcast; > + struct req_exec_cmap_mcast_item *item; > + struct iovec req_exec_cmap_iovec[MAX_REQ_EXEC_CMAP_MCAST_ITEMS + 1]; > + > + ENTER(); > + > + if (argc > MAX_REQ_EXEC_CMAP_MCAST_ITEMS) { > + return (CS_ERR_TOO_MANY_GROUPS); > + } > + > + memset(req_exec_cmap_iovec, 0, sizeof(req_exec_cmap_iovec)); > + > + for (i = 0; i < argc; i++) { > + err = icmap_get(argv[i], NULL, &value_len, &value_type); > + if (err != CS_OK && err != CS_ERR_NOT_EXIST) { > + goto free_mem; > + } > + if (err == CS_ERR_NOT_EXIST) { > + value_type = ICMAP_VALUETYPE_NOT_EXIST; > + value_len = 0; > + } > + > + item_len = sizeof(*item) + value_len; > + > + item = malloc(item_len); > + if (item == NULL) { > + goto free_mem; > + } > + memset(item, 0, sizeof(item_len)); > + > + item->value_type = value_type; > + item->value_len = value_len; > + item->key_name.length = strlen(argv[i]); > + strcpy((char *)item->key_name.value, argv[i]); > + > + if (value_type != ICMAP_VALUETYPE_NOT_EXIST) { > + err = icmap_get(argv[i], item->value, &value_len, &value_type); > + if (err != CS_OK) { > + goto free_mem; > + } > + } > + > + req_exec_cmap_iovec[i + 1].iov_base = item; > + req_exec_cmap_iovec[i + 1].iov_len = item_len; > + msg_len += item_len; > + > + qb_log(LOG_TRACE, "Item %u - type %u, len %zu", i, item->value_type, item->value_len); > + > + item = NULL; > + } > + > + memset(&req_exec_cmap_mcast, 0, sizeof(req_exec_cmap_mcast)); > + req_exec_cmap_mcast.header.size = sizeof(req_exec_cmap_mcast) + msg_len; > + req_exec_cmap_mcast.reason = reason; > + req_exec_cmap_mcast.no_items = argc; > + req_exec_cmap_iovec[0].iov_base = &req_exec_cmap_mcast; > + req_exec_cmap_iovec[0].iov_len = sizeof(req_exec_cmap_mcast); > + > + qb_log(LOG_TRACE, "Sending %u items (%u iovec) for reason %u", argc, argc + 1, reason); > + err = api->totem_mcast(req_exec_cmap_iovec, argc + 1, TOTEM_AGREED); > + > +free_mem: > + for (i = 0; i < argc; i++) { > + free(req_exec_cmap_iovec[i + 1].iov_base); > + } > + > + free(item); > + > + LEAVE(); > + return (err); > +} > + > +static struct req_exec_cmap_mcast_item *cmap_mcast_item_find( > + const void *message, > + char *key) > +{ > + const struct req_exec_cmap_mcast *req_exec_cmap_mcast = message; > + int i; > + const char *p; > + struct req_exec_cmap_mcast_item *item; > + mar_uint16_t key_name_len; > + > + p = (const char *)message + sizeof(*req_exec_cmap_mcast); > + > + for (i = 0; i < req_exec_cmap_mcast->no_items; i++) { > + item = (struct req_exec_cmap_mcast_item *)p; > + > + key_name_len = item->key_name.length; > + if (strlen(key) == key_name_len && strcmp((char *)item->key_name.value, key) == 0) { > + return (item); > + } > + > + p += sizeof(*item) + item->value_len; > + } > + > + return (NULL); > +} > + > +static void message_handler_req_exec_cmap_mcast_reason_sync( > + const void *message, > + unsigned int nodeid) > +{ > + uint64_t config_version = 0; > + struct req_exec_cmap_mcast_item *item; > + mar_size_t value_len; > + > + ENTER(); > + > + item = cmap_mcast_item_find(message, (char *)"totem.config_version"); > + if (item != NULL) { > + value_len = item->value_len; > + > + if (item->value_type == ICMAP_VALUETYPE_NOT_EXIST) { > + config_version = 0; > + } > + > + if (item->value_type == ICMAP_VALUETYPE_UINT64) { > + memcpy(&config_version, item->value, value_len); > + } > + } > + > + qb_log(LOG_TRACE, "Received config version %"PRIu64" from node %x", config_version, nodeid); > + > + LEAVE(); > +} > + > +static void message_handler_req_exec_cmap_mcast( > + const void *message, > + unsigned int nodeid) > +{ > + const struct req_exec_cmap_mcast *req_exec_cmap_mcast = message; > + > + ENTER(); > + > + switch (req_exec_cmap_mcast->reason) { > + case CMAP_MCAST_REASON_SYNC: > + message_handler_req_exec_cmap_mcast_reason_sync(message, nodeid); > + break; > + default: > + qb_log(LOG_TRACE, "Received mcast with unknown reason %u", req_exec_cmap_mcast->reason); > + }; > + > + LEAVE(); > +} > + > +static void exec_cmap_mcast_endian_convert(void *message) > +{ > + struct req_exec_cmap_mcast *req_exec_cmap_mcast = message; > + const char *p; > + int i; > + struct req_exec_cmap_mcast_item *item; > + uint16_t u16; > + uint32_t u32; > + uint64_t u64; > + > + swab_coroipc_request_header_t(&req_exec_cmap_mcast->header); > + > + p = (const char *)message + sizeof(*req_exec_cmap_mcast); > + > + for (i = 0; i < req_exec_cmap_mcast->no_items; i++) { > + item = (struct req_exec_cmap_mcast_item *)p; > + > + swab_mar_uint16_t(&item->key_name.length); > + swab_mar_size_t(&item->value_len); > + > + switch (item->value_type) { > + case ICMAP_VALUETYPE_INT16: > + case ICMAP_VALUETYPE_UINT16: > + memcpy(&u16, item->value, sizeof(u16)); > + u16 = swab16(u16); > + memcpy(item->value, &u16, sizeof(u16)); > + break; > + case ICMAP_VALUETYPE_INT32: > + case ICMAP_VALUETYPE_UINT32: > + memcpy(&u32, item->value, sizeof(u32)); > + u32 = swab32(u32); > + memcpy(item->value, &u32, sizeof(u32)); > + break; > + case ICMAP_VALUETYPE_INT64: > + case ICMAP_VALUETYPE_UINT64: > + memcpy(&u64, item->value, sizeof(u64)); > + u64 = swab64(u64); > + memcpy(item->value, &u64, sizeof(u64)); > + break; > + /* > + * TODO: Need to convert also float and double > + */ > + } > + > + p += sizeof(*item) + item->value_len; > + } > +} > _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss