Commit e3fbb630 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

crtools: use a special function for executing external utils

Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent cd2be93b
...@@ -235,118 +235,66 @@ static int close_mountpoint(DIR *dfd) ...@@ -235,118 +235,66 @@ static int close_mountpoint(DIR *dfd)
static int tmpfs_dump(struct mount_info *pm) static int tmpfs_dump(struct mount_info *pm)
{ {
int ret, status; int ret = -1;
pid_t pid;
pid = fork();
if (pid == -1) {
pr_perror("fork() failed\n");
return -1;
} else if (pid == 0) {
char tmpfs_path[PATH_MAX]; char tmpfs_path[PATH_MAX];
int fd, fd_img; int fd, fd_img = -1;
DIR *fdir; DIR *fdir = NULL;
fdir = open_mountpoint(pm); fdir = open_mountpoint(pm);
if (fdir == NULL) if (fdir == NULL)
exit(1); return -1;
fd = dirfd(fdir); fd = dirfd(fdir);
if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC) == -1) { if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC) == -1) {
pr_perror("Can not drop FD_CLOEXEC"); pr_perror("Can not drop FD_CLOEXEC");
exit(1); goto out;
} }
fd_img = open_image(CR_FD_TMPFS, O_DUMP, pm->mnt_id); fd_img = open_image(CR_FD_TMPFS, O_DUMP, pm->mnt_id);
if (fd_img < 0) if (fd_img < 0)
exit(1); goto out;
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);
/*
* tmpfs is in another mount namespace,
* a direct path is inaccessible
*/
snprintf(tmpfs_path, sizeof(tmpfs_path), snprintf(tmpfs_path, sizeof(tmpfs_path),
"/proc/self/fd/%d", fd); "/proc/self/fd/%d", fd);
execlp("tar", "tar", "--create", ret = cr_system(-1, fd_img, -1, "tar", (char *[])
{ "tar", "--create",
"--gzip", "--gzip",
"--check-links", "--check-links",
"--preserve-permissions", "--preserve-permissions",
"--sparse", "--sparse",
"--numeric-owner", "--numeric-owner",
"--directory", tmpfs_path, ".", NULL); "--directory", tmpfs_path, ".", NULL });
pr_perror("exec failed");
exit(1);
}
ret = waitpid(pid, &status, 0); if (ret)
if (ret == -1) {
pr_perror("waitpid() failed");
return -1;
}
if (status) {
pr_err("Can't dump tmpfs content\n"); 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) static int tmpfs_restore(struct mount_info *pm)
{ {
int ret, status = -1; int ret;
pid_t pid;
pid = fork();
if (pid == -1) {
pr_perror("fork() failed\n");
return -1;
} else if (pid == 0) {
int fd_img; int fd_img;
fd_img = open_image_ro(CR_FD_TMPFS, pm->mnt_id); fd_img = open_image_ro(CR_FD_TMPFS, pm->mnt_id);
if (fd_img < 0) if (fd_img < 0)
exit(1); return -1;
ret = dup2(fd_img, STDIN_FILENO); ret = cr_system(fd_img, -1, -1, "tar",
if (ret < 0) { (char *[]) {"tar", "--extract", "--gzip",
pr_perror("dup2() failed"); "--directory", pm->mountpoint, NULL});
exit(1);
}
close(fd_img); close(fd_img);
execlp("tar", "tar", "--extract", "--gzip", if (ret) {
"--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) {
pr_err("Can't restore tmpfs content\n"); pr_err("Can't restore tmpfs content\n");
return -1; return -1;
} }
return status; return 0;
} }
static int binfmt_misc_dump(struct mount_info *pm) static int binfmt_misc_dump(struct mount_info *pm)
......
...@@ -151,19 +151,9 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags) ...@@ -151,19 +151,9 @@ int dump_namespaces(struct pid *ns_pid, unsigned int ns_flags)
int prepare_namespace(int pid, unsigned long clone_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", pr_info("Restoring namespaces %d flags 0x%lx\n",
pid, clone_flags); 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 * On netns restore we launch an IP tool, thus we
* have to restore it _before_ altering the mount * have to restore it _before_ altering the mount
...@@ -171,22 +161,15 @@ int prepare_namespace(int pid, unsigned long clone_flags) ...@@ -171,22 +161,15 @@ int prepare_namespace(int pid, unsigned long clone_flags)
*/ */
if ((clone_flags & CLONE_NEWNET) && prepare_net_ns(pid)) if ((clone_flags & CLONE_NEWNET) && prepare_net_ns(pid))
goto out; return -1;
if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(pid)) if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(pid))
goto out; return -1;
if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(pid)) if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(pid))
goto out; return -1;
if ((clone_flags & CLONE_NEWNS) && prepare_mnt_ns(pid)) if ((clone_flags & CLONE_NEWNS) && prepare_mnt_ns(pid))
goto out; return -1;
ret = 0;
out:
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) {
pr_perror("Can not set mask of blocked signals");
BUG();
}
return ret; return 0;
} }
int try_show_namespaces(int ns_pid, struct cr_options *o) int try_show_namespaces(int ns_pid, struct cr_options *o)
......
...@@ -277,55 +277,19 @@ static int restore_links(int pid) ...@@ -277,55 +277,19 @@ static int restore_links(int pid)
static int run_ip_tool(char *arg1, char *arg2, int fdin, int fdout) 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); pr_debug("\tRunning ip %s %s\n", arg1, arg2);
pid = fork();
if (pid < 0) {
pr_perror("Can't forn IP tool");
return -1;
}
if (!pid) {
char *ip_tool_cmd;
ip_tool_cmd = getenv("CR_IP_TOOL"); ip_tool_cmd = getenv("CR_IP_TOOL");
if (!ip_tool_cmd) if (!ip_tool_cmd)
ip_tool_cmd = "ip"; ip_tool_cmd = "ip";
if (fdin < 0) ret = cr_system(fdin, fdout, -1, ip_tool_cmd,
close(0); (char *[]) { "ip", arg1, arg2, NULL });
else if (fdin != 0) { if (ret) {
dup2(fdin, 0); pr_err("IP tool failed on %s %s\n", arg1, arg2);
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));
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment