[lxc-devel] [lxc/master] [RFC] conf, criu: add make_anonymous_mount_file()

brauner on Github lxc-bot at linuxcontainers.org
Wed Nov 23 05:54:18 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 821 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161123/c3040d1b/attachment.bin>
-------------- next part --------------
From 0445d799537c266da7d94f493d736b363ddfd971 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 23 Nov 2016 06:47:07 +0100
Subject: [PATCH 1/2] conf: non-functional changes

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/conf.c | 78 ++++++++++++++++++++++++++++------------------------------
 1 file changed, 37 insertions(+), 41 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index d5ea3c0..2a4a13e 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -24,20 +24,34 @@
 #define _GNU_SOURCE
 #include "config.h"
 
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <inttypes.h>
+#include <libgen.h>
+#include <pwd.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
 #include <string.h>
-#include <dirent.h>
+#include <time.h>
 #include <unistd.h>
-#include <inttypes.h>
-#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <linux/loop.h>
+#include <linux/memfd.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/param.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-#include <time.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
 
 #ifdef HAVE_STATVFS
 #include <sys/statvfs.h>
@@ -49,37 +63,21 @@
 #include <../include/openpty.h>
 #endif
 
-#include <linux/loop.h>
-
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/mount.h>
-#include <sys/mman.h>
-#include <sys/prctl.h>
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <libgen.h>
-
-#include "bdev.h"
-#include "network.h"
-#include "error.h"
 #include "af_unix.h"
-#include "parse.h"
-#include "utils.h"
+#include "bdev.h"
+#include "caps.h"       /* for lxc_caps_last_cap() */
+#include "cgroup.h"
 #include "conf.h"
+#include "error.h"
 #include "log.h"
-#include "caps.h"       /* for lxc_caps_last_cap() */
 #include "lxcaufs.h"
-#include "lxcoverlay.h"
-#include "cgroup.h"
 #include "lxclock.h"
+#include "lxcoverlay.h"
+#include "lxcseccomp.h"
 #include "namespace.h"
+#include "network.h"
+#include "parse.h"
+#include "utils.h"
 #include "lsm/lsm.h"
 
 #if HAVE_SYS_CAPABILITY_H
@@ -96,8 +94,6 @@
 #include <mntent.h>
 #endif
 
-#include "lxcseccomp.h"
-
 lxc_log_define(lxc_conf, lxc);
 
 #define LINELEN 4096
@@ -135,10 +131,10 @@ lxc_log_define(lxc_conf, lxc);
 static int pivot_root(const char * new_root, const char * put_old)
 {
 #ifdef __NR_pivot_root
-return syscall(__NR_pivot_root, new_root, put_old);
+	return syscall(__NR_pivot_root, new_root, put_old);
 #else
-errno = ENOSYS;
-return -1;
+	errno = ENOSYS;
+	return -1;
 #endif
 }
 #else
@@ -150,10 +146,10 @@ extern int pivot_root(const char * new_root, const char * put_old);
 static int sethostname(const char * name, size_t len)
 {
 #ifdef __NR_sethostname
-return syscall(__NR_sethostname, name, len);
+	return syscall(__NR_sethostname, name, len);
 #else
-errno = ENOSYS;
-return -1;
+	errno = ENOSYS;
+	return -1;
 #endif
 }
 #endif

From a6bac937d07b81e8851fcff44a2224847730817a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 23 Nov 2016 06:47:37 +0100
Subject: [PATCH 2/2] conf, criu: add make_anonymous_mount_file()

Before we used tmpfile() to write out mount entries for the container. This
requires a writeable /tmp file system which can be a problem for Android where
this filesystem is not necessarily present. This commit switches from tmpfile()
to using the memfd_create() syscall. It allows us to create an anonymous tmpfs
file (And is somewhat similar to mmap().) which is automatically deleted as
soon as any references to it are dropped.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/conf.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++----------
 src/lxc/conf.h |  2 +-
 src/lxc/criu.c |  2 +-
 3 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 2a4a13e..c3d0ff4 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -163,6 +163,48 @@ static int sethostname(const char * name, size_t len)
 #define MS_PRIVATE (1<<18)
 #endif
 
