From: Christian Brauner Date: Fri, 5 Feb 2021 16:38:05 +0000 (+0100) Subject: mount_utils: add support for bind-mounts through the new mount api X-Git-Tag: lxc-5.0.0~298^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=041d1e30545a5e21fc9631b09daa1ab817e6ff15;p=thirdparty%2Flxc.git mount_utils: add support for bind-mounts through the new mount api fd_bind_mount() Signed-off-by: Christian Brauner --- diff --git a/src/lxc/mount_utils.c b/src/lxc/mount_utils.c index a11526d0e..fa02d23d6 100644 --- a/src/lxc/mount_utils.c +++ b/src/lxc/mount_utils.c @@ -4,6 +4,7 @@ #define _GNU_SOURCE 1 #endif #include +#include #include #include #include @@ -302,3 +303,57 @@ int mount_from_at(int dfd_from, const char *path_from, return ret; } + +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, + unsigned int attr_flags, bool recursive) +{ + __do_close int __fd_from = -EBADF, __fd_to = -EBADF; + __do_close int fd_tree_from = -EBADF; + unsigned int open_tree_flags = AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLONE; + int fd_from, fd_to, ret; + + if (!is_empty_string(path_from)) { + struct lxc_open_how how = { + .flags = o_flags_from, + .resolve = resolve_flags_from, + }; + + __fd_from = openat2(dfd_from, path_from, &how, sizeof(how)); + if (__fd_from < 0) + return -errno; + fd_from = __fd_from; + } else { + fd_from = dfd_from; + } + + if (recursive) + open_tree_flags |= AT_RECURSIVE; + + fd_tree_from = open_tree(fd_from, "", open_tree_flags); + if (fd_tree_from < 0) + return log_error_errno(-errno, errno, "Failed to create detached mount"); + + 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 log_error_errno(-errno, errno, "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; +} diff --git a/src/lxc/mount_utils.h b/src/lxc/mount_utils.h index 8f57802f5..cced086c4 100644 --- a/src/lxc/mount_utils.h +++ b/src/lxc/mount_utils.h @@ -12,6 +12,11 @@ #include "memory_utils.h" /* open_tree() flags */ + +#ifndef AT_RECURSIVE +#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ +#endif + #ifndef OPEN_TREE_CLONE #define OPEN_TREE_CLONE 1 #endif @@ -181,4 +186,10 @@ static inline int fs_mount(const char *fs_name, int dfd_from, return fs_attach(fd_fs, dfd_to, path_to, o_flags_to, resolve_flags_to, attr_flags); } +__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, + unsigned int attr_flags, bool recursive); + #endif /* __LXC_MOUNT_UTILS_H */