diff --git a/README.md b/README.md index e20b9fa..36fdd45 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ qbootctl [-c|-m|-s|-u|-b|-n|-x] [SLOT] -s SLOT set to active slot to SLOT -m [SLOT] mark a boot as successful (default: current) -u [SLOT] mark SLOT as unbootable (default: current) + -i still write the GPT headers even if the UFS bLun can't be changed (default: false) ``` ## Debugging diff --git a/bootctrl.h b/bootctrl.h index 1489c5f..beb9d23 100644 --- a/bootctrl.h +++ b/bootctrl.h @@ -69,7 +69,7 @@ struct boot_control_module { * setSlotAsUnbootable. * Returns 0 on success, -errno on error. */ - int (*setActiveBootSlot)(unsigned slot); + int (*setActiveBootSlot)(unsigned slot, bool ignore_missing_bsg); /* * (*setSlotAsUnbootable)() marks the slot passed in parameter as diff --git a/bootctrl_impl.c b/bootctrl_impl.c index 04d5f59..05876f6 100644 --- a/bootctrl_impl.c +++ b/bootctrl_impl.c @@ -560,7 +560,7 @@ unsigned get_active_boot_slot() return 0; } -int set_active_boot_slot(unsigned slot) +int set_active_boot_slot(unsigned slot, bool ignore_missing_bsg) { enum boot_chain chain = (enum boot_chain)slot; struct gpt_disk disk = { 0 }; @@ -576,7 +576,7 @@ int set_active_boot_slot(unsigned slot) // Do this *before* updating all the slot attributes // to make sure we can - if (!ismmc && ufs_bsg_dev_open() < 0) { + if (!ismmc && !ignore_missing_bsg && ufs_bsg_dev_open() < 0) { return -1; } @@ -599,8 +599,10 @@ int set_active_boot_slot(unsigned slot) rc = gpt_utils_set_xbl_boot_partition(chain); if (rc) { - fprintf(stderr, "%s: Failed to switch xbl boot partition\n", __func__); - goto out; + if (ignore_missing_bsg && rc == -ENODEV) + rc = 0; + else + fprintf(stderr, "%s: Failed to switch xbl boot partition\n", __func__); } out: diff --git a/gpt-utils.c b/gpt-utils.c index 097fede..b0fda61 100644 --- a/gpt-utils.c +++ b/gpt-utils.c @@ -216,7 +216,7 @@ static uint8_t *gpt_pentry_seek(const char *ptn_name, const uint8_t *pentries_st // Defined in ufs-bsg.cpp int32_t set_boot_lun(uint8_t lun_id); - // Swtich betwieen using either the primary or the backup +// Switch between using either the primary or the backup // boot LUN for boot. This is required since UFS boot partitions // cannot have a backup GPT which is what we use for failsafe // updates of the other 'critical' partitions. This function will @@ -238,6 +238,7 @@ int gpt_utils_set_xbl_boot_partition(enum boot_chain chain) struct stat st; uint8_t boot_lun_id = 0; const char *boot_dev = NULL; + int ret = -1; (void)st; (void)boot_dev; @@ -277,11 +278,12 @@ int gpt_utils_set_xbl_boot_partition(enum boot_chain chain) LOGD("%s: setting %s lun as boot lun\n", __func__, boot_dev); if (set_boot_lun(boot_lun_id)) { + ret = -ENODEV; goto error; } return 0; error: - return -1; + return ret; } // Given a parttion name(eg: rpm) get the path to the block device that diff --git a/qbootctl.c b/qbootctl.c index c0769f4..463ff25 100644 --- a/qbootctl.c +++ b/qbootctl.c @@ -74,6 +74,7 @@ fail: int usage() { + // clang-format off fprintf(stderr, "qbootctl: qcom bootctrl HAL port for Linux\n"); fprintf(stderr, "-------------------------------------------\n"); fprintf(stderr, "qbootctl [-c|-m|-s|-u|-b|-n|-x] [SLOT]\n\n"); @@ -81,17 +82,14 @@ int usage() fprintf(stderr, " -h this help text\n"); fprintf(stderr, " -c get the current slot\n"); fprintf(stderr, " -a get the active slot\n"); - fprintf(stderr, - " -b SLOT check if SLOT is marked as bootable\n"); - fprintf(stderr, - " -n SLOT check if SLOT is marked as successful\n"); - fprintf(stderr, - " -x [SLOT] get the slot suffix for SLOT (default: current)\n"); + fprintf(stderr, " -b SLOT check if SLOT is marked as bootable\n"); + fprintf(stderr, " -n SLOT check if SLOT is marked as successful\n"); + fprintf(stderr, " -x [SLOT] get the slot suffix for SLOT (default: current)\n"); fprintf(stderr, " -s SLOT set to active slot to SLOT\n"); - fprintf(stderr, - " -m [SLOT] mark a boot as successful (default: current)\n"); - fprintf(stderr, - " -u [SLOT] mark SLOT as unbootable (default: current)\n"); + fprintf(stderr, " -m [SLOT] mark a boot as successful (default: current)\n"); + fprintf(stderr, " -u [SLOT] mark SLOT as unbootable (default: current)\n"); + fprintf(stderr, " -i still write the GPT headers even if the UFS bLun can't be changed (default: false)\n"); + // clang-format on return 1; } @@ -139,6 +137,7 @@ int main(int argc, char **argv) int optflag; int slot = -1; int rc; + bool ignore_missing_bsg = false; if(geteuid() != 0) { fprintf(stderr, "This program must be run as root!\n"); @@ -185,7 +184,7 @@ int main(int argc, char **argv) printf("%s\n", impl->getSuffix(slot)); return 0; case 's': - rc = impl->setActiveBootSlot(slot); + rc = impl->setActiveBootSlot(slot, ignore_missing_bsg); if (rc < 0) { fprintf(stderr, "SLOT %s: Failed to set active\n", impl->getSuffix(slot)); @@ -210,6 +209,9 @@ int main(int argc, char **argv) } printf("SLOT %s: Set as unbootable\n", impl->getSuffix(slot)); return 0; + case 'i': + ignore_missing_bsg = true; + break; case 'h': default: usage(); diff --git a/ufs-bsg.c b/ufs-bsg.c index 05c8885..22c8da8 100644 --- a/ufs-bsg.c +++ b/ufs-bsg.c @@ -174,13 +174,12 @@ int32_t set_boot_lun(__u8 lun_id) ret = ufs_query_attr(fd_ufs_bsg, boot_lun_id, QUERY_REQ_FUNC_STD_WRITE, QUERY_REQ_OP_WRITE_ATTR, QUERY_ATTR_IDN_BOOT_LU_EN, 0, 0); - if (ret) { + if (ret) fprintf(stderr, "Error requesting ufs attr idn %d via query ioctl (return value: %d, error no: %d)", QUERY_ATTR_IDN_BOOT_LU_EN, ret, errno); - goto out; - } -out: + + ufs_bsg_dev_close(); return ret; }