add a flag to continue when ufs bsg device is missing

For some usecases it is desired to still update the GPT headers even if
the UFS BSG device is missing. Add a new flag which implements this
behaviour.

It isn't made the default because on some platforms this could result in
an unbootable device, there it's preferable to defer to the user by just
bailing out if the UFS BSG device is unavailable.

Signed-off-by: Caleb Connolly <caleb@connolly.tech>
main 0.2.0
Caleb Connolly 8 months ago
parent 3390f642e3
commit b8d2248914
No known key found for this signature in database
GPG Key ID: 7930459FB9303217
  1. 1
      README.md
  2. 2
      bootctrl.h
  3. 10
      bootctrl_impl.c
  4. 6
      gpt-utils.c
  5. 24
      qbootctl.c
  6. 7
      ufs-bsg.c

@ -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

@ -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

@ -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:

@ -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

@ -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();

@ -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;
}

Loading…
Cancel
Save