From d1db65e76df364c47be6c4ca2331c3d839468e31 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Wed, 28 Aug 2024 15:34:11 +0200 Subject: [PATCH] bootctrl: fall back to active slot if current slot not found in cmdline While postmarketOS makes use of a kernel cmdline argument, this isn't the case for all distros. Furthermore, this argument isn't present in those added automatically by the Android bootloader. In order to still be able to use `qbootctl` on other distros, this change ensures we use the currently active slot as the current slot when the cmdline argument is missing. This ensure `qbootctl -m` picks up the correct slot more often than not, instead of always defaulting to `_a`. --- bootctrl_impl.c | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/bootctrl_impl.c b/bootctrl_impl.c index 05876f6..ef4157d 100644 --- a/bootctrl_impl.c +++ b/bootctrl_impl.c @@ -331,38 +331,6 @@ int get_boot_attr(struct gpt_disk *disk, unsigned slot, enum part_attr_type attr return get_partition_attribute(disk, bootPartition, attr); } -static unsigned int get_current_slot_from_kernel_cmdline() -{ - uint32_t num_slots = 0; - char bootSlotProp[MAX_CMDLINE_SIZE] = { '\0' }; - unsigned i = 0; - num_slots = get_number_slots(); - if (num_slots <= 1) { - // Slot 0 is the only slot around. - return 0; - } - - get_kernel_cmdline_arg(BOOT_SLOT_PROP, bootSlotProp, "_a"); - if (!strncmp(bootSlotProp, "N/A\n", strlen("N/A"))) { - fprintf(stderr, "%s: Unable to read boot slot property\n", __func__); - return 0; - } - - // Iterate through a list of partitons named as boot+suffix - // and see which one is currently active. - for (i = 0; slot_suffix_arr[i] != NULL; i++) { - if (!strncmp(bootSlotProp, slot_suffix_arr[i], strlen(slot_suffix_arr[i]))) { - // printf("%s current_slot = %d\n", __func__, i); - return i; - } - } - - // The HAL spec requires that we return a number between - // 0 to num_slots - 1. Since something went wrong here we - // are just going to return the default slot. - return 0; -} - int is_slot_bootable(unsigned slot) { int attr = 0; @@ -560,6 +528,38 @@ unsigned get_active_boot_slot() return 0; } +static unsigned int get_current_slot_from_kernel_cmdline() +{ + uint32_t num_slots = 0; + char bootSlotProp[MAX_CMDLINE_SIZE] = { '\0' }; + unsigned i = 0; + num_slots = get_number_slots(); + if (num_slots <= 1) { + // Slot 0 is the only slot around. + return 0; + } + + get_kernel_cmdline_arg(BOOT_SLOT_PROP, bootSlotProp, "N/A"); + if (!strncmp(bootSlotProp, "N/A\n", strlen("N/A"))) { + fprintf(stderr, "%s: Unable to read boot slot property\n", __func__); + return get_active_boot_slot(); + } + + // Iterate through a list of partitons named as boot+suffix + // and see which one is currently active. + for (i = 0; slot_suffix_arr[i] != NULL; i++) { + if (!strncmp(bootSlotProp, slot_suffix_arr[i], strlen(slot_suffix_arr[i]))) { + // printf("%s current_slot = %d\n", __func__, i); + return i; + } + } + + // The HAL spec requires that we return a number between + // 0 to num_slots - 1. Since something went wrong here we + // are just going to return the default slot. + return 0; +} + int set_active_boot_slot(unsigned slot, bool ignore_missing_bsg) { enum boot_chain chain = (enum boot_chain)slot;