[parted-devel] [PATCH v2 1/1] Fix resizepart command

Arvin Schnell aschnell at suse.com
Thu Sep 23 17:47:05 BST 2021


The resizepart command does not work properly with busy
partitions in script mode. The check and the warning for that are
located in the middle of parameter checking and parted asks for
the partition end again. So move that after parameter checking.

---
 NEWS                                 |  3 ++
 parted/parted.c                      | 73 +++++++++++++++++++++-------
 tests/Makefile.am                    |  1 +
 tests/t-lib-helpers.sh               |  5 ++
 tests/t1101-busy-partition.sh        |  2 +-
 tests/t1102-loop-label.sh            |  2 +-
 tests/t3210-resize-partition-busy.sh | 55 +++++++++++++++++++++
 7 files changed, 121 insertions(+), 20 deletions(-)
 create mode 100755 tests/t3210-resize-partition-busy.sh

diff --git a/NEWS b/NEWS
index 408a4f3..8eb259a 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ GNU parted NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug Fixes
+
+  Fix shrinking busy partitions in script mode.
 
 * Noteworthy changes in release 3.4 (2021-01-27) [stable]
 
diff --git a/parted/parted.c b/parted/parted.c
index 975700c..63ffaa9 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -236,21 +236,39 @@ _timer_handler (PedTimer* timer, void* context)
 }
 
 static int
-_partition_warn_busy (PedPartition* part)
+_partition_warn_busy (PedPartition* part, bool yes_in_script_mode)
 {
         char* path;
 
         if (ped_partition_is_busy (part)) {
                 path = ped_partition_get_path (part);
-                if (ped_exception_throw (
-                            PED_EXCEPTION_WARNING,
-                            PED_EXCEPTION_YES_NO,
-                            _("Partition %s is being used. Are you sure you " \
-                              "want to continue?"),
-                            path) != PED_EXCEPTION_YES)
-                {
-                        free (path);
-                        return 0;
+                if (opt_script_mode) {
+                        if (yes_in_script_mode) {
+                                ped_exception_throw (
+                                        PED_EXCEPTION_WARNING,
+                                        PED_EXCEPTION_UNHANDLED,
+                                        _("Partition %s is being used, continuing anyway."),
+                                        path);
+                        } else {
+                                ped_exception_throw (
+                                        PED_EXCEPTION_ERROR,
+                                        PED_EXCEPTION_UNHANDLED,
+                                        _("Partition %s is being used, aborting."),
+                                        path);
+                                free (path);
+                                return 0;
+                        }
+                } else {
+                        if (ped_exception_throw (
+                                PED_EXCEPTION_WARNING,
+                                PED_EXCEPTION_YES_NO,
+                                _("Partition %s is being used. Are you sure you " \
+                                  "want to continue?"),
+                                path) != PED_EXCEPTION_YES)
+                        {
+                                free (path);
+                                return 0;
+                        }
                 }
                 free (path);
         }
@@ -1729,9 +1747,14 @@ do_resizepart (PedDevice** dev, PedDisk** diskp)
         PedSector               start, end, oldend;
         PedGeometry             *range_end = NULL;
         PedConstraint*          constraint;
+        int                     cmdline_words = command_line_get_word_count();
+        /* update this if adding/removing arguments to/from this command */
+        const int               part_idx = 1;
+        const int               end_idx = 2;
         int rc = 0;
         char*                   end_input = NULL;
         char*                   end_size = NULL;
+        const bool              yes_in_script_mode = true;
 
         if (!disk) {
                 disk = ped_disk_new (*dev);
@@ -1755,7 +1778,8 @@ do_resizepart (PedDevice** dev, PedDisk** diskp)
         }
 
         /* If the partition is busy this may clear the command_line and prompt the user */
-        if (!_partition_warn_busy (part))
+        /* warn early if the partition end is not provided on cmdline */
+        if (cmdline_words <= part_idx && !_partition_warn_busy (part, yes_in_script_mode))
                 goto error;
 
         /* Push the End value back onto the command_line, if it exists */
@@ -1768,6 +1792,8 @@ do_resizepart (PedDevice** dev, PedDisk** diskp)
         if (!command_line_get_sector (_("End?"), *dev, &end, &range_end, &end_input))
                 goto error;
         _adjust_end_if_iec(&start, &end, range_end, end_input);
+        if (cmdline_words >= end_idx && !_partition_warn_busy (part, yes_in_script_mode))
+                goto error;
 
         /* Do not move start of the partition */
         constraint = constraint_from_start_end_fixed_start (*dev, start, range_end);
@@ -1775,13 +1801,23 @@ do_resizepart (PedDevice** dev, PedDisk** diskp)
                                           start, end))
                 goto error_destroy_constraint;
         /* warn when shrinking partition - might lose data */
