Просмотр исходного кода

Merge trunk revision 2511:
r2511 | asalkeld | 2009-10-09 20:20:38 -0700 (Fri, 09 Oct 2009) | 6 lines

Add value types to objdb keys.

This allows you to create a key with a know type.
And then get the type with the key value.



git-svn-id: http://svn.fedorahosted.org/svn/corosync/branches/flatiron@2585 fd59a12c-fef9-0310-b244-a6a79926bd2f

Steven Dake 16 лет назад
Родитель
Сommit
ea38f7e15b

+ 3 - 0
exec/apidef.c

@@ -172,6 +172,9 @@ void apidef_init (struct objdb_iface_ver0 *objdb) {
 	apidef_corosync_api_v1.object_reload_config = objdb->object_reload_config;
 	apidef_corosync_api_v1.object_key_increment = objdb->object_key_increment;
 	apidef_corosync_api_v1.object_key_decrement = objdb->object_key_decrement;
+	apidef_corosync_api_v1.object_key_create_typed = objdb->object_key_create_typed;
+	apidef_corosync_api_v1.object_key_get_typed = objdb->object_key_get_typed;
+	apidef_corosync_api_v1.object_key_iter_typed = objdb->object_key_iter_typed;
 }
 
 struct corosync_api_v1 *apidef_get (void)

+ 2 - 3
exec/coroparse.c

@@ -172,9 +172,8 @@ static int parse_section(FILE *fp,
 				    key, error_string))
 					    return -1;
 			}
-			objdb->object_key_create (parent_handle, key,
-				strlen (key),
-				value, strlen (value) + 1);
+			objdb->object_key_create_typed (parent_handle, key,
+				value, strlen (value) + 1, OBJDB_VALUETYPE_STRING);
 		}
 
 		if ((loc = strchr_rs (line, '}'))) {

+ 96 - 19
exec/objdb.c

@@ -53,6 +53,7 @@ struct object_key {
 	size_t key_len;
 	void *value;
 	size_t value_len;
+	objdb_value_types_t value_type;
 	struct list_head list;
 };
 
@@ -498,12 +499,12 @@ error_exit:
 	return (-1);
 }
 
