On Mon, Nov 28, 2011 at 10:03:09PM -0500, Phillip Susi wrote: > I know it has been a long standing goal to remove the filesystem > specific bits from (lib)parted, but rather than remove the resize > command entirely, would it be acceptable to reimplement it as a pure > partition resize operation without any filesystem manipulation?
Hi Phillip, This has been discussed on this list some time ago: http://lists.alioth.debian.org/pipermail/parted-devel/2011-June/003873.html and it has been on my TODO list since then. I have some code that is working, but contains quite some TODOs - I'm attaching it here in case you would like to have a look. If you would like to finish/rewrite it, I would be more than happy as we need it in openSUSE, but I didn't find time to finish it myself yet. The idea is to have resize command, which moves only the end of the partition. If it is expanding, it is considered safe operation. With shrinking, we should at least warn that it is unsafe and could destroy the data. Next, there would be move command, which can move the start (and end) of the partition, but dos not alter its size. Obviously, data would be copied as well without knowing anything about the filesystem. This makes two simple and orthogonal FS-agnostic operations, but I haven't discussed it with anybody yet, so there might be far better proposals how resize/move should work. Petr -- Petr Uzel IRC: ptr_uzl @ freenode
From 0944a483b4fd7ec69c999c3b401c970e235d6fac Mon Sep 17 00:00:00 2001 From: Petr Uzel <[email protected]> Date: Mon, 26 Sep 2011 17:21:01 +0200 Subject: [PATCH] parted: resize command TODO --- parted/parted.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 96 insertions(+), 0 deletions(-) diff --git a/parted/parted.c b/parted/parted.c index 66beba6..d582f10 100644 --- a/parted/parted.c +++ b/parted/parted.c @@ -152,6 +152,9 @@ static const char* fs_type_msg_start = N_("FS-TYPE is one of: "); static const char* start_end_msg = N_("START and END are disk locations, such as " "4GB or 10%. Negative values count from the end of the disk. " "For example, -1s specifies exactly the last sector.\n"); +static const char* end_msg = N_("END is disk location, such as " + "4GB or 10%. Negative value counts from the end of the disk. " + "For example, -1s specifies exactly the last sector.\n"); static const char* state_msg = N_("STATE is one of: on, off\n"); static const char* device_msg = N_("DEVICE is usually /dev/hda or /dev/sda\n"); static const char* name_msg = N_("NAME is any word you want\n"); @@ -435,6 +438,21 @@ constraint_from_start_end (PedDevice* dev, PedGeometry* range_start, range_start, range_end, 1, dev->length); } + +static PedConstraint* +constraint_from_start_end_fixed_start (PedDevice* dev, PedSector start_sector, + PedGeometry* range_end) +{ + PedGeometry range_start; + range_start.dev = dev; + range_start.start = start_sector; + range_start.end = start_sector; + range_start.length = 1; + + return ped_constraint_new (ped_alignment_any, ped_alignment_any, + &range_start, range_end, 1, dev->length); +} + void help_on (char* topic) { @@ -1456,6 +1474,75 @@ error: return 0; } + +static int +do_resize (PedDevice** dev) +{ + PedDisk *disk; + PedPartition *part = NULL; + PedFileSystem *fs; + PedSector start, end; + PedGeometry range_start; + PedGeometry *range_end = NULL; + PedGeometry new_geom; + PedConstraint* constraint; + + disk = ped_disk_new (*dev); + if (!disk) + goto error; + + if (ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT)) + if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT, + alignment == ALIGNMENT_CYLINDER)) + goto error_destroy_disk; + + if (!command_line_get_partition (_("Partition number?"), disk, &part)) + goto error_destroy_disk; + if (part->type != PED_PARTITION_EXTENDED) { + if (!_partition_warn_busy (part)) + goto error_destroy_disk; + } else { + //XXX: support extended partitions + printf("resizing extended partition not supported yet\n"); + goto error_destroy_disk; + } + + //XXX: warn when shrinking partition - might lose data + + start = part->geom.start; + end = part->geom.end; + if (!command_line_get_sector (_("End?"), *dev, &end, &range_end, NULL)) + goto error_destroy_disk; + + /* Do not move start of the partition */ + constraint = constraint_from_start_end_fixed_start (*dev, start, range_end); + + if (!ped_disk_set_partition_geom (disk, part, constraint, + start, end)) + goto error_destroy_constraint; + + ped_disk_commit (disk); + ped_disk_destroy (disk); + ped_constraint_destroy (constraint); + if (range_end != NULL) + ped_geometry_destroy (range_end); + + if ((*dev)->type != PED_DEVICE_FILE) + disk_is_modified = 1; + + return 1; + +error_destroy_constraint: + ped_constraint_destroy (constraint); +error_destroy_disk: + ped_disk_destroy (disk); +error: + if (range_end != NULL) + ped_geometry_destroy (range_end); + return 0; +} + + static int do_rm (PedDevice** dev) { @@ -1820,6 +1907,15 @@ _("rescue START END rescue a lost partition near " NULL), str_list_create (_(start_end_msg), NULL), 1)); +//XXX: mention that this command does never move start of the partition +command_register (commands, command_create ( + str_list_create_unique ("resize", _("resize"), NULL), + do_resize, + str_list_create ( +_("resize NUMBER END resize partition NUMBER"), +NULL), + str_list_create (_(number_msg), _(end_msg), NULL), 1)); + command_register (commands, command_create ( str_list_create_unique ("rm", _("rm"), NULL), do_rm, -- 1.7.7
From 3a7514adef7e48b15a1de0d0a1bca6e019d5040e Mon Sep 17 00:00:00 2001 From: Petr Uzel <[email protected]> Date: Tue, 27 Sep 2011 09:11:29 +0200 Subject: [PATCH] tests: excersise resize command a lot of TODOs --- tests/Makefile.am | 1 + tests/t3200-resize-partition.sh | 92 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 0 deletions(-) create mode 100755 tests/t3200-resize-partition.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index 616684e..9837029 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -36,6 +36,7 @@ TESTS = \ t2310-dos-extended-2-sector-min-offset.sh \ t2400-dos-hfs-partition-type.sh \ t2500-probe-corrupt-hfs.sh \ + t3200-resize-partition.sh \ t3200-type-change.sh \ t3300-palo-prep.sh \ t3310-flags.sh \ diff --git a/tests/t3200-resize-partition.sh b/tests/t3200-resize-partition.sh new file mode 100755 index 0000000..0735ce0 --- /dev/null +++ b/tests/t3200-resize-partition.sh @@ -0,0 +1,92 @@ +#!/bin/sh +# exercise the resize sub-command +# based on t3000-resize-fs.sh test + +# Copyright (C) 2009-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_ +require_scsi_debug_module_ + +ss=$sector_size_ + +default_start=1024s +default_end=2048s + +# create memory-backed device +scsi_debug_setup_ dev_size_mb=5 > dev-name || + skip_ 'failed to create scsi_debug device' +dev=$(cat dev-name) + +# TODO test simple shrink +# TODO test expand past end of the disk +# TODO test expand past begin of next partition +# TODO test shrink before start +# TODO test everything with GPT +# TODO more tests with extended/logical partitions + +parted -s $dev mklabel msdos > out 2> err || fail=1 +# expect no output +compare out /dev/null || fail=1 +compare err /dev/null || fail=1 + +# ensure that the disk is large enough +dev_n_sectors=$(parted -s $dev u s p|sed -n '2s/.* \([0-9]*\)s$/\1/p') +device_sectors_required=$(echo $default_end | sed 's/s$//') +# Ensure that $dev is large enough for this test +test $device_sectors_required -le $dev_n_sectors || fail=1 + +# create an empty partition +parted -s $dev mkpart primary $default_start $default_end > out 2>&1 || fail=1 +echo "Warning: The resulting partition is not properly" \ + "aligned for best performance." > exp +compare out exp || fail=1 + +# print partition table +parted -m -s $dev u s p > out 2>&1 || fail=1 + +# FIXME: check expected output + +# wait for new partition device to appear +wait_for_dev_to_appear_ ${dev}1 || { warn_ "${dev}1 did not appear" fail=1; } +sleep 1 + + +# extend the filesystem to end on sector 4096 +new_end=4096s +parted -s $dev resize 1 $new_end > out 2> err || fail=1 +# expect no output +compare out /dev/null || fail=1 +compare err /dev/null || fail=1 + +# print partition table +parted -m -s $dev u s p > out 2>&1 || fail=1 + +# compare against expected output +sed -n 3p out > k && mv k out || fail=1 +printf "1:$default_start:$new_end:3073s:::$ms;\n" > exp || fail=1 +compare out exp || fail=1 + +# Remove the partition explicitly, so that mklabel doesn't evoke a warning. +parted -s $dev rm 1 || fail=1 + +# Create a clean partition table for the next iteration. +parted -s $dev mklabel msdos > out 2>&1 || fail=1 +# expect no output +compare out /dev/null || fail=1 + +Exit $fail -- 1.7.7
pgpcATeU06m0j.pgp
Description: PGP signature

