[Public] Hi Kory Maincent,
> From: Kory Maincent <[email protected]> > Sent: Monday, February 23, 2026 4:04 PM > To: Begari, Padmarao <[email protected]> > Cc: [email protected]; Simek, Michal <[email protected]>; git (AMD- > Xilinx) <[email protected]>; Toomey, John <[email protected]>; Tom Rini > <[email protected]>; Ilias Apalodimas <[email protected]>; Heinrich > Schuchardt <[email protected]>; Quentin Schulz <[email protected]>; > Mikhail Kshevetskiy <[email protected]>; Heiko Schocher > <[email protected]>; Andrew Goodbody <[email protected]>; Paul > Barker <[email protected]>; Rasmus Villemoes <[email protected]> > Subject: Re: [RFC PATCH v2] cmd: part: add dupcheck command to detect > duplicate > PARTUUIDs > > Caution: This message originated from an External Source. Use proper caution > when opening attachments, clicking links, or responding. > > > On Sun, 22 Feb 2026 12:37:39 +0530 > Padmarao Begari <[email protected]> wrote: > > > Add a 'part dupcheck' subcommand that scans all block devices for > > duplicate partition UUIDs. This helps detect situations where the same > > disk image has been flashed to multiple boot devices (e.g., USB stick > > and UFS), which can lead to unpredictable boot behavior when using > > PARTUUID-based root filesystem specifications. It iterates all block > > devices using blk_foreach_probe() and checks partition UUIDs via > > part_get_info(). > > > > When duplicates are found, a warning is printed for each occurrence: > > > > Warning: duplicate PARTUUID 20c5fba5-0171-457f-b9cd-f5129cd07228 > > first seen on usb_mass_storage.lun0:3 > > also on ufs_scsi.id0lun0:3 > > > > Add Kconfig option `CMD_PART_DUPCHECK` and update the `part` help text > > accordingly. > > It would be nice to also check the partition label, which is also used > sometimes in the > boot process. Ok, will check. > > > Signed-off-by: John Toomey <[email protected]> > > Signed-off-by: Padmarao Begari <[email protected]> > > --- > > Changes in v2: > > -Add own kconfig symbol for dupcheck subcommand and guard it. > > --- > > cmd/Kconfig | 7 ++++ > > cmd/part.c | 104 > > +++++++++++++++++++++++++++++++++++++++++++++++++++- > > 2 files changed, 110 insertions(+), 1 deletion(-) > > > > diff --git a/cmd/Kconfig b/cmd/Kconfig index 322ebe600c5..73d27fe2e28 > > 100644 > > --- a/cmd/Kconfig > > +++ b/cmd/Kconfig > > @@ -1663,6 +1663,13 @@ config CMD_PART > > Read and display information about the partition table on > > various media. > > > > +config CMD_PART_DUPCHECK > > + bool "part dupcheck" > > + depends on CMD_PART > > + help > > + Enable the 'part dupcheck' sub-command under 'part' to scan the > > + current partition table and report any duplicate partition UUIDs. > > + > > config CMD_PCI > > bool "pci - Access PCI devices" > > help > > diff --git a/cmd/part.c b/cmd/part.c > > index 975a0a08a99..c4df5053936 100644 > > --- a/cmd/part.c > > +++ b/cmd/part.c > > @@ -15,9 +15,12 @@ > > * Pavel Bartusek <[email protected]> > > */ > > > > +#include <blk.h> > > #include <config.h> > > #include <command.h> > > +#include <dm.h> > > #include <env.h> > > +#include <malloc.h> > > #include <part.h> > > #include <stdio.h> > > #include <vsprintf.h> > > @@ -246,6 +249,97 @@ static int do_part_type(int argc, char *const > > argv[]) } #endif > > > > +#if CONFIG_IS_ENABLED(CMD_PART_DUPCHECK) > > +struct part_seen { > > + char uuid[UUID_STR_LEN + 1]; > > + struct udevice *dev; > > + int part; > > +}; > > + > > +static int do_part_dupcheck(int argc, char *const argv[]) { > > + struct part_seen *seen; > > + int count = 0; > > + int duplicates = 0; > > + int max_entries; > > + int dev_count; > > + struct udevice *dev; > > + > > + if (argc) > > + return CMD_RET_USAGE; > > + > > + dev_count = blk_count_devices(BLKF_BOTH); > > + if (!dev_count) { > > + printf("No block devices found\n"); > > + return CMD_RET_SUCCESS; > > + } > > + > > + max_entries = dev_count * MAX_SEARCH_PARTITIONS; > > + seen = calloc(max_entries, sizeof(*seen)); > > + if (!seen) { > > + printf("Unable to allocate dupcheck table (%d entries)\n", > > + max_entries); > > + return CMD_RET_FAILURE; > > + } > > + > > + blk_foreach_probe(BLKF_BOTH, dev) { > > + struct blk_desc *desc = dev_get_uclass_plat(dev); > > + > > + for (int part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { > > + struct disk_partition info; > > + int first_match = -1; > > + > > + if (part_get_info(desc, part, &info)) > > + continue; > > + if (!info.uuid[0]) > > + continue; > > + > > + for (int i = 0; i < count; i++) { > > + if (strcmp(seen[i].uuid, info.uuid)) > > + continue; > > + if (first_match == -1) { > > + printf("Warning: duplicate > > + PARTUUID > > %s\n", > > + info.uuid); > > + printf(" first seen on %s:%d\n", > > + seen[i].dev->name, > > + seen[i].part); > > + printf(" also on %s:%d\n", > > + dev->name, part); > > + duplicates++; > > + first_match = i; > > + } else { > > + printf(" also on %s:%d\n", > > + seen[i].dev->name, > > + seen[i].part); > > + } > > + } > > If you have 3 partitions (A,B,C) with the same uuid you will report the > information > twice: > When processing B: "Warning ... first seen on A:x / also on B:x" > When processing C: "Warning ... first seen on A:x / also on C:x / also on B:x" > > Also this means the duplicates variable will be incremented to 2 which is > confusing > for the print in my last comment: Ok, will recheck and work on it. > > > + > > + if (count >= max_entries) { > > + printf("Error: dupcheck capacity %d > > entries\n", > > + max_entries); > > + printf(" exceeded\n"); > > Weird print here: > Maybe something like that: "Error: dupcheck capacity exceeded (%d entries)" Yes, want to do same but it is crossing 80 characters per line. > > > + free(seen); > > + return CMD_RET_FAILURE; > > + } > > + > > + strlcpy(seen[count].uuid, info.uuid, > > + sizeof(seen[0].uuid)); > > + seen[count].dev = dev; > > + seen[count].part = part; > > + count++; > > + } > > + } > > + > > + if (duplicates) > > + printf("Found %d duplicate(s) among %d partitions checked\n", > > + duplicates, count); > > So with 3 partitions using the same uuid, it will report "Found 2 > duplicate(s) ..." > > Which can be confusing. We should report either "1 UUID duplication" or "3 > copies > of the same UUID" Ok got it. Regards Padmarao > > > + > > + free(seen); > > + > > + return duplicates ? CMD_RET_FAILURE : CMD_RET_SUCCESS; } #endif > > + > > static int do_part_types(int argc, char * const argv[]) { > > struct part_driver *drv = ll_entry_start(struct part_driver, @@ > > -291,6 +385,10 @@ static int do_part(struct cmd_tbl *cmdtp, int flag, > > int argc, #ifdef CONFIG_PARTITION_TYPE_GUID > > else if (!strcmp(argv[1], "type")) > > return do_part_type(argc - 2, argv + 2); > > +#endif > > +#if CONFIG_IS_ENABLED(CMD_PART_DUPCHECK) > > + else if (!strcmp(argv[1], "dupcheck")) > > + return do_part_dupcheck(argc - 2, argv + 2); > > #endif > > return CMD_RET_USAGE; > > } > > @@ -328,5 +426,9 @@ U_BOOT_CMD( > > "part set <interface> <dev> type\n" > > " - set partition type for a device\n" > > "part types\n" > > - " - list supported partition table types" > > + " - list supported partition table types\n" > > +#if CONFIG_IS_ENABLED(CMD_PART_DUPCHECK) > > + "part dupcheck\n" > > + " - scan all block devices for duplicate partition UUIDs" > > +#endif > > ); > > > > -- > Köry Maincent, Bootlin > Embedded Linux and kernel engineering > https://bootlin.com

