Allow enabling plugins only matching a specific HwId

At the moment plugins are doing this a few different ways; either looping
through the HwIds manually (e.g. flashrom) or setting a custom flag that is
checked in fu_plugin_setup (e.g. uefi-recovery).

Define a standard 'Plugin' HwId quirk to simplify plugins.
This commit is contained in:
Richard Hughes 2021-03-01 21:12:18 +00:00
parent 05217338b3
commit d94286b9de
11 changed files with 81 additions and 61 deletions

View File

@ -345,6 +345,8 @@ fwupd_plugin_flag_to_string (FwupdPluginFlags plugin_flag)
return "legacy-bios";
if (plugin_flag == FWUPD_PLUGIN_FLAG_FAILED_OPEN)
return "failed-open";
if (plugin_flag == FWUPD_PLUGIN_FLAG_REQUIRE_HWID)
return "require-hwid";
if (plugin_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
return "unknown";
return NULL;
@ -385,6 +387,8 @@ fwupd_plugin_flag_from_string (const gchar *plugin_flag)
return FWUPD_PLUGIN_FLAG_LEGACY_BIOS;
if (g_strcmp0 (plugin_flag, "failed-open") == 0)
return FWUPD_PLUGIN_FLAG_FAILED_OPEN;
if (g_strcmp0 (plugin_flag, "require-hwid") == 0)
return FWUPD_PLUGIN_FLAG_REQUIRE_HWID;
return FWUPD_DEVICE_FLAG_UNKNOWN;
}

View File

@ -235,6 +235,7 @@ typedef enum {
* @FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND: The EFI ESP not found
* @FWUPD_PLUGIN_FLAG_LEGACY_BIOS: System running in legacy CSM mode
* @FWUPD_PLUGIN_FLAG_FAILED_OPEN: Failed to open plugin (missing dependency)
* @FWUPD_PLUGIN_FLAG_REQUIRE_HWID: A specific HWID is required
*
* The plugin flags.
**/
@ -249,6 +250,7 @@ typedef enum {
#define FWUPD_PLUGIN_FLAG_ESP_NOT_FOUND (1u << 7) /* Since: 1.5.0 */
#define FWUPD_PLUGIN_FLAG_LEGACY_BIOS (1u << 8) /* Since: 1.5.0 */
#define FWUPD_PLUGIN_FLAG_FAILED_OPEN (1u << 9) /* Since: 1.5.0 */
#define FWUPD_PLUGIN_FLAG_REQUIRE_HWID (1u << 10) /* Since: 1.5.8 */
#define FWUPD_PLUGIN_FLAG_UNKNOWN G_MAXUINT64 /* Since: 1.5.0 */
typedef guint64 FwupdPluginFlags;

View File

@ -1,15 +1,15 @@
# Purism
[HwId=a0ce5085-2dea-5086-ae72-45810a186ad0]
DeviceId=librem15v3
Plugin=flashrom
# Libretrend
[HwId=52b68c34-6b31-5ecc-8a5c-de37e666ccd5]
DeviceId=LT1000
Plugin=flashrom
VersionFormat=quad
# Starlabs LabTop L4
[HwId=baf1d04e-fd16-5e6a-93cc-1c23d171f879]
DeviceId=StarlabsLabTopL4
Plugin=flashrom
# Starlabs LabTop L4 (in coreboot)
[Guid=0ee5867c-93f0-5fb4-adf1-9d686ea1183a]

View File

@ -24,6 +24,8 @@ fu_flashrom_device_init (FuFlashromDevice *self)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_instance_id (FU_DEVICE (self), "main-system-firmware");
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_ENSURE_SEMVER);
fu_device_set_physical_id (FU_DEVICE (self), "flashrom");
fu_device_set_logical_id (FU_DEVICE (self), "bios");
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_add_icon (FU_DEVICE (self), "computer");
}

View File

