Unverified Commit 5ee510d6 by Stéphane Graber Committed by GitHub

Merge pull request #3651 from brauner/2021-02-04/fixes

cgroups: fix cgroup mounting
parents dfb71524 59114d80
......@@ -1636,9 +1636,14 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
* enough.
*/
ret = cgroup_attach(conf, name, lxcpath, pid);
if (ret == -ENOCGROUP2) {
if (ret) {
call_cleaner(cgroup_exit) struct cgroup_ops *cgroup_ops = NULL;
if (ret != -ENOCGROUP2) {
SYSERROR("Failed to attach cgroup");
goto on_error;
}
cgroup_ops = cgroup_init(conf);
if (!cgroup_ops)
goto on_error;
......@@ -1646,6 +1651,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
if (!cgroup_ops->attach(cgroup_ops, conf, name, lxcpath, pid))
goto on_error;
}
TRACE("Moved intermediate process %d into container's cgroups", pid);
}
......
......@@ -172,8 +172,7 @@ struct cgroup_ops {
bool (*chown)(struct cgroup_ops *ops, struct lxc_conf *conf);
bool (*attach)(struct cgroup_ops *ops, const struct lxc_conf *conf,
const char *name, const char *lxcpath, pid_t pid);
bool (*mount)(struct cgroup_ops *ops, struct lxc_handler *handler,
const char *root, int type);
bool (*mount)(struct cgroup_ops *ops, struct lxc_conf *conf, int type);
bool (*devices_activate)(struct cgroup_ops *ops,
struct lxc_handler *handler);
bool (*monitor_delegate_controllers)(struct cgroup_ops *ops);
......
......@@ -23,6 +23,7 @@
#include "memory_utils.h"
#include "ringbuf.h"
#include "start.h"
#include "string_utils.h"
#include "terminal.h"
#if HAVE_SYS_RESOURCE_H
......@@ -189,12 +190,13 @@ struct lxc_tty_info {
* @mountflags : the portion of @options that are flags
* @data : the portion of @options that are not flags
* @managed : whether it is managed by LXC
* @mntpt_fd : fd for @mount
* @dev_mntpt_fd : fd for /dev of the container
* @dfd_mnt : fd for @mount
* @dfd_dev : fd for /dev of the container
*/
struct lxc_rootfs {
int mntpt_fd;
int dev_mntpt_fd;
int dfd_host;
int dfd_mnt;
int dfd_dev;
char *path;
char *mount;
char buf[PATH_MAX];
......@@ -547,4 +549,11 @@ static inline int chown_mapped_root(const char *path, const struct lxc_conf *con
__hidden int lxc_setup_devpts_parent(struct lxc_handler *handler);
static inline const char *get_rootfs_mnt(const struct lxc_rootfs *rootfs)
{
static const char *s = "/";
return !is_empty_string(rootfs->path) ? rootfs->mount : s;
}
#endif /* __LXC_CONF_H */
......@@ -117,6 +117,8 @@ static inline bool is_empty_string(const char *s)
return !s || strcmp(s, "") == 0;
}
#define maybe_empty(s) ((!is_empty_string(s)) ? (s) : ("(null)"))
static inline ssize_t safe_strlcat(char *src, const char *append, size_t len)
{
size_t new_len;
......
......@@ -271,7 +271,7 @@ struct lxc_open_how {
#define PROTECT_OPEN (PROTECT_OPEN_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
#define PROTECT_OPEN_W_WITH_TRAILING_SYMLINKS (O_CLOEXEC | O_NOCTTY | O_WRONLY)
#define PROTECT_OPEN_W (PROTECT_OPEN_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
#define PROTECT_OPEN_W (PROTECT_OPEN_W_WITH_TRAILING_SYMLINKS | O_NOFOLLOW)
#ifndef HAVE_OPENAT2
static inline int openat2(int dfd, const char *filename, struct lxc_open_how *how, size_t size)
......
......@@ -1208,6 +1208,108 @@ int safe_mount(const char *src, const char *dest, const char *fstype,
return 0;
}
int mount_at(int dfd,
const char *src_under_dfd,
const char *dst_under_dfd,
__u64 o_flags,
__u64 resolve_flags,
const char *fstype,
unsigned int mnt_flags,
const void *data)
{
__do_close int source_fd = -EBADF, target_fd = -EBADF;
struct lxc_open_how how = {
.flags = o_flags,
.resolve = resolve_flags,
};
int ret;
char src_buf[LXC_PROC_PID_FD_LEN], dst_buf[LXC_PROC_PID_FD_LEN];
if (dfd < 0)
return ret_errno(EINVAL);
if (!is_empty_string(src_buf) && *src_buf == '/')
return log_error_errno(-EINVAL, EINVAL, "Absolute path specified");
if (!is_empty_string(src_under_dfd)) {
source_fd = openat2(dfd, src_under_dfd, &how, sizeof(how));
if (source_fd < 0)
return -errno;
ret = snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", source_fd);
if (ret < 0 || ret >= sizeof(src_buf))
return -EIO;
}
if (!is_empty_string(dst_under_dfd)) {
target_fd = openat2(dfd, dst_under_dfd, &how, sizeof(how));
if (target_fd < 0)
return log_error_errno(-errno, errno, "Failed to open %d(%s)", dfd, dst_under_dfd);
TRACE("Mounting %d(%s) through /proc/self/fd/%d", target_fd, dst_under_dfd, target_fd);
ret = snprintf(dst_buf, sizeof(dst_buf), "/proc/self/fd/%d", target_fd);
} else {
TRACE("Mounting %d through /proc/self/fd/%d", dfd, dfd);
ret = snprintf(dst_buf, sizeof(dst_buf), "/proc/self/fd/%d", dfd);
}
if (ret < 0 || ret >= sizeof(dst_buf))
return -EIO;
if (!is_empty_string(src_buf))
ret = mount(src_buf, dst_buf, fstype, mnt_flags, data);
else
ret = mount(NULL, dst_buf, fstype, mnt_flags, data);
return ret;
}
int mount_from_at(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,
const char *fstype, unsigned int mnt_flags, const void *data)
{
__do_close int fd_from = -EBADF, fd_to = -EBADF;
struct lxc_open_how how = {};
int ret;
char src_buf[LXC_PROC_PID_FD_LEN], dst_buf[LXC_PROC_PID_FD_LEN];
if (is_empty_string(path_from)) {
ret = snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", dfd_from);
} else {
how.flags = o_flags_from;
how.resolve = resolve_flags_from;
fd_from = openat2(dfd_from, path_from, &how, sizeof(how));
if (fd_from < 0)
return -errno;
ret = snprintf(src_buf, sizeof(src_buf), "/proc/self/fd/%d", fd_from);
}
if (ret < 0 || ret >= sizeof(src_buf))
return -EIO;
if (is_empty_string(path_to)) {
ret = snprintf(dst_buf, sizeof(dst_buf), "/proc/self/fd/%d", dfd_to);
} else {
how.flags = o_flags_to;
how.resolve = resolve_flags_to;
fd_to = openat2(dfd_to, path_to, &how, sizeof(how));
if (fd_to < 0)
return -errno;
ret = snprintf(dst_buf, sizeof(dst_buf), "/proc/self/fd/%d", fd_to);
}
if (is_empty_string(src_buf))
ret = mount(NULL, dst_buf, fstype, mnt_flags, data);
else
ret = mount(src_buf, dst_buf, fstype, mnt_flags, data);
return ret;
}
int open_devnull(void)
{
int fd = open("/dev/null", O_RDWR);
......
......@@ -243,5 +243,15 @@ __hidden extern int safe_mount_beneath(const char *beneath, const char *src, con
const char *fstype, unsigned int flags, const void *data);
__hidden extern int safe_mount_beneath_at(int beneat_fd, const char *src, const char *dst,
const char *fstype, unsigned int flags, const void *data);
__hidden extern int mount_at(int dfd, const char *src_under_dfd,
const char *dst_under_dfd, __u64 o_flags,
__u64 resolve_flags, const char *fstype,
unsigned int mnt_flags, const void *data);
__hidden extern int mount_from_at(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,
const char *fstype, unsigned int mnt_flags,
const void *data);
#endif /* __LXC_UTILS_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment