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