+#ifndef HAVE_MEMFD_CREATE
+#ifndef __NR_memfd_create
+	#if defined __i386__
+		#define __NR_memfd_create 356
+	#elif defined __x86_64__
+		#define __NR_memfd_create 319
+	#elif defined __arm__
+		#define __NR_memfd_create 385
+	#elif defined __aarch64__
+		#define __NR_memfd_create 279
+	#elif defined __s390__
+		#define __NR_memfd_create 350
+	#elif defined __powerpc__
+		#define __NR_memfd_create 360
+	#elif defined __sparc__
+		#define __NR_memfd_create 348
+	#elif defined __blackfin__
+		#define __NR_memfd_create 390
+	#elif defined __ia64__
+		#define __NR_memfd_create 1340
+	#elif defined _MIPS_SIM
+		#if _MIPS_SIM == _MIPS_SIM_ABI32
+			#define __NR_memfd_create 4354
+		#endif
+		#if _MIPS_SIM == _MIPS_SIM_NABI32
+			#define __NR_memfd_create 6318
+		#endif
+		#if _MIPS_SIM == _MIPS_SIM_ABI64
+			#define __NR_memfd_create 5314
+		#endif
+	#endif
+#endif
+static int memfd_create(const char *name, unsigned int flags) {
+#ifdef __NR_memfd_create
+	return syscall(__NR_memfd_create, name, flags);
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+#endif
+
 char *lxchook_names[NUM_LXC_HOOKS] = {
 	"pre-start", "pre-mount", "mount", "autodev", "start", "stop", "post-stop", "clone", "destroy" };
 
@@ -1946,34 +1988,42 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
 	return ret;
 }
 
-FILE *write_mount_file(struct lxc_list *mount)
+FILE *make_anonymous_mount_file(struct lxc_list *mount)
 {
-	FILE *file;
-	struct lxc_list *iterator;
+	int fd, ret;
 	char *mount_entry;
+	struct lxc_list *iterator;
+	FILE *file;
 
-	file = tmpfile();
-	if (!file) {
-		ERROR("Could not create temporary file: %s.", strerror(errno));
+	fd = memfd_create("lxc_mount_file", MFD_CLOEXEC);
+	if (fd < 0)
+		return NULL;
+
+	file = fdopen(fd, "r+");
+	if (!file)
 		return NULL;
-	}
 
 	lxc_list_for_each(iterator, mount) {
 		mount_entry = iterator->elem;
-		fprintf(file, "%s\n", mount_entry);
+		ret = fprintf(file, "%s\n", mount_entry);
+		if (ret < strlen(mount_entry))
+			WARN("Could not write mount entry to anonymous mount file.");
 	}
 
-	rewind(file);
+	if (fseek(file, 0, SEEK_SET) < 0)
+		return NULL;
+
 	return file;
 }
 
-static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount,
-	const char *lxc_name, const char *lxc_path)
+static int setup_mount_entries(const struct lxc_rootfs *rootfs,
+			       struct lxc_list *mount, const char *lxc_name,
+			       const char *lxc_path)
 {
 	FILE *file;
 	int ret;
 
-	file = write_mount_file(mount);
+	file = make_anonymous_mount_file(mount);
 	if (!file)
 		return -1;
 
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index ae29d42..b7d15cb 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -452,6 +452,6 @@ extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
 extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
 void remount_all_slave(void);
 extern void suggest_default_idmap(void);
-FILE *write_mount_file(struct lxc_list *mount);
+FILE *make_anonymous_mount_file(struct lxc_list *mount);
 struct lxc_list *sort_cgroup_settings(struct lxc_list* cgroup_settings);
 #endif
diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index 50a7400..125e674 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -330,7 +330,7 @@ static void exec_criu(struct criu_opts *opts)
 		DECLARE_ARG(opts->user->action_script);
 	}
 
-	mnts = write_mount_file(&opts->c->lxc_conf->mount_list);
+	mnts = make_anonymous_mount_file(&opts->c->lxc_conf->mount_list);
 	if (!mnts)
 		goto err;
 


More information about the lxc-devel mailing list