static void confdb_key_change_notify ( confdb_handle_t handle, confdb_change_type_t change_type, hdb_handle_t parent_object_handle, hdb_handle_t object_handle, const void *object_name, size_t object_name_len, const void *key_name, size_t key_name_len, const void *key_value, size_t key_value_len) { char str_val[255]; uint32_t val; int i; if (key_name_len == strlen(my_key_uint) && memcmp(key_name, my_key_uint, key_name_len) == 0) { expected_msgs_uint--; if (expected_msgs_uint == 0) { for (i = 0; i < burst_count; i++) { confdb_key_increment(handle, parent_object_handle, my_key_uint, strlen(my_key_uint), &val); } expected_msgs_uint = burst_count; } } if (key_name_len == strlen(my_key_str) && memcmp(key_name, my_key_str, key_name_len) == 0) { expected_msgs_str--; if (expected_msgs_str == 0) { memcpy(str_val, key_value, key_value_len); str_val[key_value_len] = '\0'; for (i = 0; i < burst_count; i++) { inc_str(str_val, key_value_len); confdb_key_replace(handle, parent_object_handle, my_key_str, strlen(my_key_str), NULL, 0, str_val, strlen(str_val)); } expected_msgs_str = burst_count; } } }
static int get_data(confdb_handle_t handle, hdb_handle_t connection_handle, hdb_handle_t query_handle, hdb_handle_t *list_handle, char **rtn, char *curpos, int list, int is_oldlist) { int cmp; char data[PATH_MAX]; char *resval; char *keyval; hdb_handle_t new_obj_handle; unsigned int value = 0; confdb_value_types_t type; size_t datalen = 0, keyvallen = PATH_MAX; memset(data, 0, PATH_MAX); // we need to handle child::*[int value] in non list mode. cmp = strcmp(curpos, "child::*"); if (cmp >= 0) { char *start = NULL, *end = NULL; // a pure child::* request should come down as list if (!cmp && !list) goto fail; if (confdb_object_iter_start(handle, query_handle) != CS_OK) goto fail; if (!is_oldlist) *list_handle = query_handle; if (cmp) { start = strstr(curpos, "["); if (!start) goto fail; start = start + 1; end = strstr(start, "]"); if (!end) goto fail; memset(end, 0, 1); value = atoi(start); if (value <= 0) goto fail; } else { if (confdb_key_increment (handle, connection_handle, "iterator_tracker", strlen("iterator_tracker"), &value) != CS_OK) value = 1; } while (value != 0) { memset(data, 0, PATH_MAX); if (confdb_object_iter (handle, query_handle, &new_obj_handle, data, &datalen) != CS_OK) { reset_iterator(handle, connection_handle); goto fail; } value--; } resval = malloc(datalen + 2); if (!resval) goto fail; snprintf(resval, datalen + 2, "%s=", data); *rtn = resval; } else if (!strncmp(curpos, "@*", strlen("@*"))) { // this query makes sense only if we are in list mode if (!list) goto fail; if (confdb_key_iter_start(handle, query_handle) != CS_OK) goto fail; *list_handle = query_handle; if (confdb_key_increment (handle, connection_handle, "iterator_tracker", strlen("iterator_tracker"), &value) != CS_OK) value = 1; while (value != 0) { memset(data, 0, PATH_MAX); keyval = NULL; if (confdb_key_iter_typed2 (handle, query_handle, data, (void **)&keyval, &keyvallen, &type) != CS_OK) { reset_iterator(handle, connection_handle); goto fail; } value--; if (value != 0) { free(keyval); keyval = NULL; } } datalen = strlen(data); resval = malloc(datalen + keyvallen + 2); if (!resval) goto fail; snprintf(resval, datalen + keyvallen + 2, "%s=%s", data, keyval); *rtn = resval; free(keyval); } else { /* pure data request */ char *query; // this query doesn't make sense in list mode if (list) goto fail; if (confdb_object_find_start(handle, query_handle) != CS_OK) goto fail; query = strstr(curpos, "@"); if (!query) goto fail; query = query + 1; keyval = NULL; if (confdb_key_get_typed2 (handle, query_handle, query, (void **)&keyval, &keyvallen, &type) != CS_OK) goto fail; *rtn = keyval; } return 0; fail: errno = EINVAL; return -1; }
static void do_write_tests(confdb_handle_t handle) { int res; unsigned int incdec_value; hdb_handle_t object_handle; char error_string[1024]; /* Add a scratch object and put some keys into it */ res = confdb_object_create(handle, OBJECT_PARENT_HANDLE, "testconfdb", strlen("testconfdb"), &object_handle); if (res != CS_OK) { printf( "error creating 'testconfdb' object: %d\n", res); return; } res = confdb_key_create(handle, object_handle, "testkey", strlen("testkey"), "one", strlen("one")); if (res != CS_OK) { printf( "error creating 'testconfdb' key 1: %d\n", res); return; } res = confdb_key_create(handle, object_handle, "testkey", strlen("testkey"), "two", strlen("two")); if (res != CS_OK) { printf( "error creating 'testconfdb' key 2: %d\n", res); return; } res = confdb_key_create(handle, object_handle, "grot", strlen("grot"), "perrins", strlen("perrins")); if (res != CS_OK) { printf( "error creating 'testconfdb' key 3: %d\n", res); return; } res = confdb_key_replace(handle, object_handle, "testkey", strlen("testkey"), "two", strlen("two"), "newtwo", strlen("newtwo")); if (res != CS_OK) { printf( "error replace 'testconfdb' key 2: %d\n", res); return; } /* Print it for verification */ print_config_tree(handle, object_handle, 0); incdec_value = INCDEC_VALUE; res = confdb_key_create(handle, object_handle, "incdec", strlen("incdec"), &incdec_value, sizeof(incdec_value)); if (res != CS_OK) { printf( "error creating 'testconfdb' key 4: %d\n", res); return; } res = confdb_key_increment(handle, object_handle, "incdec", strlen("incdec"), &incdec_value); if (res != CS_OK) { printf( "error incrementing 'testconfdb' key 4: %d\n", res); return; } if (incdec_value == INCDEC_VALUE+1) printf("incremented value = %d\n", incdec_value); else printf("ERROR: incremented value = %d (should be %d)\n", incdec_value, INCDEC_VALUE+1); res = confdb_key_decrement(handle, object_handle, "incdec", strlen("incdec"), &incdec_value); if (res != CS_OK) { printf( "error decrementing 'testconfdb' key 4: %d\n", res); return; } if (incdec_value == INCDEC_VALUE) printf("decremented value = %d\n", incdec_value); else printf("ERROR: decremented value = %d (should be %d)\n", incdec_value, INCDEC_VALUE); printf("-------------------------\n"); /* Remove it. Check that it doesn't exist when the full tree dump runs next */ res = confdb_object_destroy(handle, object_handle); if (res != CS_OK) { printf( "error destroying 'testconfdb' object: %d\n", res); return; } res = confdb_write(handle, error_string, sizeof error_string); printf("confdb_write returned %d: %s\n", res, error_string); }
int main(int argc, char *argv[]) { #ifdef USE_CONFDB confdb_handle_t handle; confdb_callbacks_t callbacks; hdb_handle_t object_handle; #endif #ifdef USE_CMAP cmap_handle_t handle; cmap_track_handle_t track_handle; int retries; cs_error_t result; #endif uint32_t u32; int status; int i; cs_error_t res; char str_val[255]; int ch; char *ep; change_uint32 = 0; change_str_len = 0; no_childs = 16; burst_count = 64; while ((ch = getopt(argc, argv, "hus:c:n:")) != -1) { switch (ch) { case 'u': change_uint32 = 1; break; case 's': change_str_len = strtol(optarg, &ep, 10); if (change_str_len <= 0 || *ep != '\0') { warnx("illegal number, -s argument -- %s", optarg); usage(); } break; case 'c': no_childs = strtol(optarg, &ep, 10); if (no_childs <= 0 || *ep != '\0') { warnx("illegal number, -c argument -- %s", optarg); usage(); } break; case 'n': burst_count = strtol(optarg, &ep, 10); if (burst_count <= 0 || *ep != '\0') { warnx("illegal number, -n argument -- %s", optarg); usage(); } break; case 'h': case '?': default: usage(); /* NOTREACHED */ } } signal(SIGPIPE, SIG_IGN); setlinebuf(stdout); #ifdef USE_CONFDB memset(&callbacks, 0, sizeof(callbacks)); assert(confdb_initialize(&handle, &callbacks) == CS_OK); assert(confdb_object_create(handle, OBJECT_PARENT_HANDLE, "testconfdb", strlen("testconfdb"), &object_handle) == CS_OK); assert(confdb_finalize(handle) == CS_OK); #endif my_id = create_childs(); u32 = my_id; #ifdef USE_CONFDB snprintf(my_key_uint, sizeof(my_key_uint), "testkeyu32id%u", my_id); snprintf(my_key_str, sizeof(my_key_str), "testkeystrid%u", my_id); #endif #ifdef USE_CMAP snprintf(my_key_uint, sizeof(my_key_uint), "testconfdb.testkeyu32id%u", my_id); snprintf(my_key_str, sizeof(my_key_str), "testconfdb.testkeystrid%u", my_id); #endif for (i = 0; i < change_str_len; i++) { str_val[i] = ((my_id + i) % ('Z' - 'A' + 1)) + 'A'; } str_val[i] = '\0'; if (my_id > 0) { #ifdef USE_CONFDB memset(&callbacks, 0, sizeof(callbacks)); callbacks.confdb_key_change_notify_fn = confdb_key_change_notify; assert(confdb_initialize(&handle, &callbacks) == CS_OK); #endif #ifdef USE_CMAP retries = 0; cs_repeat(retries, 30, result = cmap_initialize(&handle)); assert(result == CS_OK); #endif if (change_uint32) { #ifdef USE_CONFDB assert(confdb_key_create_typed(handle, object_handle, my_key_uint, &u32, sizeof(u32), CONFDB_VALUETYPE_UINT32) == CS_OK); #endif #ifdef USE_CMAP assert(cmap_set_uint32(handle, my_key_uint, u32) == CS_OK); #endif } if (change_str_len > 0) { #ifdef USE_CONFDB assert(confdb_key_create_typed(handle, object_handle, my_key_str, str_val, strlen(str_val), CONFDB_VALUETYPE_STRING) == CS_OK); #endif #ifdef USE_CMAP assert(cmap_set_string(handle, my_key_str, str_val) == CS_OK); #endif } } else { /* * "Wait" for other processes to initialize */ poll(NULL, 0, 1000); printf("Confdb-track-and-change initialization finished\n"); } if (my_id > 0) { signal(SIGINT, sigint_handler_child); #ifdef USE_CONFDB assert(confdb_track_changes(handle, object_handle, OBJECT_KEY_REPLACED) == CS_OK); #endif #ifdef USE_CMAP assert(cmap_track_add(handle, "testconfdb.", CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX, cmap_notify, NULL, &track_handle) == CS_OK); #endif if (change_uint32) { #ifdef USE_CONFDB assert(confdb_key_increment(handle, object_handle, my_key_uint, strlen(my_key_uint), &u32) == CS_OK); #endif #ifdef USE_CMAP assert(cmap_inc(handle, my_key_uint) == CS_OK); #endif expected_msgs_uint = 1; } if (change_str_len > 0) { inc_str(str_val, change_str_len); #ifdef USE_CONFDB assert(confdb_key_replace(handle, object_handle, my_key_str, strlen(my_key_str), NULL, 0, str_val, strlen(str_val)) == CS_OK); #endif #ifdef USE_CMAP assert(cmap_set_string(handle, my_key_str, str_val) == CS_OK); #endif expected_msgs_str = 1; } /* * Give other processes a little time to initialize */ poll(NULL, 0, 250); do { #ifdef USE_CONFDB res = confdb_dispatch(handle, CS_DISPATCH_BLOCKING); #endif #ifdef USE_CMAP res = cmap_dispatch(handle, CS_DISPATCH_BLOCKING); #endif } while (res == CS_OK || res == CS_ERR_TRY_AGAIN); } else { signal(SIGINT, sigint_handler_parent); for (i = 0; i < no_childs; i++) { wait(&status); } #ifdef USE_CONFDB confdb_object_destroy(handle, object_handle); #endif printf("Confdb-track-and-change finalization finished\n"); } return (0); }