Fall back to FAT32 internal partitions for detecting ESP

Fixes #2576
This commit is contained in:
Mario Limonciello 2020-11-11 16:59:30 -06:00 committed by Mario Limonciello
parent bd60de12be
commit 56d816a53b
5 changed files with 121 additions and 21 deletions

View File

@ -2249,6 +2249,7 @@ fu_common_get_volumes_by_kind (const gchar *kind, GError **error)
for (guint i = 0; i < devices->len; i++) {
GDBusProxy *proxy_blk = g_ptr_array_index (devices, i);
const gchar *type_str;
g_autoptr(FuVolume) vol = NULL;
g_autoptr(GDBusProxy) proxy_part = NULL;
g_autoptr(GDBusProxy) proxy_fs = NULL;
g_autoptr(GVariant) val = NULL;
@ -2269,10 +2270,6 @@ fu_common_get_volumes_by_kind (const gchar *kind, GError **error)
continue;
g_variant_get (val, "&s", &type_str);
g_debug ("device %s, type: %s",
g_dbus_proxy_get_object_path (proxy_blk), type_str);
if (g_strcmp0 (type_str, kind) != 0)
continue;
proxy_fs = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy_blk),
G_DBUS_PROXY_FLAGS_NONE, NULL,
UDISKS_DBUS_SERVICE,
@ -2284,11 +2281,17 @@ fu_common_get_volumes_by_kind (const gchar *kind, GError **error)
g_dbus_proxy_get_object_path (proxy_blk));
return NULL;
}
g_ptr_array_add (volumes,
g_object_new (FU_TYPE_VOLUME,
vol = g_object_new (FU_TYPE_VOLUME,
"proxy-block", proxy_blk,
"proxy-filesystem", proxy_fs,
NULL));
NULL);
g_debug ("device %s, type: %s, internal: %d, fs: %s",
g_dbus_proxy_get_object_path (proxy_blk), type_str,
fu_volume_is_internal (vol),
fu_volume_get_id_type (vol));
if (g_strcmp0 (type_str, kind) != 0)
continue;
g_ptr_array_add (volumes, g_steal_pointer (&vol));
}
if (volumes->len == 0) {
g_set_error (error,
@ -2400,18 +2403,44 @@ fu_common_get_esp_default (GError **error)
const gchar *path_tmp;
g_autoptr(GPtrArray) volumes_fstab = g_ptr_array_new ();
g_autoptr(GPtrArray) volumes_mtab = g_ptr_array_new ();
g_autoptr(GPtrArray) volumes_vfat = g_ptr_array_new ();
g_autoptr(GPtrArray) volumes = NULL;
g_autoptr(GError) error_local = NULL;
/* for the test suite use local directory for ESP */
path_tmp = g_getenv ("FWUPD_UEFI_ESP_PATH");
if (path_tmp != NULL)
return fu_volume_new_from_mount_path (path_tmp);
volumes = fu_common_get_volumes_by_kind (FU_VOLUME_KIND_ESP, error);
if (volumes == NULL)
volumes = fu_common_get_volumes_by_kind (FU_VOLUME_KIND_ESP, &error_local);
if (volumes == NULL) {
g_debug ("%s, falling back to %s", error_local->message, FU_VOLUME_KIND_BDP);
volumes = fu_common_get_volumes_by_kind (FU_VOLUME_KIND_BDP, error);
if (volumes == NULL) {
g_prefix_error (error, "%s: ", error_local->message);
return NULL;
}
}
/* only add in internal vfat partitions */
for (guint i = 0; i < volumes->len; i++) {
FuVolume *vol = g_ptr_array_index (volumes, i);
g_autofree gchar *type = fu_volume_get_id_type (vol);
if (type == NULL)
continue;
if (!fu_volume_is_internal (vol))
continue;
if (g_strcmp0 (type, "vfat") == 0)
g_ptr_array_add (volumes_vfat, vol);
}
if (volumes_vfat->len == 0) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_INVALID_FILENAME,
"No ESP found");
return NULL;
}
for (guint i = 0; i < volumes_vfat->len; i++) {
FuVolume *vol = g_ptr_array_index (volumes_vfat, i);
g_ptr_array_add (fu_volume_is_mounted (vol) ? volumes_mtab : volumes_fstab, vol);
}
if (volumes_mtab->len == 1) {

View File

@ -307,6 +307,53 @@ fu_volume_mount (FuVolume *self, GError **error)
return TRUE;
}
/**
* fu_volume_is_internal:
* @self: a @FuVolume
*
* Guesses if the drive is internal to the system
*
* Returns: %TRUE for success
*
* Since: 1.5.2
**/
gboolean
fu_volume_is_internal (FuVolume *self)
{
g_autoptr(GVariant) val_system = NULL;
g_return_val_if_fail (FU_IS_VOLUME (self), FALSE);
val_system = g_dbus_proxy_get_cached_property (self->proxy_blk, "HintSystem");
if (val_system == NULL)
return FALSE;
return g_variant_get_boolean (val_system);
}
/**
* fu_volume_get_id_type:
* @self: a @FuVolume
*
* Return the IdType of the volume
*
* Returns: string for type or NULL
*
* Since: 1.5.2
**/
gchar *
fu_volume_get_id_type (FuVolume *self)
{
g_autoptr(GVariant) val = NULL;
g_return_val_if_fail (FU_IS_VOLUME (self), NULL);
val = g_dbus_proxy_get_cached_property (self->proxy_blk, "IdType");
if (val == NULL)
return NULL;
return g_strdup (g_variant_get_string (val, NULL));
}
/**
* fu_volume_unmount:
* @self: a @FuVolume

View File

@ -16,6 +16,7 @@
G_DECLARE_FINAL_TYPE (FuVolume, fu_volume, FU, VOLUME, GObject)
#define FU_VOLUME_KIND_ESP "c12a7328-f81f-11d2-ba4b-00a0c93ec93b"
#define FU_VOLUME_KIND_BDP "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"
const gchar *fu_volume_get_id (FuVolume *self);
gboolean fu_volume_check_free_space (FuVolume *self,
@ -30,3 +31,5 @@ gboolean fu_volume_unmount (FuVolume *self,
GError **error);
FuDeviceLocker *fu_volume_locker (FuVolume *self,
GError **error);
gboolean fu_volume_is_internal (FuVolume *self);
gchar *fu_volume_get_id_type (FuVolume *self);

View File

@ -683,5 +683,7 @@ LIBFWUPDPLUGIN_1.5.1 {
LIBFWUPDPLUGIN_1.5.2 {
global:
fu_hid_device_add_flag;
fu_volume_get_id_type;
fu_volume_is_internal;
local: *;
} LIBFWUPDPLUGIN_1.5.1;

View File

@ -2373,13 +2373,32 @@ fu_util_prompt_for_volume (GError **error)
FuVolume *volume;
guint idx;
g_autoptr(GPtrArray) volumes = NULL;
g_autoptr(GPtrArray) volumes_vfat = g_ptr_array_new ();
g_autoptr(GError) error_local = NULL;
/* exactly one */
volumes = fu_common_get_volumes_by_kind (FU_VOLUME_KIND_ESP, error);
if (volumes == NULL)
volumes = fu_common_get_volumes_by_kind (FU_VOLUME_KIND_ESP, &error_local);
if (volumes == NULL) {
g_debug ("%s, falling back to %s", error_local->message, FU_VOLUME_KIND_BDP);
volumes = fu_common_get_volumes_by_kind (FU_VOLUME_KIND_BDP, error);
if (volumes == NULL) {
g_prefix_error (error, "%s: ", error_local->message);
return NULL;
if (volumes->len == 1) {
volume = g_ptr_array_index (volumes, 0);
}
}
/* only add internal vfat partitions */
for (guint i = 0; i < volumes->len; i++) {
FuVolume *vol = g_ptr_array_index (volumes, i);
g_autofree gchar *type = fu_volume_get_id_type (vol);
if (type == NULL)
continue;
if (!fu_volume_is_internal (vol))
continue;
if (g_strcmp0 (type, "vfat") == 0)
g_ptr_array_add (volumes_vfat, vol);
}
if (volumes_vfat->len == 1) {
volume = g_ptr_array_index (volumes_vfat, 0);
/* TRANSLATORS: Volume has been chosen by the user */
g_print ("%s: %s\n", _("Selected volume"), fu_volume_get_id (volume));
return g_object_ref (volume);
@ -2389,11 +2408,11 @@ fu_util_prompt_for_volume (GError **error)
g_print ("%s\n", _("Choose a volume:"));
/* TRANSLATORS: this is to abort the interactive prompt */
g_print ("0.\t%s\n", _("Cancel"));
for (guint i = 0; i < volumes->len; i++) {
volume = g_ptr_array_index (volumes, i);
for (guint i = 0; i < volumes_vfat->len; i++) {
volume = g_ptr_array_index (volumes_vfat, i);
g_print ("%u.\t%s\n", i + 1, fu_volume_get_id (volume));
}
idx = fu_util_prompt_for_number (volumes->len);
idx = fu_util_prompt_for_number (volumes_vfat->len);
if (idx == 0) {
g_set_error_literal (error,
FWUPD_ERROR,
@ -2401,7 +2420,7 @@ fu_util_prompt_for_volume (GError **error)
"Request canceled");
return NULL;
}
volume = g_ptr_array_index (volumes, idx - 1);
volume = g_ptr_array_index (volumes_vfat, idx - 1);
return g_object_ref (volume);
}