Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm init: add dm-mod.waitfor to wait for asynchronously probed block devices

Just calling wait_for_device_probe() is not enough to ensure that
asynchronously probed block devices are available (E.G. mmc, usb), so
add a "dm-mod.waitfor=<device1>[,..,<deviceN>]" parameter to get
dm-init to explicitly wait for specific block devices before
initializing the tables with logic similar to the rootwait logic that
was introduced with commit cc1ed7542c8c ("init: wait for
asynchronously scanned block devices").

E.G. with dm-verity on mmc using:
dm-mod.waitfor="PARTLABEL=hash-a,PARTLABEL=root-a"

[ 0.671671] device-mapper: init: waiting for all devices to be available before creating mapped devices
[ 0.671679] device-mapper: init: waiting for device PARTLABEL=hash-a ...
[ 0.710695] mmc0: new HS200 MMC card at address 0001
[ 0.711158] mmcblk0: mmc0:0001 004GA0 3.69 GiB
[ 0.715954] mmcblk0boot0: mmc0:0001 004GA0 partition 1 2.00 MiB
[ 0.722085] mmcblk0boot1: mmc0:0001 004GA0 partition 2 2.00 MiB
[ 0.728093] mmcblk0rpmb: mmc0:0001 004GA0 partition 3 512 KiB, chardev (249:0)
[ 0.738274] mmcblk0: p1 p2 p3 p4 p5 p6 p7
[ 0.751282] device-mapper: init: waiting for device PARTLABEL=root-a ...
[ 0.751306] device-mapper: init: all devices available
[ 0.751683] device-mapper: verity: sha256 using implementation "sha256-generic"
[ 0.759344] device-mapper: ioctl: dm-0 (vroot) is ready
[ 0.766540] VFS: Mounted root (squashfs filesystem) readonly on device 254:0.

Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>

authored by

Peter Korsgaard and committed by
Mike Snitzer
035641b0 b52c3de8

+29 -1
+8
Documentation/admin-guide/device-mapper/dm-init.rst
··· 123 123 0 1638400 verity 1 8:1 8:2 4096 4096 204800 1 sha256 124 124 fb1a5a0f00deb908d8b53cb270858975e76cf64105d412ce764225d53b8f3cfd 125 125 51934789604d1b92399c52e7cb149d1b3a1b74bbbcb103b2a0aaacbed5c08584 126 + 127 + For setups using device-mapper on top of asynchronously probed block 128 + devices (MMC, USB, ..), it may be necessary to tell dm-init to 129 + explicitly wait for them to become available before setting up the 130 + device-mapper tables. This can be done with the "dm-mod.waitfor=" 131 + module parameter, which takes a list of devices to wait for:: 132 + 133 + dm-mod.waitfor=<device1>[,..,<deviceN>]
+21 -1
drivers/md/dm-init.c
··· 8 8 */ 9 9 10 10 #include <linux/ctype.h> 11 + #include <linux/delay.h> 11 12 #include <linux/device.h> 12 13 #include <linux/device-mapper.h> 13 14 #include <linux/init.h> ··· 19 18 #define DM_MAX_DEVICES 256 20 19 #define DM_MAX_TARGETS 256 21 20 #define DM_MAX_STR_SIZE 4096 21 + #define DM_MAX_WAITFOR 256 22 22 23 23 static char *create; 24 + 25 + static char *waitfor[DM_MAX_WAITFOR]; 24 26 25 27 /* 26 28 * Format: dm-mod.create=<name>,<uuid>,<minor>,<flags>,<table>[,<table>+][;<name>,<uuid>,<minor>,<flags>,<table>[,<table>+]+] 27 29 * Table format: <start_sector> <num_sectors> <target_type> <target_args> 30 + * Block devices to wait for to become available before setting up tables: 31 + * dm-mod.waitfor=<device1>[,..,<deviceN>] 28 32 * 29 33 * See Documentation/admin-guide/device-mapper/dm-init.rst for dm-mod.create="..." format 30 34 * details. ··· 272 266 struct dm_device *dev; 273 267 LIST_HEAD(devices); 274 268 char *str; 275 - int r; 269 + int i, r; 276 270 277 271 if (!create) 278 272 return 0; ··· 292 286 DMINFO("waiting for all devices to be available before creating mapped devices"); 293 287 wait_for_device_probe(); 294 288 289 + for (i = 0; i < ARRAY_SIZE(waitfor); i++) { 290 + if (waitfor[i]) { 291 + DMINFO("waiting for device %s ...", waitfor[i]); 292 + while (!dm_get_dev_t(waitfor[i])) 293 + msleep(5); 294 + } 295 + } 296 + 297 + if (waitfor[0]) 298 + DMINFO("all devices available"); 299 + 295 300 list_for_each_entry(dev, &devices, list) { 296 301 if (dm_early_create(&dev->dmi, dev->table, 297 302 dev->target_args_array)) ··· 318 301 319 302 module_param(create, charp, 0); 320 303 MODULE_PARM_DESC(create, "Create a mapped device in early boot"); 304 + 305 + module_param_array(waitfor, charp, NULL, 0); 306 + MODULE_PARM_DESC(waitfor, "Devices to wait for before setting up tables");