diff --git a/exec/apidef.c b/exec/apidef.c index a8ae7519..37b0230b 100644 --- a/exec/apidef.c +++ b/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) diff --git a/exec/coroparse.c b/exec/coroparse.c index 5c4b3745..ba7e9540 100644 --- a/exec/coroparse.c +++ b/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, '}'))) { diff --git a/exec/objdb.c b/exec/objdb.c index 33688cba..0e4d6e9d 100644 --- a/exec/objdb.c +++ b/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; iiter_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] = { diff --git a/exec/service.c b/exec/service.c index 5cd60c35..d0c11c0b 100644 --- a/exec/service.c +++ b/exec/service.c @@ -183,29 +183,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 initialized '%s'\n", service->name); return (res); diff --git a/include/corosync/confdb.h b/include/corosync/confdb.h index e0797bb3..bb4f890e 100644 --- a/include/corosync/confdb.h +++ b/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 */ diff --git a/include/corosync/engine/coroapi.h b/include/corosync/engine/coroapi.h index e0d800ba..b860a4df 100644 --- a/include/corosync/engine/coroapi.h +++ b/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) ) diff --git a/include/corosync/engine/objdb.h b/include/corosync/engine/objdb.h index d26b6f7c..140753a8 100644 --- a/include/corosync/engine/objdb.h +++ b/include/corosync/engine/objdb.h @@ -41,6 +41,19 @@ #include #include +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 */ diff --git a/include/corosync/ipc_confdb.h b/include/corosync/ipc_confdb.h index c5c7c9bd..454d01e7 100644 --- a/include/corosync/ipc_confdb.h +++ b/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))); diff --git a/lib/confdb.c b/lib/confdb.c index 8a0d1597..797238ad 100644 --- a/lib/confdb.c +++ b/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, diff --git a/lib/sa-confdb.c b/lib/sa-confdb.c index 1178cff6..f44dc346 100644 --- a/lib/sa-confdb.c +++ b/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); diff --git a/lib/sa-confdb.h b/lib/sa-confdb.h index 102eaf5f..d9ea9063 100644 --- a/lib/sa-confdb.h +++ b/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, diff --git a/services/confdb.c b/services/confdb.c index c7c78086..64675f00 100644 --- a/services/confdb.c +++ b/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) { diff --git a/tools/corosync-objctl.c b/tools/corosync-objctl.c index 88098f3e..637f6954 100644 --- a/tools/corosync-objctl.c +++ b/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); }