mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 08:43:43 +00:00
Allow quirking devices that always require a version check
These are devices that we have to be careful with the version numbers, for instance only updating from versions that have already had data migration completed. The new flag can be set in quirk files or on the objects directly.
This commit is contained in:
parent
603e4f6956
commit
1eb7c7443e
@ -179,6 +179,8 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag)
|
||||
return "self-recovery";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE)
|
||||
return "usable-during-update";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED)
|
||||
return "version-check-required";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
|
||||
return "unknown";
|
||||
return NULL;
|
||||
@ -259,6 +261,8 @@ fwupd_device_flag_from_string (const gchar *device_flag)
|
||||
return FWUPD_DEVICE_FLAG_SELF_RECOVERY;
|
||||
if (g_strcmp0 (device_flag, "usable-during-update") == 0)
|
||||
return FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE;
|
||||
if (g_strcmp0 (device_flag, "version-check-required") == 0)
|
||||
return FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED;
|
||||
return FWUPD_DEVICE_FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ typedef enum {
|
||||
* @FWUPD_DEVICE_FLAG_DUAL_IMAGE: Device update architecture uses A/B partitions for updates
|
||||
* @FWUPD_DEVICE_FLAG_SELF_RECOVERY: In flashing mode device will only accept intended payloads
|
||||
* @FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE: Device remains usable while fwupd flashes or schedules the update
|
||||
* @FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED: All firmware updates for this device require a firmware version check
|
||||
*
|
||||
* The device flags.
|
||||
**/
|
||||
@ -131,6 +132,7 @@ typedef enum {
|
||||
#define FWUPD_DEVICE_FLAG_DUAL_IMAGE (1u << 27) /* Since: 1.3.3 */
|
||||
#define FWUPD_DEVICE_FLAG_SELF_RECOVERY (1u << 28) /* Since: 1.3.3 */
|
||||
#define FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE (1u << 29) /* Since: 1.3.3 */
|
||||
#define FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED (1u << 30) /* Since: 1.3.7 */
|
||||
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
|
||||
typedef guint64 FwupdDeviceFlags;
|
||||
|
||||
|
@ -152,6 +152,35 @@ fu_install_task_check_verfmt (FuInstallTask *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_install_task_check_requirements_version_check (FuInstallTask *self, GError **error)
|
||||
{
|
||||
g_autoptr(GError) error_local = NULL;
|
||||
g_autoptr(GPtrArray) reqs = NULL;
|
||||
|
||||
reqs = xb_node_query (fu_install_task_get_component (self),
|
||||
"requires/*", 0, &error_local);
|
||||
if (reqs == NULL) {
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
error_local->message);
|
||||
return FALSE;
|
||||
}
|
||||
for (guint i = 0; i < reqs->len; i++) {
|
||||
XbNode *req = g_ptr_array_index (reqs, i);
|
||||
if (g_strcmp0 (xb_node_get_element (req), "firmware") == 0 &&
|
||||
xb_node_get_text (req) == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
g_set_error_literal (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"no firmware requirement");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_install_task_check_requirements:
|
||||
* @self: A #FuInstallTask
|
||||
@ -211,6 +240,14 @@ fu_install_task_check_requirements (FuInstallTask *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* device requries a version check */
|
||||
if (fu_device_has_flag (self->device, FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED)) {
|
||||
if (!fu_install_task_check_requirements_version_check (self, error)) {
|
||||
g_prefix_error (error, "device requires firmware with a version check: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* does the protocol match */
|
||||
protocol = xb_node_query_text (self->component,
|
||||
"custom/value[@key='LVFS::UpdateProtocol']",
|
||||
|
@ -225,6 +225,53 @@ fu_engine_requirements_missing_func (gconstpointer user_data)
|
||||
g_assert (!ret);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_requirements_version_require_func (gconstpointer user_data)
|
||||
{
|
||||
gboolean ret;
|
||||
g_autoptr(FuDevice) device = fu_device_new ();
|
||||
g_autoptr(FuEngine) engine = fu_engine_new (FU_APP_FLAGS_NONE);
|
||||
g_autoptr(FuInstallTask) task = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(XbNode) component = NULL;
|
||||
g_autoptr(XbSilo) silo = NULL;
|
||||
const gchar *xml =
|
||||
"<component>"
|
||||
" <provides>"
|
||||
" <firmware type=\"flashed\">12345678-1234-1234-1234-123456789012</firmware>"
|
||||
" </provides>"
|
||||
" <releases>"
|
||||
" <release version=\"1.2.4\">"
|
||||
" </release>"
|
||||
" </releases>"
|
||||
"</component>";
|
||||
|
||||
/* set up a dummy device */
|
||||
fu_device_set_version (device, "1.2.3", FWUPD_VERSION_FORMAT_TRIPLET);
|
||||
fu_device_set_version_bootloader (device, "4.5.6");
|
||||
fu_device_set_vendor_id (device, "FFFF");
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED);
|
||||
fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012");
|
||||
|
||||
/* make the component require one thing */
|
||||
silo = xb_silo_new_from_xml (xml, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (silo);
|
||||
component = xb_silo_query_first (silo, "component", &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (component);
|
||||
|
||||
/* check this fails */
|
||||
task = fu_install_task_new (device, component);
|
||||
ret = fu_engine_check_requirements (engine, task,
|
||||
FWUPD_INSTALL_FLAG_NONE,
|
||||
&error);
|
||||
g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED);
|
||||
g_assert (g_str_has_prefix (error->message, "device requires firmware with a version check"));
|
||||
g_assert (!ret);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_requirements_unsupported_func (gconstpointer user_data)
|
||||
{
|
||||
@ -439,6 +486,7 @@ fu_engine_requirements_device_func (gconstpointer user_data)
|
||||
fu_device_set_version_bootloader (device, "4.5.6");
|
||||
fu_device_set_vendor_id (device, "FFFF");
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED);
|
||||
fu_device_add_guid (device, "12345678-1234-1234-1234-123456789012");
|
||||
|
||||
/* make the component require three things */
|
||||
@ -2902,6 +2950,8 @@ main (int argc, char **argv)
|
||||
fu_engine_requirements_func);
|
||||
g_test_add_data_func ("/fwupd/engine{requirements-missing}", self,
|
||||
fu_engine_requirements_missing_func);
|
||||
g_test_add_data_func ("/fwupd/engine{requirements-version-require}", self,
|
||||
fu_engine_requirements_version_require_func);
|
||||
g_test_add_data_func ("/fwupd/engine{requirements-parent-device}", self,
|
||||
fu_engine_requirements_parent_device_func);
|
||||
g_test_add_data_func ("/fwupd/engine{requirements-not-child}", self,
|
||||
|
@ -1066,6 +1066,10 @@ fu_util_device_flag_to_string (guint64 device_flag)
|
||||
/* TRANSLATORS: Device remains usable during update */
|
||||
return _("Device is usable for the duration of the update");
|
||||
}
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_VERSION_CHECK_REQUIRED) {
|
||||
/* TRANSLATORS: a version check is required for all firmware */
|
||||
return _("Device firmware is required to have a version check");
|
||||
}
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN) {
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user