[CRIU] [PATCH cr 2/2] crtools: use a special function for executing external utils

Andrey Vagin avagin at openvz.org
Tue Sep 25 18:05:42 EDT 2012


Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 mount.c      |  120 ++++++++++++++++-----------------------------------------
 namespaces.c |   27 ++-----------
 net.c        |   54 ++++----------------------
 3 files changed, 48 insertions(+), 153 deletions(-)

diff --git a/mount.c b/mount.c
index 4534ff3..cade3e1 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, -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)
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..6a22fd2 100644
--- a/net.c
+++ b/net.c
@@ -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;
 	}
 
-- 
1.7.1



More information about the CRIU mailing list