[Parted-commits] GNU Parted Official Repository: Changes to 'master'
Jim Meyering
meyering at alioth.debian.org
Fri Sep 30 07:56:49 UTC 2011
NEWS | 4 ++
include/parted/device.h | 3 +
libparted/arch/linux.c | 84 ++++++++++++++++++++++++++++++++++++----------
parted/parted.c | 2 -
tests/Makefile.am | 1
tests/t8001-loop-blkpg.sh | 64 +++++++++++++++++++++++++++++++++++
6 files changed, 138 insertions(+), 20 deletions(-)
New commits:
commit e0f8a78dd709dff5b4c4ec48593f1432a131987e
Author: Petr Uzel <petr.uzel at suse.cz>
Date: Thu Sep 29 15:14:24 2011 +0200
tests: add test for partitionable loop devices
* tests/t8001-loop-blkpg.sh: New file.
* tests/Makefile.am: Add test.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e721f88..903ca64 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -43,6 +43,7 @@ TESTS = \
t6000-dm.sh \
t7000-scripting.sh \
t8000-loop.sh \
+ t8001-loop-blkpg.sh \
t9010-big-sector.sh \
t9020-alignment.sh \
t9021-maxima.sh \
diff --git a/tests/t8001-loop-blkpg.sh b/tests/t8001-loop-blkpg.sh
new file mode 100755
index 0000000..f6e37ce
--- /dev/null
+++ b/tests/t8001-loop-blkpg.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# Test support for partitions on loop devices
+
+# Copyright (C) 2008-2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+
+require_root_
+
+cleanup_fn_()
+{
+ test -n "$loopdev" && losetup -d "$loopdev"
+}
+
+# If the loop module is loaded, unload it first
+if lsmod | grep '^loop[[:space:]]'; then
+ rmmod loop || fail=1
+fi
+
+# Insert loop module with max_part > 1
+modprobe loop max_part=7 || fail=1
+
+# Create backing file
+dd if=/dev/zero of=backing_file bs=1M count=4 >/dev/null 2>&1 || fail=1
+
+# Set up loop device on top of backing file
+loopdev=`losetup -f --show backing_file`
+test -z "$loopdev" && fail=1
+
+# Expect this to succeed
+parted -s "$loopdev" mklabel msdos > err 2>&1 || fail=1
+compare err /dev/null || fail=1 # expect no output
+
+# Create a partition
+parted -s "$loopdev" mkpart primary 1M 2M > err 2>&1 || fail=1
+compare /dev/null err || fail=1 # expect no output
+udevadm settle --timeout=5 || fail=1
+
+# Verify that the partition appeared in /proc/partitions
+entry=`basename "$loopdev"p1`
+grep "$entry" /proc/partitions || { cat /proc/partitions; fail=1; }
+
+# Remove the partition
+parted -s "$loopdev" rm 1 > err 2>&1 || fail=1
+compare /dev/null err || fail=1 # expect no output
+udevadm settle --timeout=5 || fail=1
+
+# Verify that the partition got removed from /proc/partitions
+grep "$entry" /proc/partitions && fail=1
+
+Exit $fail
commit 1eb0cc30d9a2f6a2a6c1f7ec0e4003b1081c5738
Author: Petr Uzel <petr.uzel at suse.cz>
Date: Thu Sep 29 15:14:23 2011 +0200
libparted: improve support for partitions on loopback devices
Since linux-2.6.26, the 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.
diff --git a/NEWS b/NEWS
index 6c55ec9..293dad8 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 (failed assertion) due to a nilfs2_probe bug
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 5452f30..b1c12b5 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2428,32 +2428,75 @@ _blkpg_remove_partition (PedDisk* disk, int n)
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/range, we will use our own
* value.
*/
static unsigned int
-_device_get_partition_range(PedDevice* dev)
+_device_get_partition_range(PedDevice const* dev)
{
- int range, r;
- char path[128];
- FILE* fp;
- bool ok;
-
- r = snprintf(path, sizeof(path), "/sys/block/%s/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, "range", &range);
- /* (range <= 0) is none sense.*/
return ok && range > 0 ? range : MAX_NUM_PARTS;
}
commit 3e35b6559ad1ebfbad47e8edb2b002d7c07c984c
Author: Petr Uzel <petr.uzel at suse.cz>
Date: Thu Sep 29 15:45:23 2011 +0200
libparted: differentiate between plain files and loop devices
Stop using PED_DEVICE_FILE for loopback devices;
loopback are significantly different from plain files.
* include/parted/device.h (PedDeviceType): Add PED_DEVICE_LOOP.
* libparted/arch/linux.c (_device_probe_type): Detect loopback device.
* parted/parted.c (do_print): Add "loopback" to list of transports.
diff --git a/include/parted/device.h b/include/parted/device.h
index 0634465..b94765c 100644
--- a/include/parted/device.h
+++ b/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;
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 3792b19..5452f30 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -594,7 +594,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 {
@@ -1385,6 +1385,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;
diff --git a/parted/parted.c b/parted/parted.c
index 32c2fcc..51ecdaf 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -853,7 +853,7 @@ _print_disk_info (const PedDevice *dev, const PedDisk *disk)
"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 ();
More information about the Parted-commits
mailing list