hardkernel / linux

Linux kernel source tree
Other
426 stars 406 forks source link

Race condition probing sd card and running init #390

Closed sshock closed 3 years ago

sshock commented 4 years ago

The kernel runs /init (from the initrd in the boot partition) before waiting for the sd card to be fully probed (meson-mmc driver) and available (i.e., before /sys/dev/block is fully populated).

This may not turn into a problem for the regular init, but for magiskinit this race condition results in magisk randomly not working. See https://github.com/topjohnwu/Magisk/issues/2487.

See the magisk issue for full dmesg logs, but the relevant section (that randomly occurs before/after/concurrently with init), is this:

[    1.714885] meson-mmc: [mmc_read_partition_tbl] mmc read partition OK!
[    1.714887] meson-mmc: add_emmc_partition
[    1.715000] meson-mmc: [mmcblk1p01]           bootloader  offset 0x000000000001, size 0x00000000077f
[    1.715082] meson-mmc: [mmcblk1p02]                  env  offset 0x000000000780, size 0x000000000080
[    1.715162] meson-mmc: [mmcblk1p03]               ptable  offset 0x000000000800, size 0x000000000008
[    1.715242] meson-mmc: [mmcblk1p04]                 misc  offset 0x000000000808, size 0x000000000008
[    1.715364] meson-mmc: [mmcblk1p05]                 logo  offset 0x000000000810, size 0x000000001000
[    1.715476] meson-mmc: [mmcblk1p06]                 dtbs  offset 0x000000001810, size 0x000000000100
[    1.715560] meson-mmc: [mmcblk1p07]                 boot  offset 0x000000001910, size 0x000000008000
[    1.715639] meson-mmc: [mmcblk1p08]             recovery  offset 0x000000009910, size 0x00000000c000
[    1.715720] meson-mmc: [mmcblk1p09]                cache  offset 0x000000015910, size 0x000000200000
[    1.715810] meson-mmc: [mmcblk1p10]                  odm  offset 0x000000215910, size 0x000000010000
[    1.715906] meson-mmc: [mmcblk1p11]               system  offset 0x000000225910, size 0x000000380000
[    1.715997] meson-mmc: [mmcblk1p12]               vendor  offset 0x0000005a5910, size 0x000000100000
[    1.716085] meson-mmc: [mmcblk1p13]              product  offset 0x0000006a5910, size 0x000000010000
[    1.716173] meson-mmc: [mmcblk1p14]                param  offset 0x0000006b5910, size 0x000000008000
[    1.716260] meson-mmc: [mmcblk1p15]             cri_data  offset 0x0000006bd910, size 0x000000004000
[    1.716348] meson-mmc: [mmcblk1p16]                 data  offset 0x0000006c1910, size 0x0000034b0af0
sshock commented 4 years ago

I've worked around the problem for now using a tiny program called sleep_then_init.c that looks like this:

#include <unistd.h>
int main(int argc, char* argv[])
{
    sleep(3);
    execv("/init", argv);
    return 0;
}

I built that for ARM (linking statically), then placed it inside the initrd inside the boot image, then also modified the kernel cmdline in the inside the boot image config to include rdinit=/sleep_then_init.

But it would be nice if hardkernel linux could be fixed to avoid needing this workaround, e.g., by waiting to call init until after the sd card has been probed and /sys/dev/block fully populated.

sshock commented 3 years ago

This was fixed in magisk. See https://github.com/topjohnwu/Magisk/issues/2487