No need for that. Poking around myself, /sbin/block hotplug
is the culprit:
ACTION=add DEVNAME=mtdblock23 time /sbin/block hotplug
Command exited with non-zero status 255
real 0m 2.51s
user 0m 0.00s
sys 0m 2.49s
I'm afraid this is a case of accidentally quadratic behavior. Despite the intention of looking for things relevant to a single device ($DEVNAME
), each invocation of /sbin/block hotplug
probes all block devices:
ACTION=add DEVNAME=mtdblock23 strace -t -e file /sbin/block hotplug
...
22:17:00 open("/dev/", O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
22:17:00 open("/sys/class/mtd/mtd0/type", O_RDONLY|O_LARGEFILE) = 3
22:17:00 statx(AT_FDCWD, "/dev/mtdblock0", AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFBLK|0600, stx_size=0, ...}) = 0
22:17:00 open("/dev/mtdblock0", O_RDONLY|O_LARGEFILE) = 3
22:17:00 open("/lib/libblkid.so", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
22:17:00 open("/usr/local/lib/libblkid.so", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
22:17:00 open("/usr/lib/libblkid.so", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
22:17:00 open("/lib/libblkid.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
22:17:00 open("/usr/local/lib/libblkid.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
22:17:00 open("/usr/lib/libblkid.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
22:17:00 statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=197071, ...}) = 0
22:17:00 open("/dev/mtdblock0", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC) = 3
22:17:00 statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFBLK|0600, stx_size=0, ...}) = 0
22:17:00 open("/sys/dev/block/31:0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
22:17:00 openat(4, "dm/uuid", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
22:17:00 open("/sys/class/mtd/mtd1/type", O_RDONLY|O_LARGEFILE) = 3
22:17:00 statx(AT_FDCWD, "/dev/mtdblock1", AT_STATX_SYNC_AS_STAT, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFBLK|0600, stx_size=0, ...}) = 0
22:17:00 open("/dev/mtdblock1", O_RDONLY|O_LARGEFILE) = 3
...
22:17:00 open("/dev/mtdblock10", O_RDONLY|O_LARGEFILE) = 3
...
22:17:03 open("/dev/mtdblock9", O_RDONLY|O_LARGEFILE) = 3
...
22:17:03 open("/dev/loop7", O_RDONLY|O_LARGEFILE) = 3
...
This is all happening because of the logic at https://lxr.openwrt.org/source/fstools/block.c#L1256, which probes every block device it can think of, rather than using the device name it already has! I think that call could be replaced with something like
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "/dev/%s", device);
_cache_load(buf);
to just populate the one device we know we're already looking for.
I've raised an issue report in what I hope is the right place.