vlib: add graceful termination with status
[vpp.git] / src / vlib / main.h
index 860192c..a16f603 100644 (file)
@@ -143,6 +143,8 @@ typedef struct vlib_main_t
   u32 main_loop_exit_set;
   /* Set e.g. in the SIGTERM signal handler, checked in a safe place... */
   volatile u32 main_loop_exit_now;
+  /* Exit status that will be returned by the process upon exit. */
+  volatile int main_loop_exit_status;
   clib_longjmp_t main_loop_exit;
 #define VLIB_MAIN_LOOP_EXIT_NONE 0
 #define VLIB_MAIN_LOOP_EXIT_PANIC 1
@@ -152,9 +154,6 @@ typedef struct vlib_main_t
   /* Error marker to use when exiting main loop. */
   clib_error_t *main_loop_error;
 
-  /* Name for e.g. syslog. */
-  char *name;
-
   /* Start of the heap. */
   void *heap_base;
 
@@ -173,15 +172,9 @@ typedef struct vlib_main_t
   /* Node graph main structure. */
   vlib_node_main_t node_main;
 
-  /* Command line interface. */
-  vlib_cli_main_t cli_main;
-
   /* Packet trace buffer. */
   vlib_trace_main_t trace_main;
 
-  /* Packet trace capture filter */
-  vlib_trace_filter_t trace_filter;
-
   /* Error handling. */
   vlib_error_main_t error_main;
 
@@ -194,11 +187,10 @@ typedef struct vlib_main_t
   /* Stream index to use for distribution when MC is enabled. */
   u32 mc_stream_index;
 
-  vlib_one_time_waiting_process_t *procs_waiting_for_mc_stream_join;
+  /* Hash table to record which init functions have been called. */
+  uword *worker_init_functions_called;
 
-  /* Event logger. */
-  elog_main_t elog_main;
-  u32 configured_elog_ring_size;
+  vlib_one_time_waiting_process_t *procs_waiting_for_mc_stream_join;
 
   /* Event logger trace flags */
   int elog_trace_api_messages;
@@ -219,22 +211,11 @@ typedef struct vlib_main_t
   /* Buffer of random data for various uses. */
   clib_random_buffer_t random_buffer;
 
-  /* Hash table to record which init functions have been called. */
-  uword *init_functions_called;
-
   /* thread, cpu and numa_node indices */
   u32 thread_index;
   u32 cpu_id;
   u32 numa_node;
 
-  /* List of init functions to call, setup by constructors */
-  _vlib_init_function_list_elt_t *init_function_registrations;
-  _vlib_init_function_list_elt_t *worker_init_function_registrations;
-  _vlib_init_function_list_elt_t *main_loop_enter_function_registrations;
-  _vlib_init_function_list_elt_t *main_loop_exit_function_registrations;
-  _vlib_init_function_list_elt_t *api_init_function_registrations;
-  vlib_config_function_runtime_t *config_function_registrations;
-
   /* control-plane API queue signal pending, length indication */
   volatile u32 queue_signal_pending;
   volatile u32 api_queue_nonempty;
@@ -251,15 +232,6 @@ typedef struct vlib_main_t
   /* debugging */
   volatile int parked_at_barrier;
 
-  /* post-mortem callbacks */
-  void (**post_mortem_callbacks) (void);
-
-  /*
-   * Need to call vlib_worker_thread_node_runtime_update before
-   * releasing worker thread barrier. Only valid in vlib_global_main.
-   */
-  int need_vlib_worker_thread_node_runtime_update;
-
   /* Dispatch loop time accounting */
   u64 loops_this_reporting_interval;
   f64 loop_interval_end;
@@ -301,8 +273,53 @@ typedef struct vlib_main_t
 #endif
 } vlib_main_t;
 
+typedef struct vlib_global_main_t
+{
+  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+
+  /* Per-thread Mains */
+  vlib_main_t **vlib_mains;
+
+  /* Name for e.g. syslog. */
+  char *name;
+
+  /* post-mortem callbacks */
+  void (**post_mortem_callbacks) (void);
+
+  /*
+   * Need to call vlib_worker_thread_node_runtime_update before
+   * releasing worker thread barrier.
+   */
+  int need_vlib_worker_thread_node_runtime_update;
+
+  /* Command line interface. */
+  vlib_cli_main_t cli_main;
+
+  /* Node registrations added by constructors */
+  vlib_node_registration_t *node_registrations;
+
+  /* Event logger. */
+  elog_main_t elog_main;
+  u32 configured_elog_ring_size;
+
+  /* Packet trace capture filter */
+  vlib_trace_filter_t trace_filter;
+
+  /* List of init functions to call, setup by constructors */
+  _vlib_init_function_list_elt_t *init_function_registrations;
+  _vlib_init_function_list_elt_t *main_loop_enter_function_registrations;
+  _vlib_init_function_list_elt_t *main_loop_exit_function_registrations;
+  _vlib_init_function_list_elt_t *worker_init_function_registrations;
+  _vlib_init_function_list_elt_t *api_init_function_registrations;
+  vlib_config_function_runtime_t *config_function_registrations;
+
+  /* Hash table to record which init functions have been called. */
+  uword *init_functions_called;
+
+} vlib_global_main_t;
+
 /* Global main structure. */
-extern vlib_main_t vlib_global_main;
+extern vlib_global_main_t vlib_global_main;
 
 void vlib_worker_loop (vlib_main_t * vm);
 
@@ -374,6 +391,8 @@ vlib_panic (vlib_main_t * vm)
   vlib_panic_with_error (vm, 0);
 }
 
+/* Asynchronously requests exit with the given status. */
+void vlib_exit_with_status (vlib_main_t *vm, int status);
 
 always_inline f64
 vlib_internal_node_vector_rate (vlib_main_t * vm)
@@ -441,6 +460,18 @@ always_inline void vlib_set_queue_signal_callback
   vm->queue_signal_callback = fp;
 }
 
+always_inline void
+vlib_main_init ()
+{
+  vlib_global_main_t *vgm = &vlib_global_main;
+  vlib_main_t *vm;
+
+  vgm->init_functions_called = hash_create (0, /* value bytes */ 0);
+
+  vm = clib_mem_alloc_aligned (sizeof (*vm), CLIB_CACHE_LINE_BYTES);
+  vec_add1 (vgm->vlib_mains, vm);
+}
+
 /* Main routine. */
 int vlib_main (vlib_main_t * vm, unformat_input_t * input);