mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-04 11:53:05 +00:00
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.
This commit is contained in:
parent
9160fd4dd1
commit
44b9e46d37
@ -8,7 +8,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <gio/gunixmounts.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
@ -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))
|
||||
|
@ -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
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <string.h>
|
||||
#include <efivar.h>
|
||||
#include <efivar/efiboot.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#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 *
|
||||
|
@ -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 */
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user