-static int object_key_create (
+static int object_key_create_typed(
 	hdb_handle_t object_handle,
-	const void *key_name,
-	size_t key_len,
+	const char *key_name,
 	const void *value,
-	size_t value_len)
+	size_t value_len,
+	objdb_value_types_t value_type)
 {
 	struct object_instance *instance;
 	struct object_key *object_key;
@@ -511,6 +512,7 @@ static int object_key_create (
 	struct list_head *list;
 	int found = 0;
 	int i;
+	size_t key_len = strlen(key_name);
 
 	objdb_rdlock();
 
@@ -574,11 +576,11 @@ static int object_key_create (
 		if (object_key == 0) {
 			goto error_put;
 		}
-		object_key->key_name = malloc (key_len);
+		object_key->key_name = malloc (key_len + 1);
 		if (object_key->key_name == 0) {
 			goto error_put_object;
 		}
-		memcpy (object_key->key_name, key_name, key_len);
+		memcpy (object_key->key_name, key_name, key_len + 1);
 		list_init (&object_key->list);
 		list_add_tail (&object_key->list, &instance->key_head);
 	}
@@ -590,6 +592,7 @@ static int object_key_create (
 
 	object_key->key_len = key_len;
 	object_key->value_len = value_len;
+	object_key->value_type = value_type;
 
 	object_key_changed_notification(object_handle, key_name, key_len,
 					value, value_len, OBJECT_KEY_CREATED);
@@ -610,6 +613,17 @@ error_exit:
 	return (-1);
 }
 
+static int object_key_create (
+	hdb_handle_t object_handle,
+	const void *key_name,
+	size_t key_len,
+	const void *value,
+	size_t value_len)
+{
+	return object_key_create_typed (object_handle, key_name,
+					value, value_len, OBJDB_VALUETYPE_ANY);
+}
+
 static int _clear_object(struct object_instance *instance)
 {
 	struct list_head *list;
@@ -861,18 +875,19 @@ error_exit:
 	return (-1);
 }
 
-static int object_key_get (
+static int object_key_get_typed (
 	hdb_handle_t object_handle,
-	const void *key_name,
-	size_t key_len,
+	const char *key_name,
 	void **value,
-	size_t *value_len)
+	size_t *value_len,
+	objdb_value_types_t * type)
 {
 	unsigned int res = 0;
 	struct object_instance *instance;
 	struct object_key *object_key = NULL;
 	struct list_head *list;
 	int found = 0;
+	size_t key_len = strlen(key_name);
 
 	objdb_rdlock();
 	res = hdb_handle_get (&object_instance_database,
@@ -896,6 +911,7 @@ static int object_key_get (
 		if (value_len) {
 			*value_len = object_key->value_len;
 		}
+		*type = object_key->value_type;
 	}
 	else {
 		res = -1;
@@ -910,6 +926,19 @@ error_exit:
 	return (-1);
 }
 
+static int object_key_get (
+	hdb_handle_t object_handle,
+	const void *key_name,
+	size_t key_len,
+	void **value,
+	size_t *value_len)
+{
+	objdb_value_types_t t;
+	return object_key_get_typed(object_handle,
+							  key_name,
+							  value, value_len, &t);
+}
+
 static int object_key_increment (
 	hdb_handle_t object_handle,
 	const void *key_name,
@@ -1205,8 +1234,40 @@ static int _dump_object(struct object_instance *instance, FILE *file, int depth)
 
 		memcpy(stringbuf1, object_key->key_name, object_key->key_len);
 		stringbuf1[object_key->key_len] = '\0';
-		memcpy(stringbuf2, object_key->value, object_key->value_len);
-		stringbuf2[object_key->value_len] = '\0';
+
+
+		switch (object_key->value_type) {
+			case OBJDB_VALUETYPE_INT16:
+				snprintf (stringbuf2, sizeof(int), "%hd",
+						  *(unsigned int*)object_key->value);
+				break;
+			case OBJDB_VALUETYPE_UINT16:
+				snprintf (stringbuf2, sizeof(int), "%hu",
+						  *(unsigned int*)object_key->value);
+				break;
+			case OBJDB_VALUETYPE_INT32:
+				snprintf (stringbuf2, sizeof(int), "%d",
+						  *(int*)object_key->value);
+				break;
+			case OBJDB_VALUETYPE_UINT32:
+				snprintf (stringbuf2, sizeof(int), "%u",
+						  *(unsigned int*)object_key->value);
+				break;
+			case OBJDB_VALUETYPE_INT64:
+				snprintf (stringbuf2, sizeof(int), "%ld",
+						  *(long int*)object_key->value);
+				break;
+			case OBJDB_VALUETYPE_UINT64:
+				snprintf (stringbuf2, sizeof(int), "%lu",
+						  *(unsigned long int*)object_key->value);
+				break;
+			default:
+			case OBJDB_VALUETYPE_STRING:
+			case OBJDB_VALUETYPE_ANY:
+				memcpy(stringbuf2, object_key->value, object_key->value_len);
+				stringbuf2[object_key->value_len] = '\0';
+				break;
+		}
 
 		for (i=0; i<depth+1; i++)
 			fprintf(file, "    ");
@@ -1255,12 +1316,11 @@ error_exit:
 	return (-1);
 }
 
-
-static int object_key_iter(hdb_handle_t parent_object_handle,
-			   void **key_name,
-			   size_t *key_len,
+static int object_key_iter_typed (hdb_handle_t parent_object_handle,
+			   char **key_name,
 			   void **value,
-			   size_t *value_len)
+			   size_t *value_len,
+			   objdb_value_types_t *type)
 {
 	unsigned int res;
 	struct object_instance *instance;
@@ -1284,9 +1344,8 @@ static int object_key_iter(hdb_handle_t parent_object_handle,
 	instance->iter_key_list = list;
 	if (found) {
 		*key_name = find_key->key_name;
-		if (key_len)
-			*key_len = find_key->key_len;
 		*value = find_key->value;
+		*type = find_key->value_type;
 		if (value_len)
 			*value_len = find_key->value_len;
 		res = 0;
@@ -1304,6 +1363,21 @@ error_exit:
 	return (-1);
 }
 
+static int object_key_iter(hdb_handle_t parent_object_handle,
+			   void **key_name,
+			   size_t *key_len,
+			   void **value,
+			   size_t *value_len)
+{
+	objdb_value_types_t t;
+	int ret;
+	char *str;
+	ret = object_key_iter_typed (parent_object_handle, (char**)key_name, value, value_len, &t);
+	str = *key_name;
+	*key_len = strlen(str);
+	return ret;
+}
+
 static int object_key_iter_from(hdb_handle_t parent_object_handle,
 				hdb_handle_t start_pos,
 				void **key_name,
@@ -1599,6 +1673,9 @@ struct objdb_iface_ver0 objdb_iface = {
 	.object_reload_config   = object_reload_config,
 	.object_key_increment   = object_key_increment,
 	.object_key_decrement   = object_key_decrement,
+	.object_key_create_typed	= object_key_create_typed,
+	.object_key_get_typed		= object_key_get_typed,
+	.object_key_iter_typed		= object_key_iter_typed,
 };
 
 struct lcr_iface objdb_iface_ver0[1] = {

+ 8 - 12
exec/service.c

@@ -187,29 +187,25 @@ unsigned int corosync_service_link_and_init (
 		"service",
 		strlen ("service"));
 
-	corosync_api->object_key_create (object_service_handle,
+	corosync_api->object_key_create_typed (object_service_handle,
 		"name",
-		strlen ("name"),
 		service_name,
-		strlen (service_name) + 1);
+		strlen (service_name) + 1, OBJDB_VALUETYPE_STRING);
 
-	corosync_api->object_key_create (object_service_handle,
+	corosync_api->object_key_create_typed (object_service_handle,
 		"ver",
-		strlen ("ver"),
 		&service_ver,
-		sizeof (service_ver));
+		sizeof (service_ver), OBJDB_VALUETYPE_UINT32);
 
-	res = corosync_api->object_key_create (object_service_handle,
+	res = corosync_api->object_key_create_typed (object_service_handle,
 		"handle",
-		strlen ("handle"),
 		&handle,
-		sizeof (handle));
+		sizeof (handle), OBJDB_VALUETYPE_UINT64);
 
-	corosync_api->object_key_create (object_service_handle,
+	corosync_api->object_key_create_typed (object_service_handle,
 		"service_id",
-		strlen ("service_id"),
 		&service->id,
-		sizeof (service->id));
+		sizeof (service->id), OBJDB_VALUETYPE_UINT16);
 
 	log_printf (LOGSYS_LEVEL_NOTICE, "Service engine loaded: %s\n", service->name);
 	return (res);

+ 37 - 0
include/corosync/confdb.h

@@ -50,6 +50,19 @@ typedef uint64_t confdb_handle_t;
 
 #define OBJECT_PARENT_HANDLE 0xFFFFFFFF00000000ULL
 
+typedef enum {
+	CONFDB_VALUETYPE_INT16,
+	CONFDB_VALUETYPE_UINT16,
+	CONFDB_VALUETYPE_INT32,
+	CONFDB_VALUETYPE_UINT32,
+	CONFDB_VALUETYPE_INT64,
+	CONFDB_VALUETYPE_UINT64,
+	CONFDB_VALUETYPE_FLOAT,
+	CONFDB_VALUETYPE_DOUBLE,
+	CONFDB_VALUETYPE_STRING,
+	CONFDB_VALUETYPE_ANY,
+} confdb_value_types_t;
+
 typedef enum {
 	CONFDB_TRACK_DEPTH_ONE,
 	CONFDB_TRACK_DEPTH_RECURSIVE
@@ -181,6 +194,14 @@ cs_error_t confdb_key_create (
 	const void *value,
 	size_t value_len);
 
+cs_error_t confdb_key_create_typed (
+	confdb_handle_t handle,
+	hdb_handle_t parent_object_handle,
+	const char *key_name,
+	const void *value,
+	size_t value_len,
+	confdb_value_types_t type);
+
 cs_error_t confdb_key_delete (
 	confdb_handle_t handle,
 	hdb_handle_t parent_object_handle,
@@ -200,6 +221,14 @@ cs_error_t confdb_key_get (
 	void *value,
 	size_t *value_len);
 
+cs_error_t confdb_key_get_typed (
+	confdb_handle_t handle,
+	hdb_handle_t parent_object_handle,
+	const char *key_name,
+	void *value,
+	size_t *value_len,
+	confdb_value_types_t *type);
+
 cs_error_t confdb_key_replace (
 	confdb_handle_t handle,
 	hdb_handle_t parent_object_handle,
@@ -275,6 +304,14 @@ cs_error_t confdb_key_iter (
 	void *value,
 	size_t *value_len);
 
+cs_error_t confdb_key_iter_typed (
+	confdb_handle_t handle,
+	hdb_handle_t parent_object_handle,
+	char *key_name,
+	void *value,
+	size_t *value_len,
+	confdb_value_types_t *type);
+
 /*
  * Get/set context variable
  */

+ 35 - 0
include/corosync/engine/coroapi.h

@@ -169,6 +169,19 @@ struct object_key_valid {
 };
 /* deprecated */
 
+typedef enum {
+	OBJDB_VALUETYPE_INT16,
+	OBJDB_VALUETYPE_UINT16,
+	OBJDB_VALUETYPE_INT32,
+	OBJDB_VALUETYPE_UINT32,
+	OBJDB_VALUETYPE_INT64,
+	OBJDB_VALUETYPE_UINT64,
+	OBJDB_VALUETYPE_FLOAT,
+	OBJDB_VALUETYPE_DOUBLE,
+	OBJDB_VALUETYPE_STRING,
+	OBJDB_VALUETYPE_ANY,
+} objdb_value_types_t;
+
 typedef enum {
 	OBJECT_TRACK_DEPTH_ONE,
 	OBJECT_TRACK_DEPTH_RECURSIVE
@@ -590,6 +603,28 @@ struct corosync_api_v1 {
 	 * Please avoid using any of coropoll apis in your service engines.
 	 */
 	hdb_handle_t (*poll_handle_get) (void);
+
+
+	int (*object_key_create_typed) (
+		hdb_handle_t object_handle,
+		const char *key_name,
+		const void *value,
+		size_t value_len,
+		objdb_value_types_t type);
+
+	int (*object_key_get_typed) (
+		hdb_handle_t object_handle,
+		const char *key_name,
+		void **value,
+		size_t *value_len,
+		objdb_value_types_t *type);
+
+	int (*object_key_iter_typed) (
+		hdb_handle_t parent_object_handle,
+		char **key_name,
+		void **value,
+		size_t *value_len,
+		objdb_value_types_t *type);
 };
 
 #define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) )

+ 34 - 0
include/corosync/engine/objdb.h

@@ -41,6 +41,19 @@
 #include <stdio.h>
 #include <corosync/hdb.h>
 
+typedef enum {
+	OBJDB_VALUETYPE_INT16,
+	OBJDB_VALUETYPE_UINT16,
+	OBJDB_VALUETYPE_INT32,
+	OBJDB_VALUETYPE_UINT32,
+	OBJDB_VALUETYPE_INT64,
+	OBJDB_VALUETYPE_UINT64,
+	OBJDB_VALUETYPE_FLOAT,
+	OBJDB_VALUETYPE_DOUBLE,
+	OBJDB_VALUETYPE_STRING,
+	OBJDB_VALUETYPE_ANY,
+} objdb_value_types_t;
+
 typedef enum {
 	OBJECT_TRACK_DEPTH_ONE,
 	OBJECT_TRACK_DEPTH_RECURSIVE
@@ -235,6 +248,27 @@ struct objdb_iface_ver0 {
 		const void *key_name,
 		size_t key_len,
 		unsigned int *value);
+
+	int (*object_key_create_typed) (
+		hdb_handle_t object_handle,
+		const char *key_name,
+		const void *value,
+		size_t value_len,
+		objdb_value_types_t type);
+
+	int (*object_key_get_typed) (
+		hdb_handle_t object_handle,
+		const char *key_name,
+		void **value,
+		size_t *value_len,
+		objdb_value_types_t *type);
+
+	int (*object_key_iter_typed) (
+		hdb_handle_t parent_object_handle,
+		char **key_name,
+		void **value,
+		size_t *value_len,
+		objdb_value_types_t *type);
 };
 
 #endif /* OBJDB_H_DEFINED */

+ 26 - 2
include/corosync/ipc_confdb.h

@@ -55,7 +55,10 @@ enum req_confdb_types {
 	MESSAGE_REQ_CONFDB_RELOAD = 13,
 	MESSAGE_REQ_CONFDB_OBJECT_FIND_DESTROY = 14,
 	MESSAGE_REQ_CONFDB_KEY_INCREMENT = 15,
-	MESSAGE_REQ_CONFDB_KEY_DECREMENT = 16
+	MESSAGE_REQ_CONFDB_KEY_DECREMENT = 16,
+	MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED = 17,
+	MESSAGE_REQ_CONFDB_KEY_GET_TYPED = 18,
+	MESSAGE_REQ_CONFDB_KEY_ITER_TYPED = 19,
 };
 
 enum res_confdb_types {
@@ -78,7 +81,9 @@ enum res_confdb_types {
 	MESSAGE_RES_CONFDB_RELOAD = 16,
 	MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY = 17,
 	MESSAGE_RES_CONFDB_KEY_INCREMENT = 18,
-	MESSAGE_RES_CONFDB_KEY_DECREMENT = 19
+	MESSAGE_RES_CONFDB_KEY_DECREMENT = 19,
+	MESSAGE_RES_CONFDB_KEY_GET_TYPED = 20,
+	MESSAGE_RES_CONFDB_KEY_ITER_TYPED = 21,
 };
 
 
@@ -116,6 +121,14 @@ struct req_lib_confdb_key_create {
 	mar_name_t value __attribute__((aligned(8)));
 };
 
+struct req_lib_confdb_key_create_typed {
+	coroipc_request_header_t header __attribute__((aligned(8)));
+	mar_uint64_t object_handle __attribute__((aligned(8)));
+	mar_name_t key_name __attribute__((aligned(8)));
+	mar_name_t value __attribute__((aligned(8)));
+	mar_int32_t type __attribute__((aligned(8)));
+};
+
 struct req_lib_confdb_key_delete {
 	coroipc_request_header_t header __attribute__((aligned(8)));
 	mar_uint64_t object_handle __attribute__((aligned(8)));
@@ -168,6 +181,12 @@ struct res_lib_confdb_key_iter {
 	mar_name_t key_name __attribute__((aligned(8)));
 	mar_name_t value __attribute__((aligned(8)));
 };
+struct res_lib_confdb_key_iter_typed {
+	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_name_t key_name __attribute__((aligned(8)));
+	mar_name_t value __attribute__((aligned(8)));
+	mar_int32_t type __attribute__((aligned(8)));
+};
 
 struct req_lib_confdb_key_get {
 	coroipc_request_header_t header __attribute__((aligned(8)));
@@ -184,6 +203,11 @@ struct res_lib_confdb_key_get {
 	coroipc_response_header_t header __attribute__((aligned(8)));
 	mar_name_t value __attribute__((aligned(8)));
 };
+struct res_lib_confdb_key_get_typed {
+	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_name_t value __attribute__((aligned(8)));
+	mar_int32_t type __attribute__((aligned(8)));
+};
 
 struct res_lib_confdb_key_incdec {
 	coroipc_response_header_t header __attribute__((aligned(8)));

+ 200 - 0
lib/confdb.c

@@ -722,6 +722,68 @@ error_exit:
 	return (error);
 }
 
+
+cs_error_t confdb_key_create_typed (
+	confdb_handle_t handle,
+	hdb_handle_t parent_object_handle,
+	const char *key_name,
+	const void *value,
+	size_t value_len,
+	confdb_value_types_t type)
+{
+	cs_error_t error;
+	struct confdb_inst *confdb_inst;
+	struct iovec iov;
+	struct req_lib_confdb_key_create_typed request;
+	coroipc_response_header_t res;
+
+	error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
+	if (error != CS_OK) {
+		return (error);
+	}
+
+	if (confdb_inst->standalone) {
+		error = CS_OK;
+
+		if (confdb_sa_key_create_typed(parent_object_handle,
+					 key_name, value, value_len, type))
+			error = CS_ERR_ACCESS;
+		goto error_exit;
+	}
+
+	request.header.size = sizeof (struct req_lib_confdb_key_create_typed);
+	request.header.id = MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED;
+	request.object_handle = parent_object_handle;
+	request.key_name.length = strlen(key_name)+1;
+	memcpy(request.key_name.value, key_name, request.key_name.length);
+	memcpy(request.value.value, value, value_len);
+	request.value.length = value_len;
+	request.type = type;
+
+	iov.iov_base = (char *)&request;
+	iov.iov_len = sizeof (struct req_lib_confdb_key_create_typed);
+
+	error = coroipcc_msg_send_reply_receive (
+		confdb_inst->handle,
+		&iov,
+		1,
+		&res,
+		sizeof (res));
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+
+	error = res.error;
+
+error_exit:
+	(void)hdb_handle_put (&confdb_handle_t_db, handle);
+
+	return (error);
+}
+
+
+
 cs_error_t confdb_key_delete (
 	confdb_handle_t handle,
 	hdb_handle_t parent_object_handle,
@@ -842,6 +904,69 @@ error_exit:
 	return (error);
 }
 
+
+cs_error_t confdb_key_get_typed (
+	confdb_handle_t handle,
+	hdb_handle_t parent_object_handle,
+	const char *key_name,
+	void *value,
+	size_t *value_len,
+	confdb_value_types_t *type)
+{
+	cs_error_t error;
+	struct confdb_inst *confdb_inst;
+	struct iovec iov;
+	struct req_lib_confdb_key_get req_lib_confdb_key_get;
+	struct res_lib_confdb_key_get_typed response;
+
+	error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
+	if (error != CS_OK) {
+		return (error);
+	}
+
+	if (confdb_inst->standalone) {
+		error = CS_OK;
+
+		if (confdb_sa_key_get_typed(parent_object_handle,
+				      key_name, value, value_len, (int*)type))
+			error = CS_ERR_ACCESS;
+		goto error_exit;
+	}
+
+	req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
+	req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET_TYPED;
+	req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
+	req_lib_confdb_key_get.key_name.length = strlen(key_name) + 1;
+	memcpy(req_lib_confdb_key_get.key_name.value, key_name, req_lib_confdb_key_get.key_name.length);
+
+	iov.iov_base = (char *)&req_lib_confdb_key_get;
+	iov.iov_len = sizeof (struct req_lib_confdb_key_get);
+
+        error = coroipcc_msg_send_reply_receive (
+		confdb_inst->handle,
+		&iov,
+		1,
+		&response,
+		sizeof (struct res_lib_confdb_key_get_typed));
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+
+	error = response.header.error;
+	if (error == CS_OK) {
+		*value_len = response.value.length;
+		*type = response.type;
+		memcpy(value, response.value.value, *value_len);
+	}
+
+error_exit:
+	(void)hdb_handle_put (&confdb_handle_t_db, handle);
+
+	return (error);
+}
+
+
 cs_error_t confdb_key_increment (
 	confdb_handle_t handle,
 	hdb_handle_t parent_object_handle,
@@ -1345,6 +1470,81 @@ error_exit:
 	return (error);
 }
 
+cs_error_t confdb_key_iter_typed (
+	confdb_handle_t handle,
+	hdb_handle_t parent_object_handle,
+	char *key_name,
+	void *value,
+	size_t *value_len,
+	confdb_value_types_t *type)
+{
+	cs_error_t error;
+	struct confdb_inst *confdb_inst;
+	struct iovec iov;
+	struct iter_context *context;
+	struct req_lib_confdb_key_iter req_lib_confdb_key_iter;
+	struct res_lib_confdb_key_iter_typed response;
+
+	error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
+	if (error != CS_OK) {
+		return (error);
+	}
+
+	/* You MUST call confdb_key_iter_start first */
+	context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle);
+	if (!context) {
+		error =	CS_ERR_CONTEXT_NOT_FOUND;
+		goto error_exit;
+	}
+
+	if (confdb_inst->standalone) {
+		error = CS_OK;
+
+		if (confdb_sa_key_iter_typed(parent_object_handle,
+				       context->next_entry,
+				       key_name,
+				       value, value_len, (int*)type))
+			error = CS_ERR_ACCESS;
+		goto sa_exit;
+	}
+
+	req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
+	req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER_TYPED;
+	req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
+	req_lib_confdb_key_iter.next_entry= context->next_entry;
+
+	iov.iov_base = (char *)&req_lib_confdb_key_iter;
+	iov.iov_len = sizeof (struct req_lib_confdb_key_iter);
+
+	error = coroipcc_msg_send_reply_receive (
+		confdb_inst->handle,
+		&iov,
+		1,
+		&response,
+		sizeof (struct res_lib_confdb_key_iter_typed));
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+
+	error = response.header.error;
+	if (error == CS_OK) {
+		memcpy(key_name, response.key_name.value, response.key_name.length);
+		key_name[response.key_name.length] = '\0';
+		*value_len = response.value.length;
+		memcpy(value, response.value.value, *value_len);
+		*type = response.type;
+	}
+
+sa_exit:
+	context->next_entry++;
+
+error_exit:
+	(void)hdb_handle_put (&confdb_handle_t_db, handle);
+
+	return (error);
+}
+
 cs_error_t confdb_write (
 	confdb_handle_t handle,
 	char *error_text,

+ 60 - 0
lib/sa-confdb.c

@@ -197,6 +197,18 @@ int confdb_sa_key_create (
 					value, value_len);
 }
 
+int confdb_sa_key_create_typed (
+	hdb_handle_t parent_object_handle,
+	const char *key_name,
+	const void *value,
+	size_t value_len,
+	int type)
+{
+	return objdb->object_key_create_typed(parent_object_handle,
+					key_name,
+					value, value_len, type);
+}
+
 int confdb_sa_key_delete (
 	hdb_handle_t parent_object_handle,
 	const void *key_name,
@@ -227,6 +239,25 @@ int confdb_sa_key_get (
 	return res;
 }
 
+int confdb_sa_key_get_typed (
+	hdb_handle_t parent_object_handle,
+	const char *key_name,
+	void *value,
+	size_t *value_len,
+	int *type)
+{
+	int res;
+	void *kvalue;
+
+	res = objdb->object_key_get_typed(parent_object_handle,
+				    key_name,
+				    &kvalue, value_len, (objdb_value_types_t*)type);
+	if (!res) {
+		memcpy(value, kvalue, *value_len);
+	}
+	return res;
+}
+
 int confdb_sa_key_increment (
 	hdb_handle_t parent_object_handle,
 	const void *key_name,
@@ -373,6 +404,35 @@ int confdb_sa_key_iter (
 	return res;
 }
 
+int confdb_sa_key_iter_typed (
+	hdb_handle_t parent_object_handle,
+	hdb_handle_t start_pos,
+	char *key_name,
+	void *value,
+	size_t *value_len,
+	int *type)
+{
+	int res;
+	void *kname;
+	void *kvalue;
+	size_t key_name_len;
+
+	res = objdb->object_key_iter_from(parent_object_handle,
+					  start_pos,
+					  &kname, &key_name_len,
+					  &kvalue, value_len);
+
+	if (!res) {
+		memcpy(key_name, kname, key_name_len);
+		memcpy(value, kvalue, *value_len);
+
+		objdb->object_key_get_typed(parent_object_handle,
+					  key_name,
+					  &kvalue, value_len, (objdb_value_types_t*)type);
+	}
+	return res;
+}
+
 int confdb_sa_find_destroy(hdb_handle_t find_handle)
 {
 	return objdb->object_find_destroy(find_handle);

+ 16 - 0
lib/sa-confdb.h

@@ -45,6 +45,11 @@ extern int confdb_sa_key_create(hdb_handle_t parent_object_handle,
 				size_t key_name_len,
 				const void *value,
 				size_t value_len);
+extern int confdb_sa_key_create_typed (hdb_handle_t parent_object_handle,
+				const char *key_name,
+				const void *value,
+				size_t value_len,
+				int type);
 extern int confdb_sa_key_delete(hdb_handle_t parent_object_handle,
 				const void *key_name,
 				size_t key_name_len,
@@ -55,6 +60,11 @@ extern int confdb_sa_key_get(hdb_handle_t parent_object_handle,
 			     size_t key_name_len,
 			     void *value,
 			     size_t *value_len);
+extern int confdb_sa_key_get_typed(hdb_handle_t parent_object_handle,
+			     const char *key_name,
+			     void *value,
+			     size_t *value_len,
+			     int *type);
 extern int confdb_sa_key_replace(hdb_handle_t parent_object_handle,
 				 const void *key_name,
 				 size_t key_name_len,
@@ -80,6 +90,12 @@ extern int confdb_sa_key_iter(hdb_handle_t parent_object_handle,
 			      size_t *key_name_len,
 			      void *value,
 			      size_t *value_len);
+extern int confdb_sa_key_iter_typed (hdb_handle_t parent_object_handle,
+				hdb_handle_t start_pos,
+				char *key_name,
+				void *value,
+				size_t *value_len,
+				int *type);
 extern int confdb_sa_key_increment(hdb_handle_t parent_object_handle,
 				   const void *key_name,
 				   size_t key_name_len,

+ 108 - 1
services/confdb.c

@@ -79,14 +79,20 @@ static void message_handler_req_lib_confdb_object_find_destroy (void *conn,
 								const void *message);
 
 static void message_handler_req_lib_confdb_key_create (void *conn,
-						       const void *message);
+								const void *message);
+static void message_handler_req_lib_confdb_key_create_typed (void *conn,
+								const void *message);
 static void message_handler_req_lib_confdb_key_get (void *conn,
+								const void *message);
+static void message_handler_req_lib_confdb_key_get_typed (void *conn,
 						    const void *message);
 static void message_handler_req_lib_confdb_key_replace (void *conn,
 							const void *message);
 static void message_handler_req_lib_confdb_key_delete (void *conn,
 						       const void *message);
 static void message_handler_req_lib_confdb_key_iter (void *conn,
+								const void *message);
+static void message_handler_req_lib_confdb_key_iter_typed (void *conn,
 						     const void *message);
 
 static void message_handler_req_lib_confdb_key_increment (void *conn,
@@ -204,6 +210,18 @@ static struct corosync_lib_handler confdb_lib_engine[] =
 		.lib_handler_fn				= message_handler_req_lib_confdb_key_decrement,
 		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
 	},
+	{ /* 17 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_create_typed,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 18 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_get_typed,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 19 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_iter_typed,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
 };
 
 
@@ -373,6 +391,27 @@ static void message_handler_req_lib_confdb_key_create (void *conn,
 	api->ipc_response_send(conn, &res, sizeof(res));
 }
 
+static void message_handler_req_lib_confdb_key_create_typed (void *conn,
+						       const void *message)
+{
+	const struct req_lib_confdb_key_create_typed *req_lib_confdb_key_create
+	  = message;
+	coroipc_response_header_t res;
+	int ret = CS_OK;
+
+	if (api->object_key_create_typed(req_lib_confdb_key_create->object_handle,
+					    (char*)req_lib_confdb_key_create->key_name.value,
+					    req_lib_confdb_key_create->value.value,
+					    req_lib_confdb_key_create->value.length,
+					    req_lib_confdb_key_create->type))
+		ret = CS_ERR_ACCESS;
+
+	res.size = sizeof(res);
+	res.id = MESSAGE_RES_CONFDB_KEY_CREATE;
+	res.error = ret;
+	api->ipc_response_send(conn, &res, sizeof(res));
+}
+
 static void message_handler_req_lib_confdb_key_get (void *conn,
 						    const void *message)
 {
@@ -399,6 +438,35 @@ static void message_handler_req_lib_confdb_key_get (void *conn,
 	api->ipc_response_send(conn, &res_lib_confdb_key_get, sizeof(res_lib_confdb_key_get));
 }
 
+static void message_handler_req_lib_confdb_key_get_typed (void *conn,
+						    const void *message)
+{
+	const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
+	struct res_lib_confdb_key_get_typed res_lib_confdb_key_get;
+	size_t value_len;
+	void *value;
+	int ret = CS_OK;
+	objdb_value_types_t type;
+	char * key_name = (char*)req_lib_confdb_key_get->key_name.value;
+	key_name[req_lib_confdb_key_get->key_name.length] = '\0';
+
+	if (api->object_key_get_typed(req_lib_confdb_key_get->parent_object_handle,
+					 key_name,
+					 &value,
+					 &value_len, &type))
+		ret = CS_ERR_ACCESS;
+	else {
+		memcpy(res_lib_confdb_key_get.value.value, value, value_len);
+		res_lib_confdb_key_get.value.length = value_len;
+		res_lib_confdb_key_get.type = type;
+
+	}
+	res_lib_confdb_key_get.header.size = sizeof(res_lib_confdb_key_get);
+	res_lib_confdb_key_get.header.id = MESSAGE_RES_CONFDB_KEY_GET_TYPED;
+	res_lib_confdb_key_get.header.error = ret;
+	api->ipc_response_send(conn, &res_lib_confdb_key_get, sizeof(res_lib_confdb_key_get));
+}
+
 static void message_handler_req_lib_confdb_key_increment (void *conn,
 							  const void *message)
 {
@@ -529,6 +597,45 @@ static void message_handler_req_lib_confdb_key_iter (void *conn,
 	api->ipc_response_send(conn, &res_lib_confdb_key_iter, sizeof(res_lib_confdb_key_iter));
 }
 
+static void message_handler_req_lib_confdb_key_iter_typed (void *conn,
+						     const void *message)
+{
+	const struct req_lib_confdb_key_iter *req_lib_confdb_key_iter = message;
+	struct res_lib_confdb_key_iter_typed res_lib_confdb_key_iter;
+	void *key_name;
+	size_t key_name_len;
+	void *value;
+	size_t value_len;
+	int ret = CS_OK;
+	objdb_value_types_t my_type;
+
+	if (api->object_key_iter_from(req_lib_confdb_key_iter->parent_object_handle,
+					       req_lib_confdb_key_iter->next_entry,
+					       &key_name,
+					       &key_name_len,
+					       &value,
+					       &value_len))
+		ret = CS_ERR_ACCESS;
+	else {
+		memcpy(res_lib_confdb_key_iter.key_name.value, key_name, key_name_len);
+		memcpy(res_lib_confdb_key_iter.value.value, value, value_len);
+		res_lib_confdb_key_iter.key_name.length = key_name_len;
+		res_lib_confdb_key_iter.key_name.value[key_name_len] = '\0';
+		res_lib_confdb_key_iter.value.length = value_len;
+		api->object_key_get_typed(req_lib_confdb_key_iter->parent_object_handle,
+								(const char*)res_lib_confdb_key_iter.key_name.value,
+								&value,
+								&value_len,
+								&my_type);
+		res_lib_confdb_key_iter.type = my_type;
+	}
+	res_lib_confdb_key_iter.header.size = sizeof(res_lib_confdb_key_iter);
+	res_lib_confdb_key_iter.header.id = MESSAGE_RES_CONFDB_KEY_ITER_TYPED;
+	res_lib_confdb_key_iter.header.error = ret;
+
+	api->ipc_response_send(conn, &res_lib_confdb_key_iter, sizeof(res_lib_confdb_key_iter));
+}
+
 static void message_handler_req_lib_confdb_object_iter (void *conn,
 							const void *message)
 {

+ 50 - 14
tools/corosync-objctl.c

@@ -102,6 +102,43 @@ static confdb_callbacks_t callbacks = {
 static int debug = 0;
 static int action;
 
+static void print_key (char *key_name, void *value, size_t value_len, confdb_value_types_t type)
+{
+	switch (type) {
+		case CONFDB_VALUETYPE_INT16:
+			printf ("%s=%hd\n", key_name,
+					  *(int16_t*)value);
+			break;
+		case CONFDB_VALUETYPE_UINT16:
+			printf ("%s=%hu\n", key_name,
+					  *(uint16_t*)value);
+			break;
+		case CONFDB_VALUETYPE_INT32:
+			printf ("%s=%d\n", key_name,
+					  *(int32_t*)value);
+			break;
+		case CONFDB_VALUETYPE_UINT32:
+			printf ("%s=%u\n", key_name,
+					  *(uint32_t*)value);
+			break;
+		case CONFDB_VALUETYPE_INT64:
+			printf ("%s=%lld\n", key_name,
+					  *(int64_t*)value);
+			break;
+		case CONFDB_VALUETYPE_UINT64:
+			printf ("%s=%llu\n", key_name,
+					  *(uint64_t*)value);
+			break;
+		case CONFDB_VALUETYPE_STRING:
+			printf ("%s=%s\n", key_name, (char*)value);
+			break;
+		default:
+		case CONFDB_VALUETYPE_ANY:
+			printf ("%s=**binary**(%d)\n", key_name, type);
+			break;
+	}
+}
+
 /* Recursively dump the object tree */
 static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object_handle, char * parent_name)
 {
@@ -109,11 +146,11 @@ static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object
 	char object_name[OBJ_NAME_SIZE];
 	size_t object_name_len;
 	char key_name[OBJ_NAME_SIZE];
-	size_t key_name_len;
 	char key_value[OBJ_NAME_SIZE];
 	size_t key_value_len;
 	cs_error_t res;
 	int children_printed;
+	confdb_value_types_t type;
 
 	/* Show the keys */
 	res = confdb_key_iter_start(handle, parent_object_handle);
@@ -123,18 +160,17 @@ static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object
 	}
 	children_printed = 0;
 
-	while ( (res = confdb_key_iter(handle,
+	while ( (res = confdb_key_iter_typed(handle,
 								   parent_object_handle,
 								   key_name,
-								   &key_name_len,
 								   key_value,
-								   &key_value_len)) == CS_OK) {
-		key_name[key_name_len] = '\0';
+								   &key_value_len,
+								   &type)) == CS_OK) {
 		key_value[key_value_len] = '\0';
 		if (parent_name != NULL)
-			printf("%s%c%s=%s\n", parent_name, SEPERATOR,key_name, key_value);
-		else
-			printf("%s=%s\n", key_name, key_value);
+			printf("%s%c", parent_name, SEPERATOR);
+
+		print_key(key_name, key_value, key_value_len, type);
 
 		children_printed++;
 	}
@@ -404,6 +440,7 @@ static void write_key(confdb_handle_t handle, char * path_pt)
 	char old_key_value[OBJ_NAME_SIZE];
 	size_t old_key_value_len;
 	cs_error_t res;
+	confdb_value_types_t type;
 
 	/* find the parent object */
 	get_parent_name(path_pt, parent_name);
@@ -425,12 +462,11 @@ static void write_key(confdb_handle_t handle, char * path_pt)
 	}
 
 	/* get the current key */
-	res = confdb_key_get (handle,
+	res = confdb_key_get_typed (handle,
 						  obj_handle,
 						  key_name,
-						  strlen(key_name),
 						  old_key_value,
-						  &old_key_value_len);
+						  &old_key_value_len, &type);
 
 	if (res == CS_OK) {
 		/* replace the current value */
@@ -447,12 +483,12 @@ static void write_key(confdb_handle_t handle, char * path_pt)
 			fprintf(stderr, "Failed to replace the key %s=%s. Error %d\n", key_name, key_value, res);
 	} else {
 		/* not there, create a new key */
-		res = confdb_key_create (handle,
+		res = confdb_key_create_typed (handle,
 								 obj_handle,
 								 key_name,
-								 strlen(key_name),
 								 key_value,
-								 strlen(key_value));
+								 strlen(key_value),
+								 CONFDB_VALUETYPE_STRING);
 		if (res != CS_OK)
 			fprintf(stderr, "Failed to create the key %s=%s. Error %d\n", key_name, key_value, res);
 	}