]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
conf, criu: add make_anonymous_mount_file() 1315/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 23 Nov 2016 05:47:37 +0000 (06:47 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sat, 26 Nov 2016 03:28:03 +0000 (04:28 +0100)
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 systems where
this filesystem is not 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. In case we detect that syscall is not
implemented, we fallback to using tmpfile().

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/criu.c

index 2a4a13e511f15a0adbf94de2e3afeec13ae0d690..7b66e3747a0fee4906f131b6d7bd90a5d8438002 100644 (file)
@@ -39,7 +39,6 @@
 #include <unistd.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 <../include/openpty.h>
 #endif
 
+#ifdef HAVE_LINUX_MEMFD_H
+#include <linux/memfd.h>
+#endif
+
 #include "af_unix.h"
 #include "bdev.h"
 #include "caps.h"       /* for lxc_caps_last_cap() */
@@ -163,6 +166,59 @@ static int sethostname(const char * name, size_t len)
 #define MS_PRIVATE (1<<18)
 #endif
 
+/* memfd_create() */
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#endif
+
+#ifndef MFD_ALLOW_SEALING
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+#ifndef HAVE_MEMFD_CREATE
+static int memfd_create(const char *name, unsigned int flags) {
+       #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
+       #ifdef __NR_memfd_create
+       return syscall(__NR_memfd_create, name, flags);
+       #else
+       errno = ENOSYS;
+       return -1;
+       #endif
+}
+#else
+extern int memfd_create(const char *name, unsigned int flags);
+#endif
+
 char *lxchook_names[NUM_LXC_HOOKS] = {
        "pre-start", "pre-mount", "mount", "autodev", "start", "stop", "post-stop", "clone", "destroy" };
 
@@ -1946,34 +2002,53 @@ 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 ret;
        char *mount_entry;
+       struct lxc_list *iterator;
+       FILE *file;
+       int fd = -1;
+
+       fd = memfd_create("lxc_mount_file", MFD_CLOEXEC);
+       if (fd < 0) {
+               if (errno != ENOSYS)
+                       return NULL;
+               file = tmpfile();
+       } else {
+               file = fdopen(fd, "r+");
+       }
 
-       file = tmpfile();
        if (!file) {
-               ERROR("Could not create temporary file: %s.", strerror(errno));
+               if (fd != -1)
+                       close(fd);
+               ERROR("Could not create mount entry file: %s.", strerror(errno));
                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.");
+       }
+
+       if (fseek(file, 0, SEEK_SET) < 0) {
+               fclose(file);
+               return NULL;
        }
 
-       rewind(file);
        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;
 
index ae29d42103cc8fa054bc832db14f3e652c7422ef..b7d15cbd2e7a923816432b9b3eb9f29181cce42e 100644 (file)
@@ -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
index 50a74000d8bf8f0d81faf0cf996aa096a8eaf39c..125e67428dab8f0a8ee220bd89e1f082049707e6 100644 (file)
@@ -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;