[CRIU] [PATCH v2] criu: Add --keep-on-exec option
Andrey Vagin
avagin at gmail.com
Sat Jun 22 06:42:09 MSK 2019
On Tue, Jun 04, 2019 at 10:41:21AM +0300, Cyrill Gorcunov wrote:
> When we run action scripts we communicate with third-party
> tools via file descriptors inherited from a criu execution
> caller.
>
> Since commit 6c8ea60491305482eb60d9b17a8635ab9248a5ab this
> no longer possible, moreover it breaks API.
>
> Thus lets provide --keep-on-exec option where we could
> tell explicitly which exactly fds should be kept opened.
>
> v2:
> - provide qsort_cmp_int_array to avoid code duplication
We need a test for this functionality...
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
> ---
> Documentation/criu.txt | 7 +++++++
> criu/config.c | 23 +++++++++++++++++++++++
> criu/include/cr_options.h | 2 ++
> criu/include/util.h | 2 ++
> criu/util.c | 23 +++++++++++++++++++++++
> 5 files changed, 57 insertions(+)
>
> diff --git a/Documentation/criu.txt b/Documentation/criu.txt
> index 6111c3baf0e1..5ffdd7cb1b28 100644
> --- a/Documentation/criu.txt
> +++ b/Documentation/criu.txt
> @@ -138,6 +138,13 @@ Common options are applicable to any 'command'.
> notification message contains a file descriptor for
> the master pty
>
> +*--keep-on-exec* 'fd'::
> + Keep 'fd' file descriptor when executing service programs and scripts
> + during certain stages. When *criu* is executed it inherits opened file
> + descriptors or a caller (if they are present). Sometimes it is needed
> + to pass such descriptors to the *--action-script* scripts, otherwise
> + they get closed for security reason.
> +
> *-V*, *--version*::
> Print program version and exit.
>
> diff --git a/criu/config.c b/criu/config.c
> index 24f0b33858ad..a53f0c0ab6ce 100644
> --- a/criu/config.c
> +++ b/criu/config.c
> @@ -416,6 +416,22 @@ static int parse_join_ns(const char *ptr)
> return 0;
> }
>
> +static int parse_keep_on_exec(char *optarg)
> +{
> + size_t size = sizeof(opts.keep_on_exec[0]) * (opts.nr_keep_on_exec + 1);
> + int fd = atoi(optarg);
atoi() does not detect errors. You can use strtol or sscanf.
> +
> + if (xrealloc_safe(&opts.keep_on_exec, size))
> + return -ENOMEM;
> +
> + opts.keep_on_exec[opts.nr_keep_on_exec++] = fd;
> + qsort(opts.keep_on_exec, opts.nr_keep_on_exec,
> + sizeof(opts.keep_on_exec[0]),
> + qsort_cmp_int_array);
> +
> + return 0;
> +}
> +
> /*
> * parse_options() is the point where the getopt parsing happens. The CLI
> * parsing as well as the configuration file parsing happens here.
> @@ -511,6 +527,7 @@ int parse_options(int argc, char **argv, bool *usage_error,
> BOOL_OPT("remote", &opts.remote),
> { "config", required_argument, 0, 1089},
> { "no-default-config", no_argument, 0, 1090},
> + { "keep-on-exec", required_argument, 0, 1092},
> { },
> };
>
> @@ -797,6 +814,12 @@ int parse_options(int argc, char **argv, bool *usage_error,
> case 1091:
> opts.ps_socket = atoi(optarg);
> break;
> + case 1092:
> + if (parse_keep_on_exec(optarg)) {
> + pr_err("Unable to parse value for --keep-on-exec\n");
> + return 1;
> + }
> + break;
> case 'V':
> pr_msg("Version: %s\n", CRIU_VERSION);
> if (strcmp(CRIU_GITID, "0"))
> diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
> index 8ddbf2341a48..2022ba12f8ec 100644
> --- a/criu/include/cr_options.h
> +++ b/criu/include/cr_options.h
> @@ -90,6 +90,8 @@ struct cr_options {
> struct list_head inherit_fds;
> struct list_head external;
> struct list_head join_ns;
> + int *keep_on_exec;
> + size_t nr_keep_on_exec;
> char *libdir;
> int use_page_server;
> unsigned short port;
> diff --git a/criu/include/util.h b/criu/include/util.h
> index a14be72293be..f4d2171bca35 100644
> --- a/criu/include/util.h
> +++ b/criu/include/util.h
> @@ -378,4 +378,6 @@ static inline void print_stack_trace(pid_t pid) {}
> ___ret; \
> })
>
> +extern int qsort_cmp_int_array(const void *__a, const void *__b);
> +
> #endif /* __CR_UTIL_H__ */
> diff --git a/criu/util.c b/criu/util.c
> index 31cdee1ff60f..3cfe7e02cce2 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -515,6 +515,20 @@ int cr_system(int in, int out, int err, char *cmd, char *const argv[], unsigned
> return cr_system_userns(in, out, err, cmd, argv, flags, -1);
> }
>
> +static bool should_keep_on_exec(int fd)
> +{
> + if (!opts.nr_keep_on_exec)
> + return false;
> +
> + if (bsearch(&fd, opts.keep_on_exec,
> + opts.nr_keep_on_exec,
> + sizeof(opts.keep_on_exec[0]),
> + qsort_cmp_int_array))
> + return true;
> +
> + return false;
> +}
> +
> static int close_fds(int minfd)
> {
> DIR *dir;
> @@ -541,6 +555,8 @@ static int close_fds(int minfd)
> continue;
> if (fd < minfd)
> continue;
> + if (should_keep_on_exec(fd))
> + continue;
> close(fd);
> }
> closedir(dir);
> @@ -1341,6 +1357,13 @@ void rlimit_unlimit_nofile(void)
> service_fd_rlim_cur = kdat.sysctl_nr_open;
> }
>
> +int qsort_cmp_int_array(const void *__a, const void *__b)
> +{
> + int a = ((int *)__a)[0];
> + int b = ((int *)__b)[0];
> + return a == b ? 0 : (a < b ? -1 : 1);
> +}
> +
>
> #ifdef __GLIBC__
> #include <execinfo.h>
> --
> 2.20.1
>
More information about the CRIU
mailing list