From 44b9e46d37c61b885097018a7b3df36c5b97b8da Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Tue, 22 Oct 2019 14:32:10 -0500 Subject: [PATCH] uefi: rework ESP path detection and lifecycle This makes the daemon less destructive at startup, especially if the ESP is not mounted. It's stored in 3 different places right now, so move it into one point of truth. Now the ESP is detected when needed including all point of time safety checks and dynamically mounted and unmounted if necessary. --- plugins/uefi/fu-plugin-uefi.c | 216 ++++++++++------------------------ plugins/uefi/fu-uefi-common.c | 8 +- plugins/uefi/fu-uefi-device.c | 149 +++++++++++++++++++++++ plugins/uefi/fu-uefi-tool.c | 33 +++--- plugins/uefi/fu-uefi-udisks.c | 52 ++++++++ plugins/uefi/fu-uefi-udisks.h | 3 + src/fu-engine.c | 2 + 7 files changed, 286 insertions(+), 177 deletions(-) diff --git a/plugins/uefi/fu-plugin-uefi.c b/plugins/uefi/fu-plugin-uefi.c index 48dbce66f..f322660ff 100644 --- a/plugins/uefi/fu-plugin-uefi.c +++ b/plugins/uefi/fu-plugin-uefi.c @@ -8,7 +8,6 @@ #include "config.h" #include -#include #include #include @@ -19,7 +18,6 @@ #include "fu-uefi-common.h" #include "fu-uefi-device.h" #include "fu-uefi-vars.h" -#include "fu-uefi-udisks.h" #ifndef HAVE_GIO_2_55_0 #pragma clang diagnostic push @@ -29,8 +27,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUnixMountEntry, g_unix_mount_free) #endif struct FuPluginData { - gchar *esp_path; - gboolean require_shim_for_sb; FuUefiBgrt *bgrt; }; @@ -49,7 +45,6 @@ void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); - g_free (data->esp_path); g_object_unref (data->bgrt); } @@ -182,6 +177,7 @@ fu_plugin_uefi_write_splash_data (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); + const gchar *esp_path = fu_device_get_metadata (device, "EspPath"); guint32 screen_x, screen_y; gsize buf_size = g_bytes_get_size (blob); gssize size; @@ -210,7 +206,7 @@ fu_plugin_uefi_write_splash_data (FuPlugin *plugin, } /* save to a predicatable filename */ - directory = fu_uefi_get_esp_path_for_os (data->esp_path); + directory = fu_uefi_get_esp_path_for_os (esp_path); basename = g_strdup_printf ("fwupd-%s.cap", FU_UEFI_VARS_GUID_UX_CAPSULE); fn = g_build_filename (directory, "fw", basename, NULL); if (!fu_common_mkdir_parent (fn, error)) @@ -346,30 +342,6 @@ fu_plugin_uefi_update_splash (FuPlugin *plugin, FuDevice *device, GError **error return fu_plugin_uefi_write_splash_data (plugin, device, image_bmp, error); } -static gboolean -fu_plugin_uefi_esp_mounted (FuPlugin *plugin, GError **error) -{ - FuPluginData *data = fu_plugin_get_data (plugin); - g_autofree gchar *contents = NULL; - g_auto(GStrv) lines = NULL; - gsize length; - - if (!g_file_get_contents ("/proc/mounts", &contents, &length, error)) - return FALSE; - lines = g_strsplit (contents, "\n", 0); - - for (guint i = 0; lines[i] != NULL; i++) { - if (lines[i] != NULL && g_strrstr (lines[i], data->esp_path)) - return TRUE; - } - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "EFI System partition %s is not mounted", - data->esp_path); - return FALSE; -} - gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *device, @@ -377,7 +349,6 @@ fu_plugin_update (FuPlugin *plugin, FwupdInstallFlags flags, GError **error) { - FuPluginData *data = fu_plugin_get_data (plugin); const gchar *str; guint32 flashes_left; g_autoptr(GError) error_splash = NULL; @@ -403,31 +374,14 @@ fu_plugin_update (FuPlugin *plugin, str = _("Installing firmware update…"); g_assert (str != NULL); - /* make sure that the ESP is mounted */ - if (g_getenv ("FWUPD_UEFI_ESP_PATH") == NULL) { - /* mount the partition somewhere */ - if (fu_uefi_udisks_objpath (data->esp_path)) { - g_autofree gchar *path = NULL; - path = fu_uefi_udisks_objpath_mount (data->esp_path, error); - if (path == NULL) - return FALSE; - g_debug ("Mounted ESP at %s", path); - g_free (data->esp_path); - data->esp_path = g_strdup (path); - } else if (!fu_plugin_uefi_esp_mounted (plugin, error)) { - return FALSE; - } - } - /* perform the update */ g_debug ("Performing UEFI capsule update"); - if (data->esp_path != NULL) - fu_device_set_metadata (device, "EspPath", data->esp_path); fu_device_set_status (device, FWUPD_STATUS_SCHEDULING); if (!fu_plugin_uefi_update_splash (plugin, device, &error_splash)) { g_debug ("failed to upload UEFI UX capsule text: %s", error_splash->message); } + if (!fu_device_write_firmware (device, blob_fw, flags, error)) return FALSE; @@ -435,16 +389,66 @@ fu_plugin_update (FuPlugin *plugin, str = fu_uefi_missing_capsule_header (device) ? "True" : "False"; fu_plugin_add_report_metadata (plugin, "MissingCapsuleHeader", str); + /* where the ESP was mounted during installation */ + str = fu_device_get_metadata (device, "EspPath"); + fu_plugin_add_report_metadata (plugin, "ESPMountPoint", str); + + return TRUE; +} + +static gboolean +fu_plugin_uefi_load_config (FuPlugin *plugin, FuDevice *device, GError **error) +{ + gboolean shim_needed = FALSE; + guint64 sz_reqd = FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE; + g_autofree gchar *require_esp_free_space = NULL; + g_autofree gchar *require_shim_for_sb = NULL; + g_autofree gchar *esp_path = NULL; + + /* parse free space needed for ESP */ + require_esp_free_space = fu_plugin_get_config_value (plugin, "RequireESPFreeSpace"); + if (require_esp_free_space != NULL) + sz_reqd = fu_common_strtoull (require_esp_free_space); + fu_device_set_metadata_integer (device, "RequireESPFreeSpace", sz_reqd); + + /* shim used for SB or not? */ + require_shim_for_sb = fu_plugin_get_config_value (plugin, "RequireShimForSecureBoot"); + if (require_shim_for_sb == NULL || + g_ascii_strcasecmp (require_shim_for_sb, "true") == 0) + shim_needed = TRUE; + fu_device_set_metadata_boolean (device, + "RequireShimForSecureBoot", + shim_needed); + + /* load ESP from file */ + esp_path = fu_plugin_get_config_value (plugin, "OverrideESPMountPoint"); + if (esp_path != NULL) { + g_autoptr(GError) error_local = NULL; + if (!fu_uefi_check_esp_path (esp_path, &error_local)) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_FILENAME, + "invalid OverrideESPMountPoint=%s specified in config: %s", + esp_path, error_local->message); + return FALSE; + } + fu_device_set_metadata (device, "EspPath", esp_path); + } + + /* success */ return TRUE; } static void fu_plugin_uefi_register_proxy_device (FuPlugin *plugin, FuDevice *device) { - FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr(FuUefiDevice) dev = fu_uefi_device_new_from_dev (device); - if (data->esp_path != NULL) - fu_device_set_metadata (FU_DEVICE (dev), "EspPath", data->esp_path); + g_autoptr(GError) error_local = NULL; + + /* load all configuration variables */ + if (!fu_plugin_uefi_load_config (plugin, FU_DEVICE (dev), &error_local)) + g_warning ("%s", error_local->message); + fu_plugin_device_add (plugin, FU_DEVICE (dev)); } @@ -566,34 +570,6 @@ fu_plugin_uefi_test_secure_boot (FuPlugin *plugin) fu_plugin_add_report_metadata (plugin, "SecureBoot", result_str); } -static gboolean -fu_plugin_uefi_delete_old_capsules (FuPlugin *plugin, GError **error) -{ - FuPluginData *data = fu_plugin_get_data (plugin); - g_autofree gchar *pattern = NULL; - g_autoptr(GPtrArray) files = NULL; - - /* can only do this if we're mounted */ - if (fu_uefi_udisks_objpath (data->esp_path)) - return TRUE; - - /* delete any files matching the glob in the ESP */ - files = fu_common_get_files_recursive (data->esp_path, error); - if (files == NULL) - return FALSE; - pattern = g_build_filename (data->esp_path, "EFI/*/fw/fwupd-*.cap", NULL); - for (guint i = 0; i < files->len; i++) { - const gchar *fn = g_ptr_array_index (files, i); - if (fnmatch (pattern, fn, 0) == 0) { - g_autoptr(GFile) file = g_file_new_for_path (fn); - g_debug ("deleting %s", fn); - if (!g_file_delete (file, NULL, error)) - return FALSE; - } - } - return TRUE; -} - static gboolean fu_plugin_uefi_smbios_enabled (FuPlugin *plugin, GError **error) { @@ -663,51 +639,6 @@ fu_plugin_startup (FuPlugin *plugin, GError **error) return TRUE; } -static gboolean -fu_plugin_uefi_ensure_esp_path (FuPlugin *plugin, GError **error) -{ - FuPluginData *data = fu_plugin_get_data (plugin); - guint64 sz_reqd = FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE; - g_autofree gchar *require_esp_free_space = NULL; - g_autofree gchar *require_shim_for_sb = NULL; - - /* parse free space */ - require_esp_free_space = fu_plugin_get_config_value (plugin, "RequireESPFreeSpace"); - if (require_esp_free_space != NULL) - sz_reqd = fu_common_strtoull (require_esp_free_space); - - /* load from file */ - data->esp_path = fu_plugin_get_config_value (plugin, "OverrideESPMountPoint"); - if (data->esp_path != NULL) { - g_autoptr(GError) error_local = NULL; - if (!fu_uefi_check_esp_path (data->esp_path, &error_local)) { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_FILENAME, - "invalid OverrideESPMountPoint=%s specified in config: %s", - data->esp_path, error_local->message); - return FALSE; - } - return fu_uefi_check_esp_free_space (data->esp_path, sz_reqd, error); - } - require_shim_for_sb = fu_plugin_get_config_value (plugin, "RequireShimForSecureBoot"); - if (require_shim_for_sb == NULL || - g_ascii_strcasecmp (require_shim_for_sb, "true") == 0) - data->require_shim_for_sb = TRUE; - - /* try to guess from heuristics and partitions */ - data->esp_path = fu_uefi_guess_esp_path (error); - if (data->esp_path == NULL) - return FALSE; - - /* check free space */ - if (!fu_uefi_check_esp_free_space (data->esp_path, sz_reqd, error)) - return FALSE; - - /* success */ - return TRUE; -} - static gboolean fu_plugin_uefi_ensure_efivarfs_rw (GError **error) { @@ -840,7 +771,6 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) g_autofree gchar *sysfsfwdir = NULL; g_autoptr(GError) error_bootloader = NULL; g_autoptr(GError) error_efivarfs = NULL; - g_autoptr(GError) error_esp = NULL; g_autoptr(GError) error_local = NULL; g_autoptr(GPtrArray) entries = NULL; @@ -873,10 +803,6 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) g_warning ("%s", error_bootloader->message); } - /* ensure the ESP is detected */ - if (!fu_plugin_uefi_ensure_esp_path (plugin, &error_esp)) - g_warning ("%s", error_esp->message); - /* add each device */ for (guint i = 0; i < entries->len; i++) { const gchar *path = g_ptr_array_index (entries, i); @@ -889,43 +815,25 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) fu_device_set_quirks (FU_DEVICE (dev), fu_plugin_get_quirks (plugin)); if (!fu_plugin_uefi_coldplug_device (plugin, dev, error)) return FALSE; - if (error_esp != NULL) { - fu_device_set_update_error (FU_DEVICE (dev), error_esp->message); - } else if (error_bootloader != NULL) { + if (error_bootloader != NULL) { fu_device_set_update_error (FU_DEVICE (dev), error_bootloader->message); } else if (error_efivarfs != NULL) { fu_device_set_update_error (FU_DEVICE (dev), error_efivarfs->message); } else { - fu_device_set_metadata (FU_DEVICE (dev), "EspPath", data->esp_path); - fu_device_set_metadata_boolean (FU_DEVICE (dev), - "RequireShimForSecureBoot", - data->require_shim_for_sb); fu_device_add_flag (FU_DEVICE (dev), FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (FU_DEVICE (dev), FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE); } + /* load all configuration variables */ + if (!fu_plugin_uefi_load_config (plugin, FU_DEVICE (dev), error)) + return FALSE; + fu_plugin_device_add (plugin, FU_DEVICE (dev)); } /* no devices are updatable */ - if (error_esp != NULL || error_bootloader != NULL) + if (error_bootloader != NULL) return TRUE; - /* delete any existing .cap files to avoid the small ESP partition - * from running out of space when we've done lots of firmware updates - * -- also if the distro has changed the ESP may be different anyway */ - if (fu_uefi_vars_exists (FU_UEFI_VARS_GUID_EFI_GLOBAL, "BootNext")) { - g_debug ("detected BootNext, not cleaning up"); - } else { - if (!fu_plugin_uefi_delete_old_capsules (plugin, error)) - return FALSE; - if (!fu_uefi_vars_delete_with_glob (FU_UEFI_VARS_GUID_FWUPDATE, "fwupd-*", error)) - return FALSE; - } - - /* save in report metadata */ - g_debug ("ESP mountpoint set as %s", data->esp_path); - fu_plugin_add_report_metadata (plugin, "ESPMountPoint", data->esp_path); - /* for debugging problems later */ fu_plugin_uefi_test_secure_boot (plugin); if (!fu_uefi_bgrt_setup (data->bgrt, &error_local)) diff --git a/plugins/uefi/fu-uefi-common.c b/plugins/uefi/fu-uefi-common.c index 8276fe27f..ca0db28d7 100644 --- a/plugins/uefi/fu-uefi-common.c +++ b/plugins/uefi/fu-uefi-common.c @@ -357,7 +357,7 @@ fu_uefi_check_esp_path (const gchar *path, GError **error) } static gchar * -fu_uefi_probe_for_esp (GError **error) +fu_uefi_probe_udisks_esp (GError **error) { g_autoptr(GPtrArray) devices = NULL; g_autofree gchar *found_esp = NULL; @@ -390,6 +390,7 @@ fu_uefi_probe_for_esp (GError **error) return NULL; } + g_debug ("Udisks detected objpath %s", found_esp); return g_steal_pointer (&found_esp); } @@ -414,9 +415,8 @@ fu_uefi_guess_esp_path (GError **error) return g_strdup (paths[i]); } - /* prove udisks2 */ - g_debug ("Using UDisks2 to probe for ESP"); - return fu_uefi_probe_for_esp (error); + /* probe using udisks2 */ + return fu_uefi_probe_udisks_esp (error); } void diff --git a/plugins/uefi/fu-uefi-device.c b/plugins/uefi/fu-uefi-device.c index 8c00c9ff2..692699aad 100644 --- a/plugins/uefi/fu-uefi-device.c +++ b/plugins/uefi/fu-uefi-device.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "fu-device-metadata.h" @@ -19,6 +20,7 @@ #include "fu-uefi-bootmgr.h" #include "fu-uefi-pcrs.h" #include "fu-uefi-vars.h" +#include "fu-uefi-udisks.h" struct _FuUefiDevice { FuDevice parent_instance; @@ -31,6 +33,7 @@ struct _FuUefiDevice { guint32 last_attempt_version; guint64 fmp_hardware_instance; gboolean missing_header; + gboolean automounted_esp; }; G_DEFINE_TYPE (FuUefiDevice, fu_uefi_device, FU_TYPE_DEVICE) @@ -397,6 +400,150 @@ fu_uefi_device_write_update_info (FuUefiDevice *self, return TRUE; } +static gboolean +fu_uefi_device_is_esp_mounted (FuDevice *device, GError **error) +{ + const gchar *esp_path = fu_device_get_metadata (device, "EspPath"); + g_autofree gchar *contents = NULL; + g_auto(GStrv) lines = NULL; + gsize length; + + if (esp_path == NULL) { + g_set_error_literal (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "EFI System partition is not defined"); + return FALSE; + } + + if (!g_file_get_contents ("/proc/mounts", &contents, &length, error)) + return FALSE; + lines = g_strsplit (contents, "\n", 0); + + for (guint i = 0; lines[i] != NULL; i++) { + if (lines[i] != NULL && g_strrstr (lines[i], esp_path)) + return TRUE; + } + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "EFI System partition %s is not mounted", + esp_path); + return FALSE; +} + +static gboolean +fu_uefi_device_check_esp_free (FuDevice *device, GError **error) +{ + const gchar *esp_path = fu_device_get_metadata (device, "EspPath"); + guint64 sz_reqd = fu_device_get_metadata_integer (device, "RequireESPFreeSpace"); + if (sz_reqd == G_MAXUINT) { + g_debug ("maximum size is not configured"); + return TRUE; + } + return fu_uefi_check_esp_free_space (esp_path, sz_reqd, error); +} + +static gboolean +fu_uefi_device_cleanup_esp (FuDevice *device, GError **error) +{ + const gchar *esp_path = fu_device_get_metadata (device, "EspPath"); + g_autofree gchar *pattern = NULL; + g_autoptr(GPtrArray) files = NULL; + + /* in case we call capsule install twice before reboot */ + if (fu_uefi_vars_exists (FU_UEFI_VARS_GUID_EFI_GLOBAL, "BootNext")) + return TRUE; + + /* delete any files matching the glob in the ESP */ + files = fu_common_get_files_recursive (esp_path, error); + if (files == NULL) + return FALSE; + pattern = g_build_filename (esp_path, "EFI/*/fw/fwupd-*.cap", NULL); + for (guint i = 0; i < files->len; i++) { + const gchar *fn = g_ptr_array_index (files, i); + if (fnmatch (pattern, fn, 0) == 0) { + g_autoptr(GFile) file = g_file_new_for_path (fn); + g_debug ("deleting %s", fn); + if (!g_file_delete (file, NULL, error)) + return FALSE; + } + } + + /* delete any old variables */ + if (!fu_uefi_vars_delete_with_glob (FU_UEFI_VARS_GUID_FWUPDATE, "fwupd-*", error)) + return FALSE; + + return TRUE; +} + +static gboolean +fu_uefi_device_prepare (FuDevice *device, + FwupdInstallFlags flags, + GError **error) +{ + /* not set in conf, figure it out */ + if (fu_device_get_metadata (device, "EspPath") == NULL) { + g_autofree gchar *guessed = NULL; + g_autofree gchar *detected_esp = NULL; + guessed = fu_uefi_guess_esp_path (error); + if (guessed == NULL) + return FALSE; + + /* udisks objpath */ + if (fu_uefi_udisks_objpath (guessed)) { + FuUefiDevice *self = FU_UEFI_DEVICE (device); + detected_esp = fu_uefi_udisks_objpath_is_mounted (guessed); + if (detected_esp != NULL) { + g_debug ("ESP already mounted @ %s", detected_esp); + /* not mounted */ + } else { + g_debug ("Mounting ESP @ %s", guessed); + detected_esp = fu_uefi_udisks_objpath_mount (guessed, error); + if (detected_esp == NULL) + return FALSE; + self->automounted_esp = TRUE; + } + /* already mounted */ + } else { + detected_esp = g_steal_pointer (&guessed); + } + fu_device_set_metadata (device, "EspPath", detected_esp); + } + + /* sanity checks */ + if (!fu_uefi_device_is_esp_mounted (device, error)) + return FALSE; + if (!fu_uefi_device_check_esp_free (device, error)) + return FALSE; + if (!fu_uefi_device_cleanup_esp (device, error)) + return FALSE; + + return TRUE; +} + +static gboolean +fu_uefi_device_cleanup (FuDevice *device, + FwupdInstallFlags flags, + GError **error) +{ + FuUefiDevice *self = FU_UEFI_DEVICE (device); + if (self->automounted_esp) { + g_autofree gchar *guessed = NULL; + guessed = fu_uefi_guess_esp_path (error); + if (guessed == NULL) + return FALSE; + g_debug ("Unmounting ESP @ %s", guessed); + if (!fu_uefi_udisks_objpath_umount (guessed, error)) + return FALSE; + self->automounted_esp = FALSE; + /* we will detect again if necessary */ + fu_device_remove_metadata (device, "EspPath"); + } + + return TRUE; +} + static gboolean fu_uefi_device_write_firmware (FuDevice *device, FuFirmware *firmware, @@ -594,7 +741,9 @@ fu_uefi_device_class_init (FuUefiDeviceClass *klass) object_class->finalize = fu_uefi_device_finalize; klass_device->to_string = fu_uefi_device_to_string; klass_device->probe = fu_uefi_device_probe; + klass_device->prepare = fu_uefi_device_prepare; klass_device->write_firmware = fu_uefi_device_write_firmware; + klass_device->cleanup = fu_uefi_device_cleanup; } FuUefiDevice * diff --git a/plugins/uefi/fu-uefi-tool.c b/plugins/uefi/fu-uefi-tool.c index 240451cb1..18bfca1dd 100644 --- a/plugins/uefi/fu-uefi-tool.c +++ b/plugins/uefi/fu-uefi-tool.c @@ -163,25 +163,8 @@ main (int argc, char *argv[]) error->message); return EXIT_FAILURE; } - } else { - g_autoptr(GError) error_local = NULL; - esp_path = fu_uefi_guess_esp_path (&error_local); - if (esp_path == NULL) { - g_printerr ("%s: override using --esp-path\n", - error_local->message); - return EXIT_FAILURE; - } } - /* check free space */ - if (!fu_uefi_check_esp_free_space (esp_path, - FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE, - &error)) { - g_printerr ("Unable to use EFI system partition: %s\n", error->message); - return EXIT_FAILURE; - } - g_debug ("ESP mountpoint set as %s", esp_path); - /* show the debug action_log from the last attempted update */ if (action_log) { gsize sz = 0; @@ -228,7 +211,8 @@ main (int argc, char *argv[]) path, error_parse->message); continue; } - fu_device_set_metadata (FU_DEVICE (dev), "EspPath", esp_path); + if (esp_path != NULL) + fu_device_set_metadata (FU_DEVICE (dev), "EspPath", esp_path); g_ptr_array_add (devices, g_object_ref (dev)); } } @@ -334,15 +318,26 @@ main (int argc, char *argv[]) g_printerr ("failed: %s\n", error_local->message); return EXIT_FAILURE; } - fu_device_set_metadata (FU_DEVICE (dev), "EspPath", esp_path); if (flags != NULL) fu_device_set_custom_flags (FU_DEVICE (dev), flags); + if (!fu_device_prepare (FU_DEVICE (dev), + FWUPD_INSTALL_FLAG_NONE, + &error_local)) { + g_printerr ("failed: %s\n", error_local->message); + return EXIT_FAILURE; + } if (!fu_device_write_firmware (FU_DEVICE (dev), fw, FWUPD_INSTALL_FLAG_NONE, &error_local)) { g_printerr ("failed: %s\n", error_local->message); return EXIT_FAILURE; } + if (!fu_device_cleanup (FU_DEVICE (dev), + FWUPD_INSTALL_FLAG_NONE, + &error_local)) { + g_printerr ("failed: %s\n", error_local->message); + return EXIT_FAILURE; + } } /* success */ diff --git a/plugins/uefi/fu-uefi-udisks.c b/plugins/uefi/fu-uefi-udisks.c index 84ffa6ead..f809cb09b 100644 --- a/plugins/uefi/fu-uefi-udisks.c +++ b/plugins/uefi/fu-uefi-udisks.c @@ -107,6 +107,33 @@ fu_uefi_udisks_objpath_is_esp (const gchar *obj) return g_strcmp0 (str, ESP_DISK_TYPE) == 0; } +gboolean +fu_uefi_udisks_objpath_umount (const gchar *path, GError **error) +{ + GVariant *input; + GVariantBuilder builder; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) val = NULL; + + g_return_val_if_fail (fu_uefi_udisks_objpath (path), FALSE); + + proxy = fu_uefi_udisks_get_dbus_proxy (path, + UDISKS_DBUS_FILE_INTERFACE, + error); + if (proxy == NULL) + return FALSE; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + input = g_variant_new ("(a{sv})", &builder); + val = g_dbus_proxy_call_sync (proxy, + "Unmount", input, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + return TRUE; +} + gchar * fu_uefi_udisks_objpath_mount (const gchar *path, GError **error) { @@ -136,3 +163,28 @@ fu_uefi_udisks_objpath_mount (const gchar *path, GError **error) return g_strdup (str); } + +gchar * +fu_uefi_udisks_objpath_is_mounted (const gchar *path) +{ + const gchar **mountpoints = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(GError) error_local = NULL; + + g_return_val_if_fail (fu_uefi_udisks_objpath (path), NULL); + + proxy = fu_uefi_udisks_get_dbus_proxy (path, + UDISKS_DBUS_FILE_INTERFACE, + &error_local); + if (proxy == NULL) { + g_warning ("%s", error_local->message); + return NULL; + } + val = g_dbus_proxy_get_cached_property (proxy, "MountPoints"); + if (val == NULL) + return NULL; + mountpoints = g_variant_get_bytestring_array (val, NULL); + + return g_strdup (mountpoints[0]); +} diff --git a/plugins/uefi/fu-uefi-udisks.h b/plugins/uefi/fu-uefi-udisks.h index 46b08cb5e..58018ecc4 100644 --- a/plugins/uefi/fu-uefi-udisks.h +++ b/plugins/uefi/fu-uefi-udisks.h @@ -11,3 +11,6 @@ gboolean fu_uefi_udisks_objpath (const gchar *path); gboolean fu_uefi_udisks_objpath_is_esp (const gchar *obj); gchar *fu_uefi_udisks_objpath_mount (const gchar *path, GError **error); +gboolean fu_uefi_udisks_objpath_umount (const gchar *path, + GError **error); +gchar *fu_uefi_udisks_objpath_is_mounted (const gchar *path); diff --git a/src/fu-engine.c b/src/fu-engine.c index 95d300e70..05b59077f 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -1866,6 +1866,8 @@ fu_engine_update_prepare (FuEngine *self, return FALSE; str = fu_device_to_string (device); g_debug ("performing prepare on %s", str); + if (!fu_device_prepare (device, flags, error)) + return FALSE; for (guint j = 0; j < plugins->len; j++) { FuPlugin *plugin_tmp = g_ptr_array_index (plugins, j); if (!fu_plugin_runner_update_prepare (plugin_tmp, flags, device, error))