mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
nspawn: add new --tmpfs= option to mount a tmpfs on specific directories, such as /var
This commit is contained in:
parent
9339db7187
commit
06c17c39a8
@ -503,6 +503,30 @@
|
||||
mounts.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--tmpfs=</option></term>
|
||||
|
||||
<listitem><para>Mount a tmpfs file
|
||||
system into the container. Takes a
|
||||
single absolute path argument that
|
||||
specifies where to mount the tmpfs
|
||||
instance to (in which case the
|
||||
directory access mode will be chosen
|
||||
as 0755, owned by root/root), or
|
||||
optionally a colon-separated pair of
|
||||
path and mount option string, that is
|
||||
used for mounting (in which case the
|
||||
kernel default for access mode and
|
||||
owner will be chosen, unless otherwise
|
||||
specified). This option is
|
||||
particularly useful for mounting
|
||||
directories such as
|
||||
<filename>/var</filename> as tmpfs, to
|
||||
allow state-less systems, in
|
||||
particular when combined with
|
||||
<option>--read-only</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--setenv=</option></term>
|
||||
|
||||
|
@ -146,6 +146,7 @@ static uint64_t arg_retain =
|
||||
(1ULL << CAP_MKNOD);
|
||||
static char **arg_bind = NULL;
|
||||
static char **arg_bind_ro = NULL;
|
||||
static char **arg_tmpfs = NULL;
|
||||
static char **arg_setenv = NULL;
|
||||
static bool arg_quiet = false;
|
||||
static bool arg_share_system = false;
|
||||
@ -200,6 +201,7 @@ static int help(void) {
|
||||
" --bind=PATH[:PATH] Bind mount a file or directory from the host into\n"
|
||||
" the container\n"
|
||||
" --bind-ro=PATH[:PATH] Similar, but creates a read-only bind mount\n"
|
||||
" --tmpfs=PATH:[OPTIONS] Mount an empty tmpfs to the specified directory\n"
|
||||
" --setenv=NAME=VALUE Pass an environment variable to PID 1\n"
|
||||
" --share-system Share system namespaces with host\n"
|
||||
" --register=BOOLEAN Register container as machine\n"
|
||||
@ -222,6 +224,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_LINK_JOURNAL,
|
||||
ARG_BIND,
|
||||
ARG_BIND_RO,
|
||||
ARG_TMPFS,
|
||||
ARG_SETENV,
|
||||
ARG_SHARE_SYSTEM,
|
||||
ARG_REGISTER,
|
||||
@ -247,6 +250,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "link-journal", required_argument, NULL, ARG_LINK_JOURNAL },
|
||||
{ "bind", required_argument, NULL, ARG_BIND },
|
||||
{ "bind-ro", required_argument, NULL, ARG_BIND_RO },
|
||||
{ "tmpfs", required_argument, NULL, ARG_TMPFS },
|
||||
{ "machine", required_argument, NULL, 'M' },
|
||||
{ "slice", required_argument, NULL, 'S' },
|
||||
{ "setenv", required_argument, NULL, ARG_SETENV },
|
||||
@ -469,6 +473,42 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_TMPFS: {
|
||||
_cleanup_free_ char *a = NULL, *b = NULL;
|
||||
char *e;
|
||||
|
||||
e = strchr(optarg, ':');
|
||||
if (e) {
|
||||
a = strndup(optarg, e - optarg);
|
||||
b = strdup(e + 1);
|
||||
} else {
|
||||
a = strdup(optarg);
|
||||
b = strdup("mode=0755");
|
||||
}
|
||||
|
||||
if (!a || !b)
|
||||
return log_oom();
|
||||
|
||||
if (!path_is_absolute(a)) {
|
||||
log_error("Invalid tmpfs specification: %s", optarg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = strv_push(&arg_tmpfs, a);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
a = NULL;
|
||||
|
||||
r = strv_push(&arg_tmpfs, b);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
b = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_SETENV: {
|
||||
char **n;
|
||||
|
||||
@ -561,17 +601,17 @@ static int mount_all(const char *dest) {
|
||||
} MountPoint;
|
||||
|
||||
static const MountPoint mount_table[] = {
|
||||
{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
|
||||
{ "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true }, /* Bind mount first */
|
||||
{ NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
|
||||
{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
|
||||
{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true },
|
||||
{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
|
||||
{ "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true }, /* Bind mount first */
|
||||
{ NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */
|
||||
{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true },
|
||||
{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true },
|
||||
{ "devpts", "/dev/pts", "devpts","newinstance,ptmxmode=0666,mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, true },
|
||||
{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true },
|
||||
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true },
|
||||
{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true },
|
||||
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true },
|
||||
#ifdef HAVE_SELINUX
|
||||
{ "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false }, /* Bind mount first */
|
||||
{ NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */
|
||||
{ "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false }, /* Bind mount first */
|
||||
{ NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -640,7 +680,7 @@ static int mount_binds(const char *dest, char **l, bool ro) {
|
||||
char **x, **y;
|
||||
|
||||
STRV_FOREACH_PAIR(x, y, l) {
|
||||
char *where;
|
||||
_cleanup_free_ char *where = NULL;
|
||||
struct stat source_st, dest_st;
|
||||
int r;
|
||||
|
||||
@ -649,12 +689,14 @@ static int mount_binds(const char *dest, char **l, bool ro) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
where = strappenda(dest, *y);
|
||||
where = strappend(dest, *y);
|
||||
if (!where)
|
||||
return log_oom();
|
||||
|
||||
r = stat(where, &dest_st);
|
||||
if (r == 0) {
|
||||
if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) {
|
||||
log_error("The file types of %s and %s do not match. Refusing bind mount",
|
||||
*x, where);
|
||||
log_error("The file types of %s and %s do not match. Refusing bind mount", *x, where);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (errno == ENOENT) {
|
||||
@ -667,6 +709,7 @@ static int mount_binds(const char *dest, char **l, bool ro) {
|
||||
log_error("Failed to bind mount %s: %m", *x);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* Create the mount point, but be conservative -- refuse to create block
|
||||
* and char devices. */
|
||||
if (S_ISDIR(source_st.st_mode))
|
||||
@ -699,6 +742,27 @@ static int mount_binds(const char *dest, char **l, bool ro) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_tmpfs(const char *dest) {
|
||||
char **i, **o;
|
||||
|
||||
STRV_FOREACH_PAIR(i, o, arg_tmpfs) {
|
||||
_cleanup_free_ char *where = NULL;
|
||||
|
||||
where = strappend(dest, *i);
|
||||
if (!where)
|
||||
return log_oom();
|
||||
|
||||
mkdir_label(where, 0755);
|
||||
|
||||
if (mount("tmpfs", where, "tmpfs", MS_NODEV|MS_STRICTATIME, *o) < 0) {
|
||||
log_error("tmpfs mount to %s failed: %m", where);
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_timezone(const char *dest) {
|
||||
_cleanup_free_ char *where = NULL, *p = NULL, *q = NULL, *check = NULL, *what = NULL;
|
||||
char *z, *y;
|
||||
@ -2998,6 +3062,9 @@ int main(int argc, char *argv[]) {
|
||||
if (mount_binds(arg_directory, arg_bind_ro, true) < 0)
|
||||
goto child_fail;
|
||||
|
||||
if (mount_tmpfs(arg_directory) < 0)
|
||||
goto child_fail;
|
||||
|
||||
if (setup_kdbus(arg_directory, kdbus_domain) < 0)
|
||||
goto child_fail;
|
||||
|
||||
@ -3248,6 +3315,7 @@ finish:
|
||||
strv_free(arg_network_macvlan);
|
||||
strv_free(arg_bind);
|
||||
strv_free(arg_bind_ro);
|
||||
strv_free(arg_tmpfs);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user