]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/condition: add ConditionControlGroupController=v1|v2
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 22 Feb 2021 21:09:38 +0000 (22:09 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 23 Feb 2021 00:11:18 +0000 (01:11 +0100)
Before, we only allowed conditionalizing on controllers, not the hierarchy.
This commit extends this to allow a simple check for v1 (i.e. classic or hybrid),
and v2 (full unified).

An alternative approach would be to add a separate Condition for this, but I'm
not too keen on that, considering that v1 is already being deprecrecated
(c.f. 82f3063218).

man/systemd.unit.xml
src/shared/condition.c
src/test/test-condition.c

index 333449097f440487621f17c47ec907bee12ba9a5..cd9437c509d602dab2a24070c2d08c6ce4a5b2bc 100644 (file)
         <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>
 
index 1e63956c05f1b1782135537722e885bc1a82acb7..d84377c269e2553ffa1b84398c65cc655bc5773c 100644 (file)
@@ -354,6 +354,15 @@ static int condition_test_control_group_controller(Condition *c, char **env) {
         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");
index 25483d015b3dc9b473808920076efef807051b3a..3fe961f60b5ce47dcaf83e6b7cc49538df49548e 100644 (file)
@@ -124,10 +124,26 @@ static void test_condition_test_path(void) {
         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;
 
@@ -151,7 +167,7 @@ static void test_condition_test_control_group_controller(void) {
         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)) {
@@ -881,6 +897,7 @@ int main(int argc, char *argv[]) {
         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();