diff --git a/bootctrl_impl.cpp b/bootctrl_impl.cpp index 9fdbd6c..7c1a082 100644 --- a/bootctrl_impl.cpp +++ b/bootctrl_impl.cpp @@ -602,13 +602,16 @@ int set_active_boot_slot(unsigned slot) uint32_t i; int rc = -1; map >::iterator map_iter; + bool ismmc; if (boot_control_check_slot_sanity(slot)) { fprintf(stderr, "%s: Bad arguments\n", __func__); goto error; } - if (ufs_bsg_dev_open() < 0) { + ismmc = gpt_utils_is_partition_backed_by_emmc(PTN_XBL AB_SLOT_A_SUFFIX); + + if (!ismmc && ufs_bsg_dev_open() < 0) { goto error; } @@ -618,7 +621,7 @@ int set_active_boot_slot(unsigned slot) //in the list. for (i = 0; i < ARRAY_SIZE(ptn_list); i++) { //XBL is handled differrently for ufs devices so ignore it - if (!strncmp(ptn_list[i], PTN_XBL, strlen(PTN_XBL))) + if (!ismmc && !strncmp(ptn_list[i], PTN_XBL, strlen(PTN_XBL))) continue; //The partition list will be the list of _a partitions string cur_ptn = ptn_list[i]; @@ -650,6 +653,10 @@ int set_active_boot_slot(unsigned slot) } } + // EMMC doesn't need attributes to be set. + if (ismmc) + return 0; + if (!strncmp(slot_suffix_arr[slot], AB_SLOT_A_SUFFIX, strlen(AB_SLOT_A_SUFFIX))) { //Set xbl_a as the boot lun diff --git a/gpt-utils.cpp b/gpt-utils.cpp index bb170be..b913d42 100644 --- a/gpt-utils.cpp +++ b/gpt-utils.cpp @@ -317,6 +317,7 @@ static int get_dev_path_from_partition_name(const char *partname, char *buf, { struct stat st; char path[PATH_MAX] = { 0 }; + int i; (void)st; @@ -334,7 +335,14 @@ static int get_dev_path_from_partition_name(const char *partname, char *buf, if (!buf) { return -1; } else { - buf[PATH_TRUNCATE_LOC] = '\0'; + for (i = strlen(buf); i > 0; i--) + if (!isdigit(buf[i - 1])) + break; + + if (i >= 2 && buf[i - 1] == 'p' && isdigit(buf[i - 2])) + i--; + + buf[i] = 0; } return 0; } @@ -773,3 +781,18 @@ error: close(fd); return -1; } + +//Determine whether to handle the given partition as eMMC or UFS, using the +//name of the backing device. +// +//Note: In undefined cases (i.e. /dev/mmcblk1 and unresolvable), this function +//will tend to prefer UFS behavior. If it incorrectly reports this, then the +//program should exit (e.g. by failing) before making any changes. +bool gpt_utils_is_partition_backed_by_emmc(const char *part) { + char devpath[PATH_MAX] = { '\0' }; + + if (get_dev_path_from_partition_name(part, devpath, sizeof(devpath))) + return false; + + return !strcmp(devpath, EMMC_DEVICE); +} diff --git a/gpt-utils.h b/gpt-utils.h index 4f7596f..319f3fe 100644 --- a/gpt-utils.h +++ b/gpt-utils.h @@ -84,6 +84,8 @@ extern "C" { "product" #define BOOT_DEV_DIR "/dev/disk/by-partlabel" +#define EMMC_DEVICE "/dev/mmcblk0" + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) enum gpt_instance { PRIMARY_GPT = 0, SECONDARY_GPT }; @@ -163,6 +165,8 @@ int gpt_utils_set_xbl_boot_partition(enum boot_chain chain); int gpt_utils_get_partition_map( std::vector &partition_list, std::map > &partition_map); + +bool gpt_utils_is_partition_backed_by_emmc(const char *part); #ifdef __cplusplus } #endif