]> git.proxmox.com Git - mirror_lxc.git/commitdiff
mount_utils: add two detached mount helpers
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 17 Mar 2021 15:16:48 +0000 (16:16 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 21 Apr 2021 08:05:59 +0000 (10:05 +0200)
They'll come in handy in the future.

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

index f866d92f50320547a9526d52ad3f0f29b8542fa8..95da60f073e04c513a68ea54d024e9a04a1076d4 100644 (file)
@@ -236,6 +236,63 @@ int fs_attach(int fd_fs,
        return 0;
 }
 
+int create_detached_idmapped_mount(const char *path, int userns_fd, bool recursive)
+{
+       __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,
+               .userns_fd      = userns_fd,
+
+       };
+       int ret;
+
+       TRACE("Idmapped mount \"%s\" requested with user namespace fd %d", path, userns_fd);
+
+       if (recursive)
+               open_tree_flags |= AT_RECURSIVE;
+
+       fd_tree_from = open_tree(-EBADF, path, open_tree_flags);
+       if (fd_tree_from < 0)
+               return syserror("Failed to create detached mount");
+
+       ret = mount_setattr(fd_tree_from, "",
+                           AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0),
+                           &attr, sizeof(attr));
+       if (ret < 0)
+               return syserror("Failed to change mount attributes");
+
+       return move_fd(fd_tree_from);
+}
+
+int move_detached_mount(int dfd_from, int dfd_to, const char *path_to,
+                       __u64 o_flags_to, __u64 resolve_flags_to)
+{
+       __do_close int __fd_to = -EBADF;
+       int fd_to, ret;
+
+       if (!is_empty_string(path_to)) {
+               struct lxc_open_how how = {
+                       .flags          = o_flags_to,
+                       .resolve        = resolve_flags_to,
+               };
+
+               __fd_to = openat2(dfd_to, path_to, &how, sizeof(how));
+               if (__fd_to < 0)
+                       return -errno;
+               fd_to = __fd_to;
+       } else {
+               fd_to = dfd_to;
+       }
+
+       ret = move_mount(dfd_from, "", fd_to, "", MOVE_MOUNT_F_EMPTY_PATH | MOVE_MOUNT_T_EMPTY_PATH);
+       if (ret)
+               return syserror("Failed to attach detached mount %d to filesystem at %d", dfd_from, fd_to);
+
+       TRACE("Attach detached mount %d to filesystem at %d", dfd_from, fd_to);
+       return 0;
+}
+
 static 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,
@@ -245,10 +302,10 @@ static int __fd_bind_mount(int dfd_from, const char *path_from,
        struct lxc_mount_attr attr = {
                .attr_set = attr_flags,
        };
-       __do_close int __fd_from = -EBADF, __fd_to = -EBADF;
+       __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, fd_to, ret;
+       int fd_from, ret;
 
        if (!is_empty_string(path_from)) {
                struct lxc_open_how how = {
@@ -274,36 +331,19 @@ static int __fd_bind_mount(int dfd_from, const char *path_from,
        if (userns_fd >= 0) {
                attr.attr_set   |= MOUNT_ATTR_IDMAP;
                attr.userns_fd  = userns_fd;
+               TRACE("Idmapped mount requested with user namespace fd %d", userns_fd);
        }
 
        if (attr.attr_set) {
                ret = mount_setattr(fd_tree_from, "",
-                                   AT_EMPTY_PATH | AT_RECURSIVE,
+                                   AT_EMPTY_PATH | (recursive ? AT_RECURSIVE : 0),
                                    &attr, sizeof(attr));
                if (ret < 0)
                        return syserror("Failed to change mount attributes");
        }
 
-       if (!is_empty_string(path_to)) {
-               struct lxc_open_how how = {
-                       .flags          = o_flags_to,
-                       .resolve        = resolve_flags_to,
-               };
-
-               __fd_to = openat2(dfd_to, path_to, &how, sizeof(how));
-               if (__fd_to < 0)
-                       return -errno;
-               fd_to = __fd_to;
-       } else {
-               fd_to = dfd_to;
-       }
-
-       ret = move_mount(fd_tree_from, "", fd_to, "", MOVE_MOUNT_F_EMPTY_PATH | MOVE_MOUNT_T_EMPTY_PATH);
-       if (ret)
-               return syserror("Failed to attach detached mount %d to filesystem at %d", fd_tree_from, fd_to);
-
-       TRACE("Attach detached mount %d to filesystem at %d", fd_tree_from, fd_to);
-       return 0;
+       return move_detached_mount(fd_tree_from, dfd_to, path_to, o_flags_to,
+                                  resolve_flags_to);
 }
 
 int fd_mount_idmapped(int dfd_from, const char *path_from,
index 1fb724be0ccaa22bf992dcbc6bda76f7fd4081b8..722f80b338409f8e9304b5eacd035d44199f72f0 100644 (file)
@@ -195,6 +195,11 @@ __hidden extern int fd_mount_idmapped(int dfd_from, const char *path_from,
                                      __u64 o_flags_to, __u64 resolve_flags_to,
                                      unsigned int attr_flags, int userns_fd,
                                      bool recursive);
+__hidden extern int create_detached_idmapped_mount(const char *path,
+                                                  int userns_fd, bool recursive);
+__hidden extern int move_detached_mount(int dfd_from, int dfd_to,
+                                       const char *path_to, __u64 o_flags_to,
+                                       __u64 resolve_flags_to);
 
 __hidden extern int calc_remount_flags_new(int dfd_from, const char *path_from,
                                           __u64 o_flags_from,