[CRIU] [PATCH] criu: Add exec-cmd option.
Deyan Doychev
deyan at 1h.com
Wed Mar 19 10:39:24 PDT 2014
From: Deyan Doychev <deyandoichev at gmail.com>
The --exec-cmd option specifies a command that will be execve()-ed on successful
restore. This way the command specified here will become the parent process of
the restored process tree.
When this option is specified criu will fork to become a daemon before it starts
restoring the processes. It also implies the -d option so waiting for the
restored processes to finish is responsibility of the command specified here.
This option will be used when restoring LinuX Containers.
Signed-off-by: Deyan Doychev <deyandoichev at gmail.com>
---
cr-restore.c | 3 +++
cr-service.c | 15 +++++++++++++++
crtools.c | 35 ++++++++++++++++++++++++++++++++++-
include/cr_options.h | 2 ++
lib/criu.c | 5 +++++
protobuf/rpc.proto | 1 +
6 files changed, 60 insertions(+), 1 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index b352daa..e528e3c 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1600,6 +1600,9 @@ int cr_restore_tasks(void)
{
int ret = -1;
+ if (opts.exec_cmd && daemon(1, 0))
+ return -1;
+
if (cr_plugin_init())
return -1;
diff --git a/cr-service.c b/cr-service.c
index 46a1004..bdb7257 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -265,6 +265,11 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
if (req->has_force_irmap)
opts.force_irmap = req->force_irmap;
+ if (req->exec_cmd) {
+ opts.exec_cmd = parse_exec_cmd(req->exec_cmd);
+ opts.restore_detach = true;
+ }
+
if (req->ps) {
opts.use_page_server = true;
opts.addr = req->ps->address;
@@ -342,6 +347,7 @@ static int restore_using_req(int sk, CriuOpts *req)
goto exit;
success = true;
+
exit:
if (send_criu_restore_resp(sk, success,
root_item ? root_item->pid.real : -1) == -1) {
@@ -349,6 +355,14 @@ exit:
success = false;
}
+ if (success && opts.exec_cmd) {
+ close(sk);
+ extern char **environ;
+ execve(opts.exec_cmd[0], opts.exec_cmd, environ);
+ pr_perror("Failed to exec cmd %s", opts.exec_cmd[0]);
+ success = false;
+ }
+
return success ? 0 : 1;
}
@@ -657,6 +671,7 @@ int cr_service(bool daemon_mode)
close(server_fd);
ret = cr_service_work(sk);
close(sk);
+
exit(ret != 0);
}
diff --git a/crtools.c b/crtools.c
index 047ac53..5591225 100644
--- a/crtools.c
+++ b/crtools.c
@@ -77,6 +77,23 @@ bad_ns:
return -1;
}
+char **parse_exec_cmd(char *optarg)
+{
+ int i;
+ int count = 1;
+ char **res;
+
+ for (i = strlen(optarg); i >= 0; i--)
+ if (strchr(" \t\r\n", optarg[i]))
+ count++;
+
+ res = xmalloc(count * sizeof(char *));
+ res[0] = strtok(optarg, " \t\r\n");
+ for (i = 1; (res[i] = strtok(NULL, " \t\r\n")); i++);
+
+ return res;
+}
+
static int parse_cpu_cap(struct cr_options *opts, const char *optarg)
{
bool inverse = false;
@@ -162,6 +179,7 @@ int main(int argc, char *argv[])
{ "libdir", required_argument, 0, 'L'},
{ "cpu-cap", required_argument, 0, 57},
{ "force-irmap", no_argument, 0, 58},
+ { "exec-cmd", required_argument, 0, 59},
{ },
};
@@ -333,6 +351,10 @@ int main(int argc, char *argv[])
case 'L':
opts.libdir = optarg;
break;
+ case 59:
+ opts.exec_cmd = parse_exec_cmd(optarg);
+ opts.restore_detach = true;
+ break;
case 'V':
pr_msg("Version: %s\n", CRIU_VERSION);
if (strcmp(CRIU_GITID, "0"))
@@ -390,7 +412,16 @@ int main(int argc, char *argv[])
if (!strcmp(argv[optind], "restore")) {
if (tree_id)
pr_warn("Using -t with criu restore is obsoleted\n");
- return cr_restore_tasks() != 0;
+
+ ret = cr_restore_tasks();
+ if (ret == 0 && opts.exec_cmd) {
+ extern char **environ;
+ execve(opts.exec_cmd[0], opts.exec_cmd, environ);
+ pr_perror("Failed to exec command %s\n", opts.exec_cmd[0]);
+ ret = 1;
+ }
+
+ return ret != 0;
}
if (!strcmp(argv[optind], "show"))
@@ -460,6 +491,8 @@ usage:
" (if not specified, value of --images-dir is used)\n"
" --cpu-cap CAP require certain cpu capability. CAP: may be one of:\n"
" 'fpu','all'. To disable capability, prefix it with '^'.\n"
+" --exec-cmd CMD execute this command on successful restore making it the\n"
+" parent of the restored process (implies -d)\n"
"\n"
"* Special resources support:\n"
" -x|--" USK_EXT_PARAM " allow external unix connections\n"
diff --git a/include/cr_options.h b/include/cr_options.h
index 782b866..a560324 100644
--- a/include/cr_options.h
+++ b/include/cr_options.h
@@ -48,10 +48,12 @@ struct cr_options {
bool auto_dedup;
unsigned int cpu_cap;
bool force_irmap;
+ char **exec_cmd;
};
extern struct cr_options opts;
extern void init_opts(void);
+extern char **parse_exec_cmd(char *optarg);
#endif /* __CR_OPTIONS_H__ */
diff --git a/lib/criu.c b/lib/criu.c
index 33927e8..77fdf10 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -110,6 +110,11 @@ void criu_set_cpu_cap(unsigned int cap)
opts->cpu_cap = cap;
}
+void criu_set_exec_cmd(char *cmdline)
+{
+ opts->exec_cmd = strdup(cmdline);
+}
+
static CriuResp *recv_resp(int socket_fd)
{
unsigned char buf[CR_MAX_MSG_SIZE];
diff --git a/protobuf/rpc.proto b/protobuf/rpc.proto
index 97f51fc..3e061b9 100644
--- a/protobuf/rpc.proto
+++ b/protobuf/rpc.proto
@@ -37,6 +37,7 @@ message criu_opts {
optional uint32 cpu_cap = 20 [default = 0xffffffff];
optional bool force_irmap = 21;
+ optional string exec_cmd = 22;
}
message criu_dump_resp {
--
1.7.1
More information about the CRIU
mailing list