import ostree-2022.2-4.el8

This commit is contained in:
CentOS Sources 2022-05-19 10:13:08 +00:00 committed by Stepan Oksanichenko
parent f6996b9909
commit 0ed52ad9ea
9 changed files with 763 additions and 4 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/libostree-2022.1.tar.xz
SOURCES/libostree-2022.2.tar.xz

View File

@ -1 +1 @@
31380c30eeb93de7d9850fa8a071b3fbc3f3acee SOURCES/libostree-2022.1.tar.xz
9f1cc3796da8b7892a8ef930a5086d4ff42c475f SOURCES/libostree-2022.2.tar.xz

View File

@ -0,0 +1,374 @@
From a6d45dc165e48e2a463880ebb90f34c2b9d3c4ce Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Fri, 22 Apr 2022 18:46:28 -0400
Subject: [PATCH 1/6] Add an `ostree-boot-complete.service` to propagate
staging failures
Quite a while ago we added staged deployments, which solved
a bunch of issues around the `/etc` merge. However...a persistent
problem since then is that any failures in that process that
happened in the *previous* boot are not very visible.
We ship custom code in `rpm-ostree status` to query the previous
journal. But that has a few problems - one is that on systems
that have been up a while, that failure message may even get
rotated out. And second, some systems may not even have a persistent
journal at all.
A general thing we do in e.g. Fedora CoreOS testing is to check
for systemd unit failures. We do that both in our automated tests,
and we even ship code that displays them on ssh logins. And beyond
that obviously a lot of other projects do the same; it's easy via
`systemctl --failed`.
So to make failures more visible, change our `ostree-finalize-staged.service`
to have an internal wrapper around the process that "catches" any
errors, and copies the error message into a file in `/boot/ostree`.
Then, a new `ostree-boot-complete.service` looks for this file on
startup and re-emits the error message, and fails.
It also deletes the file. The rationale is to avoid *continually*
warning. For example we need to handle the case when an upgrade
process creates a new staged deployment. Now, we could change the
ostree core code to delete the warning file when that happens instead,
but this is trying to be a conservative change.
This should make failures here much more visible as is.
---
Makefile-boot.am | 2 +
Makefile-ostree.am | 1 +
src/boot/ostree-boot-complete.service | 33 +++++++++++
src/libostree/ostree-cmdprivate.c | 1 +
src/libostree/ostree-cmdprivate.h | 1 +
src/libostree/ostree-impl-system-generator.c | 2 +
src/libostree/ostree-sysroot-deploy.c | 62 ++++++++++++++++++--
src/libostree/ostree-sysroot-private.h | 7 +++
src/libostree/ostree-sysroot.c | 2 +
src/ostree/ot-admin-builtin-boot-complete.c | 58 ++++++++++++++++++
src/ostree/ot-admin-builtins.h | 1 +
src/ostree/ot-builtin-admin.c | 3 +
tests/kolainst/destructive/staged-deploy.sh | 12 ++++
13 files changed, 181 insertions(+), 4 deletions(-)
create mode 100644 src/boot/ostree-boot-complete.service
create mode 100644 src/ostree/ot-admin-builtin-boot-complete.c
diff --git a/Makefile-boot.am b/Makefile-boot.am
index ec10a0d6..e42e5180 100644
--- a/Makefile-boot.am
+++ b/Makefile-boot.am
@@ -38,6 +38,7 @@ endif
if BUILDOPT_SYSTEMD
systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
src/boot/ostree-remount.service \
+ src/boot/ostree-boot-complete.service \
src/boot/ostree-finalize-staged.service \
src/boot/ostree-finalize-staged.path \
$(NULL)
@@ -64,6 +65,7 @@ endif
EXTRA_DIST += src/boot/dracut/module-setup.sh \
src/boot/dracut/ostree.conf \
src/boot/mkinitcpio \
+ src/boot/ostree-boot-complete.service \
src/boot/ostree-prepare-root.service \
src/boot/ostree-finalize-staged.path \
src/boot/ostree-remount.service \
diff --git a/Makefile-ostree.am b/Makefile-ostree.am
index 82af1681..0fe2c5f8 100644
--- a/Makefile-ostree.am
+++ b/Makefile-ostree.am
@@ -70,6 +70,7 @@ ostree_SOURCES += \
src/ostree/ot-admin-builtin-diff.c \
src/ostree/ot-admin-builtin-deploy.c \
src/ostree/ot-admin-builtin-finalize-staged.c \
+ src/ostree/ot-admin-builtin-boot-complete.c \
src/ostree/ot-admin-builtin-undeploy.c \
src/ostree/ot-admin-builtin-instutil.c \
src/ostree/ot-admin-builtin-cleanup.c \
diff --git a/src/boot/ostree-boot-complete.service b/src/boot/ostree-boot-complete.service
new file mode 100644
index 00000000..5c09fdc9
--- /dev/null
+++ b/src/boot/ostree-boot-complete.service
@@ -0,0 +1,33 @@
+# Copyright (C) 2022 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <https://www.gnu.org/licenses/>.
+
+[Unit]
+Description=OSTree Complete Boot
+Documentation=man:ostree(1)
+# For now, this is the only condition on which we start, but it's
+# marked as a triggering condition in case in the future we want
+# to do something else.
+ConditionPathExists=|/boot/ostree/finalize-failure.stamp
+RequiresMountsFor=/boot
+# Ensure that we propagate the failure into the current boot before
+# any further finalization attempts.
+Before=ostree-finalize-staged.service
+
+[Service]
+Type=oneshot
+# To write to /boot while keeping it read-only
+MountFlags=slave
+RemainAfterExit=yes
+ExecStart=/usr/bin/ostree admin boot-complete
diff --git a/src/libostree/ostree-cmdprivate.c b/src/libostree/ostree-cmdprivate.c
index c9a6e2e1..f6c114f4 100644
--- a/src/libostree/ostree-cmdprivate.c
+++ b/src/libostree/ostree-cmdprivate.c
@@ -51,6 +51,7 @@ ostree_cmd__private__ (void)
_ostree_repo_static_delta_delete,
_ostree_repo_verify_bindings,
_ostree_sysroot_finalize_staged,
+ _ostree_sysroot_boot_complete,
};
return &table;
diff --git a/src/libostree/ostree-cmdprivate.h b/src/libostree/ostree-cmdprivate.h
index 46452ebd..17f943c8 100644
--- a/src/libostree/ostree-cmdprivate.h
+++ b/src/libostree/ostree-cmdprivate.h
@@ -33,6 +33,7 @@ typedef struct {
gboolean (* ostree_static_delta_delete) (OstreeRepo *repo, const char *delta_id, GCancellable *cancellable, GError **error);
gboolean (* ostree_repo_verify_bindings) (const char *collection_id, const char *ref_name, GVariant *commit, GError **error);
gboolean (* ostree_finalize_staged) (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
+ gboolean (* ostree_boot_complete) (OstreeSysroot *sysroot, GCancellable *cancellable, GError **error);
} OstreeCmdPrivateVTable;
/* Note this not really "public", we just export the symbol, but not the header */
diff --git a/src/libostree/ostree-impl-system-generator.c b/src/libostree/ostree-impl-system-generator.c
index 769f0cbd..92d71605 100644
--- a/src/libostree/ostree-impl-system-generator.c
+++ b/src/libostree/ostree-impl-system-generator.c
@@ -134,6 +134,8 @@ require_internal_units (const char *normal_dir,
return FALSE;
if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-finalize-staged.path", normal_dir_dfd, "multi-user.target.wants/ostree-finalize-staged.path") < 0)
return glnx_throw_errno_prefix (error, "symlinkat");
+ if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-boot-complete.service", normal_dir_dfd, "multi-user.target.wants/ostree-boot-complete.service") < 0)
+ return glnx_throw_errno_prefix (error, "symlinkat");
return TRUE;
#else
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index b7cc232f..fc5916d8 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -3255,10 +3255,10 @@ ostree_sysroot_stage_tree_with_options (OstreeSysroot *self,
}
/* Invoked at shutdown time by ostree-finalize-staged.service */
-gboolean
-_ostree_sysroot_finalize_staged (OstreeSysroot *self,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+_ostree_sysroot_finalize_staged_inner (OstreeSysroot *self,
+ GCancellable *cancellable,
+ GError **error)
{
/* It's totally fine if there's no staged deployment; perhaps down the line
* though we could teach the ostree cmdline to tell systemd to activate the
@@ -3355,9 +3355,63 @@ _ostree_sysroot_finalize_staged (OstreeSysroot *self,
if (!ostree_sysroot_prepare_cleanup (self, cancellable, error))
return FALSE;
+ // Cleanup will have closed some FDs, re-ensure writability
+ if (!_ostree_sysroot_ensure_writable (self, error))
+ return FALSE;
+
return TRUE;
}
+/* Invoked at shutdown time by ostree-finalize-staged.service */
+gboolean
+_ostree_sysroot_finalize_staged (OstreeSysroot *self,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autoptr(GError) finalization_error = NULL;
+ if (!_ostree_sysroot_ensure_boot_fd (self, error))
+ return FALSE;
+ if (!_ostree_sysroot_finalize_staged_inner (self, cancellable, &finalization_error))
+ {
+ g_autoptr(GError) writing_error = NULL;
+ g_assert_cmpint (self->boot_fd, !=, -1);
+ if (!glnx_file_replace_contents_at (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH,
+ (guint8*)finalization_error->message, -1,
+ 0, cancellable, &writing_error))
+ {
+ // We somehow failed to write the failure message...that's not great. Maybe ENOSPC on /boot.
+ g_printerr ("Failed to write %s: %s\n", _OSTREE_FINALIZE_STAGED_FAILURE_PATH, writing_error->message);
+ }
+ g_propagate_error (error, g_steal_pointer (&finalization_error));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Invoked at bootup time by ostree-boot-complete.service */
+gboolean
+_ostree_sysroot_boot_complete (OstreeSysroot *self,
+ GCancellable *cancellable,
+ GError **error)
+{
+ if (!_ostree_sysroot_ensure_boot_fd (self, error))
+ return FALSE;
+
+ glnx_autofd int failure_fd = -1;
+ if (!ot_openat_ignore_enoent (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, &failure_fd, error))
+ return FALSE;
+ // If we didn't find a failure log, then there's nothing to do right now.
+ // (Actually this unit shouldn't even be invoked, but we may do more in the future)
+ if (failure_fd == -1)
+ return TRUE;
+ g_autofree char *failure_data = glnx_fd_readall_utf8 (failure_fd, NULL, cancellable, error);
+ if (failure_data == NULL)
+ return glnx_prefix_error (error, "Reading from %s", _OSTREE_FINALIZE_STAGED_FAILURE_PATH);
+ // Remove the file; we don't want to continually error out.
+ (void) unlinkat (self->boot_fd, _OSTREE_FINALIZE_STAGED_FAILURE_PATH, 0);
+ return glnx_throw (error, "ostree-finalize-staged.service failed on previous boot: %s", failure_data);
+}
+
/**
* ostree_sysroot_deployment_set_kargs:
* @self: Sysroot
diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h
index cb34eeb3..a49a406c 100644
--- a/src/libostree/ostree-sysroot-private.h
+++ b/src/libostree/ostree-sysroot-private.h
@@ -96,6 +96,9 @@ struct OstreeSysroot {
#define _OSTREE_SYSROOT_BOOT_INITRAMFS_OVERLAYS "ostree/initramfs-overlays"
#define _OSTREE_SYSROOT_INITRAMFS_OVERLAYS "boot/" _OSTREE_SYSROOT_BOOT_INITRAMFS_OVERLAYS
+// Relative to /boot, consumed by ostree-boot-complete.service
+#define _OSTREE_FINALIZE_STAGED_FAILURE_PATH "ostree/finalize-failure.stamp"
+
gboolean
_ostree_sysroot_ensure_writable (OstreeSysroot *self,
GError **error);
@@ -142,6 +145,10 @@ gboolean
_ostree_sysroot_finalize_staged (OstreeSysroot *self,
GCancellable *cancellable,
GError **error);
+gboolean
+_ostree_sysroot_boot_complete (OstreeSysroot *self,
+ GCancellable *cancellable,
+ GError **error);
OstreeDeployment *
_ostree_sysroot_deserialize_deployment_from_variant (GVariant *v,
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index 266a2975..f083f950 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -356,6 +356,8 @@ _ostree_sysroot_ensure_writable (OstreeSysroot *self,
ostree_sysroot_unload (self);
if (!ensure_sysroot_fd (self, error))
return FALSE;
+ if (!_ostree_sysroot_ensure_boot_fd (self, error))
+ return FALSE;
return TRUE;
}
diff --git a/src/ostree/ot-admin-builtin-boot-complete.c b/src/ostree/ot-admin-builtin-boot-complete.c
new file mode 100644
index 00000000..6e1052f5
--- /dev/null
+++ b/src/ostree/ot-admin-builtin-boot-complete.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "ot-main.h"
+#include "ot-admin-builtins.h"
+#include "ot-admin-functions.h"
+#include "ostree.h"
+#include "otutil.h"
+
+#include "ostree-cmdprivate.h"
+
+static GOptionEntry options[] = {
+ { NULL }
+};
+
+gboolean
+ot_admin_builtin_boot_complete (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
+{
+ /* Just a sanity check; we shouldn't be called outside of the service though.
+ */
+ struct stat stbuf;
+ if (fstatat (AT_FDCWD, OSTREE_PATH_BOOTED, &stbuf, 0) < 0)
+ return TRUE;
+ // We must have been invoked via systemd which should have set up a mount namespace.
+ g_assert (getenv ("INVOCATION_ID"));
+
+ g_autoptr(GOptionContext) context = g_option_context_new ("");
+ g_autoptr(OstreeSysroot) sysroot = NULL;
+ if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
+ OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER,
+ invocation, &sysroot, cancellable, error))
+ return FALSE;
+
+ if (!ostree_cmd__private__()->ostree_boot_complete (sysroot, cancellable, error))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/ostree/ot-admin-builtins.h b/src/ostree/ot-admin-builtins.h
index d32b617e..8d9451be 100644
--- a/src/ostree/ot-admin-builtins.h
+++ b/src/ostree/ot-admin-builtins.h
@@ -39,6 +39,7 @@ BUILTINPROTO(deploy);
BUILTINPROTO(cleanup);
BUILTINPROTO(pin);
BUILTINPROTO(finalize_staged);
+BUILTINPROTO(boot_complete);
BUILTINPROTO(unlock);
BUILTINPROTO(status);
BUILTINPROTO(set_origin);
diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c
index e0d2a60c..af09a614 100644
--- a/src/ostree/ot-builtin-admin.c
+++ b/src/ostree/ot-builtin-admin.c
@@ -43,6 +43,9 @@ static OstreeCommand admin_subcommands[] = {
{ "finalize-staged", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN,
ot_admin_builtin_finalize_staged,
"Internal command to run at shutdown time" },
+ { "boot-complete", OSTREE_BUILTIN_FLAG_NO_REPO | OSTREE_BUILTIN_FLAG_HIDDEN,
+ ot_admin_builtin_boot_complete,
+ "Internal command to run at boot after an update was applied" },
{ "init-fs", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_init_fs,
"Initialize a root filesystem" },

View File

@ -0,0 +1,40 @@
From e5b45f861a4d5738679f37d46ebca6e171bb3212 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Mon, 4 Apr 2022 10:25:35 -0400
Subject: [PATCH 2/6] libarchive: Handle `archive_entry_symlink()` returning
NULL
The `archive_entry_symlink()` API can definitely return `NULL`,
reading through the libarchive sources.
I hit this in the wild when using old ostree-ext to try to unpack
a chunked archive.
I didn't try to characterize this more, and sorry no unit test right
now.
---
src/libostree/ostree-repo-libarchive.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/libostree/ostree-repo-libarchive.c b/src/libostree/ostree-repo-libarchive.c
index 679aa44d..631c6d4b 100644
--- a/src/libostree/ostree-repo-libarchive.c
+++ b/src/libostree/ostree-repo-libarchive.c
@@ -146,8 +146,12 @@ file_info_from_archive_entry (struct archive_entry *entry)
g_autoptr(GFileInfo) info = _ostree_stbuf_to_gfileinfo (&stbuf);
if (S_ISLNK (stbuf.st_mode))
- g_file_info_set_attribute_byte_string (info, "standard::symlink-target",
- archive_entry_symlink (entry));
+ {
+ const char *target = archive_entry_symlink (entry);
+ if (target != NULL)
+ g_file_info_set_attribute_byte_string (info, "standard::symlink-target",
+ target);
+ }
return g_steal_pointer (&info);
}
--
2.31.1

View File

@ -0,0 +1,82 @@
From 4a997ae08605ebe6ca02d9f422082f954e667a6c Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Sat, 30 Apr 2022 12:20:11 +0100
Subject: [PATCH 3/6] repo: Factor out _ostree_repo_auto_transaction_new()
This will allow the direct allocation in
ostree_repo_prepare_transaction() to be replaced with a call to this
function, avoiding breaking encapsulation.
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 540e60c3e3ace66dd4e6cf825488fc918260a642)
---
src/libostree/ostree-repo-private.h | 4 ++++
src/libostree/ostree-repo.c | 32 ++++++++++++++++++++++++-----
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index 988c2179..96253e77 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -554,4 +554,8 @@ GType _ostree_repo_auto_transaction_get_type (void);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_unref);
+/* Internal function to break a circular dependency:
+ * should not be made into public API, even if the rest is */
+OstreeRepoAutoTransaction *_ostree_repo_auto_transaction_new (OstreeRepo *repo);
+
G_END_DECLS
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index a27591b3..f6bffd60 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -709,6 +709,32 @@ ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *auto_lock)
}
}
+/**
+ * _ostree_repo_auto_transaction_new:
+ * @repo: (not nullable): an #OsreeRepo object
+ * @cancellable: Cancellable
+ * @error: a #GError
+ *
+ * Return a guard for a transaction in @repo.
+ *
+ * Do not call this function outside the OstreeRepo transaction implementation.
+ * Use _ostree_repo_auto_transaction_start() instead.
+ *
+ * Returns: (transfer full): an #OstreeRepoAutoTransaction guard on success,
+ * %NULL otherwise.
+ */
+OstreeRepoAutoTransaction *
+_ostree_repo_auto_transaction_new (OstreeRepo *repo)
+{
+ g_assert (repo != NULL);
+
+ OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction));
+ txn->atomic_refcount = 1;
+ txn->repo = g_object_ref (repo);
+
+ return g_steal_pointer (&txn);
+}
+
/**
* _ostree_repo_auto_transaction_start:
* @repo: (not nullable): an #OsreeRepo object
@@ -730,11 +756,7 @@ _ostree_repo_auto_transaction_start (OstreeRepo *repo,
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
return NULL;
- OstreeRepoAutoTransaction *txn = g_malloc(sizeof(OstreeRepoAutoTransaction));
- txn->atomic_refcount = 1;
- txn->repo = g_object_ref (repo);
-
- return g_steal_pointer (&txn);
+ return _ostree_repo_auto_transaction_new (repo);
}
/**
--
2.31.1

View File

@ -0,0 +1,39 @@
From 51c7960bea081446ad217e9725408ce5cb531157 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Sat, 30 Apr 2022 12:53:42 +0100
Subject: [PATCH 4/6] repo: Correctly initialize refcount of temporary
transaction
Previously, the reference count was left uninitialized as a result of
bypassing the constructor, and the intended abort-on-error usually
wouldn't have happened.
Fixes: 8a9737a "repo/private: move OstreeRepoAutoTransaction to a boxed type"
Resolves: https://github.com/ostreedev/ostree/issues/2592
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 71304e854cdb344adb8b1ae7866929fbdde6c327)
---
src/libostree/ostree-repo-commit.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 5b16be5b..dba98c32 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -1688,10 +1688,10 @@ ostree_repo_prepare_transaction (OstreeRepo *self,
g_debug ("Preparing transaction in repository %p", self);
/* Set up to abort the transaction if we return early from this function.
- * This needs to be manually built here due to a circular dependency. */
- g_autoptr(OstreeRepoAutoTransaction) txn = g_malloc(sizeof(OstreeRepoAutoTransaction));
+ * We can't call _ostree_repo_auto_transaction_start() here, because that
+ * would be a circular dependency; use the lower-level version instead. */
+ g_autoptr(OstreeRepoAutoTransaction) txn = _ostree_repo_auto_transaction_new (self);
g_assert (txn != NULL);
- txn->repo = self;
memset (&self->txn.stats, 0, sizeof (OstreeRepoTransactionStats));
--
2.31.1

