FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
main.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * main.c: Unix main routine
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 #include <vlib/vlib.h>
40 #include <vlib/unix/unix.h>
41 #include <vlib/unix/plugin.h>
42 
43 #include <signal.h>
44 #include <sys/ucontext.h>
45 #include <syslog.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <sys/time.h>
50 #include <sys/resource.h>
51 
52 /** Default CLI pager limit is not configured in startup.conf */
53 #define UNIX_CLI_DEFAULT_PAGER_LIMIT 100000
54 
55 /** Default CLI history depth if not configured in startup.conf */
56 #define UNIX_CLI_DEFAULT_HISTORY 50
57 
58 
60 
61 static clib_error_t *
63 {
64  unix_main_t *um = &unix_main;
65  um->vlib_main = vm;
67 }
68 
70 
71 static void
72 unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
73 {
74  uword fatal;
75  u8 *msg = 0;
76 
77  msg = format (msg, "received signal %U, PC %U",
78  format_signal, signum, format_ucontext_pc, uc);
79 
80  if (signum == SIGSEGV)
81  msg = format (msg, ", faulting address %p", si->si_addr);
82 
83  switch (signum)
84  {
85  /* these (caught) signals cause the application to exit */
86  case SIGTERM:
87  if (unix_main.vlib_main->main_loop_exit_set)
88  {
89  syslog (LOG_ERR | LOG_DAEMON, "received SIGTERM, exiting...");
90 
93  }
94  /* fall through */
95  case SIGQUIT:
96  case SIGINT:
97  case SIGILL:
98  case SIGBUS:
99  case SIGSEGV:
100  case SIGHUP:
101  case SIGFPE:
102  fatal = 1;
103  break;
104 
105  /* by default, print a message and continue */
106  default:
107  fatal = 0;
108  break;
109  }
110 
111  /* Null terminate. */
112  vec_add1 (msg, 0);
113 
114  if (fatal)
115  {
116  syslog (LOG_ERR | LOG_DAEMON, "%s", msg);
117  os_exit (1);
118  }
119  else
120  clib_warning ("%s", msg);
121 
122  vec_free (msg);
123 }
124 
125 static clib_error_t *
127 {
128  uword i;
129  struct sigaction sa;
130 
131  for (i = 1; i < 32; i++)
132  {
133  memset (&sa, 0, sizeof (sa));
134  sa.sa_sigaction = (void *) unix_signal_handler;
135  sa.sa_flags = SA_SIGINFO;
136 
137  switch (i)
138  {
139  /* these signals take the default action */
140  case SIGABRT:
141  case SIGKILL:
142  case SIGSTOP:
143  case SIGUSR1:
144  case SIGUSR2:
145  continue;
146 
147  /* ignore SIGPIPE, SIGCHLD */
148  case SIGPIPE:
149  case SIGCHLD:
150  sa.sa_sigaction = (void *) SIG_IGN;
151  break;
152 
153  /* catch and handle all other signals */
154  default:
155  break;
156  }
157 
158  if (sigaction (i, &sa, 0) < 0)
159  return clib_error_return_unix (0, "sigaction %U", format_signal, i);
160  }
161 
162  return 0;
163 }
164 
165 static void
166 unix_error_handler (void *arg, u8 * msg, int msg_len)
167 {
168  unix_main_t *um = arg;
169 
170  /* Echo to stderr when interactive. */
171  if (um->flags & UNIX_FLAG_INTERACTIVE)
172  {
173  CLIB_UNUSED (int r) = write (2, msg, msg_len);
174  }
175  else
176  {
177  char save = msg[msg_len - 1];
178 
179  /* Null Terminate. */
180  msg[msg_len - 1] = 0;
181 
182  syslog (LOG_ERR | LOG_DAEMON, "%s", msg);
183 
184  msg[msg_len - 1] = save;
185  }
186 }
187 
188 void
190 {
191  unix_main_t *um = &unix_main;
192 
193  if (um->flags & UNIX_FLAG_INTERACTIVE || error == 0)
194  return;
195 
196  {
197  char save;
198  u8 *msg;
199  u32 msg_len;
200 
201  msg = error->what;
202  msg_len = vec_len (msg);
203 
204  /* Null Terminate. */
205  save = msg[msg_len - 1];
206  msg[msg_len - 1] = 0;
207 
208  syslog (LOG_ERR | LOG_DAEMON, "%s", msg);
209 
210  msg[msg_len - 1] = save;
211  }
212 }
213 
214 static uword
217 {
218  unix_main_t *um = &unix_main;
219  u8 *buf = 0;
220  uword l, n = 1;
221 
222  vlib_process_suspend (vm, 2.0);
223 
224  while (um->unix_config_complete == 0)
225  vlib_process_suspend (vm, 0.1);
226 
227  if (um->startup_config_filename)
228  {
229  unformat_input_t sub_input;
230  int fd;
231  struct stat s;
232  char *fn = (char *) um->startup_config_filename;
233 
234  fd = open (fn, O_RDONLY);
235  if (fd < 0)
236  {
237  clib_warning ("failed to open `%s'", fn);
238  return 0;
239  }
240 
241  if (fstat (fd, &s) < 0)
242  {
243  clib_warning ("failed to stat `%s'", fn);
244  bail:
245  close (fd);
246  return 0;
247  }
248 
249  if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
250  {
251  clib_warning ("not a regular file: `%s'", fn);
252  goto bail;
253  }
254 
255  while (n > 0)
256  {
257  l = vec_len (buf);
258  vec_resize (buf, 4096);
259  n = read (fd, buf + l, 4096);
260  if (n > 0)
261  {
262  _vec_len (buf) = l + n;
263  if (n < 4096)
264  break;
265  }
266  else
267  break;
268  }
269  if (um->log_fd && vec_len (buf))
270  {
271  u8 *lv = 0;
272  lv = format (lv, "%U: ***** Startup Config *****\n%v",
273  format_timeval, 0 /* current bat-time */ ,
274  0 /* current bat-format */ ,
275  buf);
276  {
277  int rv __attribute__ ((unused)) =
278  write (um->log_fd, lv, vec_len (lv));
279  }
280  vec_reset_length (lv);
281  lv = format (lv, "%U: ***** End Startup Config *****\n",
282  format_timeval, 0 /* current bat-time */ ,
283  0 /* current bat-format */ );
284  {
285  int rv __attribute__ ((unused)) =
286  write (um->log_fd, lv, vec_len (lv));
287  }
288  vec_free (lv);
289  }
290 
291  if (vec_len (buf))
292  {
293  unformat_init_vector (&sub_input, buf);
294  vlib_cli_input (vm, &sub_input, 0, 0);
295  /* frees buf for us */
296  unformat_free (&sub_input);
297  }
298  close (fd);
299  }
300  return 0;
301 }
302 
303 /* *INDENT-OFF* */
305  .function = startup_config_process,
306  .type = VLIB_NODE_TYPE_PROCESS,
307  .name = "startup-config-process",
308 };
309 /* *INDENT-ON* */
310 
311 static clib_error_t *
313 {
314  unix_main_t *um = &unix_main;
315  clib_error_t *error = 0;
316 
317  /* Defaults */
320 
322  {
323  char *cli_prompt;
324  if (unformat (input, "interactive"))
326  else if (unformat (input, "nodaemon"))
327  um->flags |= UNIX_FLAG_NODAEMON;
328  else if (unformat (input, "cli-prompt %s", &cli_prompt))
329  vlib_unix_cli_set_prompt (cli_prompt);
330  else
331  if (unformat (input, "cli-listen %s", &um->cli_listen_socket.config))
332  ;
333  else if (unformat (input, "cli-line-mode"))
334  um->cli_line_mode = 1;
335  else if (unformat (input, "cli-no-banner"))
336  um->cli_no_banner = 1;
337  else if (unformat (input, "cli-no-pager"))
338  um->cli_no_pager = 1;
339  else if (unformat (input, "cli-pager-buffer-limit %d",
341  ;
342  else
343  if (unformat (input, "cli-history-limit %d", &um->cli_history_limit))
344  ;
345  else if (unformat (input, "coredump-size"))
346  {
347  uword coredump_size = 0;
348  if (unformat (input, "unlimited"))
349  {
350  coredump_size = RLIM_INFINITY;
351  }
352  else
353  if (!unformat (input, "%U", unformat_memory_size, &coredump_size))
354  {
355  return clib_error_return (0,
356  "invalid coredump-size parameter `%U'",
357  format_unformat_error, input);
358  }
359  const struct rlimit new_limit = { coredump_size, coredump_size };
360  if (0 != setrlimit (RLIMIT_CORE, &new_limit))
361  {
362  clib_unix_warning ("prlimit() failed");
363  }
364  }
365  else if (unformat (input, "full-coredump"))
366  {
367  int fd;
368 
369  fd = open ("/proc/self/coredump_filter", O_WRONLY);
370  if (fd >= 0)
371  {
372  if (write (fd, "0x6f\n", 5) != 5)
373  clib_unix_warning ("coredump filter write failed!");
374  close (fd);
375  }
376  else
377  clib_unix_warning ("couldn't open /proc/self/coredump_filter");
378  }
379  else if (unformat (input, "startup-config %s",
381  ;
382  else if (unformat (input, "exec %s", &um->startup_config_filename))
383  ;
384  else if (unformat (input, "log %s", &um->log_filename))
385  {
386  um->log_fd = open ((char *) um->log_filename,
387  O_CREAT | O_WRONLY | O_APPEND, 0644);
388  if (um->log_fd < 0)
389  {
390  clib_warning ("couldn't open log '%s'\n", um->log_filename);
391  um->log_fd = 0;
392  }
393  else
394  {
395  u8 *lv = 0;
396  lv = format (0, "%U: ***** Start: PID %d *****\n",
397  format_timeval, 0 /* current bat-time */ ,
398  0 /* current bat-format */ ,
399  getpid ());
400  {
401  int rv __attribute__ ((unused)) =
402  write (um->log_fd, lv, vec_len (lv));
403  }
404  vec_free (lv);
405  }
406  }
407  else
408  return clib_error_return (0, "unknown input `%U'",
409  format_unformat_error, input);
410  }
411 
412  if (!(um->flags & UNIX_FLAG_INTERACTIVE))
413  {
414  error = setup_signal_handlers (um);
415  if (error)
416  return error;
417 
418  openlog (vm->name, LOG_CONS | LOG_PERROR | LOG_PID, LOG_DAEMON);
420 
421  if (!(um->flags & UNIX_FLAG_NODAEMON) && daemon ( /* chdir to / */ 0,
422  /* stdin/stdout/stderr -> /dev/null */
423  0) < 0)
424  clib_error_return (0, "daemon () fails");
425  }
426  um->unix_config_complete = 1;
427 
428  return 0;
429 }
430 
431 /* unix { ... } configuration. */
432 /*?
433  *
434  * @cfgcmd{interactive}
435  * Attach CLI to stdin/out and provide a debugging command line interface.
436  * Implies @c nodaemon.
437  *
438  * @cfgcmd{nodaemon}
439  * Do not fork or background the VPP process. Typically used when invoking
440  * VPP applications from a process monitor.
441  *
442  * @cfgcmd{exec, &lt;filename&gt;}
443  * @par <code>startup-config &lt;filename&gt;</code>
444  * Read startup operational configuration from @c filename.
445  * The contents of the file will be performed as though entered at the CLI.
446  * The two keywords are aliases for the same function; if both are specified,
447  * only the last will have an effect.
448  *
449  * @cfgcmd{log, &lt;filename&gt;}
450  * Logs the startup configuration and all subsequent CLI commands in
451  * @c filename.
452  * Very useful in situations where folks don't remember or can't be bothered
453  * to include CLI commands in bug reports.
454  *
455  * @cfgcmd{full-coredump}
456  * Ask the Linux kernel to dump all memory-mapped address regions, instead
457  * of just text+data+bss.
458  *
459  * @cfgcmd{cli-listen, &lt;address:port&gt;}
460  * Bind the CLI to listen at the address and port given. @clocalhost
461  * on TCP port @c 5002, given as <tt>cli-listen localhost:5002</tt>,
462  * is typical.
463  *
464  * @cfgcmd{cli-line-mode}
465  * Disable character-by-character I/O on stdin. Useful when combined with,
466  * for example, <tt>emacs M-x gud-gdb</tt>.
467  *
468  * @cfgcmd{cli-prompt, &lt;string&gt;}
469  * Configure the CLI prompt to be @c string.
470  *
471  * @cfgcmd{cli-history-limit, &lt;nn&gt;}
472  * Limit commmand history to @c nn lines. A value of @c 0
473  * disables command history. Default value: @c 50
474  *
475  * @cfgcmd{cli-no-banner}
476  * Disable the login banner on stdin and Telnet connections.
477  *
478  * @cfgcmd{cli-no-pager}
479  * Disable the output pager.
480  *
481  * @cfgcmd{cli-pager-buffer-limit, &lt;nn&gt;}
482  * Limit pager buffer to @c nn lines of output.
483  * A value of @c 0 disables the pager. Default value: @c 100000
484 ?*/
486 
487 static clib_error_t *
489 {
490  /* Close syslog connection. */
491  closelog ();
492  return 0;
493 }
494 
496 
498 
499 static uword
501 {
502  vlib_main_t *vm = (vlib_main_t *) arg;
503  unformat_input_t input;
504  int i;
505 
506  unformat_init_command_line (&input, (char **) vm->argv);
507  i = vlib_main (vm, &input);
508  unformat_free (&input);
509 
510  return i;
511 }
512 
513 int
514 vlib_unix_main (int argc, char *argv[])
515 {
516  vlib_main_t *vm = &vlib_global_main; /* one and only time for this! */
518  unformat_input_t input;
519  u8 *thread_stacks;
520  clib_error_t *e;
521  int i;
522 
523  vm->argv = (u8 **) argv;
524  vm->name = argv[0];
525  vm->heap_base = clib_mem_get_heap ();
526  ASSERT (vm->heap_base);
527 
528  unformat_init_command_line (&input, (char **) vm->argv);
529  if ((e = vlib_plugin_config (vm, &input)))
530  {
531  clib_error_report (e);
532  return 1;
533  }
534  unformat_free (&input);
535 
536  i = vlib_plugin_early_init (vm);
537  if (i)
538  return i;
539 
540  unformat_init_command_line (&input, (char **) vm->argv);
541  if (vm->init_functions_called == 0)
542  vm->init_functions_called = hash_create (0, /* value bytes */ 0);
543  e = vlib_call_all_config_functions (vm, &input, 1 /* early */ );
544  if (e != 0)
545  {
546  clib_error_report (e);
547  return 1;
548  }
549  unformat_free (&input);
550 
551  /*
552  * allocate n x VLIB_THREAD_STACK_SIZE stacks, aligned to a
553  * VLIB_THREAD_STACK_SIZE boundary
554  * See also: os_get_cpu_number() in vlib/vlib/threads.c
555  */
556  thread_stacks = clib_mem_alloc_aligned
558  VLIB_THREAD_STACK_SIZE);
559 
561  for (i = 0; i < vec_len (vlib_thread_stacks); i++)
562  {
563  vlib_thread_stacks[i] = thread_stacks;
564 
565  /*
566  * Disallow writes to the bottom page of the stack, to
567  * catch stack overflows.
568  */
569  if (mprotect (thread_stacks, clib_mem_get_page_size (), PROT_READ) < 0)
570  clib_unix_warning ("thread stack");
571 
572  thread_stacks += VLIB_THREAD_STACK_SIZE;
573  }
574 
575  i = clib_calljmp (thread0, (uword) vm,
576  (void *) (vlib_thread_stacks[0] +
577  VLIB_THREAD_STACK_SIZE));
578  return i;
579 }
580 
581 /*
582  * fd.io coding-style-patch-verification: ON
583  *
584  * Local Variables:
585  * eval: (c-set-style "gnu")
586  * End:
587  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
static clib_error_t * unix_main_init(vlib_main_t *vm)
Definition: main.c:62
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
#define CLIB_UNUSED(x)
Definition: clib.h:79
static clib_error_t * unix_input_init(vlib_main_t *vm)
Definition: input.c:269
void vlib_cli_input(vlib_main_t *vm, unformat_input_t *input, vlib_cli_output_function_t *function, uword function_arg)
Definition: cli.c:540
u32 flags
Definition: unix.h:83
volatile int unix_config_complete
Definition: unix.h:106
static uword startup_config_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: main.c:215
unix_main_t unix_main
Definition: main.c:59
u32 cli_pager_buffer_limit
Definition: unix.h:122
void vlib_unix_cli_set_prompt(char *prompt)
Set the CLI prompt.
Definition: cli.c:2536
u32 main_loop_exit_set
Definition: main.h:87
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
clib_error_t * vlib_plugin_config(vlib_main_t *vm, unformat_input_t *input)
Definition: plugin.c:466
#define VLIB_MAIN_LOOP_EXIT_CLI
Definition: main.h:92
void clib_longjmp(clib_longjmp_t *save, uword return_value)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
void clib_error_register_handler(clib_error_handler_func_t func, void *arg)
Definition: error.c:75
clib_socket_t cli_listen_socket
Definition: unix.h:92
#define UNIX_FLAG_NODAEMON
Definition: unix.h:86
int log_fd
Definition: unix.h:110
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
u8 * what
Definition: error.h:78
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
Definition: node_funcs.h:432
u8 * format_timeval(u8 *s, va_list *args)
Definition: unix-formats.c:748
static vlib_node_registration_t startup_config_node
(constructor) VLIB_REGISTER_NODE (startup_config_node)
Definition: main.c:304
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define clib_error_return(e, args...)
Definition: error.h:111
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:241
vlib_main_t * vlib_main
Definition: unix.h:81
#define vlib_call_init_function(vm, x)
Definition: init.h:162
int vlib_plugin_early_init(vlib_main_t *vm)
Definition: plugin.c:353
char * name
Definition: main.h:98
int cli_line_mode
Definition: unix.h:113
#define UNIX_CLI_DEFAULT_PAGER_LIMIT
Default CLI pager limit is not configured in startup.conf.
Definition: main.c:53
vlib_main_t vlib_global_main
Definition: main.c:1617
static clib_error_t * unix_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:312
struct _unformat_input_t unformat_input_t
#define clib_error_return_unix(e, args...)
Definition: error.h:114
int cli_no_banner
Definition: unix.h:119
void unformat_init_command_line(unformat_input_t *input, char *argv[])
Definition: unformat.c:1006
static void unix_signal_handler(int signum, siginfo_t *si, ucontext_t *uc)
Definition: main.c:72
u8 * startup_config_filename
Definition: unix.h:103
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:119
static clib_error_t * setup_signal_handlers(unix_main_t *um)
Definition: main.c:126
uword * init_functions_called
Definition: main.h:156
vlib_thread_main_t vlib_thread_main
Definition: threads.c:36
u32 cli_history_limit
Definition: unix.h:116
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1030
static clib_error_t * unix_exit(vlib_main_t *vm)
Definition: main.c:488
u8 ** argv
Definition: main.h:176
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:276
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
void * heap_base
Definition: main.h:101
int cli_no_pager
Definition: unix.h:125
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x)
Definition: init.h:116
#define clib_warning(format, args...)
Definition: error.h:59
static void * clib_mem_get_heap(void)
Definition: mem.h:217
#define hash_create(elts, value_bytes)
Definition: hash.h:658
int vlib_main(vlib_main_t *volatile vm, unformat_input_t *input)
Definition: main.c:1654
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
#define UNIX_CLI_DEFAULT_HISTORY
Default CLI history depth if not configured in startup.conf.
Definition: main.c:56
#define UNIX_FLAG_INTERACTIVE
Definition: unix.h:85
void os_exit(int code)
Definition: main.c:271
#define clib_error_report(e)
Definition: error.h:125
u64 uword
Definition: types.h:112
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u8 ** vlib_thread_stacks
Definition: main.c:497
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
u8 * format_signal(u8 *s, va_list *args)
Definition: unix-formats.c:834
clib_error_t * vlib_call_all_config_functions(vlib_main_t *vm, unformat_input_t *input, int is_early)
Definition: init.c:94
void vlib_unix_error_report(vlib_main_t *vm, clib_error_t *error)
Definition: main.c:189
#define clib_unix_warning(format, args...)
Definition: error.h:68
#define VLIB_THREAD_STACK_SIZE
Definition: threads.h:66
unformat_function_t unformat_memory_size
Definition: format.h:294
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:117
uword clib_calljmp(uword(*func)(uword func_arg), uword func_arg, void *stack)
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
static void unix_error_handler(void *arg, u8 *msg, int msg_len)
Definition: main.c:166
clib_longjmp_t main_loop_exit
Definition: main.h:88
uword clib_mem_get_page_size(void)
Definition: mem_mheap.c:110
static uword thread0(uword arg)
Definition: main.c:500
u8 * log_filename
Definition: unix.h:109
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
u8 * format_ucontext_pc(u8 *s, va_list *args)
Definition: unix-formats.c:885
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
int vlib_unix_main(int argc, char *argv[])
Definition: main.c:514