mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-15 08:42:46 +00:00
Allow adding backend tags to devices
This allows the backend to identify the specific device for a specific phase. For instance, there might be a pre-update runtime, a bootloader and a post-update runtime and allowing tags to be saved to the backend object allows us to identify each version of the same physical device. This takes us one step closer to emulating a complete byte-perfect end-to-end update without actual hardware installed.
This commit is contained in:
parent
6ce4244edd
commit
139188a5b0
@ -81,6 +81,7 @@ typedef struct {
|
|||||||
gchar *custom_flags;
|
gchar *custom_flags;
|
||||||
gulong notify_flags_handler_id;
|
gulong notify_flags_handler_id;
|
||||||
GHashTable *instance_hash;
|
GHashTable *instance_hash;
|
||||||
|
GPtrArray *backend_tags; /* of utf-8 */
|
||||||
} FuDevicePrivate;
|
} FuDevicePrivate;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -103,6 +104,7 @@ enum {
|
|||||||
PROP_CONTEXT,
|
PROP_CONTEXT,
|
||||||
PROP_PROXY,
|
PROP_PROXY,
|
||||||
PROP_PARENT,
|
PROP_PARENT,
|
||||||
|
PROP_BACKEND_TAGS,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,6 +139,9 @@ fu_device_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec
|
|||||||
case PROP_PARENT:
|
case PROP_PARENT:
|
||||||
g_value_set_object(value, fu_device_get_parent(self));
|
g_value_set_object(value, fu_device_get_parent(self));
|
||||||
break;
|
break;
|
||||||
|
case PROP_BACKEND_TAGS:
|
||||||
|
g_value_set_boxed(value, priv->backend_tags);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -1244,6 +1249,74 @@ fu_device_get_children(FuDevice *self)
|
|||||||
return fwupd_device_get_children(FWUPD_DEVICE(self));
|
return fwupd_device_get_children(FWUPD_DEVICE(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_device_get_backend_tags:
|
||||||
|
* @self: a #FuDevice
|
||||||
|
* @backend_tag: a tag, for example `bootloader` or `runtime-reload`
|
||||||
|
*
|
||||||
|
* Gets any backend tags.
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (element-type utf-8): string tags
|
||||||
|
*
|
||||||
|
* Since: 1.8.5
|
||||||
|
**/
|
||||||
|
GPtrArray *
|
||||||
|
fu_device_get_backend_tags(FuDevice *self)
|
||||||
|
{
|
||||||
|
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||||
|
g_return_val_if_fail(FU_IS_DEVICE(self), NULL);
|
||||||
|
return priv->backend_tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_device_add_backend_tag:
|
||||||
|
* @self: a #FuDevice
|
||||||
|
* @backend_tag: a tag, for example `bootloader` or `runtime-reload`
|
||||||
|
*
|
||||||
|
* Adds a backend tag, which allows the backend to identify the specific device for a specific
|
||||||
|
* phase. For instance, there might be a pre-update runtime, a bootloader and a post-update runtime
|
||||||
|
* and allowing tags to be saved to the backend object allows us to identify each version of
|
||||||
|
* the same physical device.
|
||||||
|
*
|
||||||
|
* Since: 1.8.5
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
fu_device_add_backend_tag(FuDevice *self, const gchar *backend_tag)
|
||||||
|
{
|
||||||
|
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||||
|
g_return_if_fail(FU_IS_DEVICE(self));
|
||||||
|
g_return_if_fail(backend_tag != NULL);
|
||||||
|
if (fu_device_has_backend_tag(self, backend_tag))
|
||||||
|
return;
|
||||||
|
g_ptr_array_add(priv->backend_tags, g_strdup(backend_tag));
|
||||||
|
g_object_notify(G_OBJECT(self), "backend-tags");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_device_has_backend_tag:
|
||||||
|
* @self: a #FuDevice
|
||||||
|
* @backend_tag: a tag, for example `bootloader` or `runtime-reload`
|
||||||
|
*
|
||||||
|
* Finds if the backend tag already exists.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the backend tag exists
|
||||||
|
*
|
||||||
|
* Since: 1.8.5
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
fu_device_has_backend_tag(FuDevice *self, const gchar *backend_tag)
|
||||||
|
{
|
||||||
|
FuDevicePrivate *priv = GET_PRIVATE(self);
|
||||||
|
g_return_val_if_fail(FU_IS_DEVICE(self), FALSE);
|
||||||
|
g_return_val_if_fail(backend_tag != NULL, FALSE);
|
||||||
|
for (guint i = 0; i < priv->backend_tags->len; i++) {
|
||||||
|
const gchar *backend_tag_tmp = g_ptr_array_index(priv->backend_tags, i);
|
||||||
|
if (g_strcmp0(backend_tag_tmp, backend_tag) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fu_device_add_child:
|
* fu_device_add_child:
|
||||||
* @self: a #FuDevice
|
* @self: a #FuDevice
|
||||||
@ -5584,6 +5657,20 @@ fu_device_class_init(FuDeviceClass *klass)
|
|||||||
FU_TYPE_DEVICE,
|
FU_TYPE_DEVICE,
|
||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_NAME);
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_NAME);
|
||||||
g_object_class_install_property(object_class, PROP_PARENT, pspec);
|
g_object_class_install_property(object_class, PROP_PARENT, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FuDevice:backend-tags:
|
||||||
|
*
|
||||||
|
* The device tags used for backend identification.
|
||||||
|
*
|
||||||
|
* Since: 1.5.8
|
||||||
|
*/
|
||||||
|
pspec = g_param_spec_boxed("backend-tags",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_PTR_ARRAY,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_NAME);
|
||||||
|
g_object_class_install_property(object_class, PROP_BACKEND_TAGS, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -5595,6 +5682,7 @@ fu_device_init(FuDevice *self)
|
|||||||
priv->possible_plugins = g_ptr_array_new_with_free_func(g_free);
|
priv->possible_plugins = g_ptr_array_new_with_free_func(g_free);
|
||||||
priv->retry_recs = g_ptr_array_new_with_free_func(g_free);
|
priv->retry_recs = g_ptr_array_new_with_free_func(g_free);
|
||||||
priv->instance_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
priv->instance_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||||
|
priv->backend_tags = g_ptr_array_new_with_free_func(g_free);
|
||||||
priv->acquiesce_delay = 50; /* ms */
|
priv->acquiesce_delay = 50; /* ms */
|
||||||
g_rw_lock_init(&priv->parent_guids_mutex);
|
g_rw_lock_init(&priv->parent_guids_mutex);
|
||||||
g_rw_lock_init(&priv->metadata_mutex);
|
g_rw_lock_init(&priv->metadata_mutex);
|
||||||
@ -5632,6 +5720,7 @@ fu_device_finalize(GObject *object)
|
|||||||
g_ptr_array_unref(priv->parent_guids);
|
g_ptr_array_unref(priv->parent_guids);
|
||||||
g_ptr_array_unref(priv->possible_plugins);
|
g_ptr_array_unref(priv->possible_plugins);
|
||||||
g_ptr_array_unref(priv->retry_recs);
|
g_ptr_array_unref(priv->retry_recs);
|
||||||
|
g_ptr_array_unref(priv->backend_tags);
|
||||||
g_free(priv->alternate_id);
|
g_free(priv->alternate_id);
|
||||||
g_free(priv->equivalent_id);
|
g_free(priv->equivalent_id);
|
||||||
g_free(priv->physical_id);
|
g_free(priv->physical_id);
|
||||||
|
@ -540,6 +540,12 @@ fu_device_set_version_lowest(FuDevice *self, const gchar *version);
|
|||||||
void
|
void
|
||||||
fu_device_set_version_bootloader(FuDevice *self, const gchar *version);
|
fu_device_set_version_bootloader(FuDevice *self, const gchar *version);
|
||||||
void
|
void
|
||||||
|
fu_device_add_backend_tag(FuDevice *self, const gchar *backend_tag);
|
||||||
|
gboolean
|
||||||
|
fu_device_has_backend_tag(FuDevice *self, const gchar *backend_tag);
|
||||||
|
GPtrArray *
|
||||||
|
fu_device_get_backend_tags(FuDevice *self);
|
||||||
|
void
|
||||||
fu_device_inhibit(FuDevice *self, const gchar *inhibit_id, const gchar *reason);
|
fu_device_inhibit(FuDevice *self, const gchar *inhibit_id, const gchar *reason);
|
||||||
void
|
void
|
||||||
fu_device_uninhibit(FuDevice *self, const gchar *inhibit_id);
|
fu_device_uninhibit(FuDevice *self, const gchar *inhibit_id);
|
||||||
|
@ -1226,6 +1226,7 @@ fu_plugin_runner_prepare(FuPlugin *self,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
||||||
|
fu_device_add_backend_tag(device, "prepare");
|
||||||
return fu_plugin_runner_flagged_device_generic(self,
|
return fu_plugin_runner_flagged_device_generic(self,
|
||||||
device,
|
device,
|
||||||
progress,
|
progress,
|
||||||
@ -1257,6 +1258,7 @@ fu_plugin_runner_cleanup(FuPlugin *self,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
||||||
|
fu_device_add_backend_tag(device, "cleanup");
|
||||||
return fu_plugin_runner_flagged_device_generic(self,
|
return fu_plugin_runner_flagged_device_generic(self,
|
||||||
device,
|
device,
|
||||||
progress,
|
progress,
|
||||||
@ -1283,6 +1285,7 @@ gboolean
|
|||||||
fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
fu_plugin_runner_attach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||||
{
|
{
|
||||||
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
||||||
|
fu_device_add_backend_tag(device, "attach");
|
||||||
return fu_plugin_runner_device_generic_progress(
|
return fu_plugin_runner_device_generic_progress(
|
||||||
self,
|
self,
|
||||||
device,
|
device,
|
||||||
@ -1309,6 +1312,7 @@ gboolean
|
|||||||
fu_plugin_runner_detach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
fu_plugin_runner_detach(FuPlugin *self, FuDevice *device, FuProgress *progress, GError **error)
|
||||||
{
|
{
|
||||||
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
FuPluginVfuncs *vfuncs = fu_plugin_get_vfuncs(self);
|
||||||
|
fu_device_add_backend_tag(device, "detach");
|
||||||
return fu_plugin_runner_device_generic_progress(
|
return fu_plugin_runner_device_generic_progress(
|
||||||
self,
|
self,
|
||||||
device,
|
device,
|
||||||
@ -1344,6 +1348,7 @@ fu_plugin_runner_reload(FuPlugin *self, FuDevice *device, GError **error)
|
|||||||
locker = fu_device_locker_new(proxy, error);
|
locker = fu_device_locker_new(proxy, error);
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
fu_device_add_backend_tag(device, "reload");
|
||||||
return fu_device_reload(device, error);
|
return fu_device_reload(device, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1917,6 +1922,7 @@ fu_plugin_runner_activate(FuPlugin *self, FuDevice *device, FuProgress *progress
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* run vfunc */
|
/* run vfunc */
|
||||||
|
fu_device_add_backend_tag(device, "activate");
|
||||||
if (!fu_plugin_runner_device_generic_progress(
|
if (!fu_plugin_runner_device_generic_progress(
|
||||||
self,
|
self,
|
||||||
device,
|
device,
|
||||||
@ -1966,6 +1972,7 @@ fu_plugin_runner_unlock(FuPlugin *self, FuDevice *device, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* run vfunc */
|
/* run vfunc */
|
||||||
|
fu_device_add_backend_tag(device, "unlock");
|
||||||
if (!fu_plugin_runner_device_generic(self,
|
if (!fu_plugin_runner_device_generic(self,
|
||||||
device,
|
device,
|
||||||
"fu_plugin_unlock",
|
"fu_plugin_unlock",
|
||||||
@ -2015,6 +2022,7 @@ fu_plugin_runner_write_firmware(FuPlugin *self,
|
|||||||
g_debug("plugin not enabled, skipping");
|
g_debug("plugin not enabled, skipping");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
fu_device_add_backend_tag(device, "write-firmware");
|
||||||
|
|
||||||
/* optional */
|
/* optional */
|
||||||
if (vfuncs->write_firmware == NULL) {
|
if (vfuncs->write_firmware == NULL) {
|
||||||
|
@ -1103,6 +1103,13 @@ fu_device_func(void)
|
|||||||
fu_device_add_possible_plugin(device, "test");
|
fu_device_add_possible_plugin(device, "test");
|
||||||
possible_plugins = fu_device_get_possible_plugins(device);
|
possible_plugins = fu_device_get_possible_plugins(device);
|
||||||
g_assert_cmpint(possible_plugins->len, ==, 1);
|
g_assert_cmpint(possible_plugins->len, ==, 1);
|
||||||
|
|
||||||
|
g_assert_cmpint(fu_device_get_backend_tags(device)->len, ==, 0);
|
||||||
|
fu_device_add_backend_tag(device, "foo");
|
||||||
|
fu_device_add_backend_tag(device, "bar");
|
||||||
|
g_assert_cmpint(fu_device_get_backend_tags(device)->len, ==, 2);
|
||||||
|
g_assert_true(fu_device_has_backend_tag(device, "foo"));
|
||||||
|
g_assert_false(fu_device_has_backend_tag(device, "bazbazbazbazbaz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1102,6 +1102,9 @@ LIBFWUPDPLUGIN_1.8.5 {
|
|||||||
fu_backend_save;
|
fu_backend_save;
|
||||||
fu_context_add_flag;
|
fu_context_add_flag;
|
||||||
fu_context_has_flag;
|
fu_context_has_flag;
|
||||||
|
fu_device_add_backend_tag;
|
||||||
|
fu_device_get_backend_tags;
|
||||||
|
fu_device_has_backend_tag;
|
||||||
fu_device_set_quirk_kv;
|
fu_device_set_quirk_kv;
|
||||||
fu_intel_thunderbolt_firmware_get_type;
|
fu_intel_thunderbolt_firmware_get_type;
|
||||||
fu_intel_thunderbolt_firmware_new;
|
fu_intel_thunderbolt_firmware_new;
|
||||||
|
Loading…
Reference in New Issue
Block a user