diff --git a/.gitignore b/.gitignore index e1da6d7..4fcfe73 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/libostree-2025.4.tar.xz +SOURCES/libostree-2025.7.tar.xz diff --git a/.ostree.metadata b/.ostree.metadata index 8fe8113..0f2ad5c 100644 --- a/.ostree.metadata +++ b/.ostree.metadata @@ -1 +1 @@ -231dae5d34dd543e4df092cfa89d81a0b1cce928 SOURCES/libostree-2025.4.tar.xz +d60b3c9938d14ad09fb3ea0c27bbddf1ee14dd12 SOURCES/libostree-2025.7.tar.xz diff --git a/SOURCES/0001-deploy-Fix-path-to-aboot.cfg-in-BLS-files.patch b/SOURCES/0001-deploy-Fix-path-to-aboot.cfg-in-BLS-files.patch deleted file mode 100644 index 97717f0..0000000 --- a/SOURCES/0001-deploy-Fix-path-to-aboot.cfg-in-BLS-files.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 36995ef2b6dff343434016433a46242861549edd Mon Sep 17 00:00:00 2001 -From: Alexander Larsson -Date: Wed, 6 Aug 2025 12:16:34 +0200 -Subject: [PATCH] deploy: Fix path to aboot.cfg in BLS files - -The change in https://github.com/ostreedev/ostree/pull/3413/ was meant -to change when the abootcfg option is set in the BLS file. However, -it also changed the value of this key, using the wrong directory -(bootcsumdir instead of /usr/lib/ostree-boot). - -This means that during update, aboot-update gets the wrong path to the -config and cannot correctly write the aboot partition. - -Signed-off-by: Alexander Larsson ---- - src/libostree/ostree-sysroot-deploy.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c -index bee899a3..e8f3ece5 100644 ---- a/src/libostree/ostree-sysroot-deploy.c -+++ b/src/libostree/ostree-sysroot-deploy.c -@@ -2134,7 +2134,8 @@ install_deployment_kernel (OstreeSysroot *sysroot, int new_bootversion, - g_autofree char *aboot_relpath = g_strconcat ("/", bootcsumdir, "/", aboot_fn, NULL); - ostree_bootconfig_parser_set (bootconfig, "aboot", aboot_relpath); - -- g_autofree char *abootcfg_relpath = g_strconcat ("/", bootcsumdir, "/aboot.cfg", NULL); -+ g_autofree char *abootcfg_relpath -+ = g_strconcat ("/", deployment_dirpath, "/usr/lib/ostree-boot/aboot.cfg", NULL); - ostree_bootconfig_parser_set (bootconfig, "abootcfg", abootcfg_relpath); - } - --- -2.50.1 - diff --git a/SOURCES/0001-state-overlay-Fix-ENODATA-handling-for-GLib-2.74.patch b/SOURCES/0001-state-overlay-Fix-ENODATA-handling-for-GLib-2.74.patch new file mode 100644 index 0000000..4fc9606 --- /dev/null +++ b/SOURCES/0001-state-overlay-Fix-ENODATA-handling-for-GLib-2.74.patch @@ -0,0 +1,150 @@ +From a56255cbc09f3ac01d67bcee8b355ceebc7f2d47 Mon Sep 17 00:00:00 2001 +From: Joseph Marrero Corchado +Date: Tue, 16 Dec 2025 14:30:47 -0500 +Subject: [PATCH] state-overlay: Fix ENODATA handling for GLib < 2.74 + +The state overlay feature fails on first boot with: + + error: lgetxattr(user.ostree.deploymentcsum): No data available + +This happens because `lgetxattrat_allow_noent()` checks for +`G_IO_ERROR_INVALID_DATA` to detect when an xattr doesn't exist. +However, GLib's `g_io_error_from_errno()` only maps `ENODATA` to +`G_IO_ERROR_INVALID_DATA` since GLib 2.74. Older versions (such as +GLib 2.68 shipped in CentOS Stream 9) return `G_IO_ERROR_FAILED` +instead, causing the check to fail and the error to propagate. + +This creates a chicken-and-egg problem: the code tries to read the +`user.ostree.deploymentcsum` xattr before it can set it, but the read +fails on fresh overlay directories where the xattr hasn't been set yet. + +Fix this by checking `errno == ENODATA` directly after the failed call, +which is portable across all GLib versions. Also rename the function +from `lgetxattrat_allow_noent` to `lgetxattrat_allow_nodata` to more +accurately reflect its purpose (ENODATA vs ENOENT). + +This bug has existed since the state overlay feature was introduced in +v2024.1 but was masked on systems with GLib >= 2.74 (e.g., Fedora, +CentOS Stream 10) where the mapping happens to exist. + +Assisted-by: Claude Code (Opus 4.5) + +Signed-off-by: Joseph Marrero Corchado +--- + src/ostree/ot-admin-builtin-state-overlay.c | 75 +++++++++++++++++---- + 1 file changed, 62 insertions(+), 13 deletions(-) + +diff --git a/src/ostree/ot-admin-builtin-state-overlay.c b/src/ostree/ot-admin-builtin-state-overlay.c +index 7bf386c4..3c763ae0 100644 +--- a/src/ostree/ot-admin-builtin-state-overlay.c ++++ b/src/ostree/ot-admin-builtin-state-overlay.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include "glnx-errors.h" + #include "glnx-fdio.h" +@@ -62,20 +63,68 @@ ensure_overlay_dirs (const char *overlay_dir, int *out_overlay_dfd, GCancellable + return TRUE; + } + +-/* XXX: upstream to libglnx */ ++/* Based on glnx_lgetxattrat() from libglnx, modified to treat ENODATA ++ * (xattr not set) as success with *out_bytes = NULL. We check errno ++ * immediately after the lgetxattr syscall, before any GLib calls can ++ * clobber it. This avoids depending on GLib's g_io_error_from_errno() ++ * mapping, which only maps ENODATA to G_IO_ERROR_NOT_FOUND since GLib 2.74. ++ * ++ * This implementation handles the TOCTOU race condition where the xattr size ++ * may change between the size query and the data read by retrying with ERANGE. ++ * It also handles the case where the xattr is deleted between calls (ENODATA ++ * on second call). Zero-length xattrs are handled without allocating a buffer. ++ * ++ * TODO: Upstream to libglnx. */ + static gboolean +-lgetxattrat_allow_noent (int dfd, const char *path, const char *attribute, GBytes **out_bytes, +- GError **error) ++lgetxattrat_allow_nodata (int dfd, const char *path, const char *attribute, GBytes **out_bytes, ++ GError **error) + { +- g_autoptr (GError) local_error = NULL; +- *out_bytes = glnx_lgetxattrat (dfd, path, attribute, &local_error); +- if (!*out_bytes) ++ char pathbuf[PATH_MAX]; ++ int n = snprintf (pathbuf, sizeof (pathbuf), "/proc/self/fd/%d/%s", dfd, path); ++ if (n < 0 || n >= sizeof (pathbuf)) ++ return glnx_throw (error, "Path truncated for fd %d, path %s", dfd, path); ++ ++ ssize_t bytes_read; ++ ssize_t real_size; ++ g_autofree guint8 *buf = NULL; ++ ++again: ++ errno = 0; ++ bytes_read = TEMP_FAILURE_RETRY (lgetxattr (pathbuf, attribute, NULL, 0)); ++ if (bytes_read < 0) ++ { ++ if (errno == ENODATA) ++ { ++ *out_bytes = NULL; ++ return TRUE; /* xattr not set; that's fine */ ++ } ++ return glnx_throw_errno_prefix (error, "lgetxattr(%s)", attribute); ++ } ++ ++ if (bytes_read == 0) + { +- if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) +- return TRUE; +- g_propagate_error (error, g_steal_pointer (&local_error)); +- return FALSE; ++ *out_bytes = g_bytes_new_static ("", 0); ++ return TRUE; + } ++ ++ buf = g_malloc (bytes_read); ++ real_size = TEMP_FAILURE_RETRY (lgetxattr (pathbuf, attribute, buf, bytes_read)); ++ if (real_size < 0) ++ { ++ if (errno == ERANGE) ++ { ++ g_clear_pointer (&buf, g_free); ++ goto again; ++ } ++ if (errno == ENODATA) ++ { ++ *out_bytes = NULL; ++ return TRUE; /* xattr was deleted between calls */ ++ } ++ return glnx_throw_errno_prefix (error, "lgetxattr(%s)", attribute); ++ } ++ ++ *out_bytes = g_bytes_new_take (g_steal_pointer (&buf), real_size); + return TRUE; + } + +@@ -83,7 +132,7 @@ static gboolean + is_opaque_dir (int dfd, const char *dname, gboolean *out_is_opaque, GError **error) + { + g_autoptr (GBytes) data = NULL; +- if (!lgetxattrat_allow_noent (dfd, dname, OVERLAYFS_DIR_XATTR_OPAQUE, &data, error)) ++ if (!lgetxattrat_allow_nodata (dfd, dname, OVERLAYFS_DIR_XATTR_OPAQUE, &data, error)) + return FALSE; + + if (!data) +@@ -203,8 +252,8 @@ get_overlay_deployment_checksum (int overlay_dfd, char **out_checksum, GCancella + GError **error) + { + g_autoptr (GBytes) bytes = NULL; +- if (!lgetxattrat_allow_noent (overlay_dfd, OSTREE_STATEOVERLAY_UPPER_DIR, +- OSTREE_STATEOVERLAY_XATTR_DEPLOYMENT_CSUM, &bytes, error)) ++ if (!lgetxattrat_allow_nodata (overlay_dfd, OSTREE_STATEOVERLAY_UPPER_DIR, ++ OSTREE_STATEOVERLAY_XATTR_DEPLOYMENT_CSUM, &bytes, error)) + return FALSE; + if (!bytes) + return TRUE; /* probably newly created */ +-- +2.52.0 + diff --git a/SPECS/ostree.spec b/SPECS/ostree.spec index 135e475..38e59c9 100644 --- a/SPECS/ostree.spec +++ b/SPECS/ostree.spec @@ -7,13 +7,13 @@ Summary: Tool for managing bootable, immutable filesystem trees Name: ostree -Version: 2025.4 -Release: 2%{?dist} +Version: 2025.7 +Release: 1%{?dist} Source0: https://github.com/ostreedev/%{name}/releases/download/v%{version}/libostree-%{version}.tar.xz Source1: ostree-readonly-sysroot-migration Source2: ostree-readonly-sysroot-migration.service -Patch0: 0001-deploy-Fix-path-to-aboot.cfg-in-BLS-files.patch +Patch0: 0001-state-overlay-Fix-ENODATA-handling-for-GLib-2.74.patch License: LGPLv2+ URL: https://ostree.readthedocs.io/en/latest/ @@ -139,9 +139,9 @@ find %{buildroot} -name '*.la' -delete %{_bindir}/rofiles-fuse %{_datadir}/ostree %{_datadir}/bash-completion/completions/* -%dir %{_prefix}/lib/dracut/modules.d/98ostree +%dir %{_prefix}/lib/dracut/modules.d/50ostree %{_prefix}/lib/systemd/system/ostree*.* -%{_prefix}/lib/dracut/modules.d/98ostree/* +%{_prefix}/lib/dracut/modules.d/50ostree/* %{_mandir}/man*/*.gz %{_prefix}/lib/systemd/system-generators/ostree-system-generator %exclude %{_sysconfdir}/grub.d/*ostree @@ -181,6 +181,22 @@ find %{buildroot} -name '*.la' -delete %endif %changelog +* Mon Jan 26 2026 Joseph Marrero - 2025.7-1 +- Rebase to 2025.7 + Backport https://github.com/ostreedev/ostree/pull/3555 + Resolves: #RHEL-129049 + +* Wed Jan 21 2026 Joseph Marrero - 2025.6-3 +- Backport https://github.com/ostreedev/ostree/pull/3555 + Resolves: #RHEL-131656 + +* Fri Sep 05 2025 Colin Walters - 2025.6-2 +- Update to 2025.6 + Resolves: #RHEL-113644 + +* Mon Aug 25 2025 Colin Walters - 2025.5-3 +- Update to 2025.5 + * Wed Aug 06 2025 Joseph Marrero - 2025.4-2 - Backport https://github.com/ostreedev/ostree/pull/3493 Resolves: #RHEL-107855