FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
svmdb.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
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 #include <vppinfra/serialize.h>
43 
44 #include "svmdb.h"
45 
46 static void local_set_variable_nolock (svmdb_client_t * client,
47  svmdb_namespace_t namespace,
48  u8 * var, u8 * val, u32 elsize);
49 
50 always_inline void
51 region_lock (svm_region_t * rp, int tag)
52 {
53  pthread_mutex_lock (&rp->mutex);
54 #ifdef MUTEX_DEBUG
55  rp->mutex_owner_pid = getpid ();
56  rp->mutex_owner_tag = tag;
57 #endif
58 }
59 
60 always_inline void
62 {
63 #ifdef MUTEX_DEBUG
64  rp->mutex_owner_pid = 0;
65  rp->mutex_owner_tag = 0;
66 #endif
67  pthread_mutex_unlock (&rp->mutex);
68 }
69 
72 {
73  svmdb_client_t *client = 0;
75  svm_region_t *db_rp;
76  void *oldheap;
77  svmdb_shm_hdr_t *hp = 0;
78 
79  vec_validate (client, 0);
80  vec_validate (a, 0);
81 
83 
84  a->root_path = dba->root_path;
85  a->name = "/db";
86  a->size = dba->size ? dba->size : SVMDB_DEFAULT_SIZE;
88  a->uid = dba->uid;
89  a->gid = dba->gid;
90 
91  db_rp = client->db_rp = svm_region_find_or_create (a);
92 
93  ASSERT (db_rp);
94 
95  vec_free (a);
96 
97  region_lock (client->db_rp, 10);
98  /* Has someone else set up the shared-memory variable table? */
99  if (db_rp->user_ctx)
100  {
101  client->shm = (void *) db_rp->user_ctx;
102  client->pid = getpid ();
103  region_unlock (client->db_rp);
104  ASSERT (client->shm->version == SVMDB_SHM_VERSION);
105  return (client);
106  }
107  /* Nope, it's our problem... */
108 
109  /* Add a bogus client (pid=0) so the svm won't be deallocated */
110  oldheap = svm_push_pvt_heap (db_rp);
111  vec_add1 (client->db_rp->client_pids, 0);
112  svm_pop_heap (oldheap);
113 
114  oldheap = svm_push_data_heap (db_rp);
115 
116  vec_validate (hp, 0);
119  = hash_create_string (0, sizeof (uword));
121  = hash_create_string (0, sizeof (uword));
122 
123  db_rp->user_ctx = hp;
124  client->shm = hp;
125 
126  svm_pop_heap (oldheap);
127  region_unlock (client->db_rp);
128  client->pid = getpid ();
129 
130  return (client);
131 }
132 
133 void
135 {
136  ASSERT (client);
137 
138  if (!svm_get_root_rp ())
139  return;
140 
141  svm_region_unmap ((void *) client->db_rp);
142  svm_region_exit ();
143  vec_free (client);
144 }
145 
146 static void
148 {
149  int i;
150  int rv;
151  union sigval sv;
152  u32 value;
153  u32 *dead_registrations = 0;
154 
155  svmdb_notify_t *np;
156 
157  for (i = 0; i < vec_len (v->notifications); i++)
158  {
159  np = vec_elt_at_index (v->notifications, i);
160  if (np->action == a)
161  {
162  value = (np->action << 28) | (np->opaque);
163  sv.sival_ptr = (void *) (uword) value;
164  do
165  {
166  rv = 0;
167  if (sigqueue (np->pid, np->signum, sv) == 0)
168  break;
169  rv = errno;
170  }
171  while (rv == EAGAIN);
172  if (rv == 0)
173  continue;
174  vec_add1 (dead_registrations, i);
175  }
176  }
177 
178  for (i = 0; i < vec_len (dead_registrations); i++)
179  {
180  np = vec_elt_at_index (v->notifications, dead_registrations[i]);
181  clib_warning ("dead reg pid %d sig %d action %d opaque %x",
182  np->pid, np->signum, np->action, np->opaque);
183  vec_delete (v->notifications, 1, dead_registrations[i]);
184  }
185  vec_free (dead_registrations);
186 }
187 
188 int
191 {
192  uword *h;
193  void *oldheap;
194  hash_pair_t *hp;
195  svmdb_shm_hdr_t *shm;
196  u8 *dummy_value = 0;
197  svmdb_value_t *value;
198  svmdb_notify_t *np;
199  int i;
200  int rv = 0;
201 
202  ASSERT (a->elsize);
203 
204  region_lock (client->db_rp, 18);
205  shm = client->shm;
206  oldheap = svm_push_data_heap (client->db_rp);
207 
208  h = shm->namespaces[a->nspace];
209 
210  hp = hash_get_pair_mem (h, a->var);
211  if (hp == 0)
212  {
213  local_set_variable_nolock (client, a->nspace, (u8 *) a->var,
214  dummy_value, a->elsize);
215  /* might have moved */
216  h = shm->namespaces[a->nspace];
217  hp = hash_get_pair_mem (h, a->var);
218  ASSERT (hp);
219  }
220 
221  value = pool_elt_at_index (shm->values, hp->value[0]);
222 
223  for (i = 0; i < vec_len (value->notifications); i++)
224  {
225  np = vec_elt_at_index (value->notifications, i);
226  if ((np->pid == client->pid)
227  && (np->signum == a->signum)
228  && (np->action == a->action) && (np->opaque == a->opaque))
229  {
230  if (a->add_del == 0 /* delete */ )
231  {
232  vec_delete (value->notifications, 1, i);
233  goto out;
234  }
235  else
236  { /* add */
238  ("%s: ignore dup reg pid %d signum %d action %d opaque %x",
239  a->var, client->pid, a->signum, a->action, a->opaque);
240  rv = -2;
241  goto out;
242  }
243  }
244  }
245  if (a->add_del == 0)
246  {
247  rv = -3;
248  goto out;
249  }
250 
251  vec_add2 (value->notifications, np, 1);
252  np->pid = client->pid;
253  np->signum = a->signum;
254  np->action = a->action;
255  np->opaque = a->opaque;
256 
257 out:
258  svm_pop_heap (oldheap);
259  region_unlock (client->db_rp);
260  return rv;
261 }
262 
263 
264 static void
266  svmdb_namespace_t namespace, char *var)
267 {
268  uword *h;
269  svmdb_value_t *oldvalue;
270  hash_pair_t *hp;
271 
272  h = client->shm->namespaces[namespace];
273  hp = hash_get_pair_mem (h, var);
274  if (hp)
275  {
276  oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]);
277  if (vec_len (oldvalue->notifications))
278  notify_value (oldvalue, SVMDB_ACTION_UNSET);
279  /* zero length value means unset */
280  _vec_len (oldvalue->value) = 0;
281  }
282  client->shm->namespaces[namespace] = h;
283 }
284 
285 void
287 {
288  void *oldheap;
289 
290  region_lock (client->db_rp, 11);
291  oldheap = svm_push_data_heap (client->db_rp);
293  svm_pop_heap (oldheap);
294  region_unlock (client->db_rp);
295 }
296 
297 static void
299  svmdb_namespace_t namespace,
300  u8 * var, u8 * val, u32 elsize)
301 {
302  uword *h;
303  hash_pair_t *hp;
304  u8 *name;
305  svmdb_shm_hdr_t *shm;
306 
307  shm = client->shm;
308  h = shm->namespaces[namespace];
309  hp = hash_get_pair_mem (h, var);
310  if (hp)
311  {
312  svmdb_value_t *oldvalue;
313  oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]);
314  vec_alloc (oldvalue->value, vec_len (val) * elsize);
315  clib_memcpy (oldvalue->value, val, vec_len (val) * elsize);
316  _vec_len (oldvalue->value) = vec_len (val);
317  notify_value (oldvalue, SVMDB_ACTION_SET);
318  }
319  else
320  {
321  svmdb_value_t *newvalue;
322  pool_get (shm->values, newvalue);
323  memset (newvalue, 0, sizeof (*newvalue));
324  newvalue->elsize = elsize;
325  vec_alloc (newvalue->value, vec_len (val) * elsize);
326  clib_memcpy (newvalue->value, val, vec_len (val) * elsize);
327  _vec_len (newvalue->value) = vec_len (val);
328  name = format (0, "%s%c", var, 0);
329  hash_set_mem (h, name, newvalue - shm->values);
330  }
331  shm->namespaces[namespace] = h;
332 }
333 
334 void
336  char *var, char *val)
337 {
338  void *oldheap;
339 
340  region_lock (client->db_rp, 12);
341  oldheap = svm_push_data_heap (client->db_rp);
342 
344 
346  (u8 *) var, (u8 *) val, 1 /* elsize */ );
347  svm_pop_heap (oldheap);
348  region_unlock (client->db_rp);
349 }
350 
351 static u8 *
353  svmdb_namespace_t namespace, u8 * var)
354 {
355  uword *h;
356  uword *p;
357  svmdb_shm_hdr_t *shm;
358  svmdb_value_t *oldvalue;
359 
360  shm = client->shm;
361  h = shm->namespaces[namespace];
362  p = hash_get_mem (h, var);
363  if (p)
364  {
365  oldvalue = pool_elt_at_index (shm->values, p[0]);
366  notify_value (oldvalue, SVMDB_ACTION_GET);
367  return (oldvalue->value);
368  }
369  return 0;
370 }
371 
372 void *
374  svmdb_namespace_t namespace, char *var)
375 {
376  u8 *rv;
377 
378  region_lock (client->db_rp, 19);
379  rv = local_get_variable_nolock (client, namespace, (u8 *) var);
380  region_unlock (client->db_rp);
381  return (void *) rv;
382 }
383 
384 char *
386 {
387  u8 *rv = 0;
388 
389  region_lock (client->db_rp, 13);
390  rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_STRING, (u8 *) var);
391 
392  if (rv && vec_len (rv))
393  {
394  rv = format (0, "%s", rv);
395  vec_add1 (rv, 0);
396  }
397  region_unlock (client->db_rp);
398  return ((char *) rv);
399 }
400 
401 void
403 {
404  uword *h;
405  u8 *key;
406  u32 value;
407  svmdb_shm_hdr_t *shm = client->shm;
408 
409  region_lock (client->db_rp, 14);
410 
411  h = client->shm->namespaces[SVMDB_NAMESPACE_STRING];
412 
413  /* *INDENT-OFF* */
414  hash_foreach_mem(key, value, h,
415  ({
416  svmdb_value_t *v = pool_elt_at_index (shm->values, value);
417 
418  fformat(stdout, "%s: %s\n", key,
419  vec_len(v->value) ? v->value : (u8 *)"(nil)");
420  }));
421  /* *INDENT-ON* */
422  region_unlock (client->db_rp);
423 }
424 
425 int
427 {
428  uword *h;
429  u8 *key;
430  u32 value;
431  svmdb_shm_hdr_t *shm = client->shm;
432  serialize_main_t _sm, *sm = &_sm;
433  clib_error_t *error = 0;
434  u8 *sanitized_name = 0;
435  int fd = 0;
436 
437  if (strstr (filename, "..") || index (filename, '/'))
438  {
439  error = clib_error_return (0, "Illegal characters in filename '%s'",
440  filename);
441  goto out;
442  }
443 
444  sanitized_name = format (0, "/tmp/%s%c", filename, 0);
445 
446  fd = creat ((char *) sanitized_name, 0644);
447 
448  if (fd < 0)
449  {
450  error = clib_error_return_unix (0, "Create '%s'", sanitized_name);
451  goto out;
452  }
453 
455 
456  region_lock (client->db_rp, 20);
457 
458  h = client->shm->namespaces[SVMDB_NAMESPACE_STRING];
459 
461 
462  /* *INDENT-OFF* */
463  hash_foreach_mem(key, value, h,
464  ({
465  svmdb_value_t *v = pool_elt_at_index (shm->values, value);
466 
467  /* Omit names with nil values */
468  if (vec_len(v->value))
469  {
470  serialize_cstring (sm, (char *)key);
471  serialize_cstring (sm, (char *)v->value);
472  }
473  }));
474  /* *INDENT-ON* */
475  region_unlock (client->db_rp);
476 
477  serialize_close (sm);
478 
479 out:
480  if (fd > 0 && close (fd) < 0)
481  error = clib_error_return_unix (0, "close fd %d", fd);
482 
483  if (error)
484  {
485  clib_error_report (error);
486  return -1;
487  }
488  return 0;
489 }
490 
491 int
493 {
494  serialize_main_t _sm, *sm = &_sm;
495  void *oldheap;
496  clib_error_t *error = 0;
497  u8 *key, *value;
498  int fd = 0;
499  u32 nelts;
500  int i;
501 
502  fd = open (filename, O_RDONLY);
503 
504  if (fd < 0)
505  {
506  error = clib_error_return_unix (0, "Failed to open '%s'", filename);
507  goto out;
508  }
509 
511 
512  region_lock (client->db_rp, 21);
513  oldheap = svm_push_data_heap (client->db_rp);
514 
516 
517  for (i = 0; i < nelts; i++)
518  {
519  unserialize_cstring (sm, (char **) &key);
520  unserialize_cstring (sm, (char **) &value);
522  key, value, 1 /* elsize */ );
523  vec_free (key);
524  vec_free (value);
525  }
526  svm_pop_heap (oldheap);
527  region_unlock (client->db_rp);
528 
529  serialize_close (sm);
530 
531 out:
532  if (fd > 0 && close (fd) < 0)
533  error = clib_error_return_unix (0, "close fd %d", fd);
534 
535  if (error)
536  {
537  clib_error_report (error);
538  return -1;
539  }
540  return 0;
541 }
542 
543 void
545 {
546  void *oldheap;
547 
548  region_lock (client->db_rp, 15);
549  oldheap = svm_push_data_heap (client->db_rp);
551  svm_pop_heap (oldheap);
552  region_unlock (client->db_rp);
553 }
554 
555 void
557  char *var, void *val_arg, u32 elsize)
558 {
559  u8 *val = (u8 *) val_arg;
560  void *oldheap;
561 
562  region_lock (client->db_rp, 16);
563  oldheap = svm_push_data_heap (client->db_rp);
564 
567  val, elsize);
568 
569  svm_pop_heap (oldheap);
570  region_unlock (client->db_rp);
571 }
572 
573 void *
574 svmdb_local_get_vec_variable (svmdb_client_t * client, char *var, u32 elsize)
575 {
576  u8 *rv = 0;
577  u8 *copy = 0;
578 
579  region_lock (client->db_rp, 17);
580 
581  rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var);
582 
583  if (rv && vec_len (rv))
584  {
585  /* Make a copy in process-local memory */
586  vec_alloc (copy, vec_len (rv) * elsize);
587  clib_memcpy (copy, rv, vec_len (rv) * elsize);
588  _vec_len (copy) = vec_len (rv);
589  region_unlock (client->db_rp);
590  return (copy);
591  }
592  region_unlock (client->db_rp);
593  return (0);
594 }
595 
596 void
598 {
599  uword *h;
600  u8 *key;
601  u32 value;
602  svmdb_shm_hdr_t *shm;
603 
604  region_lock (client->db_rp, 17);
605  shm = client->shm;
606 
607  h = client->shm->namespaces[SVMDB_NAMESPACE_VEC];
608 
609  /* *INDENT-OFF* */
610  hash_foreach_mem(key, value, h,
611  ({
612  svmdb_value_t *v = pool_elt_at_index (shm->values, value);
613  (void) fformat(stdout, "%s:\n %U (%.2f)\n", key,
615  vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]);
616  }));
617  /* *INDENT-ON* */
618 
619  region_unlock (client->db_rp);
620 }
621 
622 void *
624  char *var, u32 nbytes)
625 {
626  void *oldheap;
627  u8 *rv = 0;
628 
629  region_lock (client->db_rp, 18);
630  oldheap = svm_push_data_heap (client->db_rp);
631 
632  rv = local_get_variable_nolock (client, SVMDB_NAMESPACE_VEC, (u8 *) var);
633 
634  if (rv)
635  {
636  goto out;
637  }
638  else
639  {
640  uword *h;
641  u8 *name;
642  svmdb_shm_hdr_t *shm;
643  svmdb_value_t *newvalue;
644 
645  shm = client->shm;
647 
648  pool_get (shm->values, newvalue);
649  memset (newvalue, 0, sizeof (*newvalue));
650  newvalue->elsize = 1;
651  vec_alloc (newvalue->value, nbytes);
652  _vec_len (newvalue->value) = nbytes;
653  name = format (0, "%s%c", var, 0);
654  hash_set_mem (h, name, newvalue - shm->values);
656  rv = newvalue->value;
657  }
658 
659 out:
660  svm_pop_heap (oldheap);
661  region_unlock (client->db_rp);
662  return (rv);
663 }
664 
665 /*
666  * fd.io coding-style-patch-verification: ON
667  *
668  * Local Variables:
669  * eval: (c-set-style "gnu")
670  * End:
671  */
char * root_path
Definition: svm.h:72
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
svm_region_t * svm_get_root_rp(void)
Definition: svm.c:54
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
static void svm_pop_heap(void *oldheap)
Definition: svm.h:190
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
Definition: serialize.h:254
void * svmdb_local_get_variable_reference(svmdb_client_t *client, svmdb_namespace_t namespace, char *var)
Definition: svmdb.c:373
a
Definition: bitmap.h:516
#define SVMDB_SHM_VERSION
Definition: svmdb.h:63
void svmdb_local_dump_vecs(svmdb_client_t *client)
Definition: svmdb.c:597
Fixed length block allocator.
svmdb_namespace_t nspace
Definition: svmdb.h:76
void svmdb_local_unset_vec_variable(svmdb_client_t *client, char *var)
Definition: svmdb.c:544
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:561
int signum
Definition: svmdb.h:36
#define hash_set_mem(h, key, value)
Definition: hash.h:274
#define hash_get_pair_mem(h, key)
Definition: hash.h:271
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
char * root_path
Definition: svmdb.h:86
static void region_lock(svm_region_t *rp, int tag)
Definition: svmdb.c:51
u32 action
Definition: svmdb.h:37
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
#define vec_alloc(V, N)
Allocate space for N more elements (no header, unspecified alignment)
Definition: vec.h:279
uword version
Definition: svmdb.h:57
void svmdb_unmap(svmdb_client_t *client)
Definition: svmdb.c:134
#define SVM_FLAGS_MHEAP
Definition: svm.h:32
uword value[0]
Definition: hash.h:164
svmdb_namespace_t
Definition: svmdb.h:48
void svmdb_local_dump_strings(svmdb_client_t *client)
Definition: svmdb.c:402
static void * svm_push_data_heap(svm_region_t *rp)
Definition: svm.h:182
#define always_inline
Definition: clib.h:84
uword * client_pids
Definition: svm.h:59
uword * namespaces[SVMDB_N_NAMESPACES]
Definition: svmdb.h:60
void * svm_region_find_or_create(svm_map_region_args_t *a)
Definition: svm.c:839
volatile void * user_ctx
Definition: svm.h:52
char * name
Definition: svm.h:73
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
int svmdb_local_serialize_strings(svmdb_client_t *client, char *filename)
Definition: svmdb.c:426
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
#define clib_error_return(e, args...)
Definition: error.h:111
#define hash_create_string(elts, value_bytes)
Definition: hash.h:652
svmdb_shm_hdr_t * shm
Definition: svmdb.h:70
svmdb_action_t
Definition: svmdb.h:25
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
#define SVMDB_DEFAULT_SIZE
Definition: svmdb.h:96
static void serialize_likely_small_unsigned_integer(serialize_main_t *m, u64 x)
Definition: serialize.h:218
char * svmdb_local_get_string_variable(svmdb_client_t *client, char *var)
Definition: svmdb.c:385
#define v
Definition: acl.c:246
#define clib_error_return_unix(e, args...)
Definition: error.h:114
u32 elsize
Definition: svmdb.h:45
void svm_region_exit()
Definition: svm.c:1078
void unserialize_open_unix_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1214
#define hash_foreach_mem(key_var, value_var, h, body)
Definition: hash.h:437
word fformat(FILE *f, char *fmt,...)
Definition: format.c:452
void unserialize_cstring(serialize_main_t *m, char **s)
Definition: serialize.c:178
static void * svm_push_pvt_heap(svm_region_t *rp)
Definition: svm.h:174
svm_region_t * db_rp
Definition: svmdb.h:69
static void local_unset_variable_nolock(svmdb_client_t *client, svmdb_namespace_t namespace, char *var)
Definition: svmdb.c:265
static u8 * local_get_variable_nolock(svmdb_client_t *client, svmdb_namespace_t namespace, u8 *var)
Definition: svmdb.c:352
vec_header_t h
Definition: buffer.c:275
int svmdb_local_unserialize_strings(svmdb_client_t *client, char *filename)
Definition: svmdb.c:492
void * svmdb_local_find_or_add_vec_variable(svmdb_client_t *client, char *var, u32 nbytes)
Definition: svmdb.c:623
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:69
void svm_region_init_chroot_uid_gid(char *root_path, int uid, int gid)
Definition: svm.c:816
void svmdb_local_set_vec_variable(svmdb_client_t *client, char *var, void *val_arg, u32 elsize)
Definition: svmdb.c:556
svmdb_notify_t * notifications
Definition: svmdb.h:44
static uword hash_elts(void *v)
Definition: hash.h:117
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void serialize_open_unix_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1208
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:785
void serialize_close(serialize_main_t *m)
Definition: serialize.c:869
Bitmaps built as vectors of machine words.
u32 opaque
Definition: svmdb.h:38
int svmdb_local_add_del_notification(svmdb_client_t *client, svmdb_notification_args_t *a)
Definition: svmdb.c:189
#define clib_error_report(e)
Definition: error.h:125
int mutex_owner_tag
Definition: svm.h:45
u64 uword
Definition: types.h:112
void serialize_cstring(serialize_main_t *m, char *s)
Definition: serialize.c:164
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
void svmdb_local_unset_string_variable(svmdb_client_t *client, char *var)
Definition: svmdb.c:286
static void local_set_variable_nolock(svmdb_client_t *client, svmdb_namespace_t namespace, u8 *var, u8 *val, u32 elsize)
Definition: svmdb.c:298
void svm_region_unmap(void *rp_arg)
Definition: svm.c:958
svmdb_client_t * svmdb_map(svmdb_map_args_t *dba)
Definition: svmdb.c:71
void * svmdb_local_get_vec_variable(svmdb_client_t *client, char *var, u32 elsize)
Definition: svmdb.c:574
#define hash_get_mem(h, key)
Definition: hash.h:268
u8 * value
Definition: svmdb.h:43
uword size
Definition: svmdb.h:87
svmdb_value_t * values
Definition: svmdb.h:59
void svmdb_local_set_string_variable(svmdb_client_t *client, char *var, char *val)
Definition: svmdb.c:335
int mutex_owner_pid
Definition: svm.h:44
static void region_unlock(svm_region_t *rp)
Definition: svmdb.c:61
static void notify_value(svmdb_value_t *v, svmdb_action_t a)
Definition: svmdb.c:147
pthread_mutex_t mutex
Definition: svm.h:42
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".