Add pidfile cmdline option

Change-Id: Ibaa61b624eb6683b1be6901a7b29f5f73aad27b2
Signed-off-by: Pierre Pfister <ppfister@cisco.com>
This commit is contained in:
Pierre Pfister
2017-07-27 22:57:34 -04:00
parent 215961829c
commit 9a244bb5e4
3 changed files with 98 additions and 9 deletions

View File

@ -317,6 +317,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;
int pidfd = -1;
/* Defaults */
um->cli_pager_buffer_limit = UNIX_CLI_DEFAULT_PAGER_LIMIT;
@ -415,11 +416,38 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
if (setegid (gid) == -1)
return clib_error_return_unix (0, "setegid");
}
else if (unformat (input, "pidfile %s", &um->pidfile))
;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
}
if (um->runtime_dir == 0)
{
uid_t uid = geteuid ();
if (uid == 00)
um->runtime_dir = format (0, "/run/%s%c",
vlib_default_runtime_dir, 0);
else
um->runtime_dir = format (0, "/run/user/%u/%s%c", uid,
vlib_default_runtime_dir, 0);
}
if (um->pidfile)
{
if ((error = vlib_unix_validate_runtime_file (um,
(char *) um->pidfile,
&um->pidfile)))
return error;
if (((pidfd = open ((char *) um->pidfile,
O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0))
{
return clib_error_return_unix (0, "open");
}
}
error = setup_signal_handlers (um);
if (error)
return error;
@ -434,19 +462,21 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
0) < 0)
clib_error_return (0, "daemon () fails");
}
um->unix_config_complete = 1;
if (um->runtime_dir == 0)
if (pidfd >= 0)
{
uid_t uid = geteuid ();
if (uid == 00)
um->runtime_dir = format (0, "/run/%s%c",
vlib_default_runtime_dir, 0);
else
um->runtime_dir = format (0, "/run/user/%u/%s%c", uid,
vlib_default_runtime_dir, 0);
u8 *lv = format (0, "%d", getpid ());
if (write (pidfd, (char *) lv, vec_len (lv)) != vec_len (lv))
{
vec_free (lv);
close (pidfd);
return clib_error_return_unix (0, "write");
}
vec_free (lv);
close (pidfd);
}
um->unix_config_complete = 1;
return 0;
}
@ -475,6 +505,9 @@ unix_config (vlib_main_t * vm, unformat_input_t * input)
* Very useful in situations where folks don't remember or can't be bothered
* to include CLI commands in bug reports.
*
* @cfgcmd{pidfile, &lt;filename&gt;}
* Writes the pid of the main thread in @c filename.
*
* @cfgcmd{full-coredump}
* Ask the Linux kernel to dump all memory-mapped address regions, instead
* of just text+data+bss.

View File

@ -106,6 +106,9 @@ typedef struct
/* runtime directory path */
u8 *runtime_dir;
/* pidfile filename */
u8 *pidfile;
/* unix config complete */
volatile int unix_config_complete;
@ -241,6 +244,10 @@ clib_error_t *foreach_directory_file (char *dir_name,
clib_error_t *vlib_unix_recursive_mkdir (char *path);
clib_error_t *vlib_unix_validate_runtime_file (unix_main_t * um,
const char *path,
u8 ** full_path);
#endif /* included_unix_unix_h */
/*

View File

@ -257,6 +257,55 @@ done:
return error;
}
clib_error_t *
vlib_unix_validate_runtime_file (unix_main_t * um,
const char *path, u8 ** full_path)
{
u8 *fp = 0;
char *last_slash = 0;
if (path[0] == '\0')
{
return clib_error_return (0, "path is an empty string");
}
else if (strncmp (path, "../", 3) == 0 || strstr (path, "/../"))
{
return clib_error_return (0, "'..' not allowed in runtime path");
}
else if (path[0] == '/')
{
/* Absolute path. Has to start with runtime directory */
if (strncmp ((char *) um->runtime_dir, path,
strlen ((char *) um->runtime_dir)))
{
return clib_error_return (0,
"file %s is not in runtime directory %s",
path, um->runtime_dir);
}
fp = format (0, "%s%c", path, '\0');
}
else
{
/* Relative path, just append to runtime */
fp = format (0, "%s/%s%c", um->runtime_dir, path, '\0');
}
/* We don't want to create a directory out of the last file */
if ((last_slash = strrchr ((char *) fp, '/')) != NULL)
*last_slash = '\0';
clib_error_t *error = vlib_unix_recursive_mkdir ((char *) fp);
if (last_slash != NULL)
*last_slash = '/';
if (error)
vec_free (fp);
*full_path = fp;
return error;
}
/*
* fd.io coding-style-patch-verification: ON
*