@@ -366,7 +366,7 @@ static int install_from_file(char *fname, int check)
/*
* Set "recovery_status" as begin of the transaction"
*/
- bootloader_env_set("recovery_status", "in_progress");
+ bootloader_env_set(BOOTVAR_TRANSACTION, "in_progress");
ret = install_images(&swcfg, fdsw, 1);
@@ -379,7 +379,7 @@ static int install_from_file(char *fname, int check)
return EXIT_FAILURE;
}
- bootloader_env_unset("recovery_status");
+ bootloader_env_unset(BOOTVAR_TRANSACTION);
fprintf(stdout, "Software updated successfully\n");
fprintf(stdout, "Please reboot the device to start the new software\n");
@@ -955,7 +955,7 @@ int main(int argc, char **argv)
result = install_from_file(fname, opt_c);
switch (result) {
case EXIT_FAILURE:
- bootloader_env_set("recovery_status", "failed");
+ bootloader_env_set(BOOTVAR_TRANSACTION, "failed");
break;
case EXIT_SUCCESS:
notify(SUCCESS, 0, INFOLEVEL, NULL);
@@ -125,6 +125,7 @@ static int extract_files(int fd, struct swupdate_cfg *software)
struct img_type *img, *part;
char output_file[MAX_IMAGE_FNAME];
const char* TMPDIR = get_tmpdir();
+ bool installed_directly = false;
/* preset the info about the install parts */
@@ -229,6 +230,17 @@ static int extract_files(int fd, struct swupdate_cfg *software)
break;
case INSTALL_FROM_STREAM:
TRACE("Installing STREAM %s, %lld bytes", img->fname, img->size);
+
+ /*
+ * If this is the first image to be directly installed, set transaction flag
+ * to on to be checked if a power-off happens. Be sure to set the flag
+ * just once
+ */
+ if (!installed_directly) {
+ bootloader_env_set(BOOTVAR_TRANSACTION, "in_progress");
+ installed_directly = true;
+ }
+
/*
* If we are streaming data to store in a UBI volume, make
* sure that the UBI partitions are adjusted beforehand
@@ -379,12 +391,12 @@ void *network_initializer(void *data)
* must be successful. Set we have
* initiated an update
*/
- bootloader_env_set("recovery_status", "in_progress");
+ bootloader_env_set(BOOTVAR_TRANSACTION, "in_progress");
notify(RUN, RECOVERY_NO_ERROR, INFOLEVEL, "Installation in progress");
ret = install_images(software, 0, 0);
if (ret != 0) {
- bootloader_env_set("recovery_status", "failed");
+ bootloader_env_set(BOOTVAR_TRANSACTION, "failed");
notify(FAILURE, RECOVERY_ERROR, ERRORLEVEL, "Installation failed !");
inst.last_install = FAILURE;
@@ -393,7 +405,7 @@ void *network_initializer(void *data)
* Clear the recovery variable to indicate to bootloader
* that it is not required to start recovery again
*/
- bootloader_env_unset("recovery_status");
+ bootloader_env_unset(BOOTVAR_TRANSACTION);
notify(SUCCESS, RECOVERY_NO_ERROR, INFOLEVEL, "SWUPDATE successful !");
inst.last_install = SUCCESS;
}
@@ -14,6 +14,8 @@
#include "mongoose_interface.h"
#include "swupdate_dict.h"
+#define BOOTVAR_TRANSACTION "recovery_status"
+
/*
* swupdate uses SHA256 hashes
*/
The "recovery_status" flag (bootloader variable) is set when SWUpdate starts to install images on the target. This works if streaming mode is not set. When it is set, some images are already installed before SWUpdate sets the flag. In case of power-on when a single image is used or in case pf rescue system, the bootloader cannot recognize that an update was interrupted and tries to start the production software, that can be corrupted. The rescue is started again just as fallback after failing to start the production software, but there are cases where this does not work. Check if an image is streamed to the target and sets the "recoverz?status" flag before writing to the storage. Signed-off-by: Stefano Babic <sbabic@denx.de> --- core/swupdate.c | 6 +++--- corelib/stream_interface.c | 18 +++++++++++++++--- include/swupdate.h | 2 ++ 3 files changed, 20 insertions(+), 6 deletions(-)