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)
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, -1, "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, -1, -1, "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)
......
......@@ -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)
......
......@@ -277,55 +277,19 @@ 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;
}
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;
}
ip_tool_cmd = getenv("CR_IP_TOOL");
if (!ip_tool_cmd)
ip_tool_cmd = "ip";
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, -1, ip_tool_cmd,
(char *[]) { "ip", arg1, arg2, NULL });
if (ret) {
pr_err("IP tool failed on %s %s\n", arg1, arg2);
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