Skip to content

Commit

Permalink
smd: fix priority handling when marking boot successful
Browse files Browse the repository at this point in the history
When marking a boot in the current slot as successful, make
sure that the priorty level of the other slot remains below
that of the current slot.  Turns out that when the current
slot is 1, and the priority of slot 0 gets to 13, the bootloader
resets slot 0's priority to 15, and since the two slots have
the same priority on the next reboot, we'll switch back to slot 0
again, which is not the desired behavior.

So make sure that we force the other slot's priority to one
less than the current slot's priority, to remain in the current
slot on the next reboot.

Signed-off-by: Matt Madison <[email protected]>
  • Loading branch information
madisongh committed Mar 12, 2021
1 parent 4f5b163 commit fe21044
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions smd.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ smd_init (gpt_context_t *boot_gpt, int bootfd)
} /* smd_init */

/*
* smd_init
* smd_new
*
* Initialize a new, clear SMD context
* for redundancy at the specified level.
Expand Down Expand Up @@ -346,15 +346,16 @@ smd_get_current_slot (void)
*
* Marks a boot slot as successful. If the slot is
* also the current slot, it will be marked as active
* as well (i.e., priority set to 15).
* as well (i.e., priority set to 15), and we ensure
* that the alternate slot has a lower priority.
*
* Returns: 0 on success, -1 on failure
*/
int
smd_slot_mark_successful (smd_context_t *ctx, unsigned int which)
{
int curslot;
struct slot_info_s *s;
struct slot_info_s *s, *other;

if (which >= ctx->smd_ods.maxslots) {
errno = EINVAL;
Expand All @@ -366,12 +367,17 @@ smd_slot_mark_successful (smd_context_t *ctx, unsigned int which)
return -1;

s = &ctx->smd_ods.slot_info[which];
other = &ctx->smd_ods.slot_info[1-which];
ctx->needs_update = (s->successful != 1 || s->retry_count != 7 ||
((unsigned int) curslot == which && s->priority != 15));
((unsigned int) curslot == which &&
(s->priority != 15 || other->priority >= s->priority)));
s->successful = 1;
s->retry_count = 7;
if ((unsigned int) curslot == which)
if ((unsigned int) curslot == which) {
s->priority = 15;
if (other->priority >= s->priority)
other->priority = s->priority - 1;
}

return 0;

Expand Down

0 comments on commit fe21044

Please sign in to comment.