[lxc-devel] [lxcfs/master] bindings: cleanup various parts

brauner on Github lxc-bot at linuxcontainers.org
Wed Feb 26 18:16:27 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 365 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200226/9b83557c/attachment-0001.bin>
-------------- next part --------------
From 87f7558ba45d7cd190127c62ea6f9be9b09246c7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 26 Feb 2020 19:03:50 +0100
Subject: [PATCH] bindings: cleanup various parts

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 bindings.c   | 174 +++++++++++++++++++++++++--------------------------
 configure.ac |   7 +++
 utils.c      |  25 +++++---
 utils.h      |   4 +-
 4 files changed, 115 insertions(+), 95 deletions(-)

diff --git a/bindings.c b/bindings.c
index 8a84a5d..d365ce6 100644
--- a/bindings.c
+++ b/bindings.c
@@ -39,6 +39,7 @@
 #include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/param.h>
+#include <signal.h>
 #include <sys/socket.h>
 #include <sys/syscall.h>
 #include <sys/sysinfo.h>
@@ -313,6 +314,32 @@ static int send_creds_clone_wrapper(void *arg)
 	return 0;
 }
 
+/*
+ * Let's use the "standard stack limit" (i.e. glibc thread size default) for
+ * stack sizes: 8MB.
+ */
+#define __LXCFS_STACK_SIZE (8 * 1024 * 1024)
+static pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags)
+{
+	pid_t ret;
+	void *stack;
+
+	stack = malloc(__LXCFS_STACK_SIZE);
+	if (!stack)
+		return ret_errno(ENOMEM);
+
+#ifdef __ia64__
+	ret = __clone2(fn, stack, __LXCFS_STACK_SIZE, flags | SIGCHLD, arg, NULL);
+#else
+	ret = clone(fn, stack + __LXCFS_STACK_SIZE, flags | SIGCHLD, arg, NULL);
+#endif
+	return ret;
+}
+
+#define LXCFS_PROC_PID_NS_LEN                                    \
+	(STRLITERALLEN("/proc/") + INTTYPE_TO_STRLEN(uint64_t) + \
+	 STRLITERALLEN("/ns/pid") + 1)
+
 /*
  * clone a task which switches to @task's namespace and writes '1'.
  * over a unix sock so we can read the task's reaper's pid in our
@@ -325,73 +352,64 @@ static int send_creds_clone_wrapper(void *arg)
  */
 static void write_task_init_pid_exit(int sock, pid_t target)
 {
-	char fnam[100];
+	__do_close_prot_errno int fd = -EBADF;
+	char path[LXCFS_PROC_PID_NS_LEN];
 	pid_t pid;
-	int fd, ret;
-	size_t stack_size = sysconf(_SC_PAGESIZE);
-	void *stack = alloca(stack_size);
-
-	ret = snprintf(fnam, sizeof(fnam), "/proc/%d/ns/pid", (int)target);
-	if (ret < 0 || ret >= sizeof(fnam))
-		_exit(1);
-
-	fd = open(fnam, O_RDONLY);
-	if (fd < 0) {
-		perror("write_task_init_pid_exit open of ns/pid");
-		_exit(1);
-	}
-	if (setns(fd, 0)) {
-		perror("write_task_init_pid_exit setns 1");
-		close(fd);
-		_exit(1);
-	}
-	pid = clone(send_creds_clone_wrapper, stack + stack_size, SIGCHLD, &sock);
+
+	snprintf(path, sizeof(path), "/proc/%d/ns/pid", (int)target);
+	fd = open(path, O_RDONLY | O_CLOEXEC);
+	if (fd < 0)
+		log_exit("write_task_init_pid_exit open of ns/pid");
+
+	if (setns(fd, 0))
+		log_exit("Failed to setns to pid namespace of process %d", target);
+
+	pid = lxcfs_clone(send_creds_clone_wrapper, &sock, 0);
 	if (pid < 0)
-		_exit(1);
+		_exit(EXIT_FAILURE);
+
 	if (pid != 0) {
 		if (!wait_for_pid(pid))
-			_exit(1);
-		_exit(0);
+			_exit(EXIT_FAILURE);
+
+		_exit(EXIT_SUCCESS);
 	}
 }
 
 static pid_t get_init_pid_for_task(pid_t task)
 {
-	int sock[2];
-	pid_t pid;
-	pid_t ret = -1;
 	char v = '0';
+	pid_t pid_ret = -1;
+	pid_t pid;
+	int sock[2];
 	struct ucred cred;
 
-	if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sock) < 0) {
-		perror("socketpair");
+	if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sock) < 0)
 		return -1;
