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