-        if (part->geom.end < oldend)
-                if (ped_exception_throw (
+        if (part->geom.end < oldend) {
+                if (opt_script_mode) {
+                        char *path = ped_partition_get_path (part);
+                        ped_exception_throw (
                             PED_EXCEPTION_WARNING,
-                            PED_EXCEPTION_YES_NO,
-                            _("Shrinking a partition can cause data loss, " \
-                              "are you sure you want to continue?")) != PED_EXCEPTION_YES)
-                        goto error_destroy_constraint;
+                            PED_EXCEPTION_UNHANDLED,
+                            _("Shrinking partition %s, data loss possible."), path);
+                        free(path);
+                } else if (ped_exception_throw (
+                        PED_EXCEPTION_WARNING,
+                        PED_EXCEPTION_YES_NO,
+                        _("Shrinking a partition can cause data loss, " \
+                          "are you sure you want to continue?")) != PED_EXCEPTION_YES)
+                {
+		        goto error_destroy_constraint;
+                }
+        }
         ped_disk_commit (disk);
 
         if ((*dev)->type != PED_DEVICE_FILE)
@@ -1805,6 +1841,7 @@ static int
 do_rm (PedDevice** dev, PedDisk** diskp)
 {
         PedPartition*           part = NULL;
+        const bool              yes_in_script_mode = false;
 
         if (!*diskp)
                 *diskp = ped_disk_new (*dev);
@@ -1813,7 +1850,7 @@ do_rm (PedDevice** dev, PedDisk** diskp)
 
         if (!command_line_get_partition (_("Partition number?"), *diskp, &part))
                 goto error;
-        if (!_partition_warn_busy (part))
+        if (!_partition_warn_busy (part, yes_in_script_mode))
                 goto error;
 
         if (!ped_disk_delete_partition (*diskp, part))
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f9340aa..974c032 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -59,6 +59,7 @@ TESTS = \
   t3000-resize-fs.sh \
   t3200-resize-partition.sh \
   t3200-type-change.sh \
+  t3210-resize-partition-busy.sh \
   t3300-palo-prep.sh \
   t3310-flags.sh \
   t3400-whole-disk-FAT-partition.sh \
diff --git a/tests/t-lib-helpers.sh b/tests/t-lib-helpers.sh
index 33151bb..a02eeb2 100644
--- a/tests/t-lib-helpers.sh
+++ b/tests/t-lib-helpers.sh
@@ -362,6 +362,11 @@ require_xfs_()
   mkfs.xfs -V || skip_ "this test requires XFS support"
 }
 
+require_ext4_()
+{
+  mkfs.ext4 -V || skip_ "this test requires ext4 support"
+}
+
 require_dvhtool_()
 {
   dvhtool --help \
diff --git a/tests/t1101-busy-partition.sh b/tests/t1101-busy-partition.sh
index c936718..3cd1fd5 100755
--- a/tests/t1101-busy-partition.sh
+++ b/tests/t1101-busy-partition.sh
@@ -31,7 +31,7 @@ scsi_debug_setup_ dev_size_mb=10 > dev-name ||
 dev=$(cat dev-name)
 
 cat <<EOF > exp-error || framework_failure
-Warning: Partition ${dev}2 is being used. Are you sure you want to continue?
+Error: Partition ${dev}2 is being used, aborting.
 EOF
 
 parted -s "$dev" mklabel msdos > out 2>&1 || fail=1
diff --git a/tests/t1102-loop-label.sh b/tests/t1102-loop-label.sh
index 0a120b9..4fb310d 100644
--- a/tests/t1102-loop-label.sh
+++ b/tests/t1102-loop-label.sh
@@ -67,7 +67,7 @@ compare exp out || fail=1
 # make sure partition busy check works ( mklabel checks whole disk )
 parted -s "$dev" rm 1 > out 2>&1; test $? = 1 || fail=1
 # create expected output file
-echo "Warning: Partition ${dev} is being used. Are you sure you want to continue?" > exp
+echo "Error: Partition ${dev} is being used, aborting." > exp
 compare exp out || fail=1
 
 umount "$mount_point"
diff --git a/tests/t3210-resize-partition-busy.sh b/tests/t3210-resize-partition-busy.sh
new file mode 100755
index 0000000..96d1953
--- /dev/null
+++ b/tests/t3210-resize-partition-busy.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+# Test shrinking and growing a mounted partition
+
+# Copyright (C) 2021 SUSE LLC
+
+# 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_
+require_ext4_
+
+# create memory-backed device
+scsi_debug_setup_ dev_size_mb=300 > dev-name ||
+  skip_ 'failed to create scsi_debug device'
+dev=$(cat dev-name)
+
+# create GPT and partition
+parted --script "$dev" mklabel gpt > out 2> err || fail=1
+parted --script "$dev" mkpart "test1" ext4 0% 90% > out 2>&1 || fail=1
+
+# wait for new partition device to appear
+wait_for_dev_to_appear_ "${dev}1" || { warn_ "${dev}1 did not appear" fail=1; }
+
+# create ext4
+mkfs.ext4 "${dev}1" || skip_ mkfs.ext4 failed
+
+# mount ext4
+mount_point="$(pwd)/mnt"
+mkdir "$mount_point" || fail=1
+mount "${dev}1" "$mount_point" || fail=1
+
+# grow busy partition
+parted --script "$dev" resizepart 1 100% || fail=1
+
+# shrink busy partition
+parted --script "$dev" resizepart 1 95% || fail=1
+
+# unmount ext4
+umount "${dev}1" || fail=1
+
+Exit $fail
-- 
2.33.0




More information about the parted-devel mailing list