-	}
 
 	pid = fork();
 	if (pid < 0)
 		goto out;
-	if (!pid) {
+
+	if (pid == 0) {
 		close(sock[1]);
 		write_task_init_pid_exit(sock[0], task);
-		_exit(0);
+		_exit(EXIT_SUCCESS);
 	}
 
 	if (!recv_creds(sock[1], &cred, &v))
 		goto out;
-	ret = cred.pid;
+
+	pid_ret = cred.pid;
 
 out:
 	close(sock[0]);
 	close(sock[1]);
 	if (pid > 0)
 		wait_for_pid(pid);
-	return ret;
-}
 
-#define LXCFS_PROC_PID_NS_LEN                                    \
-	(STRLITERALLEN("/proc/") + INTTYPE_TO_STRLEN(uint64_t) + \
-	 STRLITERALLEN("/ns/pid") + 1)
+	return pid_ret;
+}
 
 pid_t lookup_initpid_in_store(pid_t pid)
 {
@@ -457,97 +475,79 @@ static bool has_fs_type(const struct statfs *fs, fs_type_magic magic_val)
  */
 static bool is_on_ramfs(void)
 {
-	FILE *f;
-	char *p, *p2;
-	char *line = NULL;
+	__do_free char *line = NULL;
+	__do_fclose FILE *f = NULL;
 	size_t len = 0;
-	int i;
 
-	f = fopen("/proc/self/mountinfo", "r");
+	f = fopen("/proc/self/mountinfo", "re");
 	if (!f)
 		return false;
 
 	while (getline(&line, &len, f) != -1) {
+		int i;
+		char *p, *p2;
+
 		for (p = line, i = 0; p && i < 4; i++)
 			p = strchr(p + 1, ' ');
 		if (!p)
 			continue;
+
 		p2 = strchr(p + 1, ' ');
 		if (!p2)
 			continue;
 		*p2 = '\0';
 		if (strcmp(p + 1, "/") == 0) {
-			// this is '/'.  is it the ramfs?
+			/* This is '/'. Is it the ramfs? */
 			p = strchr(p2 + 1, '-');
-			if (p && strncmp(p, "- rootfs rootfs ", 16) == 0) {
-				free(line);
-				fclose(f);
+			if (p && strncmp(p, "- rootfs rootfs ", 16) == 0)
 				return true;
-			}
 		}
 	}
-	free(line);
-	fclose(f);
+
 	return false;
 }
 
 static int pivot_enter()
 {
-	int ret = -1, oldroot = -1, newroot = -1;
+	__do_close_prot_errno int oldroot = -EBADF, newroot = -EBADF;
 
 	oldroot = open("/", O_DIRECTORY | O_RDONLY);
-	if (oldroot < 0) {
-		lxcfs_error("%s\n", "Failed to open old root for fchdir.");
-		return ret;
-	}
+	if (oldroot < 0)
+		return log_error_errno(-1, errno,
+				       "Failed to open old root for fchdir");
 
 	newroot = open(ROOTDIR, O_DIRECTORY | O_RDONLY);
-	if (newroot < 0) {
-		lxcfs_error("%s\n", "Failed to open new root for fchdir.");
-		goto err;
-	}
+	if (newroot < 0)
+		return log_error_errno(-1, errno,
+				       "Failed to open new root for fchdir");
 
 	/* change into new root fs */
-	if (fchdir(newroot) < 0) {
-		lxcfs_error("Failed to change directory to new rootfs: %s.\n", ROOTDIR);
-		goto err;
-	}
+	if (fchdir(newroot) < 0)
+		return log_error_errno(-1,
+				       errno, "Failed to change directory to new rootfs: %s",
+				       ROOTDIR);
 
 	/* pivot_root into our new root fs */
-	if (pivot_root(".", ".") < 0) {
-		lxcfs_error("pivot_root() syscall failed: %s.\n", strerror(errno));
-		goto err;
-	}
+	if (pivot_root(".", ".") < 0)
+		return log_error_errno(-1, errno,
+				       "pivot_root() syscall failed: %s",
+				       strerror(errno));
 
 	/*
 	 * At this point the old-root is mounted on top of our new-root.
 	 * To unmounted it we must not be chdir'd into it, so escape back
 	 * to the old-root.
 	 */
-	if (fchdir(oldroot) < 0) {
-		lxcfs_error("%s\n", "Failed to enter old root.");
-		goto err;
-	}
+	if (fchdir(oldroot) < 0)
+		return log_error_errno(-1, errno, "Failed to enter old root");
 
-	if (umount2(".", MNT_DETACH) < 0) {
-		lxcfs_error("%s\n", "Failed to detach old root.");
-		goto err;
-	}
-
-	if (fchdir(newroot) < 0) {
-		lxcfs_error("%s\n", "Failed to re-enter new root.");
-		goto err;
-	}
+	if (umount2(".", MNT_DETACH) < 0)
+		return log_error_errno(-1, errno, "Failed to detach old root");
 
-	ret = 0;
+	if (fchdir(newroot) < 0)
+		return log_error_errno(-1, errno, "Failed to re-enter new root");
 
-err:
-	if (oldroot > 0)
-		close(oldroot);
-	if (newroot > 0)
-		close(newroot);
-
-	return ret;
+	return 0;
 }
 
 static int chroot_enter()
diff --git a/configure.ac b/configure.ac
index ca9ebe4..ad2b0b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -177,6 +177,13 @@ AC_CHECK_FUNCS([strlcat],
 	AC_DEFINE(HAVE_STRLCAT,1,[Have strlcat]),
 	AM_CONDITIONAL(HAVE_STRLCAT, false))
 
+AC_CHECK_TYPES([struct clone_args], [], [], [[#include <linux/sched.h>]])
+
+AC_CHECK_FUNCS([clone3],
+	AM_CONDITIONAL(HAVE_CLONE3, true)
+	AC_DEFINE(HAVE_CLONE3,1,[Supports clone3]),
+	AM_CONDITIONAL(HAVE_CLONE3, false))
+
 AC_CHECK_FUNCS([pidfd_open],
 	AM_CONDITIONAL(HAVE_PIDFD_OPEN, true)
 	AC_DEFINE(HAVE_PIDFD_OPEN,1,[Supports pidfd_open]),
diff --git a/utils.c b/utils.c
index 8f8a417..6422b09 100644
--- a/utils.c
+++ b/utils.c
@@ -42,25 +42,36 @@
  * format: string format. See printf for details.
  * ...: varargs. See printf for details.
  */
-void must_strcat(char **src, size_t *sz, size_t *asz, const char *format, ...)
+/*
+ * append the given formatted string to *src.
+ * src: a pointer to a char* in which to append the formatted string.
+ * sz: the number of characters printed so far, minus trailing \0.
+ * asz: the allocated size so far
+ * format: string format. See printf for details.
+ * ...: varargs. See printf for details.
+ */
+char *must_strcat(char **src, size_t *sz, size_t *asz, const char *format, ...)
 {
 	char tmp[BUF_RESERVE_SIZE];
-	va_list		args;
+	va_list args;
+	int tmplen;
 
 	va_start (args, format);
-	int tmplen = vsnprintf(tmp, BUF_RESERVE_SIZE, format, args);
+	tmplen = vsnprintf(tmp, BUF_RESERVE_SIZE, format, args);
 	va_end(args);
 
 	if (!*src || tmplen + *sz + 1 >= *asz) {
-		char *buf;
+		char *str;
 		do {
-			buf = realloc(*src, *asz + BUF_RESERVE_SIZE);
-		} while (!buf);
-		*src = buf;
+			str = realloc(*src, *asz + BUF_RESERVE_SIZE);
+		} while (!str);
+		*src = str;
 		*asz += BUF_RESERVE_SIZE;
 	}
 	memcpy((*src) +*sz , tmp, tmplen+1); /* include the \0 */
 	*sz += tmplen;
+
+	return *src;
 }
 
 /**
diff --git a/utils.h b/utils.h
index d5673ed..f366150 100644
--- a/utils.h
+++ b/utils.h
@@ -34,7 +34,9 @@
 
 struct file_info;
 
-extern void must_strcat(char **src, size_t *sz, size_t *asz, const char *format, ...);
+__attribute__((format_arg(4))) extern char *must_strcat(char **src, size_t *sz,
+							size_t *asz,
+							const char *format, ...);
 extern bool is_shared_pidns(pid_t pid);
 extern int preserve_ns(const int pid, const char *ns);
 extern void do_release_file_info(struct fuse_file_info *fi);


More information about the lxc-devel mailing list