mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-02 07:15:31 +00:00
crtools: close a signal descriptor after passing a preparation stage
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. v3: fix a help message v4: Here is a sequence of actions how it can be used: * open a pipe * run a service with the pipe[1] as status_fd * read(pipe[0]) to wait a moment when the service will be ready to accept connections * do a work which requires the service * wait the service process to gets its exit status to be sure that everything okey travis-ci: success for crtools: close a signal descriptor after passing a preparation stage (rev6) Cc: Mike Rapoport <mike.rapoport@gmail.com> Cc: Kir Kolyshkin <kir@openvz.org> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
7e815625be
commit
ac5cac188d
@@ -506,6 +506,12 @@ Launches *criu* in page server mode.
|
|||||||
*--daemon*::
|
*--daemon*::
|
||||||
Runs page server as a daemon (background process).
|
Runs page server as a daemon (background process).
|
||||||
|
|
||||||
|
*--status_fd*::
|
||||||
|
Write \\0 to the FD and close it once page-server is ready to handle
|
||||||
|
requests. The status-fd allows to not daemonize a process and get its
|
||||||
|
exit code at the end.
|
||||||
|
It isn't supposed to use --daemon and --status-fd together.
|
||||||
|
|
||||||
*--address* 'address'::
|
*--address* 'address'::
|
||||||
Page server IP address.
|
Page server IP address.
|
||||||
|
|
||||||
|
@@ -76,6 +76,7 @@ void init_opts(void)
|
|||||||
opts.ghost_limit = DEFAULT_GHOST_LIMIT;
|
opts.ghost_limit = DEFAULT_GHOST_LIMIT;
|
||||||
opts.timeout = DEFAULT_TIMEOUT;
|
opts.timeout = DEFAULT_TIMEOUT;
|
||||||
opts.empty_ns = 0;
|
opts.empty_ns = 0;
|
||||||
|
opts.status_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_join_ns(const char *ptr)
|
static int parse_join_ns(const char *ptr)
|
||||||
@@ -285,6 +286,7 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
{ "deprecated", no_argument, 0, 1084 },
|
{ "deprecated", no_argument, 0, 1084 },
|
||||||
{ "display-stats", no_argument, 0, 1086 },
|
{ "display-stats", no_argument, 0, 1086 },
|
||||||
{ "weak-sysctls", no_argument, 0, 1087 },
|
{ "weak-sysctls", no_argument, 0, 1087 },
|
||||||
|
{ "status-fd", required_argument, 0, 1088 },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -604,6 +606,12 @@ int main(int argc, char *argv[], char *envp[])
|
|||||||
pr_msg("Will skip non-existant sysctls on restore\n");
|
pr_msg("Will skip non-existant sysctls on restore\n");
|
||||||
opts.weak_sysctls = true;
|
opts.weak_sysctls = true;
|
||||||
break;
|
break;
|
||||||
|
case 1088:
|
||||||
|
if (sscanf(optarg, "%d", &opts.status_fd) != 1) {
|
||||||
|
pr_err("Unable to parse a value of --status-fd\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
pr_msg("Version: %s\n", CRIU_VERSION);
|
pr_msg("Version: %s\n", CRIU_VERSION);
|
||||||
if (strcmp(CRIU_GITID, "0"))
|
if (strcmp(CRIU_GITID, "0"))
|
||||||
@@ -940,6 +948,8 @@ usage:
|
|||||||
" --address ADDR address of server or service\n"
|
" --address ADDR address of server or service\n"
|
||||||
" --port PORT port of page server\n"
|
" --port PORT port of page server\n"
|
||||||
" -d|--daemon run in the background after creating socket\n"
|
" -d|--daemon run in the background after creating socket\n"
|
||||||
|
" --status-fd FD write \\0 to the FD and close it once process is ready\n"
|
||||||
|
" to handle requests\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Other options:\n"
|
"Other options:\n"
|
||||||
" -h|--help show this text\n"
|
" -h|--help show this text\n"
|
||||||
|
@@ -117,6 +117,7 @@ struct cr_options {
|
|||||||
bool deprecated_ok;
|
bool deprecated_ok;
|
||||||
bool display_stats;
|
bool display_stats;
|
||||||
bool weak_sysctls;
|
bool weak_sysctls;
|
||||||
|
int status_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct cr_options opts;
|
extern struct cr_options opts;
|
||||||
|
@@ -172,6 +172,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,
|
extern int cr_system_userns(int in, int out, int err, char *cmd,
|
||||||
char *const argv[], unsigned flags, int userns_pid);
|
char *const argv[], unsigned flags, int userns_pid);
|
||||||
extern int cr_daemon(int nochdir, int noclose, int *keep_fd, int close_fd);
|
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);
|
extern int is_root_user(void);
|
||||||
|
|
||||||
static inline bool dir_dots(const struct dirent *de)
|
static inline bool dir_dots(const struct dirent *de)
|
||||||
|
18
criu/util.c
18
criu/util.c
@@ -690,6 +690,21 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int close_status_fd(void)
|
||||||
|
{
|
||||||
|
char 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 cr_daemon(int nochdir, int noclose, int *keep_fd, int close_fd)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
@@ -1155,6 +1170,9 @@ int run_tcp_server(bool daemon_mode, int *ask, int cfd, int sk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (close_status_fd())
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (sk >= 0) {
|
if (sk >= 0) {
|
||||||
ret = *ask = accept(sk, (struct sockaddr *)&caddr, &clen);
|
ret = *ask = accept(sk, (struct sockaddr *)&caddr, &clen);
|
||||||
if (*ask < 0)
|
if (*ask < 0)
|
||||||
|
Reference in New Issue
Block a user