[CRIU] [PATCH] criu: Add exec-cmd option.

Andrew Vagin avagin at parallels.com
Thu Mar 20 01:25:59 PDT 2014


Add Adrian to CC. He is integrating CRIU in OpenMPI and he may be
interested in this patch too.

On Wed, Mar 19, 2014 at 07:39:24PM +0200, Deyan Doychev wrote:
> 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
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu


More information about the CRIU mailing list