Commit 19b5201a by Christian Brauner Committed by Stéphane Graber

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 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: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 038a2174
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/loop.h> #include <linux/loop.h>
#include <linux/memfd.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sys/mman.h> #include <sys/mman.h>
...@@ -63,6 +62,10 @@ ...@@ -63,6 +62,10 @@
#include <../include/openpty.h> #include <../include/openpty.h>
#endif #endif
#ifdef HAVE_LINUX_MEMFD_H
#include <linux/memfd.h>
#endif
#include "af_unix.h" #include "af_unix.h"
#include "bdev.h" #include "bdev.h"
#include "caps.h" /* for lxc_caps_last_cap() */ #include "caps.h" /* for lxc_caps_last_cap() */
...@@ -163,6 +166,59 @@ static int sethostname(const char * name, size_t len) ...@@ -163,6 +166,59 @@ static int sethostname(const char * name, size_t len)
#define MS_PRIVATE (1<<18) #define MS_PRIVATE (1<<18)
#endif #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] = { char *lxchook_names[NUM_LXC_HOOKS] = {
"pre-start", "pre-mount", "mount", "autodev", "start", "stop", "post-stop", "clone", "destroy" }; "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, ...@@ -1946,34 +2002,53 @@ static int setup_mount(const struct lxc_rootfs *rootfs, const char *fstab,
return ret; return ret;
} }
FILE *write_mount_file(struct lxc_list *mount) FILE *make_anonymous_mount_file(struct lxc_list *mount)
{ {
FILE *file; int ret;
struct lxc_list *iterator;
char *mount_entry; 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) { 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; return NULL;
} }
lxc_list_for_each(iterator, mount) { lxc_list_for_each(iterator, mount) {
mount_entry = iterator->elem; 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; return file;
} }
static int setup_mount_entries(const struct lxc_rootfs *rootfs, struct lxc_list *mount, static int setup_mount_entries(const struct lxc_rootfs *rootfs,
const char *lxc_name, const char *lxc_path) struct lxc_list *mount, const char *lxc_name,
const char *lxc_path)
{ {
FILE *file; FILE *file;
int ret; int ret;
file = write_mount_file(mount); file = make_anonymous_mount_file(mount);
if (!file) if (!file)
return -1; return -1;
......
...@@ -445,6 +445,6 @@ extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, ...@@ -445,6 +445,6 @@ extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
extern void tmp_proc_unmount(struct lxc_conf *lxc_conf); extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
void remount_all_slave(void); void remount_all_slave(void);
extern void suggest_default_idmap(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); struct lxc_list *sort_cgroup_settings(struct lxc_list* cgroup_settings);
#endif #endif
...@@ -330,7 +330,7 @@ static void exec_criu(struct criu_opts *opts) ...@@ -330,7 +330,7 @@ static void exec_criu(struct criu_opts *opts)
DECLARE_ARG(opts->user->action_script); 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) if (!mnts)
goto err; goto err;
......
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