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 <zkabelac@redhat.com>
{
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;