FD.io VPP  v21.10.1-2-g0a485f517
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  {
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  */
demo_struct1_t::demo2
demo_struct2_t * demo2
Definition: persist.c:59
svmdb_local_set_vec_variable
void svmdb_local_set_vec_variable(svmdb_client_t *client, char *var, void *val_arg, u32 elsize)
Definition: svmdb.c:560
svmdb_unmap
void svmdb_unmap(svmdb_client_t *client)
Definition: svmdb.c:138
svmdb_client_t
Definition: svmdb.h:65
unserialize
__clib_export clib_error_t * unserialize(serialize_main_t *m,...)
Definition: serialize.c:684
persist_malloc
clib_error_t * persist_malloc(persist_main_t *pm)
Definition: persist.c:67
bitmap.h
clib.h
persist_main_t
Definition: persist.c:44
string.h
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
svmdb_client_t::db_rp
svm_region_t * db_rp
Definition: svmdb.h:69
unserialize_demo1
void unserialize_demo1(serialize_main_t *sm, va_list *args)
Definition: persist.c:124
fifo.h
demo_struct2_t::string1
u8 * string1
Definition: persist.c:53
clib_error_report
#define clib_error_report(e)
Definition: error.h:113
unformat_input_t
struct _unformat_input_t unformat_input_t
serialize_open_vector
__clib_export void serialize_open_vector(serialize_main_t *m, u8 *vector)
Definition: serialize.c:909
serialize_main_t
Definition: serialize.h:144
error
Definition: cJSON.c:88
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
svm_region_::mutex
pthread_mutex_t mutex
Definition: svm_common.h:38
svmdb_local_get_variable_reference
void * svmdb_local_get_variable_reference(svmdb_client_t *client, svmdb_namespace_t namespace, char *var)
Definition: svmdb.c:377
demo_struct2_t
Definition: persist.c:51
hash.h
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
serialize
__clib_export clib_error_t * serialize(serialize_main_t *m,...)
Definition: serialize.c:672
demo_struct1_t
Definition: persist.c:57
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
demo_struct1_t::name
u8 * name
Definition: persist.c:60
svm_pop_heap
static void svm_pop_heap(void *oldheap)
Definition: svm.h:94
pool.h
Fixed length block allocator. Pools are built from clib vectors and bitmaps. Use pools when repeatedl...
time.h
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
format.h
svmdb.h
serialize_cstring
__clib_export void serialize_cstring(serialize_main_t *m, char *s)
Definition: serialize.c:164
unserialize_open_data
__clib_export void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:891
unserialize_cstring
__clib_export void unserialize_cstring(serialize_main_t *m, char **s)
Definition: serialize.c:178
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
main
int main(int argc, char **argv)
Definition: persist.c:214
persist_main
persist_main_t persist_main
Definition: persist.c:49
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
serialize_close_vector
__clib_export void * serialize_close_vector(serialize_main_t *m)
Definition: serialize.c:919
SVMDB_NAMESPACE_VEC
@ SVMDB_NAMESPACE_VEC
Definition: svmdb.h:51
svmdb_local_get_vec_variable
void * svmdb_local_get_vec_variable(svmdb_client_t *client, char *var, u32 elsize)
Definition: svmdb.c:578
fformat
__clib_export word fformat(FILE *f, char *fmt,...)
Definition: format.c:466
persist_main_t::c
svmdb_client_t * c
Definition: persist.c:46
vec.h
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
serialize.h
serialize_demo1
void serialize_demo1(serialize_main_t *sm, va_list *args)
Definition: persist.c:143
unformat_init_command_line
void unformat_init_command_line(unformat_input_t *input, char *argv[])
Definition: unformat.c:1013
persist_serialize
clib_error_t * persist_serialize(persist_main_t *pm)
Definition: persist.c:155
svm_push_data_heap
static void * svm_push_data_heap(svm_region_t *rp)
Definition: svm.h:86
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
demo_struct2_t::string2
u8 * string2
Definition: persist.c:54
heap.h
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137