Index: grub2-2.04/grub-core/osdep/linux/getroot.c =================================================================== --- grub2-2.04.orig/grub-core/osdep/linux/getroot.c +++ grub2-2.04/grub-core/osdep/linux/getroot.c @@ -135,10 +135,18 @@ struct mountinfo_entry char fstype[ESCAPED_PATH_MAX + 1], device[ESCAPED_PATH_MAX + 1]; }; +/* GET_DISK_INFO nr_disks (total count) does not map to disk.number, + which is an internal kernel index. Instead, do what mdadm does + and keep scanning until we find enough valid disks. The limit is + copied from there, which notes that it is sufficiently high given + that the on-disk metadata for v1.x can only support 1920. */ +#define MD_MAX_DISKS 4096 + static char ** grub_util_raid_getmembers (const char *name, int bootable) { int fd, ret, i, j; + int remaining; char **devicelist; mdu_version_t version; mdu_array_info_t info; @@ -170,12 +178,17 @@ grub_util_raid_getmembers (const char *n devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); - for (i = 0, j = 0; i < info.nr_disks; i++) + remaining = info.nr_disks; + for (i = 0, j = 0; i < MD_MAX_DISKS && remaining > 0; i++) { disk.number = i; ret = ioctl (fd, GET_DISK_INFO, &disk); if (ret != 0) grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); + /* Skip empty disk slot. */ + if (disk.major == 0 && disk.minor == 0) + continue; + remaining--; if (disk.state & (1 << MD_DISK_REMOVED)) continue;