Skip to content

Commit

Permalink
src/install: ensure invalidating slot status before updating
Browse files Browse the repository at this point in the history
For the global slot status, RAUC kept the status information untouched
until a slot was actually fully written.
In most cases this is not a problem, except for when RAUC crashes
during a slot update and slot skipping (install-same=true) is enabled.
Then the respective slot might be broken but the status information
makes it look in good shape. Thus RAUC will skip it if the
to-be-installed checksum is equal to the one noted in the status file.
For this case, we would end up in an unusable installation.

Fix this by explicitly marking the status 'pending' and clearing the
checksum. This then also compatible with older RAUC installation (e.g.
in case of fallbacks) that can handle missing checksum an will thus not
erroneously assume a valid slot.

For the per-slot case this is not an issue since the status file is
stored on the slot and will thus be removed when updating the slot with
new content.

Signed-off-by: Enrico Joerns <ejo@pengutronix.de>
  • Loading branch information
ejoerns committed Aug 2, 2023
1 parent 7c8d542 commit 2aef951
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion src/install.c
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ static gboolean handle_slot_install_plan(const RaucManifest *manifest, const RIm
load_slot_status(plan->target_slot);
slot_state = plan->target_slot->status;

/* In case we failed unmounting while reading status
/* In case we failed unmounting while reading per-slot status
* file, abort here */
if (plan->target_slot->mount_point) {
g_set_error(error, R_INSTALL_ERROR, R_INSTALL_ERROR_MOUNTED,
Expand All @@ -991,6 +991,22 @@ static gboolean handle_slot_install_plan(const RaucManifest *manifest, const RIm
return FALSE;
}

/* For global slot status: Clear checksum info and make status
* 'pending' to prevent the slot status from looking valid later in
* case we crash while installing. */
if (g_strcmp0(r_context()->config->statusfile_path, "per-slot") != 0) {
g_clear_pointer(&slot_state->status, g_free);
slot_state->status = g_strdup("pending");
g_clear_pointer(&slot_state->checksum.digest, g_free);
slot_state->checksum.size = 0;

if (!save_slot_status(plan->target_slot, &ierror)) {
g_propagate_prefixed_error(error, ierror, "Error while writing status file: ");
r_context_end_step("check_slot", FALSE);
return FALSE;
}
}

/* if explicitly enabled, skip update of up-to-date slots */
if (!plan->target_slot->install_same && g_strcmp0(plan->image->checksum.digest, slot_state->checksum.digest) == 0) {
install_args_update(args, "Skipping update for correct image %s", plan->image->filename);
Expand Down

0 comments on commit 2aef951

Please sign in to comment.