<varlistentry>
<term><varname>ConditionControlGroupController=</varname></term>
- <listitem><para>Verify that the given cgroup controller (eg. <literal>cpu</literal>) is available
- for use on the system. For example, a particular controller may not be available if it was disabled
- on the kernel command line with <varname>cgroup_disable=controller</varname>. Multiple controllers
- may be passed with a space separating them; in this case the condition will only pass if all listed
- controllers are available for use. Controllers unknown to systemd are ignored. Valid controllers
- are <literal>cpu</literal>, <literal>cpuacct</literal>, <literal>io</literal>,
- <literal>blkio</literal>, <literal>memory</literal>, <literal>devices</literal>, and
- <literal>pids</literal>.</para>
+ <listitem><para>Check whether given cgroup controllers (eg. <literal>cpu</literal>) are available
+ for use on the system or whether the legacy v1 cgroup or the modern v2 cgroup hierarchy is used.
+ </para>
+
+ <para>Multiple controllers may be passed with a space separating them; in this case the condition
+ will only pass if all listed controllers are available for use. Controllers unknown to systemd are
+ ignored. Valid controllers are <literal>cpu</literal>, <literal>cpuacct</literal>,
+ <literal>io</literal>, <literal>blkio</literal>, <literal>memory</literal>,
+ <literal>devices</literal>, and <literal>pids</literal>. Even if available in the kernel, a
+ particular controller may not be available if it was disabled on the kernel command line with
+ <varname>cgroup_disable=controller</varname>.</para>
+
+ <para>Alternatively, two special strings <literal>v1</literal> and <literal>v2</literal> may be
+ specified (without any controller names). <literal>v2</literal> will pass if the unified v2 cgroup
+ hierachy is used, and <literal>v1</literal> will pass if the legacy v1 hierarchy or the hybrid
+ hierarchy are used (see the discussion of <varname>systemd.unified_cgroup_hierarchy</varname> and
+ <varname>systemd.legacy_systemd_cgroup_controller</varname> in
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for more information).</para>
</listitem>
</varlistentry>
assert(c->parameter);
assert(c->type == CONDITION_CONTROL_GROUP_CONTROLLER);
+ if (streq(c->parameter, "v2"))
+ return cg_all_unified();
+ if (streq(c->parameter, "v1")) {
+ r = cg_all_unified();
+ if (r < 0)
+ return r;
+ return !r;
+ }
+
r = cg_mask_supported(&system_mask);
if (r < 0)
return log_debug_errno(r, "Failed to determine supported controllers: %m");
condition_free(condition);
}
+static void test_condition_test_control_group_hierarchy(void) {
+ Condition *condition;
+ int r;
+
+ r = cg_unified();
+
+ condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "v1", false, false);
+ assert_se(condition);
+ assert_se(condition_test(condition, environ) == (r < CGROUP_UNIFIED_ALL));
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "v2", false, false);
+ assert_se(condition);
+ assert_se(condition_test(condition, environ) == (r >= CGROUP_UNIFIED_ALL));
+ condition_free(condition);
+}
+
static void test_condition_test_control_group_controller(void) {
Condition *condition;
CGroupMask system_mask;
- CGroupController controller;
_cleanup_free_ char *controller_name = NULL;
int r;
assert_se(cg_mask_supported(&system_mask) >= 0);
/* Individual valid controllers one by one */
- for (controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
+ for (CGroupController controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
const char *local_controller_name = cgroup_controller_to_string(controller);
log_info("chosen controller is '%s'", local_controller_name);
if (system_mask & CGROUP_CONTROLLER_TO_MASK(controller)) {
test_condition_test_virtualization();
test_condition_test_user();
test_condition_test_group();
+ test_condition_test_control_group_hierarchy();
test_condition_test_control_group_controller();
test_condition_test_cpus();
test_condition_test_memory();