Good morning.
I have had problems in all recent kernels with booting directly from MD
RAID-1 partitioned arrays (i.e. without using an initrd).
All the usual requirements - building md and raid1 into the kernel,
correct partition types, etc - are correct.
Deep investigation has led me to conclude that the issue is caused by
boot-time assembly of the array not reading the partition table, meaning
that the partitions are not visible and cannot be mounted as root
filesystem.
The change to drivers/md/md-autodetect.c in commit
a1d6bc018911390274e3904bdd28240cd96ddc54 appears to be related, although
this only covers some cases not all, so I have not been able to
determine exactly what commit led to this problem.
I have implemented a patch that causes the partition table to be read
immediately after the array is started, for the two boot-time assembly
paths (from autodetect with raid=part, and from assembly with md=d0,...)
which is included below.
Regards,
Geoff.
diff -Naur linux-5.12.2.orig/drivers/md/md-autodetect.c
linux-5.12.2/drivers/md/md-autodetect.c
--- linux-5.12.2.orig/drivers/md/md-autodetect.c 2021-05-12
09:14:07.096442083 +0100
+++ linux-5.12.2/drivers/md/md-autodetect.c 2021-05-12
09:22:07.734653840 +0100
@@ -232,8 +232,24 @@
mddev_unlock(mddev);
out_blkdev_put:
blkdev_put(bdev, FMODE_READ);
-}
+ /*
+ * Need to force read of partition table in order for partitioned
+ * arrays to be bootable. Deliberately done after all cleanup,
+ * and only for successfully loaded arrays.
+ */
+ if (err == 0)
+ {
+ struct block_device *bd;
+
+ bd = blkdev_get_by_dev(mdev, FMODE_READ, NULL);
+ if (IS_ERR(bd))
+ pr_err("md: failed to get md device\n");
+ else
+ blkdev_put(bd, FMODE_READ);
+ }
+}
+
static int __init raid_setup(char *str)
{
int len, pos;
diff -Naur linux-5.12.2.orig/drivers/md/md.c linux-5.12.2/drivers/md/md.c
--- linux-5.12.2.orig/drivers/md/md.c 2021-05-12 09:14:07.127441838 +0100
+++ linux-5.12.2/drivers/md/md.c 2021-05-12 09:34:26.960827487 +0100
@@ -6467,6 +6467,20 @@
pr_warn("md: do_md_run() returned %d\n", err);
do_md_stop(mddev, 0, NULL);
}
+ else
+ {
+ /*
+ * Need to force read of partition table in order for partitioned
+ * arrays to be bootable.
+ */
+ struct block_device *bd;
+
+ bd = blkdev_get_by_dev(mdev, FMODE_READ, NULL);
+ if (IS_ERR(bd))
+ pr_err("md: failed to get md device\n");
+ else
+ blkdev_put(bd, FMODE_READ);
+ }
}
/*
--
Geoff Back
What if we're all just characters in someone's nightmares?