View File

@ -0,0 +1,172 @@
From 62e62bcfd8a1770b906faed083d11e451a50f566 Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Wed, 9 Mar 2022 15:27:11 +0100
Subject: [PATCH 5/6] deploy: Try to rebuild policy in new deployment if needed
Whenever the user has SELinux enabled and has any local
modules/modifications installed, it is necessary to rebuild the policy
in the final deployment, otherwise ostree will leave the binary policy
files unchanged from last deployment as it detects difference against
the base content (in rpm-ostree case this is the RPM content).
To avoid the situation where the policy binaries go stale once any local
customization of the policy is made, try to rebuild the policy as part
of sysroot_finalize_deployment(). Use the special
--rebuild-if-modules-changed switch, which detects if the input module
files have changed relative to last time the policy was built and skips
the most time-consuming part of the rebuild process if modules are
unchanged (thus making this a relatively cheap operation if the user
hasn't made any modifications to the shipped policy).
As suggested by Jonathan Lebon, this uses bubblewrap (via
g_spawn_sync()) to perform the rebuild inside the deployment's
filesystem tree, which also means that ostree will have a runtime
dependency on bubblewrap.
Partially addresses: https://github.com/coreos/fedora-coreos-tracker/issues/701
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
(cherry picked from commit edb4f3893474736156c654aa43bdbf3784991811)
---
ci/gh-install.sh | 1 +
src/libostree/ostree-sysroot-deploy.c | 117 ++++++++++++++++++++++++++
2 files changed, 118 insertions(+)
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index fc5916d8..a44721d8 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -2830,6 +2830,118 @@ get_var_dfd (OstreeSysroot *self,
return glnx_opendirat (base_dfd, base_path, TRUE, ret_fd, error);
}
+#ifdef HAVE_SELINUX
+static void
+child_setup_fchdir (gpointer data)
+{
+ int fd = (int) (uintptr_t) data;
+ int rc __attribute__((unused));
+
+ rc = fchdir (fd);
+}
+
+/*
+ * Derived from rpm-ostree's rust/src/bwrap.rs
+ */
+static gboolean
+run_in_deployment (int deployment_dfd,
+ const gchar * const *child_argv,
+ gsize child_argc,
+ gint *exit_status,
+ gchar **stdout,
+ GError **error)
+{
+ static const gchar * const COMMON_ARGV[] = {
+ "/usr/bin/bwrap",
+ "--dev", "/dev", "--proc", "/proc", "--dir", "/run", "--dir", "/tmp",
+ "--chdir", "/",
+ "--die-with-parent",
+ "--unshare-pid",
+ "--unshare-uts",
+ "--unshare-ipc",
+ "--unshare-cgroup-try",
+ "--ro-bind", "/sys/block", "/sys/block",
+ "--ro-bind", "/sys/bus", "/sys/bus",
+ "--ro-bind", "/sys/class", "/sys/class",
+ "--ro-bind", "/sys/dev", "/sys/dev",
+ "--ro-bind", "/sys/devices", "/sys/devices",
+ "--bind", "usr", "/usr",
+ "--bind", "etc", "/etc",
+ "--bind", "var", "/var",
+ "--symlink", "/usr/lib", "/lib",
+ "--symlink", "/usr/lib32", "/lib32",
+ "--symlink", "/usr/lib64", "/lib64",
+ "--symlink", "/usr/bin", "/bin",
+ "--symlink", "/usr/sbin", "/sbin",
+ };
+ static const gsize COMMON_ARGC = sizeof (COMMON_ARGV) / sizeof (*COMMON_ARGV);
+
+ gsize i;
+ GPtrArray *args = g_ptr_array_sized_new (COMMON_ARGC + child_argc + 1);
+ g_autofree gchar **args_raw = NULL;
+
+ for (i = 0; i < COMMON_ARGC; i++)
+ g_ptr_array_add (args, (gchar *) COMMON_ARGV[i]);
+
+ for (i = 0; i < child_argc; i++)
+ g_ptr_array_add (args, (gchar *) child_argv[i]);
+
+ g_ptr_array_add (args, NULL);
+
+ args_raw = (gchar **) g_ptr_array_free (args, FALSE);
+
+ return g_spawn_sync (NULL, args_raw, NULL, 0, &child_setup_fchdir,
+ (gpointer) (uintptr_t) deployment_dfd,
+ stdout, NULL, exit_status, error);
+}
+
+/*
+ * Run semodule to check if the module content changed after merging /etc
+ * and rebuild the policy if needed.
+ */
+static gboolean
+sysroot_finalize_selinux_policy (int deployment_dfd, GError **error)
+{
+ struct stat stbuf;
+ gint exit_status;
+ g_autofree gchar *stdout = NULL;
+
+ if (!glnx_fstatat_allow_noent (deployment_dfd, "etc/selinux/config", &stbuf,
+ AT_SYMLINK_NOFOLLOW, error))
+ return FALSE;
+
+ /* Skip the SELinux policy refresh if /etc/selinux/config doesn't exist. */
+ if (errno != 0)
+ return TRUE;
+
+ /*
+ * Skip the SELinux policy refresh if the --rebuild-if-modules-changed
+ * flag is not supported by semodule.
+ */
+ static const gchar * const SEMODULE_HELP_ARGV[] = {
+ "semodule", "--help"
+ };
+ static const gsize SEMODULE_HELP_ARGC = sizeof (SEMODULE_HELP_ARGV) / sizeof (*SEMODULE_HELP_ARGV);
+ if (!run_in_deployment (deployment_dfd, SEMODULE_HELP_ARGV,
+ SEMODULE_HELP_ARGC, &exit_status, &stdout, error))
+ return FALSE;
+ if (!g_spawn_check_exit_status (exit_status, error))
+ return FALSE;
+ if (!strstr(stdout, "--rebuild-if-modules-changed"))
+ return TRUE;
+
+ static const gchar * const SEMODULE_REBUILD_ARGV[] = {
+ "semodule", "-N", "--rebuild-if-modules-changed"
+ };
+ static const gsize SEMODULE_REBUILD_ARGC = sizeof (SEMODULE_REBUILD_ARGV) / sizeof (*SEMODULE_REBUILD_ARGV);
+
+ if (!run_in_deployment (deployment_dfd, SEMODULE_REBUILD_ARGV,
+ SEMODULE_REBUILD_ARGC, &exit_status, NULL, error))
+ return FALSE;
+ return g_spawn_check_exit_status (exit_status, error);
+}
+#endif /* HAVE_SELINUX */
+
static gboolean
sysroot_finalize_deployment (OstreeSysroot *self,
OstreeDeployment *deployment,
@@ -2866,6 +2978,11 @@ sysroot_finalize_deployment (OstreeSysroot *self,
return FALSE;
}
+#ifdef HAVE_SELINUX
+ if (!sysroot_finalize_selinux_policy(deployment_dfd, error))
+ return FALSE;
+#endif /* HAVE_SELINUX */
+
const char *osdeploypath = glnx_strjoina ("ostree/deploy/", ostree_deployment_get_osname (deployment));
glnx_autofd int os_deploy_dfd = -1;
if (!glnx_opendirat (self->sysroot_fd, osdeploypath, TRUE, &os_deploy_dfd, error))
--
2.31.1

View File

@ -0,0 +1,35 @@
From dd194eca7272afa457541abb2d8c25f90c4f478a Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Mon, 28 Mar 2022 17:46:59 -0400
Subject: [PATCH 6/6] deploy: Be a bit more verbose about SELinux bits
Let's log when we don't find the expected CLI argument which
will help debug things.
(cherry picked from commit c58a4fe661d9d3bf2c515aa5605b1e094c0a62ca)
---
src/libostree/ostree-sysroot-deploy.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index a44721d8..404f336f 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -2926,9 +2926,12 @@ sysroot_finalize_selinux_policy (int deployment_dfd, GError **error)
SEMODULE_HELP_ARGC, &exit_status, &stdout, error))
return FALSE;
if (!g_spawn_check_exit_status (exit_status, error))
- return FALSE;
+ return glnx_prefix_error (error, "failed to run semodule");
if (!strstr(stdout, "--rebuild-if-modules-changed"))
- return TRUE;
+ {
+ ot_journal_print (LOG_INFO, "semodule does not have --rebuild-if-modules-changed");
+ return TRUE;
+ }
static const gchar * const SEMODULE_REBUILD_ARGV[] = {
"semodule", "-N", "--rebuild-if-modules-changed"
--
2.31.1

View File

@ -7,12 +7,21 @@
Summary: Tool for managing bootable, immutable filesystem trees
Name: ostree
Version: 2022.1
Release: 2%{?dist}
Version: 2022.2
Release: 4%{?dist}
Source0: https://github.com/ostreedev/%{name}/releases/download/v%{version}/libostree-%{version}.tar.xz
License: LGPLv2+
URL: https://ostree.readthedocs.io/en/latest/
# We now track the rhel8 branch upstream, these are the patches
# since the 2022.2 release.
Patch0: 0001-Add-an-ostree-boot-complete.service-to-propagate-sta.patch
Patch1: 0002-libarchive-Handle-archive_entry_symlink-returning-NU.patch
Patch2: 0003-repo-Factor-out-_ostree_repo_auto_transaction_new.patch
Patch3: 0004-repo-Correctly-initialize-refcount-of-temporary-tran.patch
Patch4: 0005-deploy-Try-to-rebuild-policy-in-new-deployment-if-ne.patch
Patch5: 0006-deploy-Be-a-bit-more-verbose-about-SELinux-bits.patch
BuildRequires: make
BuildRequires: git
# We always run autogen.sh
@ -163,6 +172,14 @@ find %{buildroot} -name '*.la' -delete
%endif
%changelog
* Wed May 04 2022 Colin Walters <walters@verbum.org> - 2022.2-4
- Backport patches from 2022.3, particularly SELinux
Resolves: rhbz#2057497
* Tue Apr 19 2022 Colin Walters <walters@verbum.org> - 2022.2-3
- https://github.com/ostreedev/ostree/releases/tag/v2022.2
Resolves: rhbz#2057497
* Mon Jan 10 2022 Colin Walters <walters@verbum.org> - 2022.1-2
- Rebase to 2022.1
Resolves: rhbz#2032593