[lvm-devel] master - devices: handle partscan loop devices

Zdenek Kabelac zkabelac at fedoraproject.org
Wed Jun 1 15:42:18 UTC 2016


Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d37a26b680f6c7ca9ec0bb1ce0cca189d19b525f
Commit:        d37a26b680f6c7ca9ec0bb1ce0cca189d19b525f
Parent:        3d333e5a296eba8ba2858ca007699fe70ec8083e
Author:        Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate:    Wed Jun 1 16:39:47 2016 +0200
Committer:     Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Wed Jun 1 17:37:47 2016 +0200

devices: handle partscan loop devices

Treat loop device created with 'losetup -P' as regular
partitioned device - so if it has partition table,
prevent its usage in commands like 'pvcreate'.

Before 'pvcreate /dev/loop0' could have erased and formated as PV,
after this patch, device is filtered out and cannot be used.
---
 WHATS_NEW             |    1 +
 lib/device/dev-type.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 lib/device/dev-type.h |    1 +
 3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index 1bad12a..74b5bdb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.155 - 
 ================================
+  Automatically filter out partitioned loop devices with partscan (losetup -P).
   Fix lvm devtypes internal error if -S used with field name from pvs/vgs/lvs.
   When reporting Data%,Snap%,Meta%,Cpy%Sync use single ioctl per LV.
   Add lvseg_percent_with_info_and_seg_status() for percent retrieval.
diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c
index f9f1418..0246c09 100644
--- a/lib/device/dev-type.c
+++ b/lib/device/dev-type.c
@@ -125,6 +125,9 @@ struct dev_types *create_dev_types(const char *proc_dir,
 		if (!strncmp("emcpower", line + i, 8) && isspace(*(line + i + 8)))
 			dt->emcpower_major = line_maj;
 
+		if (!strncmp("loop", line + i, 4) && isspace(*(line + i + 4)))
+			dt->loop_major = line_maj;
+
 		if (!strncmp("power2", line + i, 6) && isspace(*(line + i + 6)))
 			dt->power2_major = line_maj;
 
@@ -246,6 +249,9 @@ const char *dev_subsystem_name(struct dev_types *dt, struct device *dev)
 	if (MAJOR(dev->dev) == dt->blkext_major)
 		return "BLKEXT";
 
+	if (MAJOR(dev->dev) == dt->loop_major)
+		return "LOOP";
+
 	return "";
 }
 
@@ -265,6 +271,38 @@ int major_is_scsi_device(struct dev_types *dt, int major)
 	return (dt->dev_type_array[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0;
 }
 
+
+static int _loop_is_with_partscan(struct device *dev)
+{
+	FILE *fp;
+	int partscan = 0;
+	char path[PATH_MAX];
+	char buffer[64];
+
+	if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/loop/partscan",
+			dm_sysfs_dir(),
+			(int) MAJOR(dev->dev),
+			(int) MINOR(dev->dev)) < 0) {
+		log_warn("Sysfs path for partscan is too long.");
+		return 0;
+	}
+
+	if (!(fp = fopen(path, "r")))
+		return 0; /* not there -> no partscan */
+
+	if (!fgets(buffer, sizeof(buffer), fp)) {
+		log_warn("Failed to read %s.", path);
+	} else if (sscanf(buffer, "%d", &partscan) != 1) {
+		log_warn("Failed to parse %s '%s'.", path, buffer);
+		partscan = 0;
+	}
+
+	if (fclose(fp))
+		log_sys_debug("fclose", path);
+
+	return partscan;
+}
+
 /* See linux/genhd.h and fs/partitions/msdos */
 #define PART_MAGIC 0xAA55
 #define PART_MAGIC_OFFSET UINT64_C(0x1FE)
@@ -294,6 +332,11 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev)
 	if (MAJOR(dev->dev) == dt->md_major)
 		return 1;
 
+	/* All loop devices are partitionable via blkext (as of 3.2) */
+	if ((MAJOR(dev->dev) == dt->loop_major) &&
+	    _loop_is_with_partscan(dev))
+		return 1;
+
 	if ((parts <= 1) || (MINOR(dev->dev) % parts))
 		return 0;
 
diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h
index 6438b44..267b79f 100644
--- a/lib/device/dev-type.h
+++ b/lib/device/dev-type.h
@@ -43,6 +43,7 @@ struct dev_types {
 	int emcpower_major;
 	int power2_major;
 	int dasd_major;
+	int loop_major;
 	struct dev_type_def dev_type_array[NUMBER_OF_MAJORS];
 };
 




More information about the lvm-devel mailing list