Make VPP runtime directory configurable
[vpp.git] / src / vlib / unix / main.c
index 562778e..cb34a89 100644 (file)
@@ -46,6 +46,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
 
 /** Default CLI pager limit is not configured in startup.conf */
 #define UNIX_CLI_DEFAULT_PAGER_LIMIT 100000
@@ -53,6 +56,8 @@
 /** Default CLI history depth if not configured in startup.conf */
 #define UNIX_CLI_DEFAULT_HISTORY 50
 
+char *vlib_default_runtime_dir __attribute__ ((weak));
+char *vlib_default_runtime_dir = "/run/vlib";
 
 unix_main_t unix_main;
 
@@ -311,6 +316,7 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
 {
   unix_main_t *um = &unix_main;
   clib_error_t *error = 0;
+  gid_t gid;
 
   /* Defaults */
   um->cli_pager_buffer_limit = UNIX_CLI_DEFAULT_PAGER_LIMIT;
@@ -328,6 +334,8 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
       else
        if (unformat (input, "cli-listen %s", &um->cli_listen_socket.config))
        ;
+      else if (unformat (input, "runtime-dir %s", &um->runtime_dir))
+       ;
       else if (unformat (input, "cli-line-mode"))
        um->cli_line_mode = 1;
       else if (unformat (input, "cli-no-banner"))
@@ -340,6 +348,26 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
       else
        if (unformat (input, "cli-history-limit %d", &um->cli_history_limit))
        ;
+      else if (unformat (input, "coredump-size"))
+       {
+         uword coredump_size = 0;
+         if (unformat (input, "unlimited"))
+           {
+             coredump_size = RLIM_INFINITY;
+           }
+         else
+           if (!unformat (input, "%U", unformat_memory_size, &coredump_size))
+           {
+             return clib_error_return (0,
+                                       "invalid coredump-size parameter `%U'",
+                                       format_unformat_error, input);
+           }
+         const struct rlimit new_limit = { coredump_size, coredump_size };
+         if (0 != setrlimit (RLIMIT_CORE, &new_limit))
+           {
+             clib_unix_warning ("prlimit() failed");
+           }
+       }
       else if (unformat (input, "full-coredump"))
        {
          int fd;
@@ -382,17 +410,22 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
              vec_free (lv);
            }
        }
+      else if (unformat (input, "gid %U", unformat_unix_gid, &gid))
+       {
+         if (setegid (gid) == -1)
+           return clib_error_return_unix (0, "setegid");
+       }
       else
        return clib_error_return (0, "unknown input `%U'",
                                  format_unformat_error, input);
     }
 
+  error = setup_signal_handlers (um);
+  if (error)
+    return error;
+
   if (!(um->flags & UNIX_FLAG_INTERACTIVE))
     {
-      error = setup_signal_handlers (um);
-      if (error)
-       return error;
-
       openlog (vm->name, LOG_CONS | LOG_PERROR | LOG_PID, LOG_DAEMON);
       clib_error_register_handler (unix_error_handler, um);
 
@@ -403,6 +436,9 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
     }
   um->unix_config_complete = 1;
 
+  if (um->runtime_dir == 0)
+    um->runtime_dir = format (0, "%s%c", vlib_default_runtime_dir, 0);
+
   return 0;
 }
 
@@ -434,6 +470,10 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
  * Ask the Linux kernel to dump all memory-mapped address regions, instead
  * of just text+data+bss.
  *
+ * @cfgcmd{runtime-dir}
+ * Define directory where VPP is going to store all runtime files.
+ * Default is /run/vpp.
+ *
  * @cfgcmd{cli-listen, &lt;address:port&gt;}
  * Bind the CLI to listen at the address and port given. @clocalhost
  * on TCP port @c 5002, given as <tt>cli-listen localhost:5002</tt>,
@@ -460,7 +500,7 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
  * Limit pager buffer to @c nn lines of output.
  * A value of @c 0 disables the pager. Default value: @c 100000
 ?*/
-VLIB_CONFIG_FUNCTION (unix_config, "unix");
+VLIB_EARLY_CONFIG_FUNCTION (unix_config, "unix");
 
 static clib_error_t *
 unix_exit (vlib_main_t * vm)
@@ -488,13 +528,28 @@ thread0 (uword arg)
   return i;
 }
 
+u8 *
+vlib_thread_stack_init (uword thread_index)
+{
+  vec_validate (vlib_thread_stacks, thread_index);
+  vlib_thread_stacks[thread_index] = clib_mem_alloc_aligned
+    (VLIB_THREAD_STACK_SIZE, VLIB_THREAD_STACK_SIZE);
+
+  /*
+   * Disallow writes to the bottom page of the stack, to
+   * catch stack overflows.
+   */
+  if (mprotect (vlib_thread_stacks[thread_index],
+               clib_mem_get_page_size (), PROT_READ) < 0)
+    clib_unix_warning ("thread stack");
+  return vlib_thread_stacks[thread_index];
+}
+
 int
 vlib_unix_main (int argc, char *argv[])
 {
   vlib_main_t *vm = &vlib_global_main; /* one and only time for this! */
-  vlib_thread_main_t *tm = &vlib_thread_main;
   unformat_input_t input;
-  u8 *thread_stacks;
   clib_error_t *e;
   int i;
 
@@ -503,6 +558,14 @@ vlib_unix_main (int argc, char *argv[])
   vm->heap_base = clib_mem_get_heap ();
   ASSERT (vm->heap_base);
 
+  unformat_init_command_line (&input, (char **) vm->argv);
+  if ((e = vlib_plugin_config (vm, &input)))
+    {
+      clib_error_report (e);
+      return 1;
+    }
+  unformat_free (&input);
+
   i = vlib_plugin_early_init (vm);
   if (i)
     return i;
@@ -518,29 +581,9 @@ vlib_unix_main (int argc, char *argv[])
     }
   unformat_free (&input);
 
-  /*
-   * allocate n x VLIB_THREAD_STACK_SIZE stacks, aligned to a
-   * VLIB_THREAD_STACK_SIZE boundary
-   * See also: os_get_cpu_number() in vlib/vlib/threads.c
-   */
-  thread_stacks = clib_mem_alloc_aligned
-    ((uword) tm->n_thread_stacks * VLIB_THREAD_STACK_SIZE,
-     VLIB_THREAD_STACK_SIZE);
-
-  vec_validate (vlib_thread_stacks, tm->n_thread_stacks - 1);
-  for (i = 0; i < vec_len (vlib_thread_stacks); i++)
-    {
-      vlib_thread_stacks[i] = thread_stacks;
-
-      /*
-       * Disallow writes to the bottom page of the stack, to
-       * catch stack overflows.
-       */
-      if (mprotect (thread_stacks, clib_mem_get_page_size (), PROT_READ) < 0)
-       clib_unix_warning ("thread stack");
+  vlib_thread_stack_init (0);
 
-      thread_stacks += VLIB_THREAD_STACK_SIZE;
-    }
+  __os_thread_index = 0;
 
   i = clib_calljmp (thread0, (uword) vm,
                    (void *) (vlib_thread_stacks[0] +