From 11f494025ce1f0dd17915939a202b6c1aab6c8b7 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Wed, 8 Jan 2025 15:53:31 +0100 Subject: [PATCH] sysroot: Support for standard-conformance marker file Add support for standard-conformance marker file loader/entries.srel. There might be implementations of boot loading infrastructure that are also using the /loader/entries/ directory, but install files that do not follow the [1] specification. In order to minimize confusion, a boot loader implementation may place the file /loader/entries.srel next to the /loader/entries/ directory containing the ASCII string type1 (followed by a UNIX newline). Tools that need to determine whether an existing directory implements the semantics described here may check for this file and contents: if it exists and contains the mentioned string, it shall assume a standards-compliant implementation is in place. If it exists but contains a different string it shall assume other semantics are implemented. If the file does not exist, no assumptions should be made. [1] https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-entry-keys Signed-off-by: Igor Opaniuk --- src/libostree/ostree-sysroot-deploy.c | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 1fb4eb91f6..9970228525 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -2185,6 +2185,58 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion, return TRUE; } +/* Determine whether an existing directory implements the semantics described in + * https://uapi-group.org/specifications/specs/boot_loader_specification/#type-1-boot-loader-entry-keys + */ +static gboolean +is_bootconfig_type1_semantics (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +{ + struct stat stbuf; + + if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) + return FALSE; + + if (!glnx_fstatat_allow_noent (sysroot->boot_fd, "loader/entries.srel", &stbuf, AT_SYMLINK_NOFOLLOW, + error)) + return FALSE; + + + if (errno == ENOENT) + { + g_debug ("Didn't find loader/entries.srel file"); + return FALSE; + } + else + { + /* Get semantics type by reading loader/entries.srel */ + gsize len; + g_autofree char* type = + glnx_file_get_contents_utf8_at(sysroot->boot_fd, "loader/entries.srel", + &len, cancellable, error); + if (type == NULL) + { + g_debug ("Invalid loader/entries.srel file"); + return FALSE; + } + + /* Remove trailing newline symbol if there is any */ + type[strcspn(type, "\n")] = 0; + + if (g_strcmp0 (type, "type1") == 0) + { + g_debug ("type1 semantics is found in loader/entries.srel file"); + return TRUE; + } + else + { + g_debug ("Unsupported semantics type ('%s') in loader/entries.srel file", type); + return FALSE; + } + } + + return FALSE; +} + /* We generate the symlink on disk, then potentially do a syncfs() to ensure * that it (and everything else we wrote) has hit disk. Only after that do we * rename it into place. @@ -2512,6 +2564,7 @@ write_deployments_bootswap (OstreeSysroot *self, GPtrArray *new_deployments, /* Handle when boot/loader is a link (normal deployment) and as a normal directory (e.g. EFI/vfat) */ struct stat stbuf; gboolean loader_link = FALSE; + gboolean force_type1_semantics = is_bootconfig_type1_semantics(self, cancellable, error); if (!glnx_fstatat_allow_noent (self->sysroot_fd, "boot/loader", &stbuf, AT_SYMLINK_NOFOLLOW, error)) return FALSE; if (errno == ENOENT) @@ -2534,6 +2587,9 @@ write_deployments_bootswap (OstreeSysroot *self, GPtrArray *new_deployments, else return FALSE; + if (force_type1_semantics && loader_link) + return glnx_throw_errno_prefix (error, "type1 semantics, but boot/loader is symlink"); + if (loader_link) { /* Default and when loader is a link is to swap links */