From: Zbigniew Jędrzejewski-Szmek Date: Thu, 7 Apr 2022 09:51:52 +0000 (+0200) Subject: Move systemd_installation_has_version() to src/nspawn/ X-Git-Tag: v251-rc2~162^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9394f4f93b9a6baa54f9d1c953035f26dcee253;p=thirdparty%2Fsystemd.git Move systemd_installation_has_version() to src/nspawn/ This function implements a heuristic that is only used by nspawn. It doesn't belong in basic. I opted for a new file "nspawn-utils.c", because it seems likely that we'll need some other new utilities like that in the future. No functional change. --- diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 5d93e107a78..979c6f2c9df 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -17,11 +17,8 @@ #include "extract-word.h" #include "fd-util.h" #include "fs-util.h" -#include "glob-util.h" #include "log.h" #include "macro.h" -#include "nulstr-util.h" -#include "parse-util.h" #include "path-util.h" #include "stat-util.h" #include "string-util.h" @@ -1314,74 +1311,6 @@ bool valid_device_allow_pattern(const char *path) { return valid_device_node_path(path); } -int systemd_installation_has_version(const char *root, unsigned minimal_version) { - const char *pattern; - int r; - - /* Try to guess if systemd installation is later than the specified version. This - * is hacky and likely to yield false negatives, particularly if the installation - * is non-standard. False positives should be relatively rare. - */ - - NULSTR_FOREACH(pattern, - /* /lib works for systems without usr-merge, and for systems with a sane - * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary - * for Gentoo which does a merge without making /lib a symlink. - */ - "lib/systemd/libsystemd-shared-*.so\0" - "lib64/systemd/libsystemd-shared-*.so\0" - "usr/lib/systemd/libsystemd-shared-*.so\0" - "usr/lib64/systemd/libsystemd-shared-*.so\0") { - - _cleanup_strv_free_ char **names = NULL; - _cleanup_free_ char *path = NULL; - char *c; - - path = path_join(root, pattern); - if (!path) - return -ENOMEM; - - r = glob_extend(&names, path, 0); - if (r == -ENOENT) - continue; - if (r < 0) - return r; - - assert_se(c = endswith(path, "*.so")); - *c = '\0'; /* truncate the glob part */ - - STRV_FOREACH(name, names) { - /* This is most likely to run only once, hence let's not optimize anything. */ - char *t, *t2; - unsigned version; - - t = startswith(*name, path); - if (!t) - continue; - - t2 = endswith(t, ".so"); - if (!t2) - continue; - - t2[0] = '\0'; /* truncate the suffix */ - - r = safe_atou(t, &version); - if (r < 0) { - log_debug_errno(r, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name); - continue; - } - - log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).", - *name, version, - version >= minimal_version ? "OK" : "too old"); - if (version >= minimal_version) - return true; - } - } - - return false; -} - bool dot_or_dot_dot(const char *path) { if (!path) return false; diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 518f3340bf2..2f55b3abb16 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -181,8 +181,6 @@ bool is_device_path(const char *path); bool valid_device_node_path(const char *path); bool valid_device_allow_pattern(const char *path); -int systemd_installation_has_version(const char *root, unsigned minimal_version); - bool dot_or_dot_dot(const char *path); static inline const char *skip_dev_prefix(const char *p) { diff --git a/src/nspawn/meson.build b/src/nspawn/meson.build index a42e16dd99d..f6cca7099bd 100644 --- a/src/nspawn/meson.build +++ b/src/nspawn/meson.build @@ -28,6 +28,8 @@ libnspawn_core_sources = files( 'nspawn-setuid.h', 'nspawn-stub-pid1.c', 'nspawn-stub-pid1.h', + 'nspawn-util.c', + 'nspawn-util.h', 'nspawn.h', ) @@ -58,6 +60,11 @@ tests += [ libshared], [libseccomp]], + [files('test-nspawn-util.c'), + [libnspawn_core, + libshared], + [libseccomp]], + [files('test-patch-uid.c'), [libnspawn_core, libshared], diff --git a/src/nspawn/nspawn-util.c b/src/nspawn/nspawn-util.c new file mode 100644 index 00000000000..7aacbb80962 --- /dev/null +++ b/src/nspawn/nspawn-util.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "alloc-util.h" +#include "glob-util.h" +#include "log.h" +#include "nspawn-util.h" +#include "nulstr-util.h" +#include "parse-util.h" +#include "path-util.h" +#include "string-util.h" + +int systemd_installation_has_version(const char *root, unsigned minimal_version) { + const char *pattern; + int r; + + /* Try to guess if systemd installation is later than the specified version. This + * is hacky and likely to yield false negatives, particularly if the installation + * is non-standard. False positives should be relatively rare. + */ + + NULSTR_FOREACH(pattern, + /* /lib works for systems without usr-merge, and for systems with a sane + * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary + * for Gentoo which does a merge without making /lib a symlink. + */ + "lib/systemd/libsystemd-shared-*.so\0" + "lib64/systemd/libsystemd-shared-*.so\0" + "usr/lib/systemd/libsystemd-shared-*.so\0" + "usr/lib64/systemd/libsystemd-shared-*.so\0") { + + _cleanup_strv_free_ char **names = NULL; + _cleanup_free_ char *path = NULL; + char *c; + + path = path_join(root, pattern); + if (!path) + return -ENOMEM; + + r = glob_extend(&names, path, 0); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + + assert_se(c = endswith(path, "*.so")); + *c = '\0'; /* truncate the glob part */ + + STRV_FOREACH(name, names) { + /* This is most likely to run only once, hence let's not optimize anything. */ + char *t, *t2; + unsigned version; + + t = startswith(*name, path); + if (!t) + continue; + + t2 = endswith(t, ".so"); + if (!t2) + continue; + + t2[0] = '\0'; /* truncate the suffix */ + + r = safe_atou(t, &version); + if (r < 0) { + log_debug_errno(r, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name); + continue; + } + + log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).", + *name, version, + version >= minimal_version ? "OK" : "too old"); + if (version >= minimal_version) + return true; + } + } + + return false; +} diff --git a/src/nspawn/nspawn-util.h b/src/nspawn/nspawn-util.h new file mode 100644 index 00000000000..1e90862c9d0 --- /dev/null +++ b/src/nspawn/nspawn-util.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +int systemd_installation_has_version(const char *root, unsigned minimal_version); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index aa7367c5c93..1929cd12b02 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -78,13 +78,13 @@ #include "nspawn-settings.h" #include "nspawn-setuid.h" #include "nspawn-stub-pid1.h" +#include "nspawn-util.h" #include "nspawn.h" #include "nulstr-util.h" #include "os-util.h" #include "pager.h" #include "parse-argument.h" #include "parse-util.h" -#include "path-util.h" #include "pretty-print.h" #include "process-util.h" #include "ptyfwd.h" diff --git a/src/nspawn/test-nspawn-util.c b/src/nspawn/test-nspawn-util.c new file mode 100644 index 00000000000..7d55db89340 --- /dev/null +++ b/src/nspawn/test-nspawn-util.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nspawn-util.h" +#include "string-util.h" +#include "tests.h" + +TEST(systemd_installation_has_version) { + static const unsigned versions[] = {0, 231, PROJECT_VERSION, 999}; + int r; + + for (size_t i = 0; i < ELEMENTSOF(versions); i++) { + r = systemd_installation_has_version(saved_argv[1], versions[i]); + assert_se(r >= 0); + log_info("%s has systemd >= %u: %s", + saved_argv[1] ?: "Current installation", versions[i], yes_no(r)); + } +} + +DEFINE_TEST_MAIN(LOG_DEBUG); diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index d40febef5f7..4c56a7d5200 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -960,21 +960,6 @@ TEST(hidden_or_backup_file) { assert_se(!hidden_or_backup_file("test.dpkg-old.foo")); } -TEST(systemd_installation_has_version) { - int r; - const unsigned versions[] = {0, 231, PROJECT_VERSION, 999}; - unsigned i; - - log_info("/* %s */", __func__); - - for (i = 0; i < ELEMENTSOF(versions); i++) { - r = systemd_installation_has_version(saved_argv[1], versions[i]); - assert_se(r >= 0); - log_info("%s has systemd >= %u: %s", - saved_argv[1] ?: "Current installation", versions[i], yes_no(r)); - } -} - TEST(skip_dev_prefix) { assert_se(streq(skip_dev_prefix("/"), "/")); assert_se(streq(skip_dev_prefix("/dev"), ""));