bootctl: add after_slot parameter to insert_into_order()
This adds an after_slot parameter that, when not set to UINT16_MAX, requests that the new slot be placed immediately after the given slot in BootOrder. When after_slot is set and the new slot already exists in BootOrder, it will leave its position alone. This is so that if a user reorders it, we don't stomp on their changes.
This commit is contained in:
@@ -1233,7 +1233,7 @@ static int find_slot(sd_id128_t uuid, const char *path, uint16_t *id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int insert_into_order(InstallContext *c, uint16_t slot) {
|
||||
static int insert_into_order(InstallContext *c, uint16_t slot, uint16_t after_slot) {
|
||||
_cleanup_free_ uint16_t *order = NULL;
|
||||
uint16_t *t;
|
||||
int n;
|
||||
@@ -1255,7 +1255,8 @@ static int insert_into_order(InstallContext *c, uint16_t slot) {
|
||||
continue;
|
||||
|
||||
/* we do not require to be the first one, all is fine */
|
||||
if (c->operation != INSTALL_NEW)
|
||||
/* if after_slot is set, leave existing position alone to preserve user reordering. */
|
||||
if (i == 0 || c->operation != INSTALL_NEW || after_slot != UINT16_MAX)
|
||||
return 0;
|
||||
|
||||
/* move us to the first slot */
|
||||
@@ -1264,6 +1265,27 @@ static int insert_into_order(InstallContext *c, uint16_t slot) {
|
||||
return efi_set_boot_order(order, n);
|
||||
}
|
||||
|
||||
/* slot is not yet in the order, so insert after a specific slot if requested */
|
||||
if (after_slot != UINT16_MAX) {
|
||||
t = reallocarray(order, n + 1, sizeof(uint16_t));
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
order = t;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (order[i] != after_slot)
|
||||
continue;
|
||||
|
||||
memmove(order + i + 2, order + i + 1, (n - i - 1) * sizeof(uint16_t));
|
||||
order[i + 1] = slot;
|
||||
return efi_set_boot_order(order, n + 1);
|
||||
}
|
||||
|
||||
log_warning("Boot entry %04" PRIx16 " not found in BootOrder, appending new entry at the end.", after_slot);
|
||||
order[n] = slot;
|
||||
return efi_set_boot_order(order, n + 1);
|
||||
}
|
||||
|
||||
/* extend array */
|
||||
t = reallocarray(order, n + 1, sizeof(uint16_t));
|
||||
if (!t)
|
||||
@@ -1422,7 +1444,7 @@ static int install_boot_option(
|
||||
description);
|
||||
}
|
||||
|
||||
r = insert_into_order(c, slot);
|
||||
r = insert_into_order(c, slot, /* after_slot= */ UINT16_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user