From: Zdenek Kabelac Date: Sat, 14 Mar 2026 13:39:41 +0000 (+0100) Subject: libblkid: check for private DM device before open X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d05a84b22e549527cbcbcc7d5efc6bad06668170;p=thirdparty%2Futil-linux.git libblkid: check for private DM device before open blkid_new_probe_from_filename() opens the device before calling blkid_probe_set_device(), which checks sysfs_devno_is_dm_private() and sets BLKID_FL_NOSCAN_DEV. But the open() itself bumps the kernel open count, so a concurrent DM_DEVICE_REMOVE ioctl sees EBUSY even though blkid never actually probes the device. Move the private-device check before open() in blkid_new_probe_from_filename(). The sysfs UUID is readable without opening the block device, so this closes the race window between udev-worker's blkid builtin and device-mapper remove. Note: blkid_verify() in verify.c already does the check before open() -- this patch makes the probe path consistent. Signed-off-by: Zdenek Kabelac --- diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 60af2915c..d47c22c72 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -216,8 +216,18 @@ blkid_probe blkid_new_probe_from_filename(const char *filename) { int fd; blkid_probe pr = NULL; + struct stat sb; + + /* + * Check for private device-mapper devices (LVM internals, etc.) + * before open() to avoid bumping the kernel open count. A racing + * DM_DEVICE_REMOVE would otherwise see EBUSY. + */ + if (stat(filename, &sb) == 0 && S_ISBLK(sb.st_mode) && + sysfs_devno_is_dm_private(sb.st_rdev, NULL)) + return NULL; - fd = open(filename, O_RDONLY|O_CLOEXEC|O_NONBLOCK); + fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK); if (fd < 0) return NULL;