mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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.
This commit is contained in:
parent
3d333e5a29
commit
d37a26b680
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user