mirror of
git://github.com/lxc/lxc
synced 2025-08-30 23:29:33 +00:00
mount_utils: introduce mount_at()
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
@@ -1742,7 +1742,9 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
|
||||
|
||||
for (ret = -1, opts = mntopt_sets; opts && *opts; opts++) {
|
||||
/* mount new devpts instance */
|
||||
ret = mount_beneath_fd(rootfs->dfd_dev, "", "pts", "devpts", MS_NOSUID | MS_NOEXEC, *opts);
|
||||
ret = mount_at(rootfs->dfd_dev, "", 0,
|
||||
rootfs->dfd_dev, "pts", PROTECT_LOOKUP_BENEATH,
|
||||
"devpts", MS_NOSUID | MS_NOEXEC, *opts);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
@@ -1775,7 +1777,9 @@ static int lxc_setup_devpts_child(struct lxc_handler *handler)
|
||||
DEBUG("Created \"/dev/ptmx\" file as bind mount target");
|
||||
|
||||
/* Main option: use a bind-mount to please AppArmor */
|
||||
ret = mount_beneath_fd(rootfs->dfd_dev, "pts/ptmx", "ptmx", NULL, MS_BIND, NULL);
|
||||
ret = mount_at(rootfs->dfd_dev, "pts/ptmx", (PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS & ~RESOLVE_NO_XDEV),
|
||||
rootfs->dfd_dev, "ptmx", (PROTECT_LOOKUP_BENEATH_WITH_SYMLINKS & ~RESOLVE_NO_XDEV),
|
||||
NULL, MS_BIND, NULL);
|
||||
if (!ret)
|
||||
return log_debug(0, "Bind mounted \"/dev/pts/ptmx\" to \"/dev/ptmx\"");
|
||||
else
|
||||
|
@@ -606,66 +606,56 @@ bool can_use_bind_mounts(void)
|
||||
return supported == 1;
|
||||
}
|
||||
|
||||
int mount_beneath_fd(int fd, const char *source, const char *target,
|
||||
const char *fs_name, unsigned int flags, const void *data)
|
||||
int mount_at(int dfd_from, const char *path_from, __u64 resolve_flags_from,
|
||||
int dfd_to, const char *path_to, __u64 resolve_flags_to,
|
||||
const char *fs_name, unsigned int flags, const void *data)
|
||||
{
|
||||
int ret;
|
||||
char buf_source[PATH_MAX], buf_target[PATH_MAX];
|
||||
__do_close int __fd_from = -EBADF, __fd_to = -EBADF;
|
||||
char *from = NULL, *to = NULL;
|
||||
int fd_from, fd_to, ret;
|
||||
char buf_from[LXC_PROC_SELF_FD_LEN], buf_to[LXC_PROC_SELF_FD_LEN];
|
||||
|
||||
if (abspath(source) || abspath(target))
|
||||
if (dfd_from < 0 && !abspath(path_from))
|
||||
return ret_errno(EINVAL);
|
||||
|
||||
ret = strnprintf(buf_target, sizeof(buf_target), "/proc/self/fd/%d/%s", fd, target);
|
||||
if (ret < 0)
|
||||
return syserror("Failed to create path");
|
||||
if (dfd_to < 0 && !abspath(path_to))
|
||||
return ret_errno(EINVAL);
|
||||
|
||||
if (is_empty_string(source)) {
|
||||
ret = mount(fs_name ?: "", buf_target, fs_name, flags, data);
|
||||
if (!is_empty_string(path_from)) {
|
||||
__fd_from = open_at(dfd_from, path_from, PROTECT_OPATH_FILE, resolve_flags_from, 0);
|
||||
if (__fd_from < 0)
|
||||
return -errno;
|
||||
fd_from = __fd_from;
|
||||
} else {
|
||||
ret = strnprintf(buf_source, sizeof(buf_source), "/proc/self/fd/%d/%s", fd, source);
|
||||
fd_from = dfd_from;
|
||||
}
|
||||
if (fd_from >= 0) {
|
||||
ret = strnprintf(buf_from, sizeof(buf_from), "/proc/self/fd/%d", fd_from);
|
||||
if (ret < 0)
|
||||
return syserror("Failed to create path");
|
||||
|
||||
source = buf_source;
|
||||
ret = mount(source, buf_target, fs_name, flags, data);
|
||||
from = buf_from;
|
||||
}
|
||||
if (ret < 0)
|
||||
return syserror("Failed to mount \"%s\" to \"%s\"", source, buf_target);
|
||||
|
||||
TRACE("Mounted \"%s\" to \"%s\"", source, buf_target);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mount_fd(int fd_source, int fd_target, const char *fs_name,
|
||||
unsigned int flags, const void *data)
|
||||
{
|
||||
int ret;
|
||||
char buf_source[LXC_PROC_PID_FD_LEN], buf_target[LXC_PROC_PID_FD_LEN];
|
||||
char *source = buf_source, *target = buf_target;
|
||||
|
||||
if (fd_source < 0) {
|
||||
source = NULL;
|
||||
if (!is_empty_string(path_to)) {
|
||||
__fd_to = open_at(dfd_to, path_to, PROTECT_OPATH_FILE, resolve_flags_to, 0);
|
||||
if (__fd_to < 0)
|
||||
return -errno;
|
||||
fd_to = __fd_to;
|
||||
} else {
|
||||
ret = strnprintf(buf_source, sizeof(buf_source),
|
||||
"/proc/self/fd/%d", fd_source);
|
||||
fd_to = dfd_to;
|
||||
}
|
||||
if (fd_to >= 0) {
|
||||
ret = strnprintf(buf_to, sizeof(buf_to), "/proc/self/fd/%d", fd_to);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return syserror("Failed to create path");
|
||||
to = buf_to;
|
||||
}
|
||||
|
||||
if (fd_target < 0) {
|
||||
target = NULL;
|
||||
} else {
|
||||
ret = strnprintf(buf_target, sizeof(buf_target),
|
||||
"/proc/self/fd/%d", fd_target);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mount(source, target, "none", MS_BIND, 0);
|
||||
ret = mount(from ?: fs_name, to, fs_name, flags, data);
|
||||
if (ret < 0)
|
||||
return syserror("Failed to mount \"%s\" to \"%s\"",
|
||||
maybe_empty(source), maybe_empty(target));
|
||||
maybe_empty(from), maybe_empty(to));
|
||||
|
||||
TRACE("Mounted \"%s\" to \"%s\"", maybe_empty(source), maybe_empty(target));
|
||||
TRACE("Mounted \"%s\" to \"%s\"", maybe_empty(from), maybe_empty(to));
|
||||
return 0;
|
||||
}
|
||||
|
@@ -221,10 +221,15 @@ __hidden extern unsigned long add_required_remount_flags(const char *s,
|
||||
|
||||
__hidden extern bool can_use_mount_api(void);
|
||||
__hidden extern bool can_use_bind_mounts(void);
|
||||
__hidden extern int mount_beneath_fd(int fd, const char *source,
|
||||
const char *target, const char *fs_name,
|
||||
unsigned int flags, const void *data);
|
||||
__hidden extern int mount_fd(int fd_source, int fd_target, const char *fs_name,
|
||||
unsigned int flags, const void *data);
|
||||
__hidden extern int mount_at(int dfd_from, const char *path_from,
|
||||
__u64 resolve_flags_from, int dfd_to,
|
||||
const char *path_to, __u64 resolve_flags_to,
|
||||
const char *fs_name, unsigned int flags,
|
||||
const void *data);
|
||||
static inline int mount_fd(int fd_from, int fd_to, const char *fs_name,
|
||||
unsigned int flags, const void *data)
|
||||
{
|
||||
return mount_at(fd_from, "", 0, fd_to, "", 0, fs_name, flags, data);
|
||||
}
|
||||
|
||||
#endif /* __LXC_MOUNT_UTILS_H */
|
||||
|
Reference in New Issue
Block a user