FD.io VPP  v21.01.1
Vector Packet Processing
persist.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * persist.c - persistent data structure storage test / demo code
4  *
5  * Copyright (c) 2013 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 #include <svmdb.h>
43 
44 typedef struct
45 {
48 
50 
51 typedef struct
52 {
56 
57 typedef struct
58 {
60  u8 *name;
62 
63 /*
64  * Data structures in persistent shared memory, all the time
65  */
68 {
69  demo_struct2_t *demo2;
70  demo_struct1_t *demo1;
71  time_t starttime = time (0);
72  char *datestring = ctime (&starttime);
73  void *oldheap;
74 
75  /* Get back the root pointer */
77  (pm->c, SVMDB_NAMESPACE_VEC, "demo1_location");
78 
79  /* It doesnt exist create our data structures */
80  if (demo1 == 0)
81  {
82  /* If you want MP / thread safety, lock the region... */
83  pthread_mutex_lock (&pm->c->db_rp->mutex);
84 
85  /* Switch to the shared memory region heap */
86  oldheap = svm_push_data_heap (pm->c->db_rp);
87 
88  /* Allocate the top-level structure as a single element vector */
89  vec_validate (demo1, 0);
90 
91  /* Allocate the next-level structure as a plain old memory obj */
92  demo2 = clib_mem_alloc (sizeof (*demo2));
93 
94  demo1->demo2 = demo2;
95  demo1->name = format (0, "My name is Ishmael%c", 0);
96  demo2->string1 = format (0, "Here is string1%c", 0);
97  demo2->string2 = format (0, "Born at %s%c", datestring, 0);
98 
99  /* Back to the process-private heap */
100  svm_pop_heap (oldheap);
101  pthread_mutex_unlock (&pm->c->db_rp->mutex);
102 
103  /*
104  * Set the root pointer. Note: this guy switches heaps, locks, etc.
105  * We allocated demo1 as a vector to make this "just work..."
106  */
107  svmdb_local_set_vec_variable (pm->c, "demo1_location",
108  demo1, sizeof (demo1));
109 
110  }
111  else
112  {
113  /* retrieve and print data from shared memory */
114  demo2 = demo1->demo2;
115  fformat (stdout, "name: %s\n", demo1->name);
116  fformat (stdout, "demo2 location: %llx\n", demo2);
117  fformat (stdout, "string1: %s\n", demo2->string1);
118  fformat (stdout, "string2: %s\n", demo2->string2);
119  }
120  return 0;
121 }
122 
123 void
124 unserialize_demo1 (serialize_main_t * sm, va_list * args)
125 {
126  demo_struct1_t **result = va_arg (*args, demo_struct1_t **);
127  demo_struct1_t *demo1;
128  demo_struct2_t *demo2;
129 
130  /* Allocate data structures in process private memory */
131  demo1 = clib_mem_alloc (sizeof (*demo1));
132  demo2 = clib_mem_alloc (sizeof (*demo2));
133  demo1->demo2 = demo2;
134 
135  /* retrieve data from shared memory checkpoint */
136  unserialize_cstring (sm, (char **) &demo1->name);
137  unserialize_cstring (sm, (char **) &demo2->string1);
138  unserialize_cstring (sm, (char **) &demo2->string2);
139  *result = demo1;
140 }
141 
142 void
143 serialize_demo1 (serialize_main_t * sm, va_list * args)
144 {
145  demo_struct1_t *demo1 = va_arg (*args, demo_struct1_t *);
146  demo_struct2_t *demo2 = demo1->demo2;
147 
148  serialize_cstring (sm, (char *) demo1->name);
149  serialize_cstring (sm, (char *) demo2->string1);
150  serialize_cstring (sm, (char *) demo2->string2);
151 }
152 
153 /* Serialize / unserialize variant */
154 clib_error_t *
156 {
157  u8 *checkpoint;
158  serialize_main_t sm;
159 
160  demo_struct2_t *demo2;
161  demo_struct1_t *demo1;
162  time_t starttime = time (0);
163  char *datestring = ctime (&starttime);
164 
165  /* Get back the root pointer */
166  checkpoint = svmdb_local_get_vec_variable (pm->c, "demo1_checkpoint",
167  sizeof (u8));
168 
169  /* It doesnt exist create our data structures */
170  if (checkpoint == 0)
171  {
172  /* Allocate data structures in process-private memory */
173  demo1 = clib_mem_alloc (sizeof (*demo2));
174  vec_validate (demo1, 0);
175  demo2 = clib_mem_alloc (sizeof (*demo2));
176 
177  demo1->demo2 = demo2;
178  demo1->name = format (0, "My name is Ishmael%c", 0);
179  demo2->string1 = format (0, "Here is string1%c", 0);
180  demo2->string2 = format (0, "Born at %s%c", datestring, 0);
181 
182  /* Create checkpoint */
183  serialize_open_vector (&sm, checkpoint);
184  serialize (&sm, serialize_demo1, demo1);
185  checkpoint = serialize_close_vector (&sm);
186 
187  /* Copy checkpoint into shared memory */
188  svmdb_local_set_vec_variable (pm->c, "demo1_checkpoint",
189  checkpoint, sizeof (u8));
190  /* Toss the process-private-memory original.. */
191  vec_free (checkpoint);
192  }
193  else
194  {
195  /* Open the checkpoint */
196  unserialize_open_data (&sm, checkpoint, vec_len (checkpoint));
197  unserialize (&sm, unserialize_demo1, &demo1);
198 
199  /* Toss the process-private-memory checkpoint copy */
200  vec_free (checkpoint);
201 
202  /* Off we go... */
203  demo2 = demo1->demo2;
204  fformat (stdout, "name: %s\n", demo1->name);
205  fformat (stdout, "demo2 location: %llx\n", demo2);
206  fformat (stdout, "string1: %s\n", demo2->string1);
207  fformat (stdout, "string2: %s\n", demo2->string2);
208  }
209  return 0;
210 }
211 
212 
213 int
214 main (int argc, char **argv)
215 {
216  unformat_input_t _input, *input = &_input;
218  clib_error_t *error = 0;
219 
220  /* Make a 4mb database arena, chroot so it's truly private */
221  pm->c = svmdb_map_chroot_size ("/ptest", 4 << 20);
222 
223  ASSERT (pm->c);
224 
225  unformat_init_command_line (input, argv);
226 
228  {
229  if (unformat (input, "malloc"))
230  error = persist_malloc (pm);
231  else if (unformat (input, "serialize"))
232  error = persist_serialize (pm);
233  else
234  {
235  error = clib_error_return (0, "Unknown flavor '%U'",
236  format_unformat_error, input);
237  break;
238  }
239  }
240 
241  svmdb_unmap (pm->c);
242 
243  if (error)
244  {
245  clib_error_report (error);
246  exit (1);
247  }
248  return 0;
249 }
250 
251 /*
252  * fd.io coding-style-patch-verification: ON
253  *
254  * Local Variables:
255  * eval: (c-set-style "gnu")
256  * End:
257  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
u8 * string2
Definition: persist.c:54
static void svm_pop_heap(void *oldheap)
Definition: svm.h:94
void * svmdb_local_get_variable_reference(svmdb_client_t *client, svmdb_namespace_t namespace, char *var)
Definition: svmdb.c:377
Optimized string handling code, including c11-compliant "safe C library" variants.
Fixed length block allocator.
void unserialize_demo1(serialize_main_t *sm, va_list *args)
Definition: persist.c:124
clib_error_t * persist_malloc(persist_main_t *pm)
Definition: persist.c:67
unsigned char u8
Definition: types.h:56
void svmdb_unmap(svmdb_client_t *client)
Definition: svmdb.c:138
__clib_export void * serialize_close_vector(serialize_main_t *m)
Definition: serialize.c:919
__clib_export word fformat(FILE *f, char *fmt,...)
Definition: format.c:462
static void * svm_push_data_heap(svm_region_t *rp)
Definition: svm.h:86
u8 * string1
Definition: persist.c:53
description fragment has unexpected format
Definition: map.api:433
#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
Definition: cJSON.c:84
struct _unformat_input_t unformat_input_t
void unformat_init_command_line(unformat_input_t *input, char *argv[])
Definition: unformat.c:1013
svm_region_t * db_rp
Definition: svmdb.h:69
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
__clib_export clib_error_t * serialize(serialize_main_t *m,...)
Definition: serialize.c:672
svmdb_client_t * c
Definition: persist.c:46
void svmdb_local_set_vec_variable(svmdb_client_t *client, char *var, void *val_arg, u32 elsize)
Definition: svmdb.c:560
#define ASSERT(truth)
clib_error_t * persist_serialize(persist_main_t *pm)
Definition: persist.c:155
Bitmaps built as vectors of machine words.
#define clib_error_report(e)
Definition: error.h:113
static void * clib_mem_alloc(uword size)
Definition: mem.h:253
void serialize_demo1(serialize_main_t *sm, va_list *args)
Definition: persist.c:143
int main(int argc, char **argv)
Definition: persist.c:214
__clib_export void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:891
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
persist_main_t persist_main
Definition: persist.c:49
__clib_export void unserialize_cstring(serialize_main_t *m, char **s)
Definition: serialize.c:178
void * svmdb_local_get_vec_variable(svmdb_client_t *client, char *var, u32 elsize)
Definition: svmdb.c:578
demo_struct2_t * demo2
Definition: persist.c:59
__clib_export void serialize_open_vector(serialize_main_t *m, u8 *vector)
Definition: serialize.c:909
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
__clib_export clib_error_t * unserialize(serialize_main_t *m,...)
Definition: serialize.c:684
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
pthread_mutex_t mutex
Definition: svm_common.h:37
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170