X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=svm%2Fsvmdb.c;h=03dfe7c33d3c85c8245aaf9ee02b5450cb981970;hb=f07dc9e236506f50a0230e6680cf1402dea6a976;hp=481224a6742972a32f7bc675f1af6c74bb287431;hpb=f1213b82771ce929c076339c24a777cfd59690e6;p=vpp.git diff --git a/svm/svmdb.c b/svm/svmdb.c index 481224a6742..03dfe7c33d3 100644 --- a/svm/svmdb.c +++ b/svm/svmdb.c @@ -1,4 +1,4 @@ -/* +/* *------------------------------------------------------------------ * svmdb.c -- simple shared memory database * @@ -39,482 +39,633 @@ #include #include #include +#include #include "svmdb.h" -static void local_set_variable_nolock (svmdb_client_t *client, - svmdb_namespace_t namespace, - u8 * var, u8 * val, u32 elsize); +static void local_set_variable_nolock (svmdb_client_t * client, + svmdb_namespace_t namespace, + u8 * var, u8 * val, u32 elsize); -always_inline void region_lock(svm_region_t *rp, int tag) +always_inline void +region_lock (svm_region_t * rp, int tag) { - pthread_mutex_lock(&rp->mutex); + pthread_mutex_lock (&rp->mutex); #ifdef MUTEX_DEBUG - rp->mutex_owner_pid = getpid(); - rp->mutex_owner_tag = tag; -#endif + rp->mutex_owner_pid = getpid (); + rp->mutex_owner_tag = tag; +#endif } -always_inline void region_unlock(svm_region_t *rp) +always_inline void +region_unlock (svm_region_t * rp) { #ifdef MUTEX_DEBUG - rp->mutex_owner_pid = 0; - rp->mutex_owner_tag = 0; -#endif - pthread_mutex_unlock(&rp->mutex); + rp->mutex_owner_pid = 0; + rp->mutex_owner_tag = 0; +#endif + pthread_mutex_unlock (&rp->mutex); } -static svmdb_client_t *svmdb_map_internal (char *root_path, uword size) +svmdb_client_t * +svmdb_map (svmdb_map_args_t * dba) { - svmdb_client_t *client = 0; - svm_map_region_args_t *a = 0; - svm_region_t *db_rp; - void *oldheap; - svmdb_shm_hdr_t *hp = 0; - - vec_validate (client, 0); - vec_validate (a, 0); - - svm_region_init_chroot(root_path); - - a->root_path = root_path; - a->name = "/db"; - a->size = size ? size : SVMDB_DEFAULT_SIZE; - a->flags = SVM_FLAGS_MHEAP; - - db_rp = client->db_rp = svm_region_find_or_create (a); - - ASSERT(db_rp); - - vec_free (a); - - region_lock (client->db_rp, 10); - /* Has someone else set up the shared-memory variable table? */ - if (db_rp->user_ctx) { - client->shm = (void *) db_rp->user_ctx; - client->pid = getpid(); - region_unlock (client->db_rp); - ASSERT (client->shm->version == SVMDB_SHM_VERSION); - return (client); + svmdb_client_t *client = 0; + svm_map_region_args_t *a = 0; + svm_region_t *db_rp; + void *oldheap; + svmdb_shm_hdr_t *hp = 0; + + vec_validate (client, 0); + vec_validate (a, 0); + + svm_region_init_chroot_uid_gid (dba->root_path, dba->uid, dba->gid); + + a->root_path = dba->root_path; + a->name = "/db"; + a->size = dba->size ? dba->size : SVMDB_DEFAULT_SIZE; + a->flags = SVM_FLAGS_MHEAP; + a->uid = dba->uid; + a->gid = dba->gid; + + db_rp = client->db_rp = svm_region_find_or_create (a); + + ASSERT (db_rp); + + vec_free (a); + + region_lock (client->db_rp, 10); + /* Has someone else set up the shared-memory variable table? */ + if (db_rp->user_ctx) + { + client->shm = (void *) db_rp->user_ctx; + client->pid = getpid (); + region_unlock (client->db_rp); + ASSERT (client->shm->version == SVMDB_SHM_VERSION); + return (client); } - /* Nope, it's our problem... */ - - /* Add a bogus client (pid=0) so the svm won't be deallocated */ - oldheap = svm_push_pvt_heap (db_rp); - vec_add1(client->db_rp->client_pids, 0); - svm_pop_heap (oldheap); - - oldheap = svm_push_data_heap (db_rp); - - vec_validate(hp, 0); - hp->version = SVMDB_SHM_VERSION; - hp->namespaces[SVMDB_NAMESPACE_STRING] - = hash_create_string(0, sizeof(uword)); - hp->namespaces[SVMDB_NAMESPACE_VEC] - = hash_create_string(0, sizeof(uword)); - - db_rp->user_ctx = hp; - client->shm = hp; - - svm_pop_heap (oldheap); - region_unlock (client->db_rp); - client->pid = getpid(); - - return (client); -} -svmdb_client_t *svmdb_map (void) -{ - return svmdb_map_internal (0, 0); -} + /* Nope, it's our problem... */ -svmdb_client_t *svmdb_map_size (uword size) -{ - return svmdb_map_internal (0, size); -} + /* Add a bogus client (pid=0) so the svm won't be deallocated */ + oldheap = svm_push_pvt_heap (db_rp); + vec_add1 (client->db_rp->client_pids, 0); + svm_pop_heap (oldheap); -svmdb_client_t *svmdb_map_chroot (char *root_path) -{ - return svmdb_map_internal (root_path, 0); -} + oldheap = svm_push_data_heap (db_rp); -svmdb_client_t *svmdb_map_chroot_size (char *root_path, uword size) -{ - return svmdb_map_internal (root_path, size); + vec_validate (hp, 0); + hp->version = SVMDB_SHM_VERSION; + hp->namespaces[SVMDB_NAMESPACE_STRING] + = hash_create_string (0, sizeof (uword)); + hp->namespaces[SVMDB_NAMESPACE_VEC] + = hash_create_string (0, sizeof (uword)); + + db_rp->user_ctx = hp; + client->shm = hp; + + svm_pop_heap (oldheap); + region_unlock (client->db_rp); + client->pid = getpid (); + + return (client); } -void svmdb_unmap (svmdb_client_t *client) +void +svmdb_unmap (svmdb_client_t * client) { - ASSERT(client); + ASSERT (client); - if (! svm_get_root_rp()) - return; + if (!svm_get_root_rp ()) + return; - svm_region_unmap ((void *) client->db_rp); - svm_region_exit (); - vec_free(client); + svm_region_unmap ((void *) client->db_rp); + svm_region_exit (); + vec_free (client); } -static void notify_value (svmdb_value_t * v, svmdb_action_t a) +static void +notify_value (svmdb_value_t * v, svmdb_action_t a) { - int i; - int rv; - union sigval sv; - u32 value; - u32 *dead_registrations = 0; - - svmdb_notify_t *np; - - for (i = 0; i < vec_len (v->notifications); i++) { - np = vec_elt_at_index (v->notifications, i); - if (np->action == a) { - value = (np->action<<28) | (np->opaque); - sv.sival_ptr = (void *)(uword)value; - do { - rv = 0; - if (sigqueue (np->pid, np->signum, sv) == 0) - break; - rv = errno; - } while (rv == EAGAIN); - if (rv == 0) - continue; - vec_add1 (dead_registrations, i); - } + int i; + int rv; + union sigval sv; + u32 value; + u32 *dead_registrations = 0; + + svmdb_notify_t *np; + + for (i = 0; i < vec_len (v->notifications); i++) + { + np = vec_elt_at_index (v->notifications, i); + if (np->action == a) + { + value = (np->action << 28) | (np->opaque); + sv.sival_ptr = (void *) (uword) value; + do + { + rv = 0; + if (sigqueue (np->pid, np->signum, sv) == 0) + break; + rv = errno; + } + while (rv == EAGAIN); + if (rv == 0) + continue; + vec_add1 (dead_registrations, i); + } } - for (i = 0; i < vec_len (dead_registrations); i++) { - np = vec_elt_at_index (v->notifications, dead_registrations[i]); - clib_warning ("dead reg pid %d sig %d action %d opaque %x", - np->pid, np->signum, np->action, np->opaque); - vec_delete (v->notifications, 1, dead_registrations[i]); + for (i = 0; i < vec_len (dead_registrations); i++) + { + np = vec_elt_at_index (v->notifications, dead_registrations[i]); + clib_warning ("dead reg pid %d sig %d action %d opaque %x", + np->pid, np->signum, np->action, np->opaque); + vec_delete (v->notifications, 1, dead_registrations[i]); } - vec_free (dead_registrations); + vec_free (dead_registrations); } -int svmdb_local_add_del_notification (svmdb_client_t *client, - svmdb_notification_args_t *a) +int +svmdb_local_add_del_notification (svmdb_client_t * client, + svmdb_notification_args_t * a) { - uword *h; - void *oldheap; - hash_pair_t *hp; - svmdb_shm_hdr_t * shm; - u8 *dummy_value = 0; - svmdb_value_t *value; - svmdb_notify_t *np; - int i; - int rv = 0; - - ASSERT (a->elsize); - - region_lock (client->db_rp, 18); - shm = client->shm; - oldheap = svm_push_data_heap (client->db_rp); - - h = shm->namespaces[a->nspace]; - - hp = hash_get_pair_mem (h, a->var); - if (hp == 0) { - local_set_variable_nolock (client, a->nspace, (u8 *)a->var, - dummy_value, a->elsize); - /* might have moved */ - h = shm->namespaces[a->nspace]; - hp = hash_get_pair_mem (h, a->var); - ASSERT(hp); + uword *h; + void *oldheap; + hash_pair_t *hp; + svmdb_shm_hdr_t *shm; + u8 *dummy_value = 0; + svmdb_value_t *value; + svmdb_notify_t *np; + int i; + int rv = 0; + + ASSERT (a->elsize); + + region_lock (client->db_rp, 18); + shm = client->shm; + oldheap = svm_push_data_heap (client->db_rp); + + h = shm->namespaces[a->nspace]; + + hp = hash_get_pair_mem (h, a->var); + if (hp == 0) + { + local_set_variable_nolock (client, a->nspace, (u8 *) a->var, + dummy_value, a->elsize); + /* might have moved */ + h = shm->namespaces[a->nspace]; + hp = hash_get_pair_mem (h, a->var); + ASSERT (hp); } - - value = pool_elt_at_index (shm->values, hp->value[0]); - - for (i = 0; i < vec_len (value->notifications); i++) { - np = vec_elt_at_index (value->notifications, i); - if ((np->pid == client->pid) - && (np->signum == a->signum) - && (np->action == a->action) - && (np->opaque == a->opaque)) { - if (a->add_del == 0 /* delete */) { - vec_delete (value->notifications, 1, i); - goto out; - } else { /* add */ - clib_warning ( - "%s: ignore dup reg pid %d signum %d action %d opaque %x", - a->var, client->pid, a->signum, a->action, a->opaque); - rv = -2; - goto out; - } - } + + value = pool_elt_at_index (shm->values, hp->value[0]); + + for (i = 0; i < vec_len (value->notifications); i++) + { + np = vec_elt_at_index (value->notifications, i); + if ((np->pid == client->pid) + && (np->signum == a->signum) + && (np->action == a->action) && (np->opaque == a->opaque)) + { + if (a->add_del == 0 /* delete */ ) + { + vec_delete (value->notifications, 1, i); + goto out; + } + else + { /* add */ + clib_warning + ("%s: ignore dup reg pid %d signum %d action %d opaque %x", + a->var, client->pid, a->signum, a->action, a->opaque); + rv = -2; + goto out; + } + } } - if (a->add_del == 0) { - rv = -3; - goto out; + if (a->add_del == 0) + { + rv = -3; + goto out; } - - vec_add2 (value->notifications, np, 1); - np->pid = client->pid; - np->signum = a->signum; - np->action = a->action; - np->opaque = a->opaque; + + vec_add2 (value->notifications, np, 1); + np->pid = client->pid; + np->signum = a->signum; + np->action = a->action; + np->opaque = a->opaque; out: - svm_pop_heap(oldheap); - region_unlock (client->db_rp); - return rv; + svm_pop_heap (oldheap); + region_unlock (client->db_rp); + return rv; } -static void local_unset_variable_nolock (svmdb_client_t *client, - svmdb_namespace_t namespace, - char * var) +static void +local_unset_variable_nolock (svmdb_client_t * client, + svmdb_namespace_t namespace, char *var) { - uword *h; - svmdb_value_t *oldvalue; - hash_pair_t *hp; - - h = client->shm->namespaces[namespace]; - hp = hash_get_pair_mem (h, var); - if (hp) { - oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]); - if (vec_len (oldvalue->notifications)) - notify_value (oldvalue, SVMDB_ACTION_UNSET); - /* zero length value means unset */ - _vec_len (oldvalue->value) = 0; + uword *h; + svmdb_value_t *oldvalue; + hash_pair_t *hp; + + h = client->shm->namespaces[namespace]; + hp = hash_get_pair_mem (h, var); + if (hp) + { + oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]); + if (vec_len (oldvalue->notifications)) + notify_value (oldvalue, SVMDB_ACTION_UNSET); + /* zero length value means unset */ + _vec_len (oldvalue->value) = 0; } - client->shm->namespaces[namespace] = h; + client->shm->namespaces[namespace] = h; } -void svmdb_local_unset_string_variable (svmdb_client_t *client, char *var) +void +svmdb_local_unset_string_variable (svmdb_client_t * client, char *var) { - void *oldheap; + void *oldheap; - region_lock (client->db_rp, 11); - oldheap = svm_push_data_heap (client->db_rp); - local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var); - svm_pop_heap(oldheap); - region_unlock (client->db_rp); + region_lock (client->db_rp, 11); + oldheap = svm_push_data_heap (client->db_rp); + local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var); + svm_pop_heap (oldheap); + region_unlock (client->db_rp); } -static void local_set_variable_nolock (svmdb_client_t *client, - svmdb_namespace_t namespace, - u8 * var, u8 * val, u32 elsize) +static void +local_set_variable_nolock (svmdb_client_t * client, + svmdb_namespace_t namespace, + u8 * var, u8 * val, u32 elsize) { - uword *h; - hash_pair_t *hp; - u8 *name; - svmdb_shm_hdr_t * shm; - - shm = client->shm; - h = shm->namespaces[namespace]; - hp = hash_get_pair_mem (h, var); - if (hp) { - svmdb_value_t * oldvalue; - oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]); - vec_alloc (oldvalue->value, vec_len(val)*elsize); - clib_memcpy (oldvalue->value, val, vec_len(val)*elsize); - _vec_len (oldvalue->value) = vec_len(val); - notify_value (oldvalue, SVMDB_ACTION_SET); - } else { - svmdb_value_t * newvalue; - pool_get (shm->values, newvalue); - memset (newvalue, 0, sizeof (*newvalue)); - newvalue->elsize = elsize; - vec_alloc (newvalue->value, vec_len(val)*elsize); - clib_memcpy (newvalue->value, val, vec_len(val)*elsize); - _vec_len (newvalue->value) = vec_len(val); - name = format (0, "%s%c", var, 0); - hash_set_mem (h, name, newvalue - shm->values); + uword *h; + hash_pair_t *hp; + u8 *name; + svmdb_shm_hdr_t *shm; + + shm = client->shm; + h = shm->namespaces[namespace]; + hp = hash_get_pair_mem (h, var); + if (hp) + { + svmdb_value_t *oldvalue; + oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]); + vec_alloc (oldvalue->value, vec_len (val) * elsize); + clib_memcpy (oldvalue->value, val, vec_len (val) * elsize); + _vec_len (oldvalue->value) = vec_len (val); + notify_value (oldvalue, SVMDB_ACTION_SET); + } + else + { + svmdb_value_t *newvalue; + pool_get (shm->values, newvalue); + memset (newvalue, 0, sizeof (*newvalue)); + newvalue->elsize = elsize; + vec_alloc (newvalue->value, vec_len (val) * elsize); + clib_memcpy (newvalue->value, val, vec_len (val) * elsize); + _vec_len (newvalue->value) = vec_len (val); + name = format (0, "%s%c", var, 0); + hash_set_mem (h, name, newvalue - shm->values); } - shm->namespaces[namespace] = h; + shm->namespaces[namespace] = h; } -void svmdb_local_set_string_variable (svmdb_client_t *client, - char *var, char *val) +void +svmdb_local_set_string_variable (svmdb_client_t * client, + char *var, char *val) { - void *oldheap; + void *oldheap; - region_lock (client->db_rp, 12); - oldheap = svm_push_data_heap (client->db_rp); + region_lock (client->db_rp, 12); + oldheap = svm_push_data_heap (client->db_rp); - local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var); + local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var); - local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING, - (u8 *) var, (u8 *) val, 1 /* elsize */); - svm_pop_heap(oldheap); - region_unlock (client->db_rp); + local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING, + (u8 *) var, (u8 *) val, 1 /* elsize */ ); + svm_pop_heap (oldheap); + region_unlock (client->db_rp); } -static u8 * local_get_variable_nolock (svmdb_client_t *client, - svmdb_namespace_t namespace, - u8 * var) +static u8 * +local_get_variable_nolock (svmdb_client_t * client, + svmdb_namespace_t namespace, u8 * var) { - uword *h; - uword *p; - svmdb_shm_hdr_t * shm; - svmdb_value_t *oldvalue; - - shm = client->shm; - h = shm->namespaces[namespace]; - p = hash_get_mem (h, var); - if (p) { - oldvalue = pool_elt_at_index (shm->values, p[0]); - notify_value (oldvalue, SVMDB_ACTION_GET); - return (oldvalue->value); + uword *h; + uword *p; + svmdb_shm_hdr_t *shm; + svmdb_value_t *oldvalue; + + shm = client->shm; + h = shm->namespaces[namespace]; + p = hash_get_mem (h, var); + if (p) + { + oldvalue = pool_elt_at_index (shm->values, p[0]); + notify_value (oldvalue, SVMDB_ACTION_GET); + return (oldvalue->value); } - return 0; + return 0; } -void *svmdb_local_get_variable_reference (svmdb_client_t *client, - svmdb_namespace_t namespace, - char *var) +void * +svmdb_local_get_variable_reference (svmdb_client_t * client, + svmdb_namespace_t namespace, char *var) { - u8 *rv; + u8 *rv; - region_lock (client->db_rp, 19); - rv = local_get_variable_nolock (client, namespace, (u8 *)var); - region_unlock (client->db_rp); - return (void *)rv; + region_lock (client->db_rp, 19); + rv = local_get_variable_nolock (client, namespace, (u8 *) var); + region_unlock (client->db_rp); + return (void *) rv; } -char *svmdb_local_get_string_variable (svmdb_client_t *client, char *var) +char * +svmdb_local_get_string_variable (svmdb_client_t * client, char *var) { - u8 *rv = 0; + u8 *rv = 0; - region_lock (client->db_rp, 13); - rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_STRING, (u8 *) var); + region_lock (client->db_rp, 13); + rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_STRING, (u8 *) var); - if (rv && vec_len (rv)) { - rv = format (0, "%s", rv); - vec_add1(rv, 0); + if (rv && vec_len (rv)) + { + rv = format (0, "%s", rv); + vec_add1 (rv, 0); } - region_unlock (client->db_rp); - return ((char *) rv); + region_unlock (client->db_rp); + return ((char *) rv); } -void svmdb_local_dump_strings (svmdb_client_t *client) +void +svmdb_local_dump_strings (svmdb_client_t * client) { - uword *h; - u8 *key; - u32 value; - svmdb_shm_hdr_t *shm = client->shm; - - region_lock (client->db_rp, 14); - - h = client->shm->namespaces [SVMDB_NAMESPACE_STRING]; - - hash_foreach_mem(key, value, h, - ({ - svmdb_value_t *v = pool_elt_at_index (shm->values, value); - - fformat(stdout, "%s: %s\n", key, - vec_len(v->value) ? v->value : (u8 *)"(nil)"); - })); - region_unlock (client->db_rp); + uword *h; + u8 *key; + u32 value; + svmdb_shm_hdr_t *shm = client->shm; + + region_lock (client->db_rp, 14); + + h = client->shm->namespaces[SVMDB_NAMESPACE_STRING]; + + /* *INDENT-OFF* */ + hash_foreach_mem(key, value, h, + ({ + svmdb_value_t *v = pool_elt_at_index (shm->values, value); + + fformat(stdout, "%s: %s\n", key, + vec_len(v->value) ? v->value : (u8 *)"(nil)"); + })); + /* *INDENT-ON* */ + region_unlock (client->db_rp); } -void svmdb_local_unset_vec_variable (svmdb_client_t *client, char *var) +int +svmdb_local_serialize_strings (svmdb_client_t * client, char *filename) { - void *oldheap; + uword *h; + u8 *key; + u32 value; + svmdb_shm_hdr_t *shm = client->shm; + serialize_main_t _sm, *sm = &_sm; + clib_error_t *error = 0; + u8 *sanitized_name = 0; + int fd = 0; + + if (strstr (filename, "..") || index (filename, '/')) + { + error = clib_error_return (0, "Illegal characters in filename '%s'", + filename); + goto out; + } + + sanitized_name = format (0, "/tmp/%s%c", filename, 0); + + fd = creat ((char *) sanitized_name, 0644); + + if (fd < 0) + { + error = clib_error_return_unix (0, "Create '%s'", sanitized_name); + goto out; + } + + serialize_open_unix_file_descriptor (sm, fd); + + region_lock (client->db_rp, 20); + + h = client->shm->namespaces[SVMDB_NAMESPACE_STRING]; + + serialize_likely_small_unsigned_integer (sm, hash_elts (h)); + + /* *INDENT-OFF* */ + hash_foreach_mem(key, value, h, + ({ + svmdb_value_t *v = pool_elt_at_index (shm->values, value); - region_lock (client->db_rp, 15); - oldheap = svm_push_data_heap (client->db_rp); - local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var); - svm_pop_heap(oldheap); - region_unlock (client->db_rp); + /* Omit names with nil values */ + if (vec_len(v->value)) + { + serialize_cstring (sm, (char *)key); + serialize_cstring (sm, (char *)v->value); + } + })); + /* *INDENT-ON* */ + region_unlock (client->db_rp); + + serialize_close (sm); + +out: + if (fd > 0 && close (fd) < 0) + error = clib_error_return_unix (0, "close fd %d", fd); + + if (error) + { + clib_error_report (error); + return -1; + } + return 0; } -void svmdb_local_set_vec_variable (svmdb_client_t *client, - char *var, void *val_arg, u32 elsize) +int +svmdb_local_unserialize_strings (svmdb_client_t * client, char *filename) { - u8 *val = (u8 *)val_arg; - void *oldheap; + serialize_main_t _sm, *sm = &_sm; + void *oldheap; + clib_error_t *error = 0; + u8 *key, *value; + int fd = 0; + u32 nelts; + int i; + + fd = open (filename, O_RDONLY); + + if (fd < 0) + { + error = clib_error_return_unix (0, "Failed to open '%s'", filename); + goto out; + } + + unserialize_open_unix_file_descriptor (sm, fd); + + region_lock (client->db_rp, 21); + oldheap = svm_push_data_heap (client->db_rp); + + nelts = unserialize_likely_small_unsigned_integer (sm); + + for (i = 0; i < nelts; i++) + { + unserialize_cstring (sm, (char **) &key); + unserialize_cstring (sm, (char **) &value); + local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING, + key, value, 1 /* elsize */ ); + vec_free (key); + vec_free (value); + } + svm_pop_heap (oldheap); + region_unlock (client->db_rp); + + serialize_close (sm); + +out: + if (fd > 0 && close (fd) < 0) + error = clib_error_return_unix (0, "close fd %d", fd); - region_lock (client->db_rp, 16); - oldheap = svm_push_data_heap (client->db_rp); + if (error) + { + clib_error_report (error); + return -1; + } + return 0; +} - local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var); - local_set_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var, - val, elsize); +void +svmdb_local_unset_vec_variable (svmdb_client_t * client, char *var) +{ + void *oldheap; - svm_pop_heap(oldheap); - region_unlock (client->db_rp); + region_lock (client->db_rp, 15); + oldheap = svm_push_data_heap (client->db_rp); + local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var); + svm_pop_heap (oldheap); + region_unlock (client->db_rp); } -void *svmdb_local_get_vec_variable (svmdb_client_t *client, char *var, - u32 elsize) +void +svmdb_local_set_vec_variable (svmdb_client_t * client, + char *var, void *val_arg, u32 elsize) { - u8 *rv = 0; - u8 *copy = 0; + u8 *val = (u8 *) val_arg; + void *oldheap; - region_lock (client->db_rp, 17); + region_lock (client->db_rp, 16); + oldheap = svm_push_data_heap (client->db_rp); - rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var); + local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var); + local_set_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var, + val, elsize); - if (rv && vec_len(rv)) { - /* Make a copy in process-local memory */ - vec_alloc (copy, vec_len(rv)*elsize); - clib_memcpy (copy, rv, vec_len(rv)*elsize); - _vec_len(copy) = vec_len(rv); - region_unlock (client->db_rp); - return (copy); - } - region_unlock (client->db_rp); - return (0); + svm_pop_heap (oldheap); + region_unlock (client->db_rp); } -void svmdb_local_dump_vecs (svmdb_client_t *client) +void * +svmdb_local_get_vec_variable (svmdb_client_t * client, char *var, u32 elsize) { - uword *h; - u8 *key; - u32 value; - svmdb_shm_hdr_t *shm; + u8 *rv = 0; + u8 *copy = 0; - region_lock (client->db_rp, 17); - shm = client->shm; + region_lock (client->db_rp, 17); - h = client->shm->namespaces [SVMDB_NAMESPACE_VEC]; + rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var); - hash_foreach_mem(key, value, h, - ({ - svmdb_value_t *v = pool_elt_at_index (shm->values, value); - (void) fformat(stdout, "%s:\n %U (%.2f)\n", key, - format_hex_bytes, v->value, - vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]); - })); + if (rv && vec_len (rv)) + { + /* Make a copy in process-local memory */ + vec_alloc (copy, vec_len (rv) * elsize); + clib_memcpy (copy, rv, vec_len (rv) * elsize); + _vec_len (copy) = vec_len (rv); + region_unlock (client->db_rp); + return (copy); + } + region_unlock (client->db_rp); + return (0); +} - region_unlock (client->db_rp); +void +svmdb_local_dump_vecs (svmdb_client_t * client) +{ + uword *h; + u8 *key; + u32 value; + svmdb_shm_hdr_t *shm; + + region_lock (client->db_rp, 17); + shm = client->shm; + + h = client->shm->namespaces[SVMDB_NAMESPACE_VEC]; + + /* *INDENT-OFF* */ + hash_foreach_mem(key, value, h, + ({ + svmdb_value_t *v = pool_elt_at_index (shm->values, value); + (void) fformat(stdout, "%s:\n %U (%.2f)\n", key, + format_hex_bytes, v->value, + vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]); + })); + /* *INDENT-ON* */ + + region_unlock (client->db_rp); } -void *svmdb_local_find_or_add_vec_variable (svmdb_client_t *client, - char *var, u32 nbytes) +void * +svmdb_local_find_or_add_vec_variable (svmdb_client_t * client, + char *var, u32 nbytes) { - void *oldheap; - u8 *rv = 0; - - region_lock (client->db_rp, 18); - oldheap = svm_push_data_heap (client->db_rp); - - rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *)var); - - if (rv) { - goto out; - } else { - uword *h; - u8 *name; - svmdb_shm_hdr_t * shm; - svmdb_value_t * newvalue; - - shm = client->shm; - h = shm->namespaces[SVMDB_NAMESPACE_VEC]; - - pool_get (shm->values, newvalue); - memset (newvalue, 0, sizeof (*newvalue)); - newvalue->elsize = 1; - vec_alloc (newvalue->value, nbytes); - _vec_len (newvalue->value) = nbytes; - name = format (0, "%s%c", var, 0); - hash_set_mem (h, name, newvalue - shm->values); - shm->namespaces[SVMDB_NAMESPACE_VEC] = h; - rv = newvalue->value; + void *oldheap; + u8 *rv = 0; + + region_lock (client->db_rp, 18); + oldheap = svm_push_data_heap (client->db_rp); + + rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var); + + if (rv) + { + goto out; + } + else + { + uword *h; + u8 *name; + svmdb_shm_hdr_t *shm; + svmdb_value_t *newvalue; + + shm = client->shm; + h = shm->namespaces[SVMDB_NAMESPACE_VEC]; + + pool_get (shm->values, newvalue); + memset (newvalue, 0, sizeof (*newvalue)); + newvalue->elsize = 1; + vec_alloc (newvalue->value, nbytes); + _vec_len (newvalue->value) = nbytes; + name = format (0, "%s%c", var, 0); + hash_set_mem (h, name, newvalue - shm->values); + shm->namespaces[SVMDB_NAMESPACE_VEC] = h; + rv = newvalue->value; } out: - svm_pop_heap(oldheap); - region_unlock (client->db_rp); - return (rv); + svm_pop_heap (oldheap); + region_unlock (client->db_rp); + return (rv); } + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */