[PATCH][flatiron] confdb: Fix crash with long values and add API calls to get them

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

 



confdb as it stands has a limit of 256 bytes in a returned value - anything larger than that will cause corosync to crash.

This patch adds checks toprevent this happening, fixes some API calls so that they return the full value and adds some new ones where it wasn't possible to safely return am arbitrarily long string.

It refers to Red Hat Bugzilla #845626 

 include/corosync/confdb.h     |   18 +++
 include/corosync/ipc_confdb.h |   54 +++++++++
 lib/confdb.c                  |  232 +++++++++++++++++++++++++++++++++++++-----
 lib/sa-confdb.c               |   33 ++++-
 lib/sa-confdb.h               |    6 -
 services/confdb.c             |  215 ++++++++++++++++++++++++++++++++++----
 tools/corosync-objctl.c       |   27 +++-
 7 files changed, 514 insertions(+), 71 deletions(-)

Signed-Off-By: Christine Caulfield <ccaulfie@xxxxxxxxxx>
diff --git a/include/corosync/confdb.h b/include/corosync/confdb.h
index ca0d7ba..6879383 100644
--- a/include/corosync/confdb.h
+++ b/include/corosync/confdb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -246,6 +246,14 @@ cs_error_t confdb_key_get_typed (
 	size_t *value_len,
 	confdb_value_types_t *type);
 