@ -45,6 +45,7 @@ fu_plugin_init (FuPlugin *plugin)
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "linux_lockdown");
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_CONFLICTS, "coreboot"); /* obsoleted */
fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID);
}
void
@ -176,48 +177,25 @@ gboolean
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
{
FuPluginData *data = fu_plugin_get_data (plugin);
GPtrArray *hwids = fu_plugin_get_hwids (plugin);
const gchar *dmi_vendor;
gint rc;
g_autoptr(GPtrArray) devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
g_autoptr(FuDevice) device = fu_flashrom_device_new ();
for (guint i = 0; i < hwids->len; i++) {
const gchar *guid = g_ptr_array_index (hwids, i);
const gchar *quirk_str;
g_autofree gchar *quirk_key_prefixed = NULL;
quirk_key_prefixed = g_strdup_printf ("HwId=%s", guid);
quirk_str = fu_plugin_lookup_quirk_by_id (plugin,
quirk_key_prefixed,
"DeviceId");
if (quirk_str != NULL) {
g_autofree gchar *device_id = g_strdup_printf ("flashrom-%s", quirk_str);
g_autoptr(FuDevice) device = fu_flashrom_device_new ();
fu_device_set_quirks (device, fu_plugin_get_quirks (plugin));
fu_device_set_name (device, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME));
fu_device_set_vendor (device, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER));
fu_device_set_quirks (device, fu_plugin_get_quirks (plugin));
fu_device_set_name (device, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME));
fu_device_set_vendor (device, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER));
/* use same VendorID logic as with UEFI */
dmi_vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
if (dmi_vendor != NULL) {
g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", dmi_vendor);
fu_device_add_vendor_id (FU_DEVICE (device), vendor_id);
}
fu_device_set_id (device, device_id);
fu_device_add_guid (device, guid);
fu_plugin_flashrom_device_set_version (plugin, device);
fu_plugin_flashrom_device_set_hwids (plugin, device);
fu_plugin_flashrom_device_set_bios_info (plugin, device);
if (!fu_device_setup (device, error))
return FALSE;
g_ptr_array_add (devices, g_steal_pointer (&device));
break;
}
/* use same VendorID logic as with UEFI */
dmi_vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
if (dmi_vendor != NULL) {
g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", dmi_vendor);
fu_device_add_vendor_id (FU_DEVICE (device), vendor_id);
}
/* nothing to do, so don't bother initializing flashrom */
if (devices->len == 0)
return TRUE;
fu_plugin_flashrom_device_set_version (plugin, device);
fu_plugin_flashrom_device_set_hwids (plugin, device);
fu_plugin_flashrom_device_set_bios_info (plugin, device);
if (!fu_device_setup (device, error))
return FALSE;
/* actually probe hardware to check for support */
if (flashrom_init (SELFCHECK_TRUE)) {
@ -266,12 +244,9 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error)
return FALSE;
}
/* add devices */
for (guint i = 0; i < devices->len; i++) {
FuDevice *dev = g_ptr_array_index (devices, i);
fu_plugin_device_add (plugin, dev);
fu_plugin_cache_add (plugin, fu_device_get_id (dev), dev);
}
/* success */
fu_plugin_device_add (plugin, device);
fu_plugin_cache_add (plugin, fu_device_get_id (device), device);
return TRUE;
}

View File

@ -15,19 +15,7 @@ fu_plugin_init (FuPlugin *plugin)
/* make sure that UEFI plugin is ready to receive devices */
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "uefi_capsule");
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
}
gboolean
fu_plugin_startup (FuPlugin *plugin, GError **error)
{
if (!fu_plugin_has_custom_flag (plugin, "requires-uefi-recovery")) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"not required");
return FALSE;
}
return TRUE;
fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID);
}
gboolean

View File

@ -1,3 +1,3 @@
# Silicom Minnowboard Turbot MNW2MAX1.X64.0100.R01.1811141729
[HwId=ea358e00-39f1-55b6-97be-a39225a585e1]
Flags = requires-uefi-recovery
Plugin = uefi_recovery

View File

