trivial: Add some sanity checks to the device list

This commit is contained in:
Richard Hughes 2021-07-12 16:34:24 +01:00 committed by Mario Limonciello
parent 1ca9c92919
commit 6578fb13e7
2 changed files with 103 additions and 4 deletions

View File

@ -78,6 +78,35 @@ fu_device_list_emit_device_changed (FuDeviceList *self, FuDevice *device)
g_signal_emit (self, signals[SIGNAL_CHANGED], 0, device);
}
static gchar *
fu_device_list_to_string (FuDeviceList *self)
{
GString *str = g_string_new (NULL);
g_rw_lock_reader_lock (&self->devices_mutex);
for (guint i = 0; i < self->devices->len; i++) {
FuDeviceItem *item = g_ptr_array_index (self->devices, i);
gboolean wfr;
g_string_append_printf (str, "%u [%p]\n", i, item);
wfr = fu_device_has_flag (item->device,
FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
g_string_append_printf (str, "new: %s [%p] %s\n",
fu_device_get_id (item->device),
item->device,
wfr ? "WAIT_FOR_REPLUG" : "");
if (item->device_old != NULL) {
wfr = fu_device_has_flag (item->device_old,
FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
g_string_append_printf (str, "old: %s [%p] %s\n",
fu_device_get_id (item->device_old),
item->device_old,
wfr ? "WAIT_FOR_REPLUG" : "");
}
}
g_rw_lock_reader_unlock (&self->devices_mutex);
return g_string_free (str, FALSE);
}
/* we cannot use fu_device_get_children() as this will not find "parent-only"
* logical relationships added using fu_device_add_parent_guid() */
static GPtrArray *
@ -544,6 +573,25 @@ fu_device_list_item_set_device (FuDeviceItem *item, FuDevice *device)
g_set_object (&item->device, device);
}
static void
fu_device_list_clear_wait_for_replug (FuDeviceList *self, FuDeviceItem *item)
{
if (fu_device_has_flag (item->device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG)) {
g_debug ("%s device came back, clearing flag", fu_device_get_id (item->device));
fu_device_remove_flag (item->device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
}
if (item->device_old != NULL) {
if (fu_device_has_flag (item->device_old, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG)) {
g_debug ("%s old device came back, clearing flag", fu_device_get_id (item->device_old));
fu_device_remove_flag (item->device_old, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
}
}
if (g_getenv ("FWUPD_DEVICE_LIST_VERBOSE") != NULL) {
g_autofree gchar *str = fu_device_list_to_string (self);
g_debug ("\n%s", str);
}
}
static void
fu_device_list_replace (FuDeviceList *self, FuDeviceItem *item, FuDevice *device)
{
@ -627,12 +675,13 @@ fu_device_list_replace (FuDeviceList *self, FuDeviceItem *item, FuDevice *device
g_set_object (&item->device_old, item->device);
fu_device_list_item_set_device (item, device);
fu_device_list_emit_device_changed (self, device);
if (g_getenv ("FWUPD_DEVICE_LIST_VERBOSE") != NULL) {
g_autofree gchar *str = fu_device_list_to_string (self);
g_debug ("\n%s", str);
}
/* we were waiting for this... */
if (fu_device_has_flag (item->device_old, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG)) {
g_debug ("device came back, clearing flag");
fu_device_remove_flag (item->device_old, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
}
fu_device_list_clear_wait_for_replug (self, item);
}
/**
@ -668,6 +717,33 @@ fu_device_list_add (FuDeviceList *self, FuDevice *device)
/* is the device waiting to be replugged? */
item = fu_device_list_find_by_id (self, fu_device_get_id (device), NULL);
if (item != NULL) {
/* literally the same object */
if (g_strcmp0 (fu_device_get_id (device),
fu_device_get_id (item->device)) == 0) {
g_debug ("found existing device %s",
fu_device_get_id (device));
if (device != item->device)
fu_device_list_item_set_device (item, device);
fu_device_list_clear_wait_for_replug (self, item);
fu_device_list_emit_device_changed (self, device);
return;
}
/* the old device again */
if (item->device_old != NULL &&
g_strcmp0 (fu_device_get_id (device),
fu_device_get_id (item->device_old)) == 0) {
g_debug ("found old device %s, swapping",
fu_device_get_id (device));
g_set_object (&item->device_old, item->device);
fu_device_list_item_set_device (item, device);
fu_device_list_clear_wait_for_replug (self, item);
fu_device_list_emit_device_changed (self, device);
return;
}
/* same ID, different object */
g_debug ("found existing device %s, reusing item",
fu_device_get_id (item->device));
fu_device_list_replace (self, item, device);

View File

@ -2294,6 +2294,7 @@ fu_device_list_replug_user_func (gconstpointer user_data)
/* fake devices */
fu_device_set_id (device1, "device1");
fu_device_set_name (device1, "device1");
fu_device_add_internal_flag (device1, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_instance_id (device1, "foo");
fu_device_add_instance_id (device1, "bar");
@ -2301,6 +2302,7 @@ fu_device_list_replug_user_func (gconstpointer user_data)
fu_device_set_remove_delay (device1, FU_DEVICE_REMOVE_DELAY_USER_REPLUG);
fu_device_convert_instance_ids (device1);
fu_device_set_id (device2, "device2");
fu_device_set_name (device2, "device2");
fu_device_add_internal_flag (device2, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_instance_id (device2, "baz");
fu_device_add_instance_id (device2, "bar"); /* matches */
@ -2316,6 +2318,11 @@ fu_device_list_replug_user_func (gconstpointer user_data)
/* add device */
fu_device_list_add (device_list, device1);
/* add duplicate */
fu_device_add_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
fu_device_list_add (device_list, device1);
g_assert_false (fu_device_has_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG));
/* not waiting */
ret = fu_device_list_wait_for_replug (device_list, &error);
g_assert_no_error (error);
@ -2332,6 +2339,21 @@ fu_device_list_replug_user_func (gconstpointer user_data)
g_assert_no_error (error);
g_assert (ret);
g_assert_false (fu_device_has_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG));
/* should not be possible, but here we are */
fu_device_add_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
fu_device_add_flag (device2, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
fu_device_list_add (device_list, device1);
g_assert_false (fu_device_has_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG));
g_assert_false (fu_device_has_flag (device2, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG));
/* add back the old device */
fu_device_add_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
fu_device_add_flag (device2, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG);
fu_device_list_remove (device_list, device2);
fu_device_list_add (device_list, device1);
g_assert_false (fu_device_has_flag (device1, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG));
g_assert_false (fu_device_has_flag (device2, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG));
}
static void
@ -3322,6 +3344,7 @@ main (int argc, char **argv)
/* only critical and error are fatal */
g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
g_setenv ("FWUPD_DEVICE_LIST_VERBOSE", "1", TRUE);
g_setenv ("FWUPD_DATADIR", TESTDATADIR_SRC, TRUE);
g_setenv ("FWUPD_PLUGINDIR", TESTDATADIR_SRC, TRUE);
g_setenv ("FWUPD_SYSCONFDIR", TESTDATADIR_SRC, TRUE);