From: Yu Watanabe Date: Sat, 8 Apr 2023 16:02:13 +0000 (+0900) Subject: os-util: split-out open_os_release() from open_extension_release() X-Git-Tag: v254-rc1~760^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a84677e0f43e142094ebb1a870cd840cb2cac158;p=thirdparty%2Fsystemd.git os-util: split-out open_os_release() from open_extension_release() The logics of opening os-release and extension-release are completely different. No functional change, just refactoring. --- diff --git a/src/basic/os-util.c b/src/basic/os-util.c index 79056ccd1e3..17ab376ac2a 100644 --- a/src/basic/os-util.c +++ b/src/basic/os-util.c @@ -122,111 +122,123 @@ static int extension_release_strict_xattr_value(int extension_release_fd, const return false; } -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_os_release(const char *root, char **ret_path, int *ret_fd) { + const char *e; + int r; + + e = secure_getenv("SYSTEMD_OS_RELEASE"); + if (e) + return chase(e, root, 0, 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); + if (r != -ENOENT) + return r; + } + + return -ENOENT; +} + +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 fd = -EBADF; _cleanup_free_ char *q = NULL; int r; - if (extension) { - assert(image_class >= 0); - assert(image_class < _IMAGE_CLASS_MAX); + assert(!extension || (image_class >= 0 && image_class < _IMAGE_CLASS_MAX)); - const char *extension_full_path; + if (!extension) + return open_os_release(root, ret_path, ret_fd); - if (!image_name_is_valid(extension)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), - "The extension name %s is invalid.", extension); + const char *extension_full_path; - extension_full_path = strjoina(image_class_release_info[image_class].release_file_path_prefix, extension); - r = chase(extension_full_path, root, CHASE_PREFIX_ROOT, ret_path ? &q : NULL, ret_fd ? &fd : NULL); - log_full_errno_zerook(LOG_DEBUG, MIN(r, 0), "Checking for %s: %m", extension_full_path); + if (!image_name_is_valid(extension)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "The extension name %s is invalid.", extension); - /* Cannot find the expected extension-release file? The image filename might have been - * mangled on deployment, so fallback to checking for any file in the extension-release.d - * directory, and return the first one with a user.extension-release xattr instead. - * The user.extension-release.strict xattr is checked to ensure the author of the image - * considers it OK if names do not match. */ - if (r == -ENOENT) { - _cleanup_free_ char *extension_release_dir_path = NULL; - _cleanup_closedir_ DIR *extension_release_dir = NULL; + extension_full_path = strjoina(image_class_release_info[image_class].release_file_path_prefix, extension); + r = chase(extension_full_path, root, CHASE_PREFIX_ROOT, ret_path ? &q : NULL, ret_fd ? &fd : NULL); + log_full_errno_zerook(LOG_DEBUG, MIN(r, 0), "Checking for %s: %m", extension_full_path); - r = chase_and_opendir(image_class_release_info[image_class].release_file_directory, root, CHASE_PREFIX_ROOT, - &extension_release_dir_path, &extension_release_dir); - if (r < 0) - return log_debug_errno(r, "Cannot open %s%s, ignoring: %m", root, image_class_release_info[image_class].release_file_directory); + /* Cannot find the expected extension-release file? The image filename might have been mangled on + * deployment, so fallback to checking for any file in the extension-release.d directory, and return + * the first one with a user.extension-release xattr instead. The user.extension-release.strict + * xattr is checked to ensure the author of the image considers it OK if names do not match. */ + if (r == -ENOENT) { + _cleanup_free_ char *extension_release_dir_path = NULL; + _cleanup_closedir_ DIR *extension_release_dir = NULL; - r = -ENOENT; - FOREACH_DIRENT(de, extension_release_dir, return -errno) { - int k; + r = chase_and_opendir(image_class_release_info[image_class].release_file_directory, root, CHASE_PREFIX_ROOT, + &extension_release_dir_path, &extension_release_dir); + if (r < 0) + return log_debug_errno(r, "Cannot open %s%s, ignoring: %m", root, image_class_release_info[image_class].release_file_directory); - if (!IN_SET(de->d_type, DT_REG, DT_UNKNOWN)) - continue; + r = -ENOENT; + FOREACH_DIRENT(de, extension_release_dir, return -errno) { + int k; - const char *image_name = startswith(de->d_name, "extension-release."); - if (!image_name) - continue; + if (!IN_SET(de->d_type, DT_REG, DT_UNKNOWN)) + continue; - if (!image_name_is_valid(image_name)) { - log_debug("%s/%s is not a valid release file name, ignoring.", - extension_release_dir_path, de->d_name); - continue; - } - - /* We already chased the directory, and checked that - * this is a real file, so we shouldn't fail to open it. */ - _cleanup_close_ int extension_release_fd = openat(dirfd(extension_release_dir), - de->d_name, - O_PATH|O_CLOEXEC|O_NOFOLLOW); - if (extension_release_fd < 0) - return log_debug_errno(errno, - "Failed to open release file %s/%s: %m", - extension_release_dir_path, - de->d_name); - - /* Really ensure it is a regular file after we open it. */ - if (fd_verify_regular(extension_release_fd) < 0) { - log_debug("%s/%s is not a regular file, ignoring.", extension_release_dir_path, de->d_name); + const char *image_name = startswith(de->d_name, "extension-release."); + if (!image_name) + continue; + + if (!image_name_is_valid(image_name)) { + log_debug("%s/%s is not a valid release file name, ignoring.", + extension_release_dir_path, de->d_name); + continue; + } + + /* We already chased the directory, and checked that + * this is a real file, so we shouldn't fail to open it. */ + _cleanup_close_ int extension_release_fd = openat(dirfd(extension_release_dir), + de->d_name, + O_PATH|O_CLOEXEC|O_NOFOLLOW); + if (extension_release_fd < 0) + return log_debug_errno(errno, + "Failed to open release file %s/%s: %m", + extension_release_dir_path, + de->d_name); + + /* Really ensure it is a regular file after we open it. */ + if (fd_verify_regular(extension_release_fd) < 0) { + log_debug("%s/%s is not a regular file, ignoring.", extension_release_dir_path, de->d_name); + continue; + } + + if (!relax_extension_release_check) { + k = extension_release_strict_xattr_value(extension_release_fd, + extension_release_dir_path, + de->d_name); + if (k != 0) continue; - } - - if (!relax_extension_release_check) { - k = extension_release_strict_xattr_value(extension_release_fd, - extension_release_dir_path, - de->d_name); - if (k != 0) - continue; - } - - /* We already found what we were looking for, but there's another candidate? - * We treat this as an error, as we want to enforce that there are no ambiguities - * in case we are in the fallback path. */ - if (r == 0) { - r = -ENOTUNIQ; - break; - } - - r = 0; /* Found it! */ - - if (ret_fd) - fd = TAKE_FD(extension_release_fd); - - if (ret_path) { - q = path_join(extension_release_dir_path, de->d_name); - if (!q) - return -ENOMEM; - } } - } - } else { - const char *var = secure_getenv("SYSTEMD_OS_RELEASE"); - if (var) - r = chase(var, root, 0, ret_path ? &q : NULL, ret_fd ? &fd : NULL); - else - FOREACH_STRING(path, "/etc/os-release", "/usr/lib/os-release") { - r = chase(path, root, CHASE_PREFIX_ROOT, ret_path ? &q : NULL, ret_fd ? &fd : NULL); - if (r != -ENOENT) - break; + + /* We already found what we were looking for, but there's another candidate? + * We treat this as an error, as we want to enforce that there are no ambiguities + * in case we are in the fallback path. */ + if (r == 0) { + r = -ENOTUNIQ; + break; + } + + r = 0; /* Found it! */ + + if (ret_fd) + fd = TAKE_FD(extension_release_fd); + + if (ret_path) { + q = path_join(extension_release_dir_path, de->d_name); + if (!q) + return -ENOMEM; } + } } if (r < 0) return r; diff --git a/src/basic/os-util.h b/src/basic/os-util.h index 374b4ee584e..bd9e8949e6e 100644 --- a/src/basic/os-util.h +++ b/src/basic/os-util.h @@ -29,9 +29,7 @@ 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); -static inline int open_os_release(const char *root, char **ret_path, int *ret_fd) { - return open_extension_release(root, _IMAGE_CLASS_INVALID, NULL, false, ret_path, ret_fd); -} +int open_os_release(const char *root, char **ret_path, int *ret_fd); int _parse_extension_release(const char *root, ImageClass image_class, bool relax_extension_release_check, const char *extension, ...) _sentinel_; int _parse_os_release(const char *root, ...) _sentinel_;