@ -5110,6 +5110,12 @@ fu_engine_plugins_setup (FuEngine *self)
for (guint i = 0; i < plugins->len; i++) {
g_autoptr(GError) error = NULL;
FuPlugin *plugin = g_ptr_array_index (plugins, i);
if (fu_plugin_has_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID)) {
fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_NO_HARDWARE);
g_message ("disabling plugin %s because no HwId",
fu_plugin_get_name (plugin));
continue;
}
if (!fu_plugin_runner_startup (plugin, &error)) {
fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_DISABLED);
if (g_error_matches (error,
@ -6104,12 +6110,50 @@ fu_engine_backend_device_changed_cb (FuBackend *backend, FuDevice *device, FuEng
}
}
static void
fu_engine_load_quirks_for_hwid (FuEngine *self, const gchar *hwid)
{
FuPlugin *plugin;
const gchar *value;
g_autofree gchar *key = g_strdup_printf ("HwId=%s", hwid);
g_auto(GStrv) plugins = NULL;
/* does prefixed quirk exist */
value = fu_quirks_lookup_by_id (self->quirks, key, FU_QUIRKS_PLUGIN);
if (value == NULL)
return;
plugins = g_strsplit (value, ",", -1);
for (guint i = 0; plugins[i] != NULL; i++) {
g_autoptr(GError) error_local = NULL;
plugin = fu_plugin_list_find_by_name (self->plugin_list,
plugins[i], &error_local);
if (plugin == NULL) {
g_debug ("no %s plugin for HwId %s: %s",
plugins[i], hwid, error_local->message);
continue;
}
g_debug ("enabling %s due to HwId %s", plugins[i], hwid);
fu_plugin_remove_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID);
}
}
static void
fu_engine_load_quirks (FuEngine *self, FuQuirksLoadFlags quirks_flags)
{
GPtrArray *hwids = fu_hwids_get_guids (self->hwids);
g_autoptr(GError) error = NULL;
if (!fu_quirks_load (self->quirks, quirks_flags, &error))
/* rebuild silo if required */
if (!fu_quirks_load (self->quirks, quirks_flags, &error)) {
g_warning ("Failed to load quirks: %s", error->message);
return;
}
/* search each hwid */
for (guint i = 0; i < hwids->len; i++) {
const gchar *hwid = g_ptr_array_index (hwids, i);
fu_engine_load_quirks_for_hwid (self, hwid);
}
}
static void

View File

@ -138,6 +138,7 @@ fu_util_show_plugin_warnings (FuUtilPrivate *priv)
/* never show these, they're way too generic */
flags &= ~FWUPD_PLUGIN_FLAG_DISABLED;
flags &= ~FWUPD_PLUGIN_FLAG_NO_HARDWARE;
flags &= ~FWUPD_PLUGIN_FLAG_REQUIRE_HWID;
/* print */
for (guint i = 0; i < 64; i++) {

View File

@ -1330,6 +1330,8 @@ fu_util_plugin_flag_to_string (FwupdPluginFlags plugin_flag)
return NULL;
if (plugin_flag == FWUPD_PLUGIN_FLAG_USER_WARNING)
return NULL;
if (plugin_flag == FWUPD_PLUGIN_FLAG_REQUIRE_HWID)
return NULL;
if (plugin_flag == FWUPD_PLUGIN_FLAG_NONE) {
/* TRANSLATORS: Plugin is active and in use */
return _("Enabled");
@ -1378,6 +1380,7 @@ fu_util_plugin_flag_to_cli_text (FwupdPluginFlags plugin_flag)
case FWUPD_PLUGIN_FLAG_UNKNOWN:
case FWUPD_PLUGIN_FLAG_CLEAR_UPDATABLE:
case FWUPD_PLUGIN_FLAG_USER_WARNING:
case FWUPD_PLUGIN_FLAG_REQUIRE_HWID:
return NULL;
case FWUPD_PLUGIN_FLAG_NONE:
return fu_util_term_format (fu_util_plugin_flag_to_string (plugin_flag),

View File

@ -2683,6 +2683,7 @@ fu_util_show_plugin_warnings (FuUtilPrivate *priv)
/* never show these, they're way too generic */
flags &= ~FWUPD_PLUGIN_FLAG_DISABLED;
flags &= ~FWUPD_PLUGIN_FLAG_NO_HARDWARE;
flags &= ~FWUPD_PLUGIN_FLAG_REQUIRE_HWID;
/* print */
for (guint i = 0; i < 64; i++) {