+cs_error_t confdb_key_get_typed2 (
+	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,
@@ -329,6 +337,14 @@ cs_error_t confdb_key_iter_typed (
 	size_t *value_len,
 	confdb_value_types_t *type);
 
+cs_error_t confdb_key_iter_typed2 (
+	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
  */
diff --git a/include/corosync/ipc_confdb.h b/include/corosync/ipc_confdb.h
index 856c8a6..709c677 100644
--- a/include/corosync/ipc_confdb.h
+++ b/include/corosync/ipc_confdb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -60,6 +60,10 @@ enum req_confdb_types {
 	MESSAGE_REQ_CONFDB_KEY_GET_TYPED = 18,
 	MESSAGE_REQ_CONFDB_KEY_ITER_TYPED = 19,
 	MESSAGE_REQ_CONFDB_OBJECT_NAME_GET = 20,
+	MESSAGE_REQ_CONFDB_KEY_ITER_TYPED2 = 21,
+	MESSAGE_REQ_CONFDB_KEY_REPLACE2 = 22,
+	MESSAGE_REQ_CONFDB_KEY_GET_TYPED2 = 23,
+	MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED2 = 24,
 };
 
 enum res_confdb_types {
@@ -87,6 +91,9 @@ enum res_confdb_types {
 	MESSAGE_RES_CONFDB_KEY_ITER_TYPED = 21,
 	MESSAGE_RES_CONFDB_RELOAD_CALLBACK = 22,
 	MESSAGE_RES_CONFDB_OBJECT_NAME_GET = 23,
+	MESSAGE_RES_CONFDB_KEY_ITER_TYPED2 = 24,
+	MESSAGE_RES_CONFDB_KEY_GET_TYPED2 = 25,
+	MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK2 = 26,
 };
 
 
@@ -141,6 +148,15 @@ struct req_lib_confdb_key_create_typed {
 	mar_int32_t type __attribute__((aligned(8)));
 };
 
+struct req_lib_confdb_key_create_typed2 {
+	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_int32_t type __attribute__((aligned(8)));
+	mar_int32_t value_length __attribute__((aligned(8)));
+	mar_uint8_t value __attribute__((aligned(8))); /* First byte of value */
+};
+
 struct req_lib_confdb_key_delete {
 	coroipc_request_header_t header __attribute__((aligned(8)));
 	mar_uint64_t object_handle __attribute__((aligned(8)));
@@ -251,6 +267,17 @@ struct res_lib_confdb_key_change_callback {
 	mar_name_t key_value __attribute__((aligned(8)));
 };
 
+struct res_lib_confdb_key_change_callback2 {
+	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_uint64_t change_type __attribute__((aligned(8)));
+	mar_uint64_t parent_object_handle __attribute__((aligned(8)));
+	mar_uint64_t object_handle __attribute__((aligned(8)));
+	mar_name_t object_name __attribute__((aligned(8)));
+	mar_name_t key_name __attribute__((aligned(8)));
+	mar_uint32_t key_value_length __attribute__((aligned(8)));
+	mar_uint8_t key_value __attribute__((aligned(8)));   /* First byte of new value */
+};
+
 struct res_lib_confdb_object_create_callback {
 	coroipc_response_header_t header __attribute__((aligned(8)));
 	mar_uint64_t parent_object_handle __attribute__((aligned(8)));
@@ -275,4 +302,29 @@ struct req_lib_confdb_object_track_start {
 	mar_uint32_t flags __attribute__((aligned(8)));
 };
 
+struct res_lib_confdb_key_get_typed2 {
+	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_int32_t type __attribute__((aligned(8)));
+	mar_uint32_t value_length __attribute__((aligned(8)));
+	mar_uint8_t value __attribute__((aligned(8)));
+	// Actual value follows this
+};
+
+struct res_lib_confdb_key_iter_typed2 {
+	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_name_t key_name __attribute__((aligned(8)));
+	mar_int32_t type __attribute__((aligned(8)));
+	mar_int32_t value_length __attribute__((aligned(8)));
+	mar_uint8_t value __attribute__((aligned(8))); /* First byte of value */
+};
+
+struct req_lib_confdb_key_replace2 {
+	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_int32_t new_value_length __attribute__((aligned(8)));
+	mar_uint8_t new_value __attribute__((aligned(8)));  /* First byte of new value */
+	/* Oddly objdb doesn't use the old value, so we don't bother sending it */
+};
+
 #endif /* IPC_CONFDB_H_DEFINED */
diff --git a/lib/confdb.c b/lib/confdb.c
index 1ea2ed0..0dbecb9 100644
--- a/lib/confdb.c
+++ b/lib/confdb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -358,6 +358,25 @@ cs_error_t confdb_dispatch (
 					res_key_changed_pt->key_value.length);
 				break;
 
+		        case MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK2:
+				if (callbacks.confdb_key_change_notify_fn == NULL) {
+					break;
+				}
+
+				res_key_changed_pt = (struct res_lib_confdb_key_change_callback *)dispatch_data;
+
+				callbacks.confdb_key_change_notify_fn(handle,
+					res_key_changed_pt->change_type,
+					res_key_changed_pt->object_handle,
+					res_key_changed_pt->parent_object_handle,
+					res_key_changed_pt->object_name.value,
+					res_key_changed_pt->object_name.length,
+					res_key_changed_pt->key_name.value,
+					res_key_changed_pt->key_name.length,
+					&res_key_changed_pt->key_value.value,
+					res_key_changed_pt->key_value.length);
+				break;
+
 			case MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK:
 				if (callbacks.confdb_object_create_change_notify_fn == NULL) {
 					break;
@@ -795,7 +814,7 @@ cs_error_t confdb_key_create_typed (
 	cs_error_t error;
 	struct confdb_inst *confdb_inst;
 	struct iovec iov;
-	struct req_lib_confdb_key_create_typed request;
+	struct req_lib_confdb_key_create_typed2 *request;
 	coroipc_response_header_t res;
 
 	error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
@@ -812,17 +831,23 @@ cs_error_t confdb_key_create_typed (
 		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;
+	request = malloc(sizeof(struct req_lib_confdb_key_create_typed2)+value_len);
+	if (!request) {
+		error = CS_ERR_NO_MEMORY;
+		goto error_exit;
+	}
 
-	iov.iov_base = (char *)&request;
-	iov.iov_len = sizeof (struct req_lib_confdb_key_create_typed);
+	request->header.size = sizeof (struct req_lib_confdb_key_create_typed2) + value_len;
+	request->header.id = MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED2;
+	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_len);
+	request->value_length = value_len;
+	request->type = type;
+
+	iov.iov_base = (char *)request;
+	iov.iov_len = request->header.size;
 
 	error = coroipcc_msg_send_reply_receive (
 		confdb_inst->handle,
@@ -989,7 +1014,7 @@ cs_error_t confdb_key_get_typed (
 		error = CS_OK;
 
 		if (confdb_sa_key_get_typed(parent_object_handle,
-				      key_name, value, value_len, (int*)type))
+				      key_name, &value, value_len, (int*)type))
 			error = CS_ERR_ACCESS;
 		goto error_exit;
 	}
@@ -1027,6 +1052,77 @@ error_exit:
 	return (error);
 }
 
+cs_error_t confdb_key_get_typed2 (
+	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_typed2 *response;
+	void *return_address;
+
+	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_TYPED2;
+	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_in_buf_get (
+		confdb_inst->handle,
+		&iov,
+		1,
+		&return_address);
+	response = return_address;
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+	error = response->header.error;
+
+	if (error == CS_OK) {
+		if (!*value) {
+			/* Allow space for naughty callers to put a NUL for printing */
+			*value = malloc(response->value_length+1);
+			if (!*value) {
+				error = CS_ERR_NO_MEMORY;
+				goto error_exit;
+			}
+		}
+		memcpy(*value, &response->value, response->value_length);
+		*value_len = response->value_length;
+		*type = response->type;
+	}
+
+error_exit:
+	(void)hdb_handle_put (&confdb_handle_t_db, handle);
+
+	return (error);
+
+}
+
 
 cs_error_t confdb_key_increment (
 	confdb_handle_t handle,
@@ -1159,7 +1255,7 @@ cs_error_t confdb_key_replace (
 	cs_error_t error;
 	struct confdb_inst *confdb_inst;
 	struct iovec iov;
-	struct req_lib_confdb_key_replace req_lib_confdb_key_replace;
+	struct req_lib_confdb_key_replace2 *req_lib_confdb_key_replace;
 	coroipc_response_header_t res;
 
 	error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
@@ -1177,18 +1273,19 @@ cs_error_t confdb_key_replace (
 			error = CS_ERR_ACCESS;
 		goto error_exit;
 	}
-	req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace);
-	req_lib_confdb_key_replace.header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE;
-	req_lib_confdb_key_replace.object_handle = parent_object_handle;
-	memcpy(req_lib_confdb_key_replace.key_name.value, key_name, key_name_len);
-	req_lib_confdb_key_replace.key_name.length = key_name_len;
-	memcpy(req_lib_confdb_key_replace.old_value.value, old_value, old_value_len);
-	req_lib_confdb_key_replace.old_value.length = old_value_len;
-	memcpy(req_lib_confdb_key_replace.new_value.value, new_value, new_value_len);
-	req_lib_confdb_key_replace.new_value.length = new_value_len;
 
-	iov.iov_base = (char *)&req_lib_confdb_key_replace;
-	iov.iov_len = sizeof (struct req_lib_confdb_key_replace);
+	req_lib_confdb_key_replace = malloc(sizeof(struct req_lib_confdb_key_replace2) + new_value_len);
+
+	req_lib_confdb_key_replace->header.size = sizeof(struct req_lib_confdb_key_replace2) + new_value_len;
+	req_lib_confdb_key_replace->header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE2;
+	req_lib_confdb_key_replace->object_handle = parent_object_handle;
+	memcpy(req_lib_confdb_key_replace->key_name.value, key_name, key_name_len);
+	req_lib_confdb_key_replace->key_name.length = key_name_len;
+	memcpy(&req_lib_confdb_key_replace->new_value, new_value, new_value_len);
+	req_lib_confdb_key_replace->new_value_length = new_value_len;
+	/* Oddly objdb doesn't use the old value, so we don't bother sending it */
+	iov.iov_base = (char *)req_lib_confdb_key_replace;
+	iov.iov_len = sizeof(struct req_lib_confdb_key_replace2) +  new_value_len;
 
         error = coroipcc_msg_send_reply_receive (
 		confdb_inst->handle,
@@ -1566,7 +1663,7 @@ cs_error_t confdb_key_iter_typed (
 		if (confdb_sa_key_iter_typed(parent_object_handle,
 				       context->next_entry,
 				       key_name,
-				       value, value_len, (int*)type))
+				       &value, value_len, (int*)type))
 			error = CS_ERR_ACCESS;
 		goto sa_exit;
 	}
@@ -1608,6 +1705,89 @@ error_exit:
 	return (error);
 }
 
+cs_error_t confdb_key_iter_typed2 (
+	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_typed2 *response;
+	void *return_address;
+
+	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_TYPED2;
+	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_in_buf_get (
+		confdb_inst->handle,
+		&iov,
+		1,
+		&return_address);
+	response = return_address;
+
+	if (error != CS_OK) {
+		goto error_exit;
+	}
+	error = response->header.error;
+
+	if (error == CS_OK) {
+		if (!*value) {
+			/* Allow space for naughty callers to put a NUL for printing */
+			*value = malloc(response->value_length+1);
+			if (!*value) {
+				error = CS_ERR_NO_MEMORY;
+				goto error_exit;
+			}
+		}
+		memcpy(key_name, response->key_name.value, response->key_name.length);
+		key_name[response->key_name.length] = '\0';
+		memcpy(*value, &response->value, response->value_length);
+		*value_len = response->value_length;
+		*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,
diff --git a/lib/sa-confdb.c b/lib/sa-confdb.c
index 03995e3..9a11418 100644
--- a/lib/sa-confdb.c
+++ b/lib/sa-confdb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009 Red Hat, Inc.
+ * Copyright (c) 2008, 2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -251,7 +251,7 @@ int confdb_sa_key_get (
 int confdb_sa_key_get_typed (
 	hdb_handle_t parent_object_handle,
 	const char *key_name,
-	void *value,
+	void **value,
 	size_t *value_len,
 	int *type)
 {
@@ -262,7 +262,15 @@ int confdb_sa_key_get_typed (
 				    key_name,
 				    &kvalue, value_len, (objdb_value_types_t*)type);
 	if (!res) {
-		memcpy(value, kvalue, *value_len);
+		if (!*value) {
+			*value = malloc(*value_len);
+			if (!*value) {
+				res = CS_ERR_NO_MEMORY;
+			}
+		}
+		if (*value) {
+			memcpy(*value, kvalue, *value_len);
+		}
 	}
 	return res;
 }
@@ -417,7 +425,7 @@ int confdb_sa_key_iter_typed (
 	hdb_handle_t parent_object_handle,
 	hdb_handle_t start_pos,
 	char *key_name,
-	void *value,
+	void **value,
 	size_t *value_len,
 	int *type)
 {
@@ -434,11 +442,18 @@ int confdb_sa_key_iter_typed (
 	if (!res) {
 		memcpy(key_name, kname, key_name_len);
 		key_name[key_name_len] = '\0';
-		memcpy(value, kvalue, *value_len);
-
-		objdb->object_key_get_typed(parent_object_handle,
-					  key_name,
-					  &kvalue, value_len, (objdb_value_types_t*)type);
+		if (!*value) {
+			*value = malloc(*value_len);
+			if (!*value) {
+				res = CS_ERR_NO_MEMORY;
+			}
+		}
+		if (*value) {
+			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;
 }
diff --git a/lib/sa-confdb.h b/lib/sa-confdb.h
index 61a0fa7..439c760 100644
--- a/lib/sa-confdb.h
+++ b/lib/sa-confdb.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009 Red Hat, Inc.
+ * Copyright (c) 2008, 2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -65,7 +65,7 @@ extern int confdb_sa_key_get(hdb_handle_t parent_object_handle,
 			     size_t *value_len);
 extern int confdb_sa_key_get_typed(hdb_handle_t parent_object_handle,
 			     const char *key_name,
-			     void *value,
+			     void **value,
 			     size_t *value_len,
 			     int *type);
 extern int confdb_sa_key_replace(hdb_handle_t parent_object_handle,
@@ -96,7 +96,7 @@ extern int confdb_sa_key_iter(hdb_handle_t parent_object_handle,
 extern int confdb_sa_key_iter_typed (hdb_handle_t parent_object_handle,
 				hdb_handle_t start_pos,
 				char *key_name,
-				void *value,
+				void **value,
 				size_t *value_len,
 				int *type);
 extern int confdb_sa_key_increment(hdb_handle_t parent_object_handle,
diff --git a/services/confdb.c b/services/confdb.c
index 39dbd93..1559604 100644
--- a/services/confdb.c
+++ b/services/confdb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -103,20 +103,33 @@ static void message_handler_req_lib_confdb_object_find_destroy (void *conn,
 static void message_handler_req_lib_confdb_key_create (void *conn,
 								const void *message);
 static void message_handler_req_lib_confdb_key_create_typed (void *conn,
-								const void *message);
+							const void *message);
+static void message_handler_req_lib_confdb_key_create_typed2 (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_get_typed2 (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_replace2 (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);
+					       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_iter_typed2 (void *conn,
+						      const void *message);
+
 static void message_handler_req_lib_confdb_key_increment (void *conn,
 							  const void *message);
 static void message_handler_req_lib_confdb_key_decrement (void *conn,
@@ -255,6 +268,22 @@ static struct corosync_lib_handler confdb_lib_engine[] =
 		.lib_handler_fn				= message_handler_req_lib_confdb_object_name_get,
 		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
 	},
+	{ /* 21 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_iter_typed2,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 22 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_replace2,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 23 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_get_typed2,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
+	{ /* 24 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_key_create_typed2,
+		.flow_control				= CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
 };
 
 
@@ -501,7 +530,11 @@ static void message_handler_req_lib_confdb_key_get (void *conn,
 					 &value_len))
 		ret = CS_ERR_ACCESS;
 	else {
-		memcpy(res_lib_confdb_key_get.value.value, value, value_len);
+		if (value_len > CS_MAX_NAME_LENGTH) {
+			ret = CS_ERR_TOO_BIG;
+		} else {
+			memcpy(res_lib_confdb_key_get.value.value, value, value_len);
+		}
 		res_lib_confdb_key_get.value.length = value_len;
 
 	}
@@ -529,10 +562,13 @@ static void message_handler_req_lib_confdb_key_get_typed (void *conn,
 					 &value_len, &type))
 		ret = CS_ERR_ACCESS;
 	else {
-		memcpy(res_lib_confdb_key_get.value.value, value, value_len);
+		if (value_len > CS_MAX_NAME_LENGTH) {
+			ret = CS_ERR_TOO_BIG;
+		} 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;
@@ -540,6 +576,42 @@ static void message_handler_req_lib_confdb_key_get_typed (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_typed2 (void *conn,
+						     const void *message)
+{
+	const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
+	struct res_lib_confdb_key_get_typed2 res_lib_confdb_key_get;
+	struct res_lib_confdb_key_get_typed2 *res = &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;
+		res->header.size = sizeof(res_lib_confdb_key_get);
+	}
+	else {
+		res = alloca(sizeof(struct res_lib_confdb_key_get_typed2) + value_len);
+
+		memcpy(&res->value, value, value_len);
+		res->value_length = value_len;
+		res->type = type;
+
+		res->header.size = sizeof(struct res_lib_confdb_key_get_typed2)+value_len;
+		res->header.error = ret;
+	}
+	res->header.id = MESSAGE_RES_CONFDB_KEY_GET_TYPED2;
+	res->header.error = ret;
+
+	api->ipc_response_send(conn, res, res->header.size);
+
+}
 static void message_handler_req_lib_confdb_key_increment (void *conn,
 							  const void *message)
 {
@@ -681,7 +753,11 @@ static void message_handler_req_lib_confdb_key_iter (void *conn,
 		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);
+		if (value_len > CS_MAX_NAME_LENGTH) {
+			ret = CS_ERR_TOO_BIG;
+		} else {
+			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.value.length = value_len;
 	}
@@ -713,7 +789,11 @@ static void message_handler_req_lib_confdb_key_iter_typed (void *conn,
 		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);
+		if (value_len > CS_MAX_NAME_LENGTH) {
+			ret = CS_ERR_TOO_BIG;
+		} else {
+			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;
@@ -731,6 +811,52 @@ static void message_handler_req_lib_confdb_key_iter_typed (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_typed2 (void *conn,
+						     const void *message)
+{
+	const struct req_lib_confdb_key_iter *req_lib_confdb_key_iter = message;
+	struct res_lib_confdb_key_iter_typed2 res_lib_confdb_key_iter;
+	struct res_lib_confdb_key_iter_typed2 *res = &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;
+		res->header.size = sizeof(res_lib_confdb_key_iter);
+		}
+	else {
+		res = alloca(sizeof(struct res_lib_confdb_key_iter_typed2) + value_len);
+
+		memcpy(res->key_name.value, key_name, key_name_len);
+		res->key_name.length = key_name_len;
+		res->key_name.value[key_name_len] = '\0';
+		memcpy(&res->value, value, value_len);
+		res->value_length = value_len;
+
+		api->object_key_get_typed(req_lib_confdb_key_iter->parent_object_handle,
+					  (const char*)res->key_name.value,
+					  &value,
+					  &value_len,
+					  &my_type);
+		res->type = my_type;
+
+		res->header.size = sizeof(res_lib_confdb_key_iter)+value_len;
+	}
+	res->header.id = MESSAGE_RES_CONFDB_KEY_ITER_TYPED2;
+	res->header.error = ret;
+
+	api->ipc_response_send(conn, res, res->header.size);
+}
+
 static void message_handler_req_lib_confdb_object_iter (void *conn,
 							const void *message)
 {
@@ -983,26 +1109,28 @@ static void confdb_notify_lib_of_key_change(object_change_type_t change_type,
 	const void *key_value_pt, size_t key_value_len,
 	void *priv_data_pt)
 {
-	struct res_lib_confdb_key_change_callback res;
+	struct res_lib_confdb_key_change_callback2 *res;
 
-	res.header.size = sizeof(res);
-	res.header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK;
-	res.header.error = CS_OK;
+	res = alloca(sizeof(struct res_lib_confdb_key_change_callback2) + key_value_len);
+
+	res->header.size = sizeof(struct res_lib_confdb_key_change_callback2) + key_value_len;
+	res->header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK2;
+	res->header.error = CS_OK;
 // handle & type
-	res.change_type = change_type;
-	res.parent_object_handle = parent_object_handle;
-	res.object_handle = object_handle;
+	res->change_type = change_type;
+	res->parent_object_handle = parent_object_handle;
+	res->object_handle = object_handle;
 //object
-	memcpy(res.object_name.value, object_name_pt, object_name_len);
-	res.object_name.length = object_name_len;
+	memcpy(res->object_name.value, object_name_pt, object_name_len);
+	res->object_name.length = object_name_len;
 //key name
-	memcpy(res.key_name.value, key_name_pt, key_name_len);
-	res.key_name.length = key_name_len;
+	memcpy(res->key_name.value, key_name_pt, key_name_len);
+	res->key_name.length = key_name_len;
 //key value
-	memcpy(res.key_value.value, key_value_pt, key_value_len);
-	res.key_value.length = key_value_len;
+	memcpy(&res->key_value, key_value_pt, key_value_len);
+	res->key_value_length = key_value_len;
 
-	ipc_dispatch_send_from_poll_thread(priv_data_pt, &res, sizeof(res));
+	ipc_dispatch_send_from_poll_thread(priv_data_pt, res, res->header.size);
 }
 
 static void confdb_notify_lib_of_new_object(hdb_handle_t parent_object_handle,
@@ -1090,3 +1218,46 @@ static void message_handler_req_lib_confdb_track_stop (void *conn,
 	res.error = CS_OK;
 	api->ipc_response_send(conn, &res, sizeof(res));
 }
+
+static void message_handler_req_lib_confdb_key_create_typed2 (void *conn,
+							const void *message)
+{
+	const struct req_lib_confdb_key_create_typed2 *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,
+					 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_replace2 (void *conn,
+							 const void *message)
+{
+	const struct req_lib_confdb_key_replace2 *req_lib_confdb_key_replace
+	  = message;
+	coroipc_response_header_t res;
+	int ret = CS_OK;
+
+	if (api->object_key_replace(req_lib_confdb_key_replace->object_handle,
+					     req_lib_confdb_key_replace->key_name.value,
+					     req_lib_confdb_key_replace->key_name.length,
+					     &req_lib_confdb_key_replace->new_value,
+					     req_lib_confdb_key_replace->new_value_length))
+		ret = CS_ERR_ACCESS;
+
+	res.size = sizeof(res);
+	res.id = MESSAGE_RES_CONFDB_KEY_REPLACE;
+	res.error = ret;
+	api->ipc_response_send(conn, &res, sizeof(res));
+}
diff --git a/tools/corosync-objctl.c b/tools/corosync-objctl.c
index d7909bb..3e2bd4c 100644
--- a/tools/corosync-objctl.c
+++ b/tools/corosync-objctl.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2008 Allied Telesis Labs NZ
+ *                 (c) 2012 Red Hat, Inc.
  *
  * All rights reserved.
  *
@@ -49,7 +50,7 @@
 
 #define SEPERATOR '.'
 #define SEPERATOR_STR "."
-#define OBJ_NAME_SIZE 512
+#define OBJ_NAME_SIZE 4096
 
 
 typedef enum {
@@ -183,7 +184,8 @@ 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];
-	char key_value[OBJ_NAME_SIZE];
+	char output_string[OBJ_NAME_SIZE];
+	char *key_value=NULL;/* Dynamically allocated value */
 	size_t key_value_len;
 	cs_error_t res;
 	int children_printed;
@@ -197,10 +199,10 @@ static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object
 	}
 	children_printed = 0;
 
-	while ( (res = confdb_key_iter_typed(handle,
+	while ( (res = confdb_key_iter_typed2(handle,
 								   parent_object_handle,
 								   key_name,
-								   key_value,
+					                           (void**)&key_value,
 								   &key_value_len,
 								   &type)) == CS_OK) {
 		key_value[key_value_len] = '\0';
@@ -208,6 +210,8 @@ static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object
 			printf("%s%c", parent_name, SEPERATOR);
 
 		print_key(key_name, key_value, key_value_len, type);
+		free(key_value);
+		key_value = NULL;
 
 		children_printed++;
 	}
@@ -227,12 +231,12 @@ static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object
 
 		object_name[object_name_len] = '\0';
 		if (parent_name != NULL) {
-			snprintf(key_value, OBJ_NAME_SIZE, "%s%c%s", parent_name, SEPERATOR, object_name);
+			snprintf(output_string, OBJ_NAME_SIZE, "%s%c%s", parent_name, SEPERATOR, object_name);
 		} else {
 			if ((action == ACTION_PRINT_DEFAULT) && strcmp(object_name, "internal_configuration") == 0) continue;
-			snprintf(key_value, OBJ_NAME_SIZE, "%s", object_name);
+			snprintf(output_string, OBJ_NAME_SIZE, "%s", object_name);
 		}
-		print_config_tree(handle, object_handle, key_value);
+		print_config_tree(handle, object_handle, output_string);
 		children_printed++;
 	}
 	if (children_printed == 0 && parent_name != NULL) {
@@ -489,6 +493,7 @@ static void write_key(confdb_handle_t handle, char * path_pt)
 	char key_name[OBJ_NAME_SIZE];
 	char key_value[OBJ_NAME_SIZE];
 	char old_key_value[OBJ_NAME_SIZE];
+	char *old_key_value_ptr = old_key_value;
 	size_t old_key_value_len;
 	cs_error_t res;
 	confdb_value_types_t type;
@@ -513,12 +518,16 @@ static void write_key(confdb_handle_t handle, char * path_pt)
 	}
 
 	/* get the current key */
-	res = confdb_key_get_typed (handle,
+	res = confdb_key_get_typed2 (handle,
 						  obj_handle,
 						  key_name,
-						  old_key_value,
+				                  (void**)&old_key_value_ptr,
 						  &old_key_value_len, &type);
 
+	if (debug == 1 && res==CS_OK)
+		printf ("%d: key:\"%s\", old value:\"%s\"\n",
+				__LINE__, key_name, old_key_value);
+
 	if (res == CS_OK) {
 		/* replace the current value */
 		res = confdb_key_replace (handle,
_______________________________________________
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