Unverified Commit 7e925736 by Stéphane Graber Committed by GitHub

Merge pull request #3673 from brauner/2021-02-15/nesting

cgroups: first batch of cgroup mounting fixes
parents 4b946797 a3e5ec26
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
#include "af_unix.h" #include "af_unix.h"
#include "attach.h" #include "attach.h"
#include "caps.h" #include "caps.h"
#include "cgroup.h" #include "cgroups/cgroup.h"
#include "cgroups/cgroup_utils.h"
#include "commands.h" #include "commands.h"
#include "conf.h" #include "conf.h"
#include "config.h" #include "config.h"
......
...@@ -172,7 +172,7 @@ struct cgroup_ops { ...@@ -172,7 +172,7 @@ struct cgroup_ops {
bool (*chown)(struct cgroup_ops *ops, struct lxc_conf *conf); bool (*chown)(struct cgroup_ops *ops, struct lxc_conf *conf);
bool (*attach)(struct cgroup_ops *ops, const struct lxc_conf *conf, bool (*attach)(struct cgroup_ops *ops, const struct lxc_conf *conf,
const char *name, const char *lxcpath, pid_t pid); const char *name, const char *lxcpath, pid_t pid);
bool (*mount)(struct cgroup_ops *ops, struct lxc_conf *conf, int type); bool (*mount)(struct cgroup_ops *ops, struct lxc_handler *handler, int type);
bool (*devices_activate)(struct cgroup_ops *ops, bool (*devices_activate)(struct cgroup_ops *ops,
struct lxc_handler *handler); struct lxc_handler *handler);
bool (*monitor_delegate_controllers)(struct cgroup_ops *ops); bool (*monitor_delegate_controllers)(struct cgroup_ops *ops);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include "compiler.h" #include "compiler.h"
#include "file_utils.h"
/* Retrieve the cgroup version of a given entry from /proc/<pid>/mountinfo. */ /* Retrieve the cgroup version of a given entry from /proc/<pid>/mountinfo. */
__hidden extern int get_cgroup_version(char *line); __hidden extern int get_cgroup_version(char *line);
...@@ -32,4 +33,14 @@ __hidden extern int unified_cgroup_hierarchy(void); ...@@ -32,4 +33,14 @@ __hidden extern int unified_cgroup_hierarchy(void);
__hidden extern int unified_cgroup_fd(int fd); __hidden extern int unified_cgroup_fd(int fd);
static inline bool cgns_supported(void)
{
static int supported = -1;
if (supported == -1)
supported = file_exists("/proc/self/ns/cgroup");
return supported == 1;
}
#endif /* __LXC_CGROUP_UTILS_H */ #endif /* __LXC_CGROUP_UTILS_H */
...@@ -564,7 +564,7 @@ static int add_shmount_to_list(struct lxc_conf *conf) ...@@ -564,7 +564,7 @@ static int add_shmount_to_list(struct lxc_conf *conf)
return add_elem_to_mount_list(new_mount, conf); return add_elem_to_mount_list(new_mount, conf);
} }
static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_handler *handler) static int lxc_mount_auto_mounts(struct lxc_handler *handler, int flags)
{ {
int i, ret; int i, ret;
static struct { static struct {
...@@ -608,6 +608,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha ...@@ -608,6 +608,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha
{ LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, NULL, "%r/sys/devices/virtual/net", NULL, MS_REMOUNT|MS_BIND|MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL, false }, { LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED, NULL, "%r/sys/devices/virtual/net", NULL, MS_REMOUNT|MS_BIND|MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL, false },
{ 0, 0, NULL, NULL, NULL, 0, NULL, false } { 0, 0, NULL, NULL, NULL, 0, NULL, false }
}; };
struct lxc_conf *conf = handler->conf;
struct lxc_rootfs *rootfs = &conf->rootfs; struct lxc_rootfs *rootfs = &conf->rootfs;
bool has_cap_net_admin; bool has_cap_net_admin;
...@@ -703,7 +704,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha ...@@ -703,7 +704,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha
if (flags & LXC_AUTO_CGROUP_FORCE) if (flags & LXC_AUTO_CGROUP_FORCE)
cg_flags |= LXC_AUTO_CGROUP_FORCE; cg_flags |= LXC_AUTO_CGROUP_FORCE;
if (!handler->cgroup_ops->mount(handler->cgroup_ops, conf, cg_flags)) if (!handler->cgroup_ops->mount(handler->cgroup_ops, handler, cg_flags))
return log_error_errno(-1, errno, "Failed to mount \"/sys/fs/cgroup\""); return log_error_errno(-1, errno, "Failed to mount \"/sys/fs/cgroup\"");
} }
...@@ -3432,7 +3433,7 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3432,7 +3433,7 @@ int lxc_setup(struct lxc_handler *handler)
/* Do automatic mounts (mainly /proc and /sys), but exclude those that /* Do automatic mounts (mainly /proc and /sys), but exclude those that
* need to wait until other stuff has finished. * need to wait until other stuff has finished.
*/ */
ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & ~LXC_AUTO_CGROUP_MASK, handler); ret = lxc_mount_auto_mounts(handler, lxc_conf->auto_mounts & ~LXC_AUTO_CGROUP_MASK);
if (ret < 0) if (ret < 0)
return log_error(-1, "Failed to setup first automatic mounts"); return log_error(-1, "Failed to setup first automatic mounts");
...@@ -3473,7 +3474,7 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3473,7 +3474,7 @@ int lxc_setup(struct lxc_handler *handler)
* mounted. It is guaranteed to be mounted now either through * mounted. It is guaranteed to be mounted now either through
* automatically or via fstab entries. * automatically or via fstab entries.
*/ */
ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler); ret = lxc_mount_auto_mounts(handler, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK);
if (ret < 0) if (ret < 0)
return log_error(-1, "Failed to setup remaining automatic mounts"); return log_error(-1, "Failed to setup remaining automatic mounts");
......
...@@ -241,7 +241,7 @@ enum { ...@@ -241,7 +241,7 @@ enum {
LXC_AUTO_CGROUP_NOSPEC = 0x0B0, /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */ LXC_AUTO_CGROUP_NOSPEC = 0x0B0, /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */
LXC_AUTO_CGROUP_FULL_NOSPEC = 0x0E0, /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */ LXC_AUTO_CGROUP_FULL_NOSPEC = 0x0E0, /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */
LXC_AUTO_CGROUP_FORCE = 0x100, /* mount cgroups even when cgroup namespaces are supported */ LXC_AUTO_CGROUP_FORCE = 0x100, /* mount cgroups even when cgroup namespaces are supported */
LXC_AUTO_CGROUP_MASK = 0x1F0, /* all known cgroup options, doe not contain LXC_AUTO_CGROUP_FORCE */ LXC_AUTO_CGROUP_MASK = 0x1F0, /* all known cgroup options */
LXC_AUTO_SHMOUNTS = 0x200, /* shared mount point */ LXC_AUTO_SHMOUNTS = 0x200, /* shared mount point */
LXC_AUTO_SHMOUNTS_MASK = 0x200, /* shared mount point mask */ LXC_AUTO_SHMOUNTS_MASK = 0x200, /* shared mount point mask */
......
...@@ -494,6 +494,13 @@ __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \ ...@@ -494,6 +494,13 @@ __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
__internal_ret__; \ __internal_ret__; \
}) })
#define syserrno(__ret__, format, ...) \
({ \
typeof(__ret__) __internal_ret__ = (__ret__); \
SYSERROR(format, ##__VA_ARGS__); \
__internal_ret__; \
})
#define log_error(__ret__, format, ...) \ #define log_error(__ret__, format, ...) \
({ \ ({ \
typeof(__ret__) __internal_ret__ = (__ret__); \ typeof(__ret__) __internal_ret__ = (__ret__); \
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <unistd.h> #include <unistd.h>
#include "caps.h" #include "caps.h"
#include "cgroups/cgroup_utils.h"
#include "conf.h" #include "conf.h"
#include "config.h" #include "config.h"
#include "initutils.h" #include "initutils.h"
......
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
#include "af_unix.h" #include "af_unix.h"
#include "caps.h" #include "caps.h"
#include "cgroup.h" #include "cgroups/cgroup.h"
#include "cgroups/cgroup_utils.h"
#include "commands.h" #include "commands.h"
#include "commands_utils.h" #include "commands_utils.h"
#include "compiler.h" #include "compiler.h"
......
...@@ -180,4 +180,10 @@ __hidden extern int __lxc_start(struct lxc_handler *, struct lxc_operations *, v ...@@ -180,4 +180,10 @@ __hidden extern int __lxc_start(struct lxc_handler *, struct lxc_operations *, v
__hidden extern int resolve_clone_flags(struct lxc_handler *handler); __hidden extern int resolve_clone_flags(struct lxc_handler *handler);
__hidden extern void lxc_expose_namespace_environment(const struct lxc_handler *handler); __hidden extern void lxc_expose_namespace_environment(const struct lxc_handler *handler);
static inline bool container_uses_namespace(const struct lxc_handler *handler,
unsigned int ns_flag)
{
return (handler->ns_clone_flags & ns_flag);
}
#endif #endif
...@@ -747,11 +747,6 @@ char *on_path(const char *cmd, const char *rootfs) ...@@ -747,11 +747,6 @@ char *on_path(const char *cmd, const char *rootfs)
return NULL; return NULL;
} }
bool cgns_supported(void)
{
return file_exists("/proc/self/ns/cgroup");
}
/* historically lxc-init has been under /usr/lib/lxc and under /* historically lxc-init has been under /usr/lib/lxc and under
* /usr/lib/$ARCH/lxc. It now lives as $prefix/sbin/init.lxc. * /usr/lib/$ARCH/lxc. It now lives as $prefix/sbin/init.lxc.
*/ */
...@@ -1860,3 +1855,53 @@ bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res) ...@@ -1860,3 +1855,53 @@ bool multiply_overflow(int64_t base, uint64_t mult, int64_t *res)
*res = base * mult; *res = base * mult;
return true; return true;
} }
int print_r(int fd, const char *path)
{
__do_close int dfd = -EBADF;
__do_closedir DIR *dir = NULL;
int ret = 0;
struct dirent *direntp;
struct stat st;
if (is_empty_string(path))
dfd = dup(fd);
else
dfd = openat(fd, path, O_CLOEXEC | O_DIRECTORY);
if (dfd < 0)
return -1;
dir = fdopendir(dfd);
if (!dir)
return -1;
/* Transfer ownership to fdopendir(). */
move_fd(dfd);
while ((direntp = readdir(dir))) {
if (!strcmp(direntp->d_name, ".") ||
!strcmp(direntp->d_name, ".."))
continue;
ret = fstatat(dfd, direntp->d_name, &st, AT_SYMLINK_NOFOLLOW);
if (ret < 0 && errno != ENOENT)
break;
ret = 0;
if (S_ISDIR(st.st_mode))
ret = print_r(dfd, direntp->d_name);
else
INFO("mode(%o):uid(%d):gid(%d) -> %s/%s\n",
(st.st_mode & ~S_IFMT), st.st_uid, st.st_gid, path,
direntp->d_name);
if (ret < 0 && errno != ENOENT)
break;
}
ret = fstatat(fd, path, &st, AT_SYMLINK_NOFOLLOW);
if (ret)
return -1;
else
INFO("mode(%o):uid(%d):gid(%d) -> %s",
(st.st_mode & ~S_IFMT), st.st_uid, st.st_gid, path);
return ret;
}
...@@ -138,7 +138,6 @@ __hidden extern bool is_shared_mountpoint(const char *path); ...@@ -138,7 +138,6 @@ __hidden extern bool is_shared_mountpoint(const char *path);
__hidden extern int detect_shared_rootfs(void); __hidden extern int detect_shared_rootfs(void);
__hidden extern bool detect_ramfs_rootfs(void); __hidden extern bool detect_ramfs_rootfs(void);
__hidden extern char *on_path(const char *cmd, const char *rootfs); __hidden extern char *on_path(const char *cmd, const char *rootfs);
__hidden extern bool cgns_supported(void);
__hidden extern char *choose_init(const char *rootfs); __hidden extern char *choose_init(const char *rootfs);
__hidden extern bool switch_to_ns(pid_t pid, const char *ns); __hidden extern bool switch_to_ns(pid_t pid, const char *ns);
__hidden extern char *get_template_path(const char *t); __hidden extern char *get_template_path(const char *t);
...@@ -244,5 +243,6 @@ __hidden extern int safe_mount_beneath(const char *beneath, const char *src, con ...@@ -244,5 +243,6 @@ __hidden extern int safe_mount_beneath(const char *beneath, const char *src, con
const char *fstype, unsigned int flags, const void *data); 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, __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); const char *fstype, unsigned int flags, const void *data);
__hidden __lxc_unused int print_r(int fd, const char *path);
#endif /* __LXC_UTILS_H */ #endif /* __LXC_UTILS_H */
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include "cgroups/cgroup_utils.h"
#include "lxctest.h" #include "lxctest.h"
#include "namespace.h" #include "namespace.h"
#include "process_utils.h" #include "process_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