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

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

 



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;
+	}
+}
-- 
1.7.1

_______________________________________________
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