Add pidfile cmdline option
Change-Id: Ibaa61b624eb6683b1be6901a7b29f5f73aad27b2 Signed-off-by: Pierre Pfister <ppfister@cisco.com>
This commit is contained in:
@ -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, <filename>}
|
||||
* 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.
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
*
|
||||
|
Reference in New Issue
Block a user