diff options
author | Luca Boccassi <luca.boccassi@microsoft.com> | 2021-01-10 23:54:15 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-01-19 13:41:42 +0100 |
commit | 6ddd05119383d998a69d8c9ce66e27dbb78c40cf (patch) | |
tree | dcf3091fe21f631b97879d5e148e07e1a2b12db4 | |
parent | sysext: add verity boilerplate (diff) | |
download | systemd-6ddd05119383d998a69d8c9ce66e27dbb78c40cf.tar.xz systemd-6ddd05119383d998a69d8c9ce66e27dbb78c40cf.zip |
os-release: add support for /usr/lib/extension-release.d/
Add helpers to look for extension-release.$NAME files in
/usr/lib/extension-release.d/ following the same pattern as os-release.
Diffstat (limited to '')
-rw-r--r-- | src/shared/os-util.c | 62 | ||||
-rw-r--r-- | src/shared/os-util.h | 14 |
2 files changed, 59 insertions, 17 deletions
diff --git a/src/shared/os-util.c b/src/shared/os-util.c index 3b7e495846..d1cf41283b 100644 --- a/src/shared/os-util.c +++ b/src/shared/os-util.c @@ -6,6 +6,7 @@ #include "fileio.h" #include "fs-util.h" #include "macro.h" +#include "machine-image.h" #include "os-util.h" #include "string-util.h" #include "strv.h" @@ -31,17 +32,31 @@ int path_is_os_tree(const char *path) { return 1; } -int open_os_release(const char *root, char **ret_path, int *ret_fd) { +int open_extension_release(const char *root, const char *extension, char **ret_path, int *ret_fd) { _cleanup_free_ char *q = NULL; - const char *p; int r, fd; - FOREACH_STRING(p, "/etc/os-release", "/usr/lib/os-release") { - r = chase_symlinks(p, root, CHASE_PREFIX_ROOT, - ret_path ? &q : NULL, - ret_fd ? &fd : NULL); - if (r != -ENOENT) - break; + if (extension) { + const char *extension_full_path; + + if (!image_name_is_valid(extension)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "The extension name %s is invalid.", extension); + + extension_full_path = strjoina("/usr/lib/extension-release.d/extension-release.", extension); + r = chase_symlinks(extension_full_path, root, CHASE_PREFIX_ROOT, + ret_path ? &q : NULL, + ret_fd ? &fd : NULL); + } else { + const char *p; + + FOREACH_STRING(p, "/etc/os-release", "/usr/lib/os-release") { + r = chase_symlinks(p, root, CHASE_PREFIX_ROOT, + ret_path ? &q : NULL, + ret_fd ? &fd : NULL); + if (r != -ENOENT) + break; + } } if (r < 0) return r; @@ -64,16 +79,16 @@ int open_os_release(const char *root, char **ret_path, int *ret_fd) { return 0; } -int fopen_os_release(const char *root, char **ret_path, FILE **ret_file) { +int fopen_extension_release(const char *root, const char *extension, char **ret_path, FILE **ret_file) { _cleanup_free_ char *p = NULL; _cleanup_close_ int fd = -1; FILE *f; int r; if (!ret_file) - return open_os_release(root, ret_path, NULL); + return open_extension_release(root, extension, ret_path, NULL); - r = open_os_release(root, ret_path ? &p : NULL, &fd); + r = open_extension_release(root, extension, ret_path ? &p : NULL, &fd); if (r < 0) return r; @@ -89,18 +104,35 @@ int fopen_os_release(const char *root, char **ret_path, FILE **ret_file) { return 0; } -int parse_os_release(const char *root, ...) { +static int parse_release_internal(const char *root, const char *extension, va_list ap) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; - va_list ap; int r; - r = fopen_os_release(root, &p, &f); + r = fopen_extension_release(root, extension, &p, &f); if (r < 0) return r; + return parse_env_filev(f, p, ap); +} + +int parse_extension_release(const char *root, const char *extension, ...) { + va_list ap; + int r; + + va_start(ap, extension); + r = parse_release_internal(root, extension, ap); + va_end(ap); + + return r; +} + +int parse_os_release(const char *root, ...) { + va_list ap; + int r; + va_start(ap, root); - r = parse_env_filev(f, p, ap); + r = parse_release_internal(root, NULL, ap); va_end(ap); return r; diff --git a/src/shared/os-util.h b/src/shared/os-util.h index 1d9b0b146b..5b724eb7ac 100644 --- a/src/shared/os-util.h +++ b/src/shared/os-util.h @@ -5,9 +5,19 @@ int path_is_os_tree(const char *path); -int open_os_release(const char *root, char **ret_path, int *ret_fd); -int fopen_os_release(const char *root, char **ret_path, FILE **ret_file); +/* The *_extension_release flavours will look for /usr/lib/extension-release/extension-release.NAME + * in accordance with the OS extension specification, rather than for /usr/lib/ or /etc/os-release. */ +int open_extension_release(const char *root, const char *extension, char **ret_path, int *ret_fd); +static inline int open_os_release(const char *root, char **ret_path, int *ret_fd) { + return open_extension_release(root, NULL, ret_path, ret_fd); +} +int fopen_extension_release(const char *root, const char *extension, char **ret_path, FILE **ret_file); +static inline int fopen_os_release(const char *root, char **ret_path, FILE **ret_file) { + return fopen_extension_release(root, NULL, ret_path, ret_file); +} + +int parse_extension_release(const char *root, const char *extension, ...) _sentinel_; int parse_os_release(const char *root, ...) _sentinel_; int load_os_release_pairs(const char *root, char ***ret); int load_os_release_pairs_with_prefix(const char *root, const char *prefix, char ***ret); |