From dcde1e903ae57cb7ad52e3a5716ce28bb91fdf63 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Sun, 16 Mar 2025 02:48:29 +0100 Subject: [PATCH] match glibc in ConditionVersion Extend ConditionVersion= to allow matching against glibc version, as proposed in https://github.com/systemd/systemd/pull/36468#issuecomment-2674600909 --- man/systemd.unit.xml | 8 ++++---- src/shared/condition.c | 4 ++++ src/test/test-condition.c | 30 ++++++++++++++++++++++++++++ test/test-execute/exec-basic.service | 5 +++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 5be9225a587..0bc3668f4cb 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1487,10 +1487,10 @@ ConditionVersion= 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 - kernel and systemd are supported. If this argument is - omitted, kernel is implied. The second argument must be a list - of (potentially quoted) expressions. Each expression starts with one of = or - != for string comparisons, <, <=, + kernel, systemd and glibc are supported. + If this argument is omitted, kernel is implied. The second argument must be a + list of (potentially quoted) expressions. Each expression starts with one of = + or != for string comparisons, <, <=, ==, <>, >=, > for version comparisons, or $=, !$= for a shell-style glob match. If no operator is specified, $= is implied. diff --git a/src/shared/condition.c b/src/shared/condition.c index b65d64d300d..e6481c46417 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -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; diff --git a/src/test/test-condition.c b/src/test/test-condition.c index a6132f1132b..b02f4cce6da 100644 --- a/src/test/test-condition.c +++ b/src/test/test-condition.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include #include #include #include @@ -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) { diff --git a/test/test-execute/exec-basic.service b/test/test-execute/exec-basic.service index 1fb300dc152..c29d46c2dfb 100644 --- a/test/test-execute/exec-basic.service +++ b/test/test-execute/exec-basic.service @@ -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 -- 2.47.3