Since kernel 2.6.26, kernel allows partitions on loopback devices. Implement support for this feature in parted.
* libparted/arch/linux.c (_sysfs_int_entry_from_dev): New function. (_loop_get_partition_range): New function. (_device_get_partition_range): Add special handling for loop devices. * NEWS: Mention this change. Signed-off-by: Petr Uzel <[email protected]> --- NEWS | 4 +++ libparted/arch/linux.c | 70 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index cb61ac1..ed30409 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ GNU parted NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + parted has improved support for partitionable loopback devices + ** Bug fixes libparted: no longer aborts when reading a truncated GPT-formatted device diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c index adaf89a..2c0619a 100644 --- a/libparted/arch/linux.c +++ b/libparted/arch/linux.c @@ -2419,32 +2419,74 @@ _blkpg_remove_partition (PedDisk* disk, int n) BLKPG_DEL_PARTITION); } -/* - * The number of partitions that a device can have depends on the kernel. - * If we don't find this value in /sys/block/DEV/range, we will use our own - * value. - */ -static unsigned int -_device_get_partition_range(PedDevice* dev) +static int +_sysfs_int_entry_from_dev(PedDevice *dev, const char *entry, int *val) { - int range, r; + int r; char path[128]; FILE* fp; bool ok; - r = snprintf(path, sizeof(path), "/sys/block/%s/range", - last_component(dev->path)); + r = snprintf(path, sizeof(path), "/sys/block/%s/%s", + last_component(dev->path), entry); if (r < 0 || r >= sizeof(path)) - return MAX_NUM_PARTS; + return 0; fp = fopen(path, "r"); if (!fp) - return MAX_NUM_PARTS; + return 0; - ok = fscanf(fp, "%d", &range) == 1; + ok = fscanf(fp, "%d", val) == 1; fclose(fp); - /* (range <= 0) is none sense.*/ + return ok; +} + +static unsigned int +_loop_get_partition_range(PedDevice* dev) +{ + int max_part; + FILE* fp; + bool ok = 0; + + /* max_part module param is exported since kernel 3.0 */ + 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/range, we will use our own + * value. + */ +static unsigned int +_device_get_partition_range(PedDevice* dev) +{ + int range; + bool ok; + + /* loop handling is special */ + if (dev->type == PED_DEVICE_LOOP) + return _loop_get_partition_range(dev); + + ok = _sysfs_int_entry_from_dev(dev, "range", &range); + return ok && range > 0 ? range : MAX_NUM_PARTS; } -- 1.7.3.4 _______________________________________________ parted-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/parted-devel

