From: Yu Watanabe Date: Sat, 8 Apr 2023 09:48:57 +0000 (+0900) Subject: os-util: introduce several _at() variants of os-release parsers X-Git-Tag: v254-rc1~760^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=538d878dbd5367b90116b33c6b90230a7c96320f;p=thirdparty%2Fsystemd.git os-util: introduce several _at() variants of os-release parsers --- diff --git a/src/basic/os-util.c b/src/basic/os-util.c index 0f123aaf829..dd8faf23765 100644 --- a/src/basic/os-util.c +++ b/src/basic/os-util.c @@ -122,16 +122,18 @@ static int extension_release_strict_xattr_value(int extension_release_fd, const return false; } -int open_os_release(const char *root, char **ret_path, int *ret_fd) { +int open_os_release_at(int rfd, char **ret_path, int *ret_fd) { const char *e; int r; + assert(rfd >= 0 || rfd == AT_FDCWD); + e = secure_getenv("SYSTEMD_OS_RELEASE"); if (e) - return chase(e, root, CHASE_PREFIX_ROOT, ret_path, ret_fd); + return chaseat(rfd, e, CHASE_AT_RESOLVE_IN_ROOT, ret_path, ret_fd); FOREACH_STRING(path, "/etc/os-release", "/usr/lib/os-release") { - r = chase(path, root, CHASE_PREFIX_ROOT, ret_path, ret_fd); + r = chaseat(rfd, path, CHASE_AT_RESOLVE_IN_ROOT, ret_path, ret_fd); if (r != -ENOENT) return r; } @@ -139,8 +141,33 @@ int open_os_release(const char *root, char **ret_path, int *ret_fd) { return -ENOENT; } -int open_extension_release( - const char *root, +int open_os_release(const char *root, char **ret_path, int *ret_fd) { + _cleanup_close_ int rfd = -EBADF, fd = -EBADF; + _cleanup_free_ char *p = NULL; + int r; + + rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH); + if (rfd < 0) + return -errno; + + r = open_os_release_at(rfd, ret_path ? &p : NULL, ret_fd ? &fd : NULL); + if (r < 0) + return r; + + if (ret_path) { + r = path_prefix_root_cwd(p, root, ret_path); + if (r < 0) + return r; + } + + if (ret_fd) + *ret_fd = TAKE_FD(fd); + + return 0; +} + +int open_extension_release_at( + int rfd, ImageClass image_class, const char *extension, bool relax_extension_release_check, @@ -154,10 +181,11 @@ int open_extension_release( const char *p; int r; + assert(rfd >= 0 || rfd == AT_FDCWD); assert(!extension || (image_class >= 0 && image_class < _IMAGE_CLASS_MAX)); if (!extension) - return open_os_release(root, ret_path, ret_fd); + return open_os_release_at(rfd, ret_path, ret_fd); if (!IN_SET(image_class, IMAGE_SYSEXT, IMAGE_CONFEXT)) return -EINVAL; @@ -166,7 +194,7 @@ int open_extension_release( return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "The extension name %s is invalid.", extension); p = strjoina(image_class_release_info[image_class].release_file_path_prefix, extension); - r = chase(p, root, CHASE_PREFIX_ROOT, ret_path, ret_fd); + r = chaseat(rfd, p, CHASE_AT_RESOLVE_IN_ROOT, ret_path, ret_fd); log_full_errno_zerook(LOG_DEBUG, MIN(r, 0), "Checking for %s: %m", p); if (r != -ENOENT) return r; @@ -177,9 +205,9 @@ int open_extension_release( * xattr is checked to ensure the author of the image considers it OK if names do not match. */ p = image_class_release_info[image_class].release_file_directory; - r = chase_and_opendir(p, root, CHASE_PREFIX_ROOT, &dir_path, &dir); + r = chase_and_opendirat(rfd, p, CHASE_AT_RESOLVE_IN_ROOT, &dir_path, &dir); if (r < 0) - return log_debug_errno(r, "Cannot open %s%s, ignoring: %m", root, p); + return log_debug_errno(r, "Cannot open %s, ignoring: %m", p); FOREACH_DIRENT(de, dir, return -errno) { _cleanup_close_ int fd = -EBADF; @@ -242,24 +270,94 @@ int open_extension_release( return 0; } -int parse_extension_release_sentinel( +int open_extension_release( const char *root, ImageClass image_class, + const char *extension, bool relax_extension_release_check, + char **ret_path, + int *ret_fd) { + + _cleanup_close_ int rfd = -EBADF, fd = -EBADF; + _cleanup_free_ char *p = NULL; + int r; + + rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH); + if (rfd < 0) + return -errno; + + r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check, + ret_path ? &p : NULL, ret_fd ? &fd : NULL); + if (r < 0) + return r; + + if (ret_path) { + r = path_prefix_root_cwd(p, root, ret_path); + if (r < 0) + return r; + } + + if (ret_fd) + *ret_fd = TAKE_FD(fd); + + return 0; +} + +static int parse_extension_release_atv( + int rfd, + ImageClass image_class, const char *extension, - ...) { + bool relax_extension_release_check, + va_list ap) { _cleanup_close_ int fd = -EBADF; _cleanup_free_ char *p = NULL; - va_list ap; int r; - r = open_extension_release(root, image_class, extension, relax_extension_release_check, &p, &fd); + assert(rfd >= 0 || rfd == AT_FDCWD); + + r = open_extension_release_at(rfd, image_class, extension, relax_extension_release_check, &p, &fd); if (r < 0) return r; + return parse_env_file_fdv(fd, p, ap); +} + +int parse_extension_release_at_sentinel( + int rfd, + ImageClass image_class, + bool relax_extension_release_check, + const char *extension, + ...) { + + va_list ap; + int r; + + assert(rfd >= 0 || rfd == AT_FDCWD); + + va_start(ap, extension); + r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap); + va_end(ap); + return r; +} + +int parse_extension_release_sentinel( + const char *root, + ImageClass image_class, + bool relax_extension_release_check, + const char *extension, + ...) { + + _cleanup_close_ int rfd = -EBADF; + va_list ap; + int r; + + rfd = open(empty_to_root(root), O_CLOEXEC | O_DIRECTORY | O_PATH); + if (rfd < 0) + return -errno; + va_start(ap, extension); - r = parse_env_file_fdv(fd, p, ap); + r = parse_extension_release_atv(rfd, image_class, extension, relax_extension_release_check, ap); va_end(ap); return r; } diff --git a/src/basic/os-util.h b/src/basic/os-util.h index 243d3c58ead..480f71e614c 100644 --- a/src/basic/os-util.h +++ b/src/basic/os-util.h @@ -29,7 +29,9 @@ static inline int path_is_os_tree(const char *path) { } int open_extension_release(const char *root, ImageClass image_class, const char *extension, bool relax_extension_release_check, char **ret_path, int *ret_fd); +int open_extension_release_at(int rfd, ImageClass image_class, const char *extension, bool relax_extension_release_check, char **ret_path, int *ret_fd); int open_os_release(const char *root, char **ret_path, int *ret_fd); +int open_os_release_at(int rfd, char **ret_path, int *ret_fd); int parse_extension_release_sentinel(const char *root, ImageClass image_class, bool relax_extension_release_check, const char *extension, ...) _sentinel_; #define parse_extension_release(root, image_class, extension, relax_extension_release_check, ...) \ @@ -37,6 +39,12 @@ int parse_extension_release_sentinel(const char *root, ImageClass image_class, b #define parse_os_release(root, ...) \ parse_extension_release_sentinel(root, _IMAGE_CLASS_INVALID, false, NULL, __VA_ARGS__, NULL) +int parse_extension_release_at_sentinel(int rfd, ImageClass image_class, bool relax_extension_release_check, const char *extension, ...) _sentinel_; +#define parse_extension_release_at(rfd, image_class, extension, relax_extension_release_check, ...) \ + parse_extension_release_at_sentinel(rfd, image_class, relax_extension_release_check, extension, __VA_ARGS__, NULL) +#define parse_os_release_at(rfd, ...) \ + parse_extension_release_at_sentinel(rfd, _IMAGE_CLASS_INVALID, false, NULL, __VA_ARGS__, NULL) + int load_extension_release_pairs(const char *root, ImageClass image_class, const char *extension, bool relax_extension_release_check, char ***ret); static inline int load_os_release_pairs(const char *root, char ***ret) { return load_extension_release_pairs(root, _IMAGE_CLASS_INVALID, NULL, false, ret);