diff --git a/eos-updater/apply.c b/eos-updater/apply.c index 374d76e4..b16809ed 100644 --- a/eos-updater/apply.c +++ b/eos-updater/apply.c @@ -27,6 +27,7 @@ #include #include #include +#include /* Closure containing the data for the apply worker thread. The * worker thread must not access EosUpdater or EosUpdaterData directly, @@ -227,6 +228,65 @@ update_remote_branches (OstreeRepo *repo, return TRUE; } +static gboolean +sysroot_boot_is_automount (OstreeSysroot *sysroot) +{ + GFile *sysroot_file; + g_autoptr(GFile) boot_file = NULL; + g_autofree gchar *boot_path = NULL; + gboolean ret = FALSE; + struct libmnt_table *tb = NULL; + struct libmnt_cache *cache; + struct libmnt_fs *fs; + + sysroot_file = ostree_sysroot_get_path (sysroot); + boot_file = g_file_get_child (sysroot_file, "boot"); + boot_path = g_file_get_path (boot_file); + if (boot_path == NULL) + { + g_autofree gchar *sysroot_path = g_file_get_path (sysroot_file); + g_warning ("No boot directory in sysroot %s", sysroot_path); + goto out; + } + + tb = mnt_new_table_from_file ("/proc/self/mountinfo"); + if (tb == NULL) + { + g_warning ("Failed to parse /proc/self/mountinfo: %s", + g_strerror (errno)); + goto out; + } + + cache = mnt_new_cache (); + if (cache == NULL) + { + g_warning ("Failed to create libmount cache: %s", g_strerror (errno)); + goto out; + } + mnt_table_set_cache (tb, cache); + mnt_unref_cache (cache); + + /* Find the /boot mountpoint iterating forward so that the autofs mount is + * found and not the automount target filesystem. + */ + fs = mnt_table_find_mountpoint (tb, boot_path, MNT_ITER_FORWARD); + if (fs == NULL) + { + g_warning ("Failed to find mountpoint for %s", boot_path); + goto out; + } + + ret = g_strcmp0 (mnt_fs_get_fstype (fs), "autofs") == 0; + g_debug ("Boot directory %s is%s on an autofs filesystem", + boot_path, ret ? "" : " not"); + + out: + if (tb != NULL) + mnt_unref_table (tb); + + return ret; +} + static gboolean apply_internal (ApplyData *apply_data, GCancellable *cancellable, @@ -270,11 +330,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) && + !sysroot_boot_is_automount (sysroot); if (staged_deploy) { g_message ("Creating staged deployment for revision %s", update_id); diff --git a/eos-updater/meson.build b/eos-updater/meson.build index 61156308..e522e3cf 100644 --- a/eos-updater/meson.build +++ b/eos-updater/meson.build @@ -73,7 +73,10 @@ eos_updater_sources = [ 'poll-common.h', ] + eos_updater_resources -eos_updater_deps = libeos_updater_dbus_deps + [libeos_updater_dbus_dep] +eos_updater_deps = libeos_updater_dbus_deps + [ + dependency('mount', version: '>= 2.24'), + libeos_updater_dbus_dep, +] eos_updater_cppflags = [ '-DG_LOG_DOMAIN="eos-updater"',