2020-11-09 05:23:58 +01:00
|
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
2013-11-11 10:03:31 +01:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2018-11-17 12:19:07 +01:00
|
|
|
#include "cgroup.h"
|
|
|
|
#include "cgroup-util.h"
|
2013-11-11 10:03:31 +01:00
|
|
|
#include "macro.h"
|
2015-11-16 22:09:36 +01:00
|
|
|
#include "manager.h"
|
2016-04-08 18:54:05 +02:00
|
|
|
#include "rm-rf.h"
|
2017-11-08 19:01:18 +01:00
|
|
|
#include "string-util.h"
|
2016-04-08 18:54:05 +02:00
|
|
|
#include "tests.h"
|
2015-11-16 22:09:36 +01:00
|
|
|
#include "unit.h"
|
2013-11-11 10:03:31 +01:00
|
|
|
|
2018-11-17 12:19:07 +01:00
|
|
|
#define ASSERT_CGROUP_MASK(got, expected) \
|
|
|
|
log_cgroup_mask(got, expected); \
|
|
|
|
assert_se(got == expected)
|
|
|
|
|
|
|
|
#define ASSERT_CGROUP_MASK_JOINED(got, expected) ASSERT_CGROUP_MASK(got, CGROUP_MASK_EXTEND_JOINED(expected))
|
|
|
|
|
|
|
|
static void log_cgroup_mask(CGroupMask got, CGroupMask expected) {
|
|
|
|
_cleanup_free_ char *e_store = NULL, *g_store = NULL;
|
|
|
|
|
|
|
|
assert_se(cg_mask_to_string(expected, &e_store) >= 0);
|
|
|
|
log_info("Expected mask: %s\n", e_store);
|
|
|
|
assert_se(cg_mask_to_string(got, &g_store) >= 0);
|
|
|
|
log_info("Got mask: %s\n", g_store);
|
|
|
|
}
|
|
|
|
|
2013-11-11 10:03:31 +01:00
|
|
|
static int test_cgroup_mask(void) {
|
2017-02-14 22:33:52 +01:00
|
|
|
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
2018-03-09 21:55:55 +01:00
|
|
|
_cleanup_(manager_freep) Manager *m = NULL;
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
Unit *son, *daughter, *parent, *root, *grandchild, *parent_deep, *nomem_parent, *nomem_leaf;
|
2013-11-11 10:03:31 +01:00
|
|
|
int r;
|
2018-11-17 12:19:07 +01:00
|
|
|
CGroupMask cpu_accounting_mask = get_cpu_accounting_mask();
|
2013-11-11 10:03:31 +01:00
|
|
|
|
2019-11-08 16:57:25 +01:00
|
|
|
r = enter_cgroup_subroot(NULL);
|
2018-09-13 13:34:12 +02:00
|
|
|
if (r == -ENOMEDIUM)
|
|
|
|
return log_tests_skipped("cgroupfs not available");
|
tests: when running a manager object in a test, migrate to private cgroup subroot first (#6576)
Without this "meson test" will end up running all tests in the same
cgroup root, and they all will try to manage it. Which usually isn't too
bad, except when they end up clearing up each other's cgroups. This race
is hard to trigger but has caused various CI runs to fail spuriously.
With this change we simply move every test that runs a manager object
into their own private cgroup. Note that we don't clean up the cgroup at
the end, we leave that to the cgroup manager around it.
This fixes races that become visible by test runs throwing out errors
like this:
```
exec-systemcallfilter-failing.service: Passing 0 fds to service
exec-systemcallfilter-failing.service: About to execute: /bin/echo 'This should not be seen'
exec-systemcallfilter-failing.service: Forked /bin/echo as 5693
exec-systemcallfilter-failing.service: Changed dead -> start
exec-systemcallfilter-failing.service: Failed to attach to cgroup /exec-systemcallfilter-failing.service: No such file or directory
Received SIGCHLD from PID 5693 ((echo)).
Child 5693 ((echo)) died (code=exited, status=219/CGROUP)
exec-systemcallfilter-failing.service: Child 5693 belongs to exec-systemcallfilter-failing.service
exec-systemcallfilter-failing.service: Main process exited, code=exited, status=219/CGROUP
exec-systemcallfilter-failing.service: Changed start -> failed
exec-systemcallfilter-failing.service: Unit entered failed state.
exec-systemcallfilter-failing.service: Failed with result 'exit-code'.
exec-systemcallfilter-failing.service: cgroup is empty
Assertion 'service->main_exec_status.status == status_expected' failed at ../src/src/test/test-execute.c:71, function check(). Aborting.
```
BTW, I tracked this race down by using perf:
```
# perf record -e cgroup:cgroup_mkdir,cgroup_rmdir
…
# perf script
```
Thanks a lot @iaguis, @alban for helping me how to use perf for this.
Fixes #5895.
2017-08-09 15:42:49 +02:00
|
|
|
|
2013-11-11 10:03:31 +01:00
|
|
|
/* Prepare the manager. */
|
2019-12-06 21:51:59 +01:00
|
|
|
_cleanup_free_ char *unit_dir = NULL;
|
|
|
|
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
|
|
|
|
assert_se(set_unit_path(unit_dir) >= 0);
|
2017-02-14 22:33:52 +01:00
|
|
|
assert_se(runtime_dir = setup_fake_runtime_dir());
|
2018-03-10 11:02:18 +01:00
|
|
|
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
|
2017-10-04 16:01:32 +02:00
|
|
|
if (IN_SET(r, -EPERM, -EACCES)) {
|
2018-09-13 13:34:12 +02:00
|
|
|
log_error_errno(r, "manager_new: %m");
|
|
|
|
return log_tests_skipped("cannot create manager");
|
2013-11-11 10:03:31 +01:00
|
|
|
}
|
2018-09-13 13:34:12 +02:00
|
|
|
|
2016-01-20 02:20:02 +01:00
|
|
|
assert_se(r >= 0);
|
2015-11-13 19:28:32 +01:00
|
|
|
|
|
|
|
/* Turn off all kinds of default accouning, so that we can
|
|
|
|
* verify the masks resulting of our configuration and nothing
|
|
|
|
* else. */
|
|
|
|
m->default_cpu_accounting =
|
|
|
|
m->default_memory_accounting =
|
|
|
|
m->default_blockio_accounting =
|
2016-05-19 02:35:12 +02:00
|
|
|
m->default_io_accounting =
|
2015-11-13 19:28:32 +01:00
|
|
|
m->default_tasks_accounting = false;
|
2019-11-05 13:50:28 +01:00
|
|
|
m->default_tasks_max = TASKS_MAX_UNSET;
|
2015-11-13 19:28:32 +01:00
|
|
|
|
2018-06-20 22:19:26 +02:00
|
|
|
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
2013-11-11 10:03:31 +01:00
|
|
|
|
|
|
|
/* Load units and verify hierarchy. */
|
2018-04-12 15:51:39 +02:00
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "parent.slice", NULL, &parent) >= 0);
|
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "son.service", NULL, &son) >= 0);
|
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "daughter.service", NULL, &daughter) >= 0);
|
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "grandchild.service", NULL, &grandchild) >= 0);
|
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "parent-deep.slice", NULL, &parent_deep) >= 0);
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "nomem.slice", NULL, &nomem_parent) >= 0);
|
|
|
|
assert_se(manager_load_startable_unit_or_warn(m, "nomemleaf.service", NULL, &nomem_leaf) >= 0);
|
2014-10-04 23:51:45 +02:00
|
|
|
assert_se(UNIT_DEREF(son->slice) == parent);
|
|
|
|
assert_se(UNIT_DEREF(daughter->slice) == parent);
|
|
|
|
assert_se(UNIT_DEREF(parent_deep->slice) == parent);
|
|
|
|
assert_se(UNIT_DEREF(grandchild->slice) == parent_deep);
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
assert_se(UNIT_DEREF(nomem_leaf->slice) == nomem_parent);
|
2013-11-11 10:03:31 +01:00
|
|
|
root = UNIT_DEREF(parent->slice);
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
assert_se(UNIT_DEREF(nomem_parent->slice) == root);
|
2013-11-11 10:03:31 +01:00
|
|
|
|
|
|
|
/* Verify per-unit cgroups settings. */
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(son), CGROUP_MASK_CPU);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(daughter), cpu_accounting_mask);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(grandchild), 0);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(parent_deep), CGROUP_MASK_MEMORY);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(parent), (CGROUP_MASK_IO | CGROUP_MASK_BLKIO));
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(nomem_parent), 0);
|
2020-05-01 14:00:42 +02:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(nomem_leaf), (CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_own_mask(root), 0);
|
2014-02-14 19:11:07 +01:00
|
|
|
|
|
|
|
/* Verify aggregation of member masks */
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(son), 0);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(daughter), 0);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(grandchild), 0);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(parent_deep), 0);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(parent), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
|
2020-05-01 14:00:42 +02:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(nomem_parent), (CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(nomem_leaf), 0);
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_members_mask(root), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
2014-02-14 19:11:07 +01:00
|
|
|
|
|
|
|
/* Verify aggregation of sibling masks. */
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(son), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(daughter), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(grandchild), 0);
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(parent_deep), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY));
|
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(parent), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(nomem_parent), (CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
2020-05-01 14:00:42 +02:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(nomem_leaf), (CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK_JOINED(unit_get_siblings_mask(root), (CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY));
|
2014-02-14 19:11:07 +01:00
|
|
|
|
|
|
|
/* Verify aggregation of target masks. */
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(son), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(daughter), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(grandchild), 0);
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(parent_deep), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(parent), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
cgroup: Add DisableControllers= directive to disable controller in subtree
Some controllers (like the CPU controller) have a performance cost that
is non-trivial on certain workloads. While this can be mitigated and
improved to an extent, there will for some controllers always be some
overheads associated with the benefits gained from the controller.
Inside Facebook, the fix applied has been to disable the CPU controller
forcibly with `cgroup_disable=cpu` on the kernel command line.
This presents a problem: to disable or reenable the controller, a reboot
is required, but this is quite cumbersome and slow to do for many
thousands of machines, especially machines where disabling/enabling a
stateful service on a machine is a matter of several minutes.
Currently systemd provides some configuration knobs for these in the
form of `[Default]CPUAccounting`, `[Default]MemoryAccounting`, and the
like. The limitation of these is that Default*Accounting is overrideable
by individual services, of which any one could decide to reenable a
controller within the hierarchy at any point just by using a controller
feature implicitly (eg. `CPUWeight`), even if the use of that CPU
feature could just be opportunistic. Since many services are provided by
the distribution, or by upstream teams at a particular organisation,
it's not a sustainable solution to simply try to find and remove
offending directives from these units.
This commit presents a more direct solution -- a DisableControllers=
directive that forcibly disallows a controller from being enabled within
a subtree.
2018-12-03 15:38:06 +01:00
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(nomem_parent), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | CGROUP_MASK_CPUACCT | CGROUP_MASK_IO | CGROUP_MASK_BLKIO) & m->cgroup_supported));
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(nomem_leaf), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_IO | CGROUP_MASK_BLKIO) & m->cgroup_supported));
|
2018-11-17 12:19:07 +01:00
|
|
|
ASSERT_CGROUP_MASK(unit_get_target_mask(root), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
2013-11-11 10:03:31 +01:00
|
|
|
|
2020-05-01 14:00:42 +02:00
|
|
|
/* Verify aggregation of enable masks. */
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(son), 0);
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(daughter), 0);
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(grandchild), 0);
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(parent_deep), 0);
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(parent), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(nomem_parent), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_IO | CGROUP_MASK_BLKIO) & m->cgroup_supported));
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(nomem_leaf), 0);
|
|
|
|
ASSERT_CGROUP_MASK(unit_get_enable_mask(root), (CGROUP_MASK_EXTEND_JOINED(CGROUP_MASK_CPU | cpu_accounting_mask | CGROUP_MASK_IO | CGROUP_MASK_BLKIO | CGROUP_MASK_MEMORY) & m->cgroup_supported));
|
|
|
|
|
2013-11-11 10:03:31 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-08 19:01:18 +01:00
|
|
|
static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
|
|
|
|
_cleanup_free_ char *b = NULL;
|
|
|
|
|
|
|
|
assert_se(cg_mask_to_string(mask, &b) >= 0);
|
|
|
|
assert_se(streq_ptr(b, t));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void test_cg_mask_to_string(void) {
|
|
|
|
test_cg_mask_to_string_one(0, NULL);
|
2019-07-29 17:50:05 +02:00
|
|
|
test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids bpf-firewall bpf-devices");
|
2017-11-08 19:01:18 +01:00
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct");
|
2019-07-29 17:50:05 +02:00
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPUSET, "cpuset");
|
2017-11-08 19:01:18 +01:00
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_IO, "io");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_BLKIO, "blkio");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_MEMORY, "memory");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_DEVICES, "devices");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_PIDS, "pids");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPU|CGROUP_MASK_CPUACCT, "cpu cpuacct");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPU|CGROUP_MASK_PIDS, "cpu pids");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT|CGROUP_MASK_PIDS, "cpuacct pids");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_DEVICES|CGROUP_MASK_PIDS, "devices pids");
|
|
|
|
test_cg_mask_to_string_one(CGROUP_MASK_IO|CGROUP_MASK_BLKIO, "io blkio");
|
|
|
|
}
|
|
|
|
|
2013-11-11 10:03:31 +01:00
|
|
|
int main(int argc, char* argv[]) {
|
2018-09-13 13:34:12 +02:00
|
|
|
int rc = EXIT_SUCCESS;
|
2016-04-08 18:54:05 +02:00
|
|
|
|
2018-09-13 14:31:13 +02:00
|
|
|
test_setup_logging(LOG_DEBUG);
|
2017-11-08 19:01:18 +01:00
|
|
|
|
|
|
|
test_cg_mask_to_string();
|
2018-09-13 13:34:12 +02:00
|
|
|
TEST_REQ_RUNNING_SYSTEMD(rc = test_cgroup_mask());
|
2016-04-08 18:54:05 +02:00
|
|
|
|
2013-11-11 10:03:31 +01:00
|
|
|
return rc;
|
|
|
|
}
|