From f99a0d038e7634469cf7141812351e415c0f2eb7 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Thu, 3 Mar 2022 12:26:36 -0700 Subject: [PATCH] apply: Don't use staged deployments when /boot is automounted The ostree staged deployment process works by waiting until shutdown to swap the `/boot` symlinks to make the new deployment the default. However, when `/boot` is the EFI System Partition and there's no `fstab` entry, `systemd-gpt-auto-generator` sets up an automount so that the VFAT filesystem is only exposed when needed. Unfortunately, there are 2 bugs that make this process very fragile: * Once a systemd automount unit is scheduled to be stopped, it ignores notifications from autofs that the target filesystem should be mounted. Therefore, if `/boot` isn't mounted when shutdown begins, `ostree admin finalize-staged` will fail. See https://github.com/systemd/systemd/issues/22528. * autofs is not mount namespace aware, so it will begin the expiration timer for a mount unit unless a process in the root namespace is keeping it active. Since `ostree admin finalize-staged` is run from a mount namespace (either via systemd or its own to ensure `/sysroot` and `/boot` are mounted read-write), the automount daemon (systemd) will try to unmount the filesystem if it expires during this process. See https://bugzilla.redhat.com/show_bug.cgi?id=2056090. Therefore, if `/boot` is an autofs filesystem, use a full deployment instead of a staged deployment. Since systems with an automounted `/boot` are not common, we want to retain the benefit of staged deployments for more normal systems. See https://github.com/ostreedev/ostree/issues/2543 for potential future fixes in ostree. https://phabricator.endlessm.com/T33136 (cherry picked from commit a19821a2b419850e188da3eee4fe3465528ca920) --- eos-updater/apply.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eos-updater/apply.c b/eos-updater/apply.c index 374d76e4..a327c9c0 100644 --- a/eos-updater/apply.c +++ b/eos-updater/apply.c @@ -270,11 +270,13 @@ apply_internal (ApplyData *apply_data, origin = ostree_sysroot_origin_new_from_refspec (sysroot, update_refspec); - /* When booted into an OSTree system, stage the deployment so that the - * /etc merge happens during shutdown. Otherwise (primarily the test - * suite), deploy the finalized tree immediately. + /* When booted into an OSTree system without an automount /boot, stage the + * deployment so that the /etc merge happens during shutdown. Otherwise + * (primarily sd-boot and the test suite), deploy the finalized tree + * immediately. */ - staged_deploy = ostree_sysroot_is_booted (sysroot); + staged_deploy = ostree_sysroot_is_booted (sysroot) && + !eos_updater_sysroot_boot_is_automount (sysroot, NULL); if (staged_deploy) { g_message ("Creating staged deployment for revision %s", update_id);