Re: [PATCH 2/8] Add support for sending cmap values to wire

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

 



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


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

  Powered by Linux