int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
size_t len, dev_t *diskdevno);
+int sysfs_devno_is_dm_hidden(dev_t devno, char **uuid);
int sysfs_devno_is_dm_private(dev_t devno, char **uuid);
int sysfs_devno_is_wholedisk(dev_t devno);
return rc;
}
+/*
+ * Returns 1 if the device is a hidden device-mapper device -- i.e. a device
+ * that exists only as a building block for another DM target and should not
+ * be opened by user-space tools (blkid, mkfs, etc.) during udev processing.
+ *
+ * Unlike sysfs_devno_is_dm_private(), this does NOT flag Stratis devices.
+ * Stratis places its own UUID ("stratis-1-private*") in the DM uuid field,
+ * but its devices are legitimately opened by tools such as mkfs.xfs to
+ * obtain device geometry.
+ *
+ * The @uuid (if not NULL) returns DM device UUID, use free() to deallocate.
+ */
+int sysfs_devno_is_dm_hidden(dev_t devno, char **uuid)
+{
+ struct path_cxt *pc = NULL;
+ char *id = NULL;
+ int rc = 0;
+
+ pc = ul_new_sysfs_path(devno, NULL, NULL);
+ if (!pc)
+ goto done;
+ if (ul_path_read_string(pc, &id, "dm/uuid") <= 0 || !id)
+ goto done;
+
+ /* Private LVM devices use "LVM-<uuid>-<name>" uuid format (important
+ * is the "LVM" prefix and "-<name>" postfix).
+ */
+ if (strncmp(id, "LVM-", 4) == 0) {
+ char *p = strrchr(id + 4, '-');
+
+ if (p && *(p + 1))
+ rc = 1;
+ }
+done:
+ ul_unref_path(pc);
+ if (uuid)
+ *uuid = id;
+ else
+ free(id);
+ return rc;
+}
+
/*
* Returns 1 if the device is private device mapper device. The @uuid
* (if not NULL) returns DM device UUID, use free() to deallocate.
struct stat sb;
/*
- * Check for private device-mapper devices (LVM internals, etc.)
+ * Check for hidden device-mapper devices (LVM internals, etc.)
* before open() to avoid bumping the kernel open count. A racing
* DM_DEVICE_REMOVE would otherwise see EBUSY.
+ *
+ * Use sysfs_devno_is_dm_hidden() rather than _dm_private() so that
+ * Stratis devices remain accessible to tools like mkfs.xfs that
+ * need to probe device geometry.
*/
if (stat(filename, &sb) == 0 && S_ISBLK(sb.st_mode) &&
- sysfs_devno_is_dm_private(sb.st_rdev, NULL)) {
- DBG(LOWPROBE, ul_debug("ignore private device mapper device"));
+ sysfs_devno_is_dm_hidden(sb.st_rdev, NULL)) {
+ DBG(LOWPROBE, ul_debug("ignore hidden device mapper device"));
errno = EINVAL;
return NULL;
}