mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-17 19:38:22 +00:00
Allow devices to save the old firmware to disk for recovery
This would also help, for example, to go back to the nonfree firmware when the alternate firmware did not work as well as hoped. It would also allow flashing the firmware using an SPI programmer if everything went very wrong indeed.
This commit is contained in:
parent
460c4b75fe
commit
1a61258239
@ -199,6 +199,8 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag)
|
|||||||
return "skips-restart";
|
return "skips-restart";
|
||||||
if (device_flag == FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES)
|
if (device_flag == FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES)
|
||||||
return "has-multiple-branches";
|
return "has-multiple-branches";
|
||||||
|
if (device_flag == FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL)
|
||||||
|
return "backup-before-install";
|
||||||
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
|
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -299,6 +301,8 @@ fwupd_device_flag_from_string (const gchar *device_flag)
|
|||||||
return FWUPD_DEVICE_FLAG_SKIPS_RESTART;
|
return FWUPD_DEVICE_FLAG_SKIPS_RESTART;
|
||||||
if (g_strcmp0 (device_flag, "has-multiple-branches") == 0)
|
if (g_strcmp0 (device_flag, "has-multiple-branches") == 0)
|
||||||
return FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES;
|
return FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES;
|
||||||
|
if (g_strcmp0 (device_flag, "backup-before-install") == 0)
|
||||||
|
return FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL;
|
||||||
return FWUPD_DEVICE_FLAG_UNKNOWN;
|
return FWUPD_DEVICE_FLAG_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ typedef enum {
|
|||||||
* @FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN: Device is updatable but should not be called by the client
|
* @FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN: Device is updatable but should not be called by the client
|
||||||
* @FWUPD_DEVICE_FLAG_SKIPS_RESTART: Device relies upon activation or power cycle to load firmware
|
* @FWUPD_DEVICE_FLAG_SKIPS_RESTART: Device relies upon activation or power cycle to load firmware
|
||||||
* @FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES: Device supports switching to a different stream of firmware
|
* @FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES: Device supports switching to a different stream of firmware
|
||||||
|
* @FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL: Device firmware should be saved before installing firmware
|
||||||
*
|
*
|
||||||
* The device flags.
|
* The device flags.
|
||||||
**/
|
**/
|
||||||
@ -171,6 +172,7 @@ typedef enum {
|
|||||||
#define FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN (1llu << 37) /* Since: 1.4.1 */
|
#define FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN (1llu << 37) /* Since: 1.4.1 */
|
||||||
#define FWUPD_DEVICE_FLAG_SKIPS_RESTART (1llu << 38) /* Since: 1.5.0 */
|
#define FWUPD_DEVICE_FLAG_SKIPS_RESTART (1llu << 38) /* Since: 1.5.0 */
|
||||||
#define FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES (1llu << 39) /* Since: 1.5.0 */
|
#define FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES (1llu << 39) /* Since: 1.5.0 */
|
||||||
|
#define FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL (1llu << 40) /* Since: 1.5.0 */
|
||||||
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
|
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
|
||||||
typedef guint64 FwupdDeviceFlags;
|
typedef guint64 FwupdDeviceFlags;
|
||||||
|
|
||||||
|
@ -1052,6 +1052,32 @@ fu_plugin_device_write_firmware (FuPlugin *self, FuDevice *device,
|
|||||||
locker = fu_device_locker_new (device, error);
|
locker = fu_device_locker_new (device, error);
|
||||||
if (locker == NULL)
|
if (locker == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* back the old firmware up to /var/lib/fwupd */
|
||||||
|
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL)) {
|
||||||
|
g_autoptr(GBytes) fw_old = NULL;
|
||||||
|
g_autofree gchar *path = NULL;
|
||||||
|
g_autofree gchar *fn = NULL;
|
||||||
|
g_autofree gchar *localstatedir = NULL;
|
||||||
|
|
||||||
|
fw_old = fu_device_dump_firmware (device, error);
|
||||||
|
if (fw_old == NULL) {
|
||||||
|
g_prefix_error (error, "failed to backup old firmware: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
localstatedir = fu_common_get_path (FU_PATH_KIND_LOCALSTATEDIR_PKG);
|
||||||
|
fn = g_strdup_printf ("%s.bin", fu_device_get_version (device));
|
||||||
|
path = g_build_filename (localstatedir,
|
||||||
|
"backup",
|
||||||
|
fu_device_get_id (device),
|
||||||
|
fu_device_get_serial (device) != NULL ?
|
||||||
|
fu_device_get_serial (device) :
|
||||||
|
"default",
|
||||||
|
fn, NULL);
|
||||||
|
if (!fu_common_set_contents_bytes (path, fw_old, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return fu_device_write_firmware (device, fw, flags, error);
|
return fu_device_write_firmware (device, fw, flags, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,6 +1077,10 @@ fu_util_device_flag_to_string (guint64 device_flag)
|
|||||||
/* TRANSLATORS: there is more than one supplier of the firmware */
|
/* TRANSLATORS: there is more than one supplier of the firmware */
|
||||||
return _("Device supports switching to a different branch of firmware");
|
return _("Device supports switching to a different branch of firmware");
|
||||||
}
|
}
|
||||||
|
if (device_flag == FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL) {
|
||||||
|
/* TRANSLATORS: save the old firmware to disk before installing the new one */
|
||||||
|
return _("Device will backup firmware before installing");
|
||||||
|
}
|
||||||
if (device_flag == FWUPD_DEVICE_FLAG_MD_SET_NAME) {
|
if (device_flag == FWUPD_DEVICE_FLAG_MD_SET_NAME) {
|
||||||
/* skip */
|
/* skip */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user