]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
conf: allow mount options for rootfs when using new mount api
authorChristian Brauner <christian.brauner@ubuntu.com>
Tue, 3 Aug 2021 11:16:45 +0000 (13:16 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 3 Aug 2021 11:16:45 +0000 (13:16 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/mount_utils.c
src/lxc/mount_utils.h
src/lxc/storage/dir.c

index 969ae76091dcc7a511839a59269b28a74a1c34b0..10b6010d923ea0b2bdb9023f9f7dbd38ef3f72c7 100644 (file)
@@ -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;
index cdefc2ad5c4d9903ecc91e00c3e15c97f55fad0b..c5bf3a702b1d0e4b9575dc2cdfc1cb8c1ebb26b8 100644 (file)
@@ -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);
index ca2bb0d37e04f7208bed479e50533960d00b5128..0e327d666b942735b6ef96490a116ce6d1817ead 100644 (file)
@@ -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;
 }
 
index b04c2646d3a73b372689a72ff9f1496175fca433..945de8c1a346f553c68c2c9c65fa17bb91cfc1a2 100644 (file)
 
 lxc_log_define(mount_utils, lxc);
 
+/*
+ * Since the MOUNT_ATTR_<atime> 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,
index d2494971491419dab5bb8de48a651e3b79d3cfdf..7d6857866bcdbde342792ac0dbb6ca54340bb53e 100644 (file)
@@ -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);
index ab21d11ec34bc7d2b8bcce454ef8bbb0115593ae..03ad036d596ec6dd651abfd814f881ea8ade4d33 100644 (file)
@@ -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);