From: Christian Brauner Date: Tue, 3 Aug 2021 11:16:45 +0000 (+0200) Subject: conf: allow mount options for rootfs when using new mount api X-Git-Tag: lxc-5.0.0~124^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=704cadd524b8c50321210ee66e7ab3e02ab4852f;p=thirdparty%2Flxc.git conf: allow mount options for rootfs when using new mount api Signed-off-by: Christian Brauner --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 969ae7609..10b6010d9 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -615,6 +615,7 @@ int lxc_rootfs_prepare_parent(struct lxc_handler *handler) __do_close int dfd_idmapped = -EBADF, fd_userns = -EBADF; struct lxc_rootfs *rootfs = &handler->conf->rootfs; struct lxc_storage *storage = rootfs->storage; + const struct lxc_mount_options *mnt_opts = &rootfs->mnt_opts; int ret; const char *path_source; @@ -643,7 +644,9 @@ int lxc_rootfs_prepare_parent(struct lxc_handler *handler) path_source = lxc_storage_get_path(storage->src, storage->type); - dfd_idmapped = create_detached_idmapped_mount(path_source, fd_userns, true); + dfd_idmapped = create_detached_idmapped_mount(path_source, fd_userns, true, + mnt_opts->attr.attr_set, + mnt_opts->attr.attr_clr); if (dfd_idmapped < 0) return syserror("Failed to create detached idmapped mount"); @@ -1008,7 +1011,10 @@ static int lxc_setup_ttys(struct lxc_conf *conf) PROTECT_LOOKUP_BENEATH_XDEV, fd_to, "", PROTECT_OPATH_FILE, - PROTECT_LOOKUP_BENEATH_XDEV, 0, + PROTECT_LOOKUP_BENEATH_XDEV, + 0, + 0, + 0, false); else ret = mount_fd(tty->pty, fd_to, "none", MS_BIND, 0); @@ -1042,7 +1048,10 @@ static int lxc_setup_ttys(struct lxc_conf *conf) PROTECT_LOOKUP_BENEATH_XDEV, fd_to, "", PROTECT_OPATH_FILE, - PROTECT_LOOKUP_BENEATH, 0, + PROTECT_LOOKUP_BENEATH, + 0, + 0, + 0, false); else ret = mount_fd(tty->pty, fd_to, "none", MS_BIND, 0); @@ -1360,7 +1369,11 @@ static int lxc_fill_autodev(struct lxc_rootfs *rootfs) PROTECT_LOOKUP_BENEATH_XDEV, rootfs->dfd_dev, device->name, PROTECT_OPATH_FILE, - PROTECT_LOOKUP_BENEATH, 0, false); + PROTECT_LOOKUP_BENEATH, + 0, + 0, + 0, + false); } else { char path[PATH_MAX]; @@ -1874,7 +1887,7 @@ static int bind_mount_console(int fd_devpts, struct lxc_rootfs *rootfs, * we're operating directly on the fd. */ if (can_use_mount_api()) - return fd_bind_mount(fd_pty, "", 0, 0, fd_to, "", 0, 0, 0, false); + return fd_bind_mount(fd_pty, "", 0, 0, fd_to, "", 0, 0, 0, 0, 0, false); return mount_fd(fd_pty, fd_to, "none", MS_BIND, 0); } @@ -2015,6 +2028,8 @@ static int lxc_setup_ttydir_console(int fd_devpts, struct lxc_rootfs *rootfs, PROTECT_OPATH_FILE, PROTECT_LOOKUP_BENEATH, 0, + 0, + 0, false); else ret = mount_fd(fd_dev_console, fd_reg_console, "none", MS_BIND, 0); @@ -2225,7 +2240,7 @@ static int parse_vfs_attr(struct lxc_mount_options *opts, char *opt, size_t size return 0; } -static int parse_mount_attrs(struct lxc_mount_options *opts, const char *mntopts) +int parse_mount_attrs(struct lxc_mount_options *opts, const char *mntopts) { __do_free char *mntopts_new = NULL, *mntopts_dup = NULL; char *end = NULL, *mntopt_cur = NULL; diff --git a/src/lxc/conf.h b/src/lxc/conf.h index cdefc2ad5..c5bf3a702 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -546,6 +546,7 @@ __hidden extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), v __hidden extern int parse_mntopts_legacy(const char *mntopts, unsigned long *mntflags, char **mntdata); __hidden extern int parse_propagationopts(const char *mntopts, unsigned long *pflags); __hidden extern int parse_lxc_mount_attrs(struct lxc_mount_options *opts, char *mnt_opts); +__hidden extern int parse_mount_attrs(struct lxc_mount_options *opts, const char *mntopts); __hidden extern void tmp_proc_unmount(struct lxc_conf *lxc_conf); __hidden extern void suggest_default_idmap(void); __hidden extern FILE *make_anonymous_mount_file(struct lxc_list *mount, bool include_nesting_helpers); diff --git a/src/lxc/confile.c b/src/lxc/confile.c index ca2bb0d37..0e327d666 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -2786,7 +2786,7 @@ static int set_config_rootfs_mount(const char *key, const char *value, static int set_config_rootfs_options(const char *key, const char *value, struct lxc_conf *lxc_conf, void *data) { - __do_free char *__data = NULL, *dup = NULL, *mdata = NULL, *opts = NULL; + __do_free char *dup = NULL, *raw_options = NULL; struct lxc_rootfs *rootfs = &lxc_conf->rootfs; struct lxc_mount_options *mnt_opts = &rootfs->mnt_opts; int ret; @@ -2795,6 +2795,10 @@ static int set_config_rootfs_options(const char *key, const char *value, if (lxc_config_value_empty(value)) return 0; + ret = set_config_string_item(&raw_options, value); + if (ret < 0) + return ret_errno(ENOMEM); + dup = strdup(value); if (!dup) return -ENOMEM; @@ -2802,27 +2806,17 @@ static int set_config_rootfs_options(const char *key, const char *value, ret = parse_lxc_mount_attrs(mnt_opts, dup); if (ret < 0) return ret; - __data = mnt_opts->data; - - ret = parse_mntopts_legacy(dup, &mnt_opts->mnt_flags, &mdata); - if (ret < 0) - return ret_errno(EINVAL); - - ret = parse_propagationopts(dup, &mnt_opts->prop_flags); - if (ret < 0) - return ret_errno(EINVAL); - - ret = set_config_string_item(&opts, dup); - if (ret < 0) - return ret_errno(ENOMEM); + /* Make sure we're only valid LXC specific mount options. */ if (mnt_opts->create_dir || mnt_opts->create_file || mnt_opts->optional || mnt_opts->relative) return syserror_set(-EINVAL, "Invalid LXC specific mount option for rootfs mount"); - mnt_opts->data = move_ptr(mdata); - rootfs->options = move_ptr(opts); + ret = parse_mount_attrs(mnt_opts, dup); + if (ret < 0) + return ret_errno(EINVAL); + rootfs->options = move_ptr(raw_options); return 0; } diff --git a/src/lxc/mount_utils.c b/src/lxc/mount_utils.c index b04c2646d..945de8c1a 100644 --- a/src/lxc/mount_utils.c +++ b/src/lxc/mount_utils.c @@ -26,6 +26,25 @@ lxc_log_define(mount_utils, lxc); +/* + * Since the MOUNT_ATTR_ values are an enum, not a bitmap, users wanting + * to transition to a different atime setting cannot simply specify the atime + * setting in @attr_set, but must also specify MOUNT_ATTR__ATIME in the + * @attr_clr field. + */ +static inline void set_atime(struct lxc_mount_attr *attr) +{ + switch (attr->attr_set & MOUNT_ATTR__ATIME) { + case MOUNT_ATTR_RELATIME: + __fallthrough; + case MOUNT_ATTR_NOATIME: + __fallthrough; + case MOUNT_ATTR_STRICTATIME: + attr->attr_clr = MOUNT_ATTR__ATIME; + break; + } +} + int mnt_attributes_new(unsigned int old_flags, unsigned int *new_flags) { unsigned int flags = 0; @@ -249,18 +268,22 @@ int fs_attach(int fd_fs, return 0; } -int create_detached_idmapped_mount(const char *path, int userns_fd, bool recursive) +int create_detached_idmapped_mount(const char *path, int userns_fd, + bool recursive, __u64 attr_set, __u64 attr_clr) { __do_close int fd_tree_from = -EBADF; unsigned int open_tree_flags = OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC; struct lxc_mount_attr attr = { - .attr_set = MOUNT_ATTR_IDMAP, + .attr_set = MOUNT_ATTR_IDMAP | attr_set, + .attr_clr = attr_clr, .userns_fd = userns_fd, .propagation = MS_SLAVE, }; int ret; + set_atime(&attr); + TRACE("Idmapped mount \"%s\" requested with user namespace fd %d", path, userns_fd); if (recursive) @@ -309,17 +332,22 @@ int move_detached_mount(int dfd_from, int dfd_to, const char *path_to, int __fd_bind_mount(int dfd_from, const char *path_from, __u64 o_flags_from, __u64 resolve_flags_from, int dfd_to, const char *path_to, - __u64 o_flags_to, __u64 resolve_flags_to, __u64 attr_flags, - int userns_fd, bool recursive) + __u64 o_flags_to, __u64 resolve_flags_to, __u64 attr_set, + __u64 attr_clr, __u64 propagation, int userns_fd, + bool recursive) { struct lxc_mount_attr attr = { - .attr_set = attr_flags, + .attr_set = attr_set, + .attr_clr = attr_clr, + .propagation = propagation, }; __do_close int __fd_from = -EBADF; __do_close int fd_tree_from = -EBADF; unsigned int open_tree_flags = AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC; int fd_from, ret; + set_atime(&attr); + if (!is_empty_string(path_from)) { struct lxc_open_how how = { .flags = o_flags_from, diff --git a/src/lxc/mount_utils.h b/src/lxc/mount_utils.h index d24949714..7d6857866 100644 --- a/src/lxc/mount_utils.h +++ b/src/lxc/mount_utils.h @@ -190,32 +190,37 @@ __hidden extern int __fd_bind_mount(int dfd_from, const char *path_from, __u64 o_flags_from, __u64 resolve_flags_from, int dfd_to, const char *path_to, __u64 o_flags_to, - __u64 resolve_flags_to, __u64 attr_flags, + __u64 resolve_flags_to, __u64 attr_set, + __u64 attr_clr, __u64 propagation, int userns_fd, bool recursive); static inline int fd_mount_idmapped(int dfd_from, const char *path_from, __u64 o_flags_from, __u64 resolve_flags_from, int dfd_to, const char *path_to, __u64 o_flags_to, - __u64 resolve_flags_to, __u64 attr_flags, + __u64 resolve_flags_to, __u64 attr_set, + __u64 attr_clr, __u64 propagation, int userns_fd, bool recursive) { - return __fd_bind_mount(dfd_from, path_from, o_flags_from, resolve_flags_from, - dfd_to, path_to, o_flags_to, resolve_flags_to, - attr_flags, userns_fd, recursive); + return __fd_bind_mount(dfd_from, path_from, o_flags_from, + resolve_flags_from, dfd_to, path_to, o_flags_to, + resolve_flags_to, attr_set, attr_clr, + propagation, userns_fd, recursive); } static inline int fd_bind_mount(int dfd_from, const char *path_from, __u64 o_flags_from, __u64 resolve_flags_from, int dfd_to, const char *path_to, __u64 o_flags_to, __u64 resolve_flags_to, - __u64 attr_flags, bool recursive) + __u64 attr_set, __u64 attr_clr, + __u64 propagation, bool recursive) { return __fd_bind_mount(dfd_from, path_from, o_flags_from, resolve_flags_from, dfd_to, path_to, o_flags_to, resolve_flags_to, - attr_flags, -EBADF, recursive); + attr_set, attr_clr, propagation, -EBADF, recursive); } __hidden extern int create_detached_idmapped_mount(const char *path, - int userns_fd, bool recursive); + int userns_fd, bool recursive, + __u64 attr_set, __u64 attr_clr); __hidden extern int move_detached_mount(int dfd_from, int dfd_to, const char *path_to, __u64 o_flags_to, __u64 resolve_flags_to); diff --git a/src/lxc/storage/dir.c b/src/lxc/storage/dir.c index ab21d11ec..03ad036d5 100644 --- a/src/lxc/storage/dir.c +++ b/src/lxc/storage/dir.c @@ -165,9 +165,14 @@ int dir_mount(struct lxc_storage *bdev) ret = fd_bind_mount(fd_source, "", PROTECT_OPATH_DIRECTORY, - PROTECT_LOOKUP_BENEATH, fd_target, - "", PROTECT_OPATH_DIRECTORY, - PROTECT_LOOKUP_BENEATH, 0, true); + PROTECT_LOOKUP_BENEATH, + fd_target, "", + PROTECT_OPATH_DIRECTORY, + PROTECT_LOOKUP_BENEATH, + mnt_opts->attr.attr_set, + mnt_opts->attr.attr_clr, + mnt_opts->attr.propagation, + true); } } else { ret = mount(source, target, "bind", MS_BIND | MS_REC | mnt_opts->mnt_flags | mnt_opts->prop_flags, mnt_opts->data);