mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-17 19:38:22 +00:00
Force the device locker to ->close() an aborted ->open()
Fixes https://github.com/fwupd/fwupd/issues/3187
This commit is contained in:
parent
ddc40ab595
commit
54d9de9290
@ -202,8 +202,14 @@ fu_device_locker_new_full (gpointer device,
|
|||||||
self->close_func = close_func;
|
self->close_func = close_func;
|
||||||
|
|
||||||
/* open device */
|
/* open device */
|
||||||
if (!self->open_func (device, error))
|
if (!self->open_func (device, error)) {
|
||||||
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
if (!self->close_func (device, &error_local)) {
|
||||||
|
g_debug ("ignoring close error on aborted open: %s",
|
||||||
|
error_local->message);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
self->device_open = TRUE;
|
self->device_open = TRUE;
|
||||||
|
@ -3337,6 +3337,13 @@ fu_device_open_cb (FuDevice *self, gpointer user_data, GError **error)
|
|||||||
* It is expected that plugins issue the same number of fu_device_open() and
|
* It is expected that plugins issue the same number of fu_device_open() and
|
||||||
* fu_device_close() methods when using a specific @self.
|
* fu_device_close() methods when using a specific @self.
|
||||||
*
|
*
|
||||||
|
* If the `->probe()`, `->open()` and `->setup()` actions all complete
|
||||||
|
* successfully the internal device flag %FU_DEVICE_INTERNAL_FLAG_IS_OPEN will
|
||||||
|
* be set.
|
||||||
|
*
|
||||||
|
* NOTE: It is important to still call fu_device_close() even if this function
|
||||||
|
* fails as the device may still be partially initialized.
|
||||||
|
*
|
||||||
* Returns: %TRUE for success
|
* Returns: %TRUE for success
|
||||||
*
|
*
|
||||||
* Since: 1.1.2
|
* Since: 1.1.2
|
||||||
@ -3386,6 +3393,7 @@ fu_device_open (FuDevice *self, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
|
fu_device_add_internal_flag (self, FU_DEVICE_INTERNAL_FLAG_IS_OPEN);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3405,6 +3413,9 @@ fu_device_open (FuDevice *self, GError **error)
|
|||||||
* An error is returned if this method is called without having used the
|
* An error is returned if this method is called without having used the
|
||||||
* fu_device_open() method beforehand.
|
* fu_device_open() method beforehand.
|
||||||
*
|
*
|
||||||
|
* If the close action completed successfully the internal device flag
|
||||||
|
* %FU_DEVICE_INTERNAL_FLAG_IS_OPEN will be cleared.
|
||||||
|
*
|
||||||
* Returns: %TRUE for success
|
* Returns: %TRUE for success
|
||||||
*
|
*
|
||||||
* Since: 1.1.2
|
* Since: 1.1.2
|
||||||
@ -3436,6 +3447,7 @@ fu_device_close (FuDevice *self, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
|
fu_device_remove_internal_flag (self, FU_DEVICE_INTERNAL_FLAG_IS_OPEN);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +224,7 @@ FuDevice *fu_device_new (void);
|
|||||||
* @FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN: Retry the device open up to 5 times if it fails
|
* @FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN: Retry the device open up to 5 times if it fails
|
||||||
* @FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID: Match GUIDs on device replug where the physical and logical IDs will be different
|
* @FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID: Match GUIDs on device replug where the physical and logical IDs will be different
|
||||||
* @FU_DEVICE_INTERNAL_FLAG_INHERIT_ACTIVATION: Inherit activation status from the history database on startup
|
* @FU_DEVICE_INTERNAL_FLAG_INHERIT_ACTIVATION: Inherit activation status from the history database on startup
|
||||||
|
* @FU_DEVICE_INTERNAL_FLAG_IS_OPEN: The device opened successfully and ready to use
|
||||||
*
|
*
|
||||||
* The device internal flags.
|
* The device internal flags.
|
||||||
**/
|
**/
|
||||||
@ -239,6 +240,7 @@ typedef enum {
|
|||||||
FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN = (1llu << 7), /* Since: 1.5.5 */
|
FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN = (1llu << 7), /* Since: 1.5.5 */
|
||||||
FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID = (1llu << 8), /* Since: 1.5.8 */
|
FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID = (1llu << 8), /* Since: 1.5.8 */
|
||||||
FU_DEVICE_INTERNAL_FLAG_INHERIT_ACTIVATION = (1llu << 9), /* Since: 1.5.9 */
|
FU_DEVICE_INTERNAL_FLAG_INHERIT_ACTIVATION = (1llu << 9), /* Since: 1.5.9 */
|
||||||
|
FU_DEVICE_INTERNAL_FLAG_IS_OPEN = (1llu << 10), /* Since: 1.6.1 */
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
FU_DEVICE_INTERNAL_FLAG_UNKNOWN = G_MAXUINT64,
|
FU_DEVICE_INTERNAL_FLAG_UNKNOWN = G_MAXUINT64,
|
||||||
} FuDeviceInternalFlags;
|
} FuDeviceInternalFlags;
|
||||||
|
@ -695,17 +695,19 @@ fu_device_locker_func (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_fail_open_cb (GObject *device, GError **error)
|
_fail_open_cb (FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
|
fu_device_set_metadata_boolean (device, "Test::Open", TRUE);
|
||||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "fail");
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "fail");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_fail_close_cb (GObject *device, GError **error)
|
_fail_close_cb (FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
g_assert_not_reached ();
|
fu_device_set_metadata_boolean (device, "Test::Close", TRUE);
|
||||||
return TRUE;
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_BUSY, "busy");
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -713,10 +715,16 @@ fu_device_locker_fail_func (void)
|
|||||||
{
|
{
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(GObject) device = g_object_new (G_TYPE_OBJECT, NULL);
|
g_autoptr(FuDevice) device = fu_device_new ();
|
||||||
locker = fu_device_locker_new_full (device, _fail_open_cb, _fail_close_cb, &error);
|
locker = fu_device_locker_new_full (device,
|
||||||
|
(FuDeviceLockerFunc) _fail_open_cb,
|
||||||
|
(FuDeviceLockerFunc) _fail_close_cb,
|
||||||
|
&error);
|
||||||
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
|
||||||
g_assert_null (locker);
|
g_assert_null (locker);
|
||||||
|
g_assert_true (fu_device_get_metadata_boolean (device, "Test::Open"));
|
||||||
|
g_assert_true (fu_device_get_metadata_boolean (device, "Test::Close"));
|
||||||
|
g_assert_false (fu_device_has_internal_flag (device, FU_DEVICE_INTERNAL_FLAG_IS_OPEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user