cgroups/cgfsng: do not prematurely close file descriptors

When adding the new improved cgroup setup logic I didn't account for the fact that we need the hierarchy fds up until chown. Add a dedicated cleanup method to fix this: lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, , 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, tasks, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) lxc b1 20191212205052.712 WARN cgfsng - cgroups/cgfsng.c:fchowmodat:1481 - Bad file descriptor - Failed to fchownat(-9, cgroup.procs, 1000000000, 0, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW ) Closes #3228. Fixes: 1973b62a ("cgroups/cgfsng: improve cgroup creation and removal") Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent 28a41fc2
...@@ -1413,9 +1413,9 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, ...@@ -1413,9 +1413,9 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops,
return log_error_errno(false, errno, "Failed to enter cgroup \"%s\"", h->monitor_full_path); return log_error_errno(false, errno, "Failed to enter cgroup \"%s\"", h->monitor_full_path);
/* /*
* We don't keep the fds for non-unified hierarchies around * we don't keep the fds for non-unified hierarchies around
* mainly because we don't make use of them anymore after the * mainly because we don't make use of them anymore after the
* core cgroup setup is done but also because they're quite a * core cgroup setup is done but also because there are quite a
* lot of them. * lot of them.
*/ */
if (!is_unified_hierarchy(h)) if (!is_unified_hierarchy(h))
...@@ -1453,15 +1453,6 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, ...@@ -1453,15 +1453,6 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops,
ret = lxc_writeat(h->cgfd_con, "cgroup.procs", pidstr, len); ret = lxc_writeat(h->cgfd_con, "cgroup.procs", pidstr, len);
if (ret != 0) if (ret != 0)
return log_error_errno(false, errno, "Failed to enter cgroup \"%s\"", h->container_full_path); return log_error_errno(false, errno, "Failed to enter cgroup \"%s\"", h->container_full_path);
/*
* We don't keep the fds for non-unified hierarchies around
* mainly because we don't make use of them anymore after the
* core cgroup setup is done but also because they're quite a
* lot of them.
*/
if (!is_unified_hierarchy(h))
close_prot_errno_disarm(h->cgfd_con);
} }
return true; return true;
...@@ -1582,6 +1573,27 @@ __cgfsng_ops static bool cgfsng_chown(struct cgroup_ops *ops, ...@@ -1582,6 +1573,27 @@ __cgfsng_ops static bool cgfsng_chown(struct cgroup_ops *ops,
return true; return true;
} }
__cgfsng_ops void cgfsng_payload_finalize(struct cgroup_ops *ops)
{
if (!ops)
return;
if (!ops->hierarchies)
return;
for (int i = 0; ops->hierarchies[i]; i++) {
struct hierarchy *h = ops->hierarchies[i];
/*
* we don't keep the fds for non-unified hierarchies around
* mainly because we don't make use of them anymore after the
* core cgroup setup is done but also because there are quite a
* lot of them.
*/
if (!is_unified_hierarchy(h))
close_prot_errno_disarm(h->cgfd_con);
}
}
/* cgroup-full:* is done, no need to create subdirs */ /* cgroup-full:* is done, no need to create subdirs */
static bool cg_mount_needs_subdirs(int type) static bool cg_mount_needs_subdirs(int type)
{ {
...@@ -3253,6 +3265,7 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf) ...@@ -3253,6 +3265,7 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
cgfsng_ops->payload_delegate_controllers = cgfsng_payload_delegate_controllers; cgfsng_ops->payload_delegate_controllers = cgfsng_payload_delegate_controllers;
cgfsng_ops->payload_create = cgfsng_payload_create; cgfsng_ops->payload_create = cgfsng_payload_create;
cgfsng_ops->payload_enter = cgfsng_payload_enter; cgfsng_ops->payload_enter = cgfsng_payload_enter;
cgfsng_ops->payload_finalize = cgfsng_payload_finalize;
cgfsng_ops->escape = cgfsng_escape; cgfsng_ops->escape = cgfsng_escape;
cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies; cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies;
cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies; cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies;
......
...@@ -166,6 +166,7 @@ struct cgroup_ops { ...@@ -166,6 +166,7 @@ struct cgroup_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);
bool (*payload_delegate_controllers)(struct cgroup_ops *ops); bool (*payload_delegate_controllers)(struct cgroup_ops *ops);
void (*payload_finalize)(struct cgroup_ops *ops);
}; };
extern struct cgroup_ops *cgroup_init(struct lxc_conf *conf); extern struct cgroup_ops *cgroup_init(struct lxc_conf *conf);
......
...@@ -1922,6 +1922,9 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1922,6 +1922,9 @@ static int lxc_spawn(struct lxc_handler *handler)
} }
} }
cgroup_ops->payload_finalize(cgroup_ops);
TRACE("Finished setting up cgroups");
/* Run any host-side start hooks */ /* Run any host-side start hooks */
ret = run_lxc_hooks(name, "start-host", conf, NULL); ret = run_lxc_hooks(name, "start-host", conf, NULL);
if (ret < 0) { if (ret < 0) {
......
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