blob: c0680bc327988fdeac8e36c45c38b13e88702c4d [file] [log] [blame]
Dave Barach8a7fb0c2016-07-08 14:44:23 -04001/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07002 *------------------------------------------------------------------
3 * svmdb.c -- simple shared memory database
4 *
5 * Copyright (c) 2009 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
18 */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <sys/types.h>
23#include <sys/mman.h>
24#include <sys/stat.h>
25#include <netinet/in.h>
26#include <signal.h>
27#include <pthread.h>
28#include <unistd.h>
29#include <time.h>
30#include <fcntl.h>
31#include <string.h>
32#include <vppinfra/clib.h>
33#include <vppinfra/vec.h>
34#include <vppinfra/hash.h>
35#include <vppinfra/bitmap.h>
36#include <vppinfra/fifo.h>
37#include <vppinfra/time.h>
38#include <vppinfra/mheap.h>
39#include <vppinfra/heap.h>
40#include <vppinfra/pool.h>
41#include <vppinfra/format.h>
42
43#include "svmdb.h"
44
Dave Barach8a7fb0c2016-07-08 14:44:23 -040045static void local_set_variable_nolock (svmdb_client_t * client,
46 svmdb_namespace_t namespace,
47 u8 * var, u8 * val, u32 elsize);
Ed Warnickecb9cada2015-12-08 15:45:58 -070048
Dave Barach8a7fb0c2016-07-08 14:44:23 -040049always_inline void
50region_lock (svm_region_t * rp, int tag)
Ed Warnickecb9cada2015-12-08 15:45:58 -070051{
Dave Barach8a7fb0c2016-07-08 14:44:23 -040052 pthread_mutex_lock (&rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -070053#ifdef MUTEX_DEBUG
Dave Barach8a7fb0c2016-07-08 14:44:23 -040054 rp->mutex_owner_pid = getpid ();
55 rp->mutex_owner_tag = tag;
56#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -070057}
58
Dave Barach8a7fb0c2016-07-08 14:44:23 -040059always_inline void
60region_unlock (svm_region_t * rp)
Ed Warnickecb9cada2015-12-08 15:45:58 -070061{
62#ifdef MUTEX_DEBUG
Dave Barach8a7fb0c2016-07-08 14:44:23 -040063 rp->mutex_owner_pid = 0;
64 rp->mutex_owner_tag = 0;
65#endif
66 pthread_mutex_unlock (&rp->mutex);
Ed Warnickecb9cada2015-12-08 15:45:58 -070067}
68
Dave Barach98cfc1a2016-07-18 14:23:36 -040069svmdb_client_t *
70svmdb_map (svmdb_map_args_t * dba)
Ed Warnickecb9cada2015-12-08 15:45:58 -070071{
Dave Barach8a7fb0c2016-07-08 14:44:23 -040072 svmdb_client_t *client = 0;
73 svm_map_region_args_t *a = 0;
74 svm_region_t *db_rp;
75 void *oldheap;
76 svmdb_shm_hdr_t *hp = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070077
Dave Barach8a7fb0c2016-07-08 14:44:23 -040078 vec_validate (client, 0);
79 vec_validate (a, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -070080
Dave Barach98cfc1a2016-07-18 14:23:36 -040081 svm_region_init_chroot_uid_gid (dba->root_path, dba->uid, dba->gid);
Ed Warnickecb9cada2015-12-08 15:45:58 -070082
Dave Barach98cfc1a2016-07-18 14:23:36 -040083 a->root_path = dba->root_path;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040084 a->name = "/db";
Dave Barach98cfc1a2016-07-18 14:23:36 -040085 a->size = dba->size ? dba->size : SVMDB_DEFAULT_SIZE;
Dave Barach8a7fb0c2016-07-08 14:44:23 -040086 a->flags = SVM_FLAGS_MHEAP;
Dave Barach98cfc1a2016-07-18 14:23:36 -040087 a->uid = dba->uid;
88 a->gid = dba->gid;
Ed Warnickecb9cada2015-12-08 15:45:58 -070089
Dave Barach8a7fb0c2016-07-08 14:44:23 -040090 db_rp = client->db_rp = svm_region_find_or_create (a);
Ed Warnickecb9cada2015-12-08 15:45:58 -070091
Dave Barach8a7fb0c2016-07-08 14:44:23 -040092 ASSERT (db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
Dave Barach8a7fb0c2016-07-08 14:44:23 -040094 vec_free (a);
95
96 region_lock (client->db_rp, 10);
97 /* Has someone else set up the shared-memory variable table? */
98 if (db_rp->user_ctx)
99 {
100 client->shm = (void *) db_rp->user_ctx;
101 client->pid = getpid ();
102 region_unlock (client->db_rp);
103 ASSERT (client->shm->version == SVMDB_SHM_VERSION);
104 return (client);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700105 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400106 /* Nope, it's our problem... */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700107
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400108 /* Add a bogus client (pid=0) so the svm won't be deallocated */
109 oldheap = svm_push_pvt_heap (db_rp);
110 vec_add1 (client->db_rp->client_pids, 0);
111 svm_pop_heap (oldheap);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700112
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400113 oldheap = svm_push_data_heap (db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700114
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400115 vec_validate (hp, 0);
116 hp->version = SVMDB_SHM_VERSION;
117 hp->namespaces[SVMDB_NAMESPACE_STRING]
118 = hash_create_string (0, sizeof (uword));
119 hp->namespaces[SVMDB_NAMESPACE_VEC]
120 = hash_create_string (0, sizeof (uword));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700121
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400122 db_rp->user_ctx = hp;
123 client->shm = hp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700124
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400125 svm_pop_heap (oldheap);
126 region_unlock (client->db_rp);
127 client->pid = getpid ();
128
129 return (client);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700130}
131
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400132void
133svmdb_unmap (svmdb_client_t * client)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700134{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400135 ASSERT (client);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700136
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400137 if (!svm_get_root_rp ())
138 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700139
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400140 svm_region_unmap ((void *) client->db_rp);
141 svm_region_exit ();
142 vec_free (client);
143}
144
145static void
146notify_value (svmdb_value_t * v, svmdb_action_t a)
147{
148 int i;
149 int rv;
150 union sigval sv;
151 u32 value;
152 u32 *dead_registrations = 0;
153
154 svmdb_notify_t *np;
155
156 for (i = 0; i < vec_len (v->notifications); i++)
157 {
158 np = vec_elt_at_index (v->notifications, i);
159 if (np->action == a)
160 {
161 value = (np->action << 28) | (np->opaque);
162 sv.sival_ptr = (void *) (uword) value;
163 do
164 {
165 rv = 0;
166 if (sigqueue (np->pid, np->signum, sv) == 0)
167 break;
168 rv = errno;
169 }
170 while (rv == EAGAIN);
171 if (rv == 0)
172 continue;
173 vec_add1 (dead_registrations, i);
174 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700175 }
176
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400177 for (i = 0; i < vec_len (dead_registrations); i++)
178 {
179 np = vec_elt_at_index (v->notifications, dead_registrations[i]);
180 clib_warning ("dead reg pid %d sig %d action %d opaque %x",
181 np->pid, np->signum, np->action, np->opaque);
182 vec_delete (v->notifications, 1, dead_registrations[i]);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400184 vec_free (dead_registrations);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700185}
186
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400187int
188svmdb_local_add_del_notification (svmdb_client_t * client,
189 svmdb_notification_args_t * a)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400191 uword *h;
192 void *oldheap;
193 hash_pair_t *hp;
194 svmdb_shm_hdr_t *shm;
195 u8 *dummy_value = 0;
196 svmdb_value_t *value;
197 svmdb_notify_t *np;
198 int i;
199 int rv = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700200
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400201 ASSERT (a->elsize);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700202
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400203 region_lock (client->db_rp, 18);
204 shm = client->shm;
205 oldheap = svm_push_data_heap (client->db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700206
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400207 h = shm->namespaces[a->nspace];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400209 hp = hash_get_pair_mem (h, a->var);
210 if (hp == 0)
211 {
212 local_set_variable_nolock (client, a->nspace, (u8 *) a->var,
213 dummy_value, a->elsize);
214 /* might have moved */
215 h = shm->namespaces[a->nspace];
216 hp = hash_get_pair_mem (h, a->var);
217 ASSERT (hp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700218 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400219
220 value = pool_elt_at_index (shm->values, hp->value[0]);
221
222 for (i = 0; i < vec_len (value->notifications); i++)
223 {
224 np = vec_elt_at_index (value->notifications, i);
225 if ((np->pid == client->pid)
226 && (np->signum == a->signum)
227 && (np->action == a->action) && (np->opaque == a->opaque))
228 {
229 if (a->add_del == 0 /* delete */ )
230 {
231 vec_delete (value->notifications, 1, i);
232 goto out;
233 }
234 else
235 { /* add */
236 clib_warning
237 ("%s: ignore dup reg pid %d signum %d action %d opaque %x",
238 a->var, client->pid, a->signum, a->action, a->opaque);
239 rv = -2;
240 goto out;
241 }
242 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700243 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400244 if (a->add_del == 0)
245 {
246 rv = -3;
247 goto out;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700248 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400249
250 vec_add2 (value->notifications, np, 1);
251 np->pid = client->pid;
252 np->signum = a->signum;
253 np->action = a->action;
254 np->opaque = a->opaque;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700255
256out:
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400257 svm_pop_heap (oldheap);
258 region_unlock (client->db_rp);
259 return rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700260}
261
262
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400263static void
264local_unset_variable_nolock (svmdb_client_t * client,
265 svmdb_namespace_t namespace, char *var)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700266{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400267 uword *h;
268 svmdb_value_t *oldvalue;
269 hash_pair_t *hp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700270
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400271 h = client->shm->namespaces[namespace];
272 hp = hash_get_pair_mem (h, var);
273 if (hp)
274 {
275 oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]);
276 if (vec_len (oldvalue->notifications))
277 notify_value (oldvalue, SVMDB_ACTION_UNSET);
278 /* zero length value means unset */
279 _vec_len (oldvalue->value) = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700280 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400281 client->shm->namespaces[namespace] = h;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700282}
283
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400284void
285svmdb_local_unset_string_variable (svmdb_client_t * client, char *var)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700286{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400287 void *oldheap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700288
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400289 region_lock (client->db_rp, 11);
290 oldheap = svm_push_data_heap (client->db_rp);
291 local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var);
292 svm_pop_heap (oldheap);
293 region_unlock (client->db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700294}
295
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400296static void
297local_set_variable_nolock (svmdb_client_t * client,
298 svmdb_namespace_t namespace,
299 u8 * var, u8 * val, u32 elsize)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700300{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400301 uword *h;
302 hash_pair_t *hp;
303 u8 *name;
304 svmdb_shm_hdr_t *shm;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700305
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400306 shm = client->shm;
307 h = shm->namespaces[namespace];
308 hp = hash_get_pair_mem (h, var);
309 if (hp)
310 {
311 svmdb_value_t *oldvalue;
312 oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]);
313 vec_alloc (oldvalue->value, vec_len (val) * elsize);
314 clib_memcpy (oldvalue->value, val, vec_len (val) * elsize);
315 _vec_len (oldvalue->value) = vec_len (val);
316 notify_value (oldvalue, SVMDB_ACTION_SET);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700317 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400318 else
319 {
320 svmdb_value_t *newvalue;
321 pool_get (shm->values, newvalue);
322 memset (newvalue, 0, sizeof (*newvalue));
323 newvalue->elsize = elsize;
324 vec_alloc (newvalue->value, vec_len (val) * elsize);
325 clib_memcpy (newvalue->value, val, vec_len (val) * elsize);
326 _vec_len (newvalue->value) = vec_len (val);
327 name = format (0, "%s%c", var, 0);
328 hash_set_mem (h, name, newvalue - shm->values);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700329 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400330 shm->namespaces[namespace] = h;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700331}
332
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400333void
334svmdb_local_set_string_variable (svmdb_client_t * client,
335 char *var, char *val)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700336{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400337 void *oldheap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700338
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400339 region_lock (client->db_rp, 12);
340 oldheap = svm_push_data_heap (client->db_rp);
341
342 local_unset_variable_nolock (client, SVMDB_NAMESPACE_STRING, var);
343
344 local_set_variable_nolock (client, SVMDB_NAMESPACE_STRING,
345 (u8 *) var, (u8 *) val, 1 /* elsize */ );
346 svm_pop_heap (oldheap);
347 region_unlock (client->db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700348}
349
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400350static u8 *
351local_get_variable_nolock (svmdb_client_t * client,
352 svmdb_namespace_t namespace, u8 * var)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700353{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400354 uword *h;
355 uword *p;
356 svmdb_shm_hdr_t *shm;
357 svmdb_value_t *oldvalue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700358
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400359 shm = client->shm;
360 h = shm->namespaces[namespace];
361 p = hash_get_mem (h, var);
362 if (p)
363 {
364 oldvalue = pool_elt_at_index (shm->values, p[0]);
365 notify_value (oldvalue, SVMDB_ACTION_GET);
366 return (oldvalue->value);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700367 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400368 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700369}
370
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400371void *
372svmdb_local_get_variable_reference (svmdb_client_t * client,
373 svmdb_namespace_t namespace, char *var)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700374{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400375 u8 *rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700376
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400377 region_lock (client->db_rp, 19);
378 rv = local_get_variable_nolock (client, namespace, (u8 *) var);
379 region_unlock (client->db_rp);
380 return (void *) rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700381}
382
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400383char *
384svmdb_local_get_string_variable (svmdb_client_t * client, char *var)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700385{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400386 u8 *rv = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700387
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400388 region_lock (client->db_rp, 13);
389 rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_STRING, (u8 *) var);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700390
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400391 if (rv && vec_len (rv))
392 {
393 rv = format (0, "%s", rv);
394 vec_add1 (rv, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700395 }
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400396 region_unlock (client->db_rp);
397 return ((char *) rv);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700398}
399
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400400void
401svmdb_local_dump_strings (svmdb_client_t * client)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700402{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400403 uword *h;
404 u8 *key;
405 u32 value;
406 svmdb_shm_hdr_t *shm = client->shm;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700407
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400408 region_lock (client->db_rp, 14);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700409
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400410 h = client->shm->namespaces[SVMDB_NAMESPACE_STRING];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700411
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400412 /* *INDENT-OFF* */
413 hash_foreach_mem(key, value, h,
414 ({
415 svmdb_value_t *v = pool_elt_at_index (shm->values, value);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700416
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400417 fformat(stdout, "%s: %s\n", key,
418 vec_len(v->value) ? v->value : (u8 *)"(nil)");
419 }));
420 /* *INDENT-ON* */
421 region_unlock (client->db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700422}
423
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400424void
425svmdb_local_unset_vec_variable (svmdb_client_t * client, char *var)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700426{
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400427 void *oldheap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700428
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400429 region_lock (client->db_rp, 15);
430 oldheap = svm_push_data_heap (client->db_rp);
431 local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var);
432 svm_pop_heap (oldheap);
433 region_unlock (client->db_rp);
434}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700435
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400436void
437svmdb_local_set_vec_variable (svmdb_client_t * client,
438 char *var, void *val_arg, u32 elsize)
439{
440 u8 *val = (u8 *) val_arg;
441 void *oldheap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700442
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400443 region_lock (client->db_rp, 16);
444 oldheap = svm_push_data_heap (client->db_rp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700445
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400446 local_unset_variable_nolock (client, SVMDB_NAMESPACE_VEC, var);
447 local_set_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var,
448 val, elsize);
449
450 svm_pop_heap (oldheap);
451 region_unlock (client->db_rp);
452}
453
454void *
455svmdb_local_get_vec_variable (svmdb_client_t * client, char *var, u32 elsize)
456{
457 u8 *rv = 0;
458 u8 *copy = 0;
459
460 region_lock (client->db_rp, 17);
461
462 rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var);
463
464 if (rv && vec_len (rv))
465 {
466 /* Make a copy in process-local memory */
467 vec_alloc (copy, vec_len (rv) * elsize);
468 clib_memcpy (copy, rv, vec_len (rv) * elsize);
469 _vec_len (copy) = vec_len (rv);
470 region_unlock (client->db_rp);
471 return (copy);
472 }
473 region_unlock (client->db_rp);
474 return (0);
475}
476
477void
478svmdb_local_dump_vecs (svmdb_client_t * client)
479{
480 uword *h;
481 u8 *key;
482 u32 value;
483 svmdb_shm_hdr_t *shm;
484
485 region_lock (client->db_rp, 17);
486 shm = client->shm;
487
488 h = client->shm->namespaces[SVMDB_NAMESPACE_VEC];
489
490 /* *INDENT-OFF* */
491 hash_foreach_mem(key, value, h,
492 ({
493 svmdb_value_t *v = pool_elt_at_index (shm->values, value);
494 (void) fformat(stdout, "%s:\n %U (%.2f)\n", key,
495 format_hex_bytes, v->value,
496 vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]);
497 }));
498 /* *INDENT-ON* */
499
500 region_unlock (client->db_rp);
501}
502
503void *
504svmdb_local_find_or_add_vec_variable (svmdb_client_t * client,
505 char *var, u32 nbytes)
506{
507 void *oldheap;
508 u8 *rv = 0;
509
510 region_lock (client->db_rp, 18);
511 oldheap = svm_push_data_heap (client->db_rp);
512
513 rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var);
514
515 if (rv)
516 {
517 goto out;
518 }
519 else
520 {
521 uword *h;
522 u8 *name;
523 svmdb_shm_hdr_t *shm;
524 svmdb_value_t *newvalue;
525
526 shm = client->shm;
527 h = shm->namespaces[SVMDB_NAMESPACE_VEC];
528
529 pool_get (shm->values, newvalue);
530 memset (newvalue, 0, sizeof (*newvalue));
531 newvalue->elsize = 1;
532 vec_alloc (newvalue->value, nbytes);
533 _vec_len (newvalue->value) = nbytes;
534 name = format (0, "%s%c", var, 0);
535 hash_set_mem (h, name, newvalue - shm->values);
536 shm->namespaces[SVMDB_NAMESPACE_VEC] = h;
537 rv = newvalue->value;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700538 }
539
540out:
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400541 svm_pop_heap (oldheap);
542 region_unlock (client->db_rp);
543 return (rv);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700544}
Dave Barach8a7fb0c2016-07-08 14:44:23 -0400545
546/*
547 * fd.io coding-style-patch-verification: ON
548 *
549 * Local Variables:
550 * eval: (c-set-style "gnu")
551 * End:
552 */