[CRIU] [PATCH] crtools: close a signal descriptor after passing a preparation stage

Kir Kolyshkin kir at openvz.org
Wed Nov 16 23:24:39 PST 2016


On 11/16/2016 10:35 PM, Andrei Vagin wrote:
> From: Andrei Vagin <avagin at virtuozzo.com>
>
> This patch adds the --siganl-fd FD option to specify a file descriptor.
> CRIU will write '\0' to this descriptor and close it after passing
> a preparation stage.
>
> It is alternative way to demonizing a criu process after a preparation
> stage. It's imposiable to get exit code, if a process has daemonized.
>
> The introduced way allows to wait a preparation stage and to get an exit
> code. It can be easy used from shell and other script languages.
>
> Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
> ---
>   criu/crtools.c            | 13 ++++++++++++-
>   criu/include/cr_options.h |  1 +
>   criu/include/util.h       |  1 +
>   criu/uffd.c               |  3 +++
>   criu/util.c               | 18 ++++++++++++++++++
>   5 files changed, 35 insertions(+), 1 deletion(-)
>
> diff --git a/criu/crtools.c b/criu/crtools.c
> index 710059f..6c468f6 100644
> --- a/criu/crtools.c
> +++ b/criu/crtools.c
> @@ -55,7 +55,9 @@
>   
>   #include "../soccr/soccr.h"
>   
> -struct cr_options opts;
> +struct cr_options opts = {
> +	.status_fd = -1,
> +};
>   
>   void init_opts(void)
>   {
> @@ -285,6 +287,7 @@ int main(int argc, char *argv[], char *envp[])
>   		{ "deprecated",			no_argument,		0, 1084 },
>   		{ "check-only",			no_argument,		0, 1085 },
>   		{ "display-stats",		no_argument,		0, 1086 },
> +		{ "status-fd",			required_argument,	0, 1087 },
>   		{ },
>   	};
>   
> @@ -608,6 +611,12 @@ int main(int argc, char *argv[], char *envp[])
>   		case 1086:
>   			opts.display_stats = true;
>   			break;
> +		case 1087:
> +			if (sscanf(optarg, "%d", &opts.status_fd) != 1) {
> +				pr_err("Unable to parse a value of --status-fd\n");
> +				return 1;
> +			}
> +			break;
>   		case 'V':
>   			pr_msg("Version: %s\n", CRIU_VERSION);
>   			if (strcmp(CRIU_GITID, "0"))
> @@ -945,6 +954,8 @@ usage:
>   "  --address ADDR        address of server or service\n"
>   "  --port PORT           port of page server\n"
>   "  -d|--daemon           run in the background after creating socket\n"
> +"  --status-fd FD        write '\\0' and close FD after passing a preparation\n"
> +"                        stage\n"

"write \0 to and close FD once daemon is ready"

Also, try hard to fit help text in a single line. If needed, longer
explanation can be provided in other places like the man page
and wiki.

>   "\n"
>   "Other options:\n"
>   "  -h|--help             show this text\n"
> diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
> index e017236..abebe05 100644
> --- a/criu/include/cr_options.h
> +++ b/criu/include/cr_options.h
> @@ -118,6 +118,7 @@ struct cr_options {
>   	bool			deprecated_ok;
>   	bool			display_stats;
>   	bool			check_only;
> +	int			status_fd;
>   };
>   
>   extern struct cr_options opts;
> diff --git a/criu/include/util.h b/criu/include/util.h
> index 8eaee33..ea1053b 100644
> --- a/criu/include/util.h
> +++ b/criu/include/util.h
> @@ -170,6 +170,7 @@ extern int cr_system(int in, int out, int err, char *cmd, char *const argv[], un
>   extern int cr_system_userns(int in, int out, int err, char *cmd,
>   				char *const argv[], unsigned flags, int userns_pid);
>   extern int cr_daemon(int nochdir, int noclose, int *keep_fd, int close_fd);
> +extern int close_status_fd(void);
>   extern int is_root_user(void);
>   
>   static inline bool dir_dots(const struct dirent *de)
> diff --git a/criu/uffd.c b/criu/uffd.c
> index 7efccf5..ba81f4b 100644
> --- a/criu/uffd.c
> +++ b/criu/uffd.c
> @@ -1031,6 +1031,9 @@ int cr_lazy_pages(bool daemon)
>   		}
>   	}
>   
> +	if (close_status_fd())
> +		return -1;
> +
>   	nr_fds = epoll_nr_fds(task_entries->nr_tasks);
>   	epollfd = prepare_epoll(nr_fds, &events);
>   	if (epollfd < 0)
> diff --git a/criu/util.c b/criu/util.c
> index 2cf0355..4ecfd4d 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -687,6 +687,21 @@ out:
>   	return ret;
>   }
>   
> +int close_status_fd(void)
> +{
> +	int c = 0;
> +
> +	if (opts.status_fd < 0)
> +		return 0;
> +
> +	if (write(opts.status_fd, &c, 1) != 1) {
> +		pr_perror("Unable to write into the status fd");
> +		return -1;
> +	}
> +
> +	return close_safe(&opts.status_fd);
> +}
> +
>   int cr_daemon(int nochdir, int noclose, int *keep_fd, int close_fd)
>   {
>   	int pid;
> @@ -1144,6 +1159,9 @@ int run_tcp_server(bool daemon_mode, int *ask, int cfd, int sk)
>   		}
>   	}
>   
> +	if (close_status_fd())
> +		return -1;
> +
>   	if (sk >= 0) {
>   		ret = *ask = accept(sk, (struct sockaddr *)&caddr, &clen);
>   		if (*ask < 0)
otherwise
Reviewed-by: Kir Kolyshkin <kir at openvz.org>


More information about the CRIU mailing list