forked from pool/parted
parted-improve-loop-support.patch (bnc#726603) OBS-URL: https://build.opensuse.org/package/show/Base:System/parted?expand=0&rev=55
158 lines
5.5 KiB
Diff
158 lines
5.5 KiB
Diff
Index: parted-2.4/NEWS
|
|
===================================================================
|
|
--- parted-2.4.orig/NEWS
|
|
+++ parted-2.4/NEWS
|
|
@@ -2,6 +2,10 @@ GNU parted NEWS
|
|
|
|
* Noteworthy changes in release 2.4 (2011-05-18) [stable]
|
|
|
|
+** New features
|
|
+
|
|
+ parted has improved support for partitionable loopback devices
|
|
+
|
|
** Bug fixes
|
|
|
|
parted no longer allows the modification of certain in-use partitions.
|
|
Index: parted-2.4/include/parted/device.h
|
|
===================================================================
|
|
--- parted-2.4.orig/include/parted/device.h
|
|
+++ parted-2.4/include/parted/device.h
|
|
@@ -48,7 +48,8 @@ typedef enum {
|
|
PED_DEVICE_SDMMC = 14,
|
|
PED_DEVICE_VIRTBLK = 15,
|
|
PED_DEVICE_AOE = 16,
|
|
- PED_DEVICE_MD = 17
|
|
+ PED_DEVICE_MD = 17,
|
|
+ PED_DEVICE_LOOP = 18
|
|
} PedDeviceType;
|
|
|
|
typedef struct _PedDevice PedDevice;
|
|
Index: parted-2.4/libparted/arch/linux.c
|
|
===================================================================
|
|
--- parted-2.4.orig/libparted/arch/linux.c
|
|
+++ parted-2.4/libparted/arch/linux.c
|
|
@@ -586,7 +586,7 @@ _device_probe_type (PedDevice* dev)
|
|
} else if (_is_virtblk_major(dev_major)) {
|
|
dev->type = PED_DEVICE_VIRTBLK;
|
|
} else if (dev_major == LOOP_MAJOR) {
|
|
- dev->type = PED_DEVICE_FILE;
|
|
+ dev->type = PED_DEVICE_LOOP;
|
|
} else if (dev_major == MD_MAJOR) {
|
|
dev->type = PED_DEVICE_MD;
|
|
} else {
|
|
@@ -1376,6 +1376,11 @@ linux_new (const char* path)
|
|
goto error_free_arch_specific;
|
|
break;
|
|
|
|
+ case PED_DEVICE_LOOP:
|
|
+ if (!init_generic (dev, _("Loopback device")))
|
|
+ goto error_free_arch_specific;
|
|
+ break;
|
|
+
|
|
case PED_DEVICE_DM:
|
|
{
|
|
char* type;
|
|
@@ -2411,6 +2416,61 @@ _blkpg_remove_partition (PedDisk* disk,
|
|
BLKPG_DEL_PARTITION);
|
|
}
|
|
|
|
+/* Read the integer from /sys/block/DEV_BASE/ENTRY and set *VAL
|
|
+ to that value, where DEV_BASE is the last component of DEV->path.
|
|
+ Upon success, return true. Otherwise, return false. */
|
|
+static bool
|
|
+_sysfs_int_entry_from_dev(PedDevice const* dev, const char *entry, int *val)
|
|
+{
|
|
+ char path[128];
|
|
+ int r = snprintf(path, sizeof(path), "/sys/block/%s/%s",
|
|
+ last_component(dev->path), entry);
|
|
+ if (r < 0 || r >= sizeof(path))
|
|
+ return false;
|
|
+
|
|
+ FILE *fp = fopen(path, "r");
|
|
+ if (!fp)
|
|
+ return false;
|
|
+
|
|
+ bool ok = fscanf(fp, "%d", val) == 1;
|
|
+ fclose(fp);
|
|
+
|
|
+ return ok;
|
|
+}
|
|
+
|
|
+/* Return the maximum number of partitions that the loopback device can hold.
|
|
+ First, check the loop-module-exported max_part parameter (since linux-3.0).
|
|
+ If that is not available, fall back to checking ext_range, which seems to
|
|
+ have (for some reason) different semantics compared to other devices;
|
|
+ specifically, ext_range <= 1 means that the loopback device does
|
|
+ not support partitions. */
|
|
+static unsigned int
|
|
+_loop_get_partition_range(PedDevice const* dev)
|
|
+{
|
|
+ int max_part;
|
|
+ bool ok = false;
|
|
+
|
|
+ /* max_part module param is exported since kernel 3.0 */
|
|
+ FILE *fp = fopen("/sys/module/loop/parameters/max_part", "r");
|
|
+ if (fp) {
|
|
+ ok = fscanf(fp, "%d", &max_part) == 1;
|
|
+ fclose(fp);
|
|
+ }
|
|
+
|
|
+ if (ok)
|
|
+ return max_part > 0 ? max_part : 0;
|
|
+
|
|
+ /*
|
|
+ * max_part is not exported - check ext_range;
|
|
+ * device supports partitions if ext_range > 1
|
|
+ */
|
|
+ int range;
|
|
+ ok = _sysfs_int_entry_from_dev(dev, "range", &range);
|
|
+
|
|
+ return ok && range > 1 ? range : 0;
|
|
+}
|
|
+
|
|
+
|
|
/*
|
|
* The number of partitions that a device can have depends on the kernel.
|
|
* If we don't find this value in /sys/block/DEV/ext_range, we will use our own
|
|
@@ -2419,22 +2479,12 @@ _blkpg_remove_partition (PedDisk* disk,
|
|
static unsigned int
|
|
_device_get_partition_range(PedDevice* dev)
|
|
{
|
|
- int range, r;
|
|
- char path[128];
|
|
- FILE* fp;
|
|
- bool ok;
|
|
-
|
|
- r = snprintf(path, sizeof(path), "/sys/block/%s/ext_range",
|
|
- last_component(dev->path));
|
|
- if (r < 0 || r >= sizeof(path))
|
|
- return MAX_NUM_PARTS;
|
|
+ /* loop handling is special */
|
|
+ if (dev->type == PED_DEVICE_LOOP)
|
|
+ return _loop_get_partition_range(dev);
|
|
|
|
- fp = fopen(path, "r");
|
|
- if (!fp)
|
|
- return MAX_NUM_PARTS;
|
|
-
|
|
- ok = fscanf(fp, "%d", &range) == 1;
|
|
- fclose(fp);
|
|
+ int range;
|
|
+ bool ok = _sysfs_int_entry_from_dev(dev, "ext_range", &range);
|
|
|
|
/* (range <= 0) is none sense.*/
|
|
return ok && range > 0 ? range : MAX_NUM_PARTS;
|
|
Index: parted-2.4/parted/parted.c
|
|
===================================================================
|
|
--- parted-2.4.orig/parted/parted.c
|
|
+++ parted-2.4/parted/parted.c
|
|
@@ -1464,7 +1464,7 @@ _print_disk_info (const PedDevice *dev,
|
|
"cpqarray", "file", "ataraid", "i2o",
|
|
"ubd", "dasd", "viodasd", "sx8", "dm",
|
|
"xvd", "sd/mmc", "virtblk", "aoe",
|
|
- "md"};
|
|
+ "md", "loopback"};
|
|
|
|
char* start = ped_unit_format (dev, 0);
|
|
PedUnit default_unit = ped_unit_get_default ();
|