[CRIU] [PATCH cr 2/2] crtools: use a special function for executing
external utils
Andrey Vagin
avagin at openvz.org
Thu Sep 20 09:24:45 EDT 2012
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
mount.c | 120 ++++++++++++++++-----------------------------------------
namespaces.c | 27 ++-----------
net.c | 53 ++++---------------------
3 files changed, 48 insertions(+), 152 deletions(-)
diff --git a/mount.c b/mount.c
index 4534ff3..c4f575a 100644
--- a/mount.c
+++ b/mount.c
@@ -235,118 +235,66 @@ static int close_mountpoint(DIR *dfd)
static int tmpfs_dump(struct mount_info *pm)
{
- int ret, status;
- pid_t pid;
+ int ret = -1;
+ char tmpfs_path[PATH_MAX];
+ int fd, fd_img = -1;
+ DIR *fdir = NULL;
- pid = fork();
- if (pid == -1) {
- pr_perror("fork() failed\n");
+ fdir = open_mountpoint(pm);
+ if (fdir == NULL)
return -1;
- } else if (pid == 0) {
- char tmpfs_path[PATH_MAX];
- int fd, fd_img;
- DIR *fdir;
-
- fdir = open_mountpoint(pm);
- if (fdir == NULL)
- exit(1);
-
- fd = dirfd(fdir);
- if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC) == -1) {
- pr_perror("Can not drop FD_CLOEXEC");
- exit(1);
- }
-
- fd_img = open_image(CR_FD_TMPFS, O_DUMP, pm->mnt_id);
- if (fd_img < 0)
- exit(1);
- ret = dup2(fd_img, STDOUT_FILENO);
- if (ret < 0) {
- pr_perror("dup2() failed");
- exit(1);
- }
- ret = dup2(log_get_fd(), STDERR_FILENO);
- if (ret < 0) {
- pr_perror("dup2() failed");
- exit(1);
- }
- close(fd_img);
+ fd = dirfd(fdir);
+ if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC) == -1) {
+ pr_perror("Can not drop FD_CLOEXEC");
+ goto out;
+ }
- /*
- * tmpfs is in another mount namespace,
- * a direct path is inaccessible
- */
+ fd_img = open_image(CR_FD_TMPFS, O_DUMP, pm->mnt_id);
+ if (fd_img < 0)
+ goto out;
- snprintf(tmpfs_path, sizeof(tmpfs_path),
- "/proc/self/fd/%d", fd);
+ snprintf(tmpfs_path, sizeof(tmpfs_path),
+ "/proc/self/fd/%d", fd);
- execlp("tar", "tar", "--create",
+ ret = cr_system(-1, fd_img, log_get_fd(), "tar", (char *[])
+ { "tar", "--create",
"--gzip",
"--check-links",
"--preserve-permissions",
"--sparse",
"--numeric-owner",
- "--directory", tmpfs_path, ".", NULL);
- pr_perror("exec failed");
- exit(1);
- }
-
- ret = waitpid(pid, &status, 0);
- if (ret == -1) {
- pr_perror("waitpid() failed");
- return -1;
- }
+ "--directory", tmpfs_path, ".", NULL });
- if (status) {
+ if (ret)
pr_err("Can't dump tmpfs content\n");
- return -1;
- }
- return 0;
+out:
+ close_safe(&fd_img);
+ close_mountpoint(fdir);
+ return ret;
}
static int tmpfs_restore(struct mount_info *pm)
{
- int ret, status = -1;
- pid_t pid;
+ int ret;
+ int fd_img;
- pid = fork();
- if (pid == -1) {
- pr_perror("fork() failed\n");
+ fd_img = open_image_ro(CR_FD_TMPFS, pm->mnt_id);
+ if (fd_img < 0)
return -1;
- } else if (pid == 0) {
- int fd_img;
- fd_img = open_image_ro(CR_FD_TMPFS, pm->mnt_id);
- if (fd_img < 0)
- exit(1);
+ ret = cr_system(fd_img, log_get_fd(), log_get_fd(), "tar",
+ (char *[]) {"tar", "--extract", "--gzip",
+ "--directory", pm->mountpoint, NULL});
+ close(fd_img);
- ret = dup2(fd_img, STDIN_FILENO);
- if (ret < 0) {
- pr_perror("dup2() failed");
- exit(1);
- }
- close(fd_img);
-
- execlp("tar", "tar", "--extract", "--gzip",
- "--directory", pm->mountpoint, NULL);
- pr_perror("exec failed");
- exit(1);
- }
-
- ret = waitpid(pid, &status, 0);
- if (ret == -1) {
- pr_perror("waitpid() failed");
- return -1;
- }
-
- if (status) {
+ if (ret) {
pr_err("Can't restore tmpfs content\n");
return -1;
}
- return status;
+ return 0;
}
static int binfmt_misc_dump(struct mount_info *pm)
diff --git a/namespaces.c b/namespaces.c
index 55c0228..dc8e008 100644
--- a/namespaces.c
+++ b/namespaces.c
@@ -151,19 +151,9 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags)
int prepare_namespace(int pid, unsigned long clone_flags)
{
- sigset_t blockmask, oldmask;
- int ret = -1;
-
pr_info("Restoring namespaces %d flags 0x%lx\n",
pid, clone_flags);
- sigemptyset(&blockmask);
- sigaddset(&blockmask, SIGCHLD);
- if (sigprocmask(SIG_BLOCK, &blockmask, &oldmask) == -1) {
- pr_perror("Can not set mask of blocked signals");
- return -1;
- }
-
/*
* On netns restore we launch an IP tool, thus we
* have to restore it _before_ altering the mount
@@ -171,22 +161,15 @@ int prepare_namespace(int pid, unsigned long clone_flags)
*/
if ((clone_flags & CLONE_NEWNET) && prepare_net_ns(pid))
- goto out;
+ return -1;
if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(pid))
- goto out;
+ return -1;
if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(pid))
- goto out;
+ return -1;
if ((clone_flags & CLONE_NEWNS) && prepare_mnt_ns(pid))
- goto out;
-
- ret = 0;
-out:
- if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
- pr_perror("Can not set mask of blocked signals");
- BUG();
- }
+ return -1;
- return ret;
+ return 0;
}
int try_show_namespaces(int ns_pid, struct cr_options *o)
diff --git a/net.c b/net.c
index 0e5017b..84633d3 100644
--- a/net.c
+++ b/net.c
@@ -277,55 +277,20 @@ static int restore_links(int pid)
static int run_ip_tool(char *arg1, char *arg2, int fdin, int fdout)
{
- int pid, ret, status;
+ char *ip_tool_cmd;
+ int ret;
pr_debug("\tRunning ip %s %s\n", arg1, arg2);
- pid = fork();
- if (pid < 0) {
- pr_perror("Can't forn IP tool");
- return -1;
- }
+ ip_tool_cmd = getenv("CR_IP_TOOL");
+ if (!ip_tool_cmd)
+ ip_tool_cmd = "ip";
- if (!pid) {
- char *ip_tool_cmd;
-
- ip_tool_cmd = getenv("CR_IP_TOOL");
- if (!ip_tool_cmd)
- ip_tool_cmd = "ip";
-
- if (fdin < 0)
- close(0);
- else if (fdin != 0) {
- dup2(fdin, 0);
- close(fdin);
- }
-
- if (fdout < 0)
- close(1);
- else if (fdout != 1) {
- dup2(fdout, 1);
- close(fdout);
- }
-
- if (log_get_fd() != 2) {
- dup2(log_get_fd(), 2);
- close(log_get_fd());
- }
-
- execlp(ip_tool_cmd, "ip", arg1, arg2, NULL);
- exit(-1);
- }
-
- ret = waitpid(pid, &status, 0);
- if (ret < 0) {
- pr_perror("Can't wait IP tool");
- return -1;
- }
- if (!(WIFEXITED(status) && !WEXITSTATUS(status))) {
- pr_err("IP tool failed on %s %s with %d (%d)\n", arg1, arg2,
- status, WEXITSTATUS(status));
+ ret = cr_system(fdin, fdout, log_get_fd(), ip_tool_cmd,
+ (char *[]) { "ip", arg1, arg2, NULL });
+ if (ret) {
+ pr_err("IP tool failed on %s %s\n", arg1, arg2);
return -1;
}
--
1.7.1
More information about the CRIU
mailing list