From d30521a3cfa831856271fbde98a4562a518f5bc5 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Tue, 17 Jun 2014 21:08:49 +0400 Subject: [PATCH] crtools: Add internal "swrk" action To help restoring tasks from images as kids to the caller, we can do the trick. 1. Caller sets himself as child reaper with PR_SET_CHILD_SUBREAPER prctl 2. Caller makes sure criu binary is suid-ed and owned by root 3. Caller forks and calls execv() on criu asking it to restore 4. Criu finishes restore and exits. All its kids get reparented to the criu's parent, i.e. -- to the library caller. 5. Caller stops being subreaper In order to make the execv() and arguments passing simpler I propose to execv() the service worker function, that accepts options via socket. This is good for two reasons. 1. We don't have to construct CLI options in libcriu 2. We reuse other service's facilities, such as security checks, ability to dump, pre-dump and other stuff Signed-off-by: Pavel Emelyanov --- cr-service.c | 5 ++--- crtools.c | 9 +++++++++ include/cr-service.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cr-service.c b/cr-service.c index dc0ff5a1e..64ce751b7 100644 --- a/cr-service.c +++ b/cr-service.c @@ -493,12 +493,10 @@ out: return send_criu_msg(sk, &resp); } -static int cr_service_work(int sk) +int cr_service_work(int sk) { CriuReq *msg = 0; - init_opts(); - if (recv_criu_msg(sk, &msg) == -1) { pr_perror("Can't recv request"); goto err; @@ -684,6 +682,7 @@ int cr_service(bool daemon_mode) exit(1); close(server_fd); + init_opts(); ret = cr_service_work(sk); close(sk); exit(ret != 0); diff --git a/crtools.c b/crtools.c index 568418657..c3a2e270b 100644 --- a/crtools.c +++ b/crtools.c @@ -183,6 +183,15 @@ int main(int argc, char *argv[]) if (init_service_fd()) return 1; + if (!strcmp(argv[1], "swrk")) + /* + * This is to start criu service worker from libcriu calls. + * The usage is "criu swrk " and is not for CLI/scripts. + * The arguments semantics can change at any tyme with the + * corresponding lib call change. + */ + return cr_service_work(atoi(argv[2])); + while (1) { idx = -1; opt = getopt_long(argc, argv, short_opts, long_opts, &idx); diff --git a/include/cr-service.h b/include/cr-service.h index fa048de25..eadc0c30c 100644 --- a/include/cr-service.h +++ b/include/cr-service.h @@ -4,6 +4,7 @@ #include "protobuf/rpc.pb-c.h" extern int cr_service(bool deamon_mode); +int cr_service_work(int sk); extern int send_criu_dump_resp(int socket_fd, bool success, bool restored); extern int send_criu_rpc_script(char *name, int arg);