]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
match glibc in ConditionVersion
authorMatteo Croce <teknoraver@meta.com>
Sun, 16 Mar 2025 01:48:29 +0000 (02:48 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 20 Mar 2025 21:57:28 +0000 (06:57 +0900)
Extend ConditionVersion= to allow matching against glibc version,
as proposed in https://github.com/systemd/systemd/pull/36468#issuecomment-2674600909

man/systemd.unit.xml
src/shared/condition.c
src/test/test-condition.c
test/test-execute/exec-basic.service

index 5be9225a587fe4b0cadb785977fcb93fbdcf9ea4..0bc3668f4cb32f3e001e8bba5acbccc5ee59e4c5 100644 (file)
           <listitem><para><varname>ConditionVersion=</varname> may be used to check whether a software
           version matches a certain expression, or if prefixed with the exclamation mark, does not match.
           The first argument is the software whose version has to be checked. Currently
-          <literal>kernel</literal> and <literal>systemd</literal> are supported. If this argument is
-          omitted, <literal>kernel</literal> is implied. The second argument must be a list
-          of (potentially quoted) expressions. Each expression starts with one of <literal>=</literal> or
-          <literal>!=</literal> for string comparisons, <literal>&lt;</literal>, <literal>&lt;=</literal>,
+          <literal>kernel</literal>, <literal>systemd</literal> and <literal>glibc</literal> are supported.
+          If this argument is omitted, <literal>kernel</literal> is implied. The second argument must be a
+          list of (potentially quoted) expressions. Each expression starts with one of <literal>=</literal>
+          or <literal>!=</literal> for string comparisons, <literal>&lt;</literal>, <literal>&lt;=</literal>,
           <literal>==</literal>, <literal>&lt;&gt;</literal>, <literal>&gt;=</literal>,
           <literal>&gt;</literal> for version comparisons, or <literal>$=</literal>, <literal>!$=</literal>
           for a shell-style glob match. If no operator is specified, <literal>$=</literal> is implied.</para>
index b65d64d300d852877de899bc11543db37f7776c3..e6481c46417124c5ad3d4f3e9941874e86f3b959 100644 (file)
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <fnmatch.h>
+#include <gnu/libc-version.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <sys/stat.h>
@@ -258,6 +259,9 @@ static int condition_test_version(Condition *c, char **env) {
         if (streq(word, "systemd"))
                 return condition_test_version_cmp(p, STRINGIFY(PROJECT_VERSION));
 
+        if (streq(word, "glibc"))
+                return condition_test_version_cmp(p, gnu_get_libc_version());
+
         /* if no predicate has been set, default to "kernel" and use the whole parameter as condition */
         if (!streq(word, "kernel"))
                 p = c->parameter;
index a6132f1132b7b5aa208767fb4bd5fe74c85d14ba..b02f4cce6dae48e03077732fe798a87d251783f5 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <gnu/libc-version.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/utsname.h>
@@ -676,6 +677,35 @@ TEST(condition_test_version) {
         ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, v, false, false)));
         ASSERT_OK_ZERO(condition_test(condition, environ));
         condition_free(condition);
+
+        /* Test glibc version */
+        ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, "glibc > 1", false, false)));
+        ASSERT_OK_POSITIVE(condition_test(condition, environ));
+        condition_free(condition);
+
+        ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, "glibc < 2", false, false)));
+        ASSERT_OK_ZERO(condition_test(condition, environ));
+        condition_free(condition);
+
+        ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, "glibc < 9999", false, false)));
+        ASSERT_OK_POSITIVE(condition_test(condition, environ));
+        condition_free(condition);
+
+        ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, "glibc > 9999", false, false)));
+        ASSERT_OK_ZERO(condition_test(condition, environ));
+        condition_free(condition);
+
+        v = strjoina("glibc = ", gnu_get_libc_version());
+
+        ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, v, false, false)));
+        ASSERT_OK_POSITIVE(condition_test(condition, environ));
+        condition_free(condition);
+
+        v = strjoina("glibc != ", gnu_get_libc_version());
+
+        ASSERT_NOT_NULL((condition = condition_new(CONDITION_VERSION, v, false, false)));
+        ASSERT_OK_ZERO(condition_test(condition, environ));
+        condition_free(condition);
 }
 
 TEST(condition_test_credential) {
index 1fb300dc152bceffeec5ad3c217ecdb25da86bc5..c29d46c2dfbbf58a7e64a54adb5c103e0e4943f4 100644 (file)
@@ -21,6 +21,11 @@ ConditionVersion=systemd ">=20" "<=9000" "!=14"
 ConditionVersion=systemd " >= 20" " <= 9000 " "!= 14"
 ConditionVersion=systemd " >= 20" " * "
 
+ConditionVersion=glibc ">=2"
+ConditionVersion=glibc ">=2" "<=9000" "!=1"
+ConditionVersion=glibc " >= 2" " <= 9000 " "!= 1"
+ConditionVersion=glibc " >= 2" " * "
+
 [Service]
 ExecStart=touch /tmp/a ; /bin/sh -c 'touch /tmp/b' ; touch /tmp/c
 ExecStart=test -f /tmp/a