[CRIU] [PATCH] criu: Add --keep-on-exec option
Cyrill Gorcunov
gorcunov at gmail.com
Tue May 28 18:17:57 MSK 2019
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.
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
Documentation/criu.txt | 7 +++++++
criu/config.c | 29 +++++++++++++++++++++++++++++
criu/include/cr_options.h | 2 ++
criu/util.c | 23 +++++++++++++++++++++++
4 files changed, 61 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..ae2bf2070f87 100644
--- a/criu/config.c
+++ b/criu/config.c
@@ -416,6 +416,28 @@ static int parse_join_ns(const char *ptr)
return 0;
}
+static int cmp_keep_on_exec(const void *__a, const void *__b)
+{
+ int a = ((int *)__a)[0];
+ int b = ((int *)__b)[0];
+ return a == b ? 0 : (a < b ? -1 : 1);
+}
+
+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);
+
+ 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]), cmp_keep_on_exec);
+
+ 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 +533,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 +820,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/util.c b/criu/util.c
index 31cdee1ff60f..d093b8669d86 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -515,6 +515,27 @@ 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 int cmp_keep_on_exec(const void *__a, const void *__b)
+{
+ int a = ((int *)__a)[0];
+ int b = ((int *)__b)[0];
+ return a == b ? 0 : (a < b ? -1 : 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]),
+ cmp_keep_on_exec))
+ return true;
+
+ return false;
+}
+
static int close_fds(int minfd)
{
DIR *dir;
@@ -541,6 +562,8 @@ static int close_fds(int minfd)
continue;
if (fd < minfd)
continue;
+ if (should_keep_on_exec(fd))
+ continue;
close(fd);
}
closedir(dir);
--
2.20.1
More information about the CRIU
mailing list