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