[parted-devel] [PATCH] optionally delay commit in parted until requested

Arvin Schnell aschnell at suse.com
Tue Mar 22 13:26:44 UTC 2016


Hi Brian,

here is a updated version of my patch including your suggestions.

ciao
  Arvin

-- 
Arvin Schnell, <aschnell at suse.com>
Senior Software Engineer, Research & Development
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
Maxfeldstraße 5
90409 Nürnberg
Germany

---
 doc/C/parted.8                |  7 ++++
 libparted/tests/common.c      |  2 --
 libparted/tests/common.h      |  3 +-
 parted/parted.c               | 77 ++++++++++++++++++++++++++++++++++---------
 tests/Makefile.am             |  1 +
 tests/t0600-confirm-commit.sh | 55 +++++++++++++++++++++++++++++++
 6 files changed, 126 insertions(+), 19 deletions(-)
 create mode 100755 tests/t0600-confirm-commit.sh

diff --git a/doc/C/parted.8 b/doc/C/parted.8
index 5304375..fda211a 100644
--- a/doc/C/parted.8
+++ b/doc/C/parted.8
@@ -48,6 +48,9 @@ Use optimum alignment as given by the disk topology information. This
 aligns to a multiple of the physical block size in a way that guarantees
 optimal performance.
 .RE
+.TP
+.B -c, --confirm-commit
+require explicit confirmation to commit changes to the device
 
 .SH COMMANDS
 .TP
@@ -88,6 +91,10 @@ Display the partition table.
 .B quit
 Exit from \fBparted\fP.
 .TP
+.B commit
+Commit changes to the device and exit from \fBparted\fP. Only useful with
+option --confirm-commit.
+.TP
 .B rescue \fIstart\fP \fIend\fP
 Rescue a lost partition that was located somewhere between \fIstart\fP and
 \fIend\fP.  If a partition is found, \fBparted\fP will ask if you want to
diff --git a/libparted/tests/common.c b/libparted/tests/common.c
index a0be997..2b59305 100644
--- a/libparted/tests/common.c
+++ b/libparted/tests/common.c
@@ -16,8 +16,6 @@ _test_exception_handler (PedException* e)
         fail ("Exception of type %s has been raised: %s",
               ped_exception_get_type_string (e->type),
               e->message);
-
-        return PED_EXCEPTION_UNHANDLED;
 }
 
 char*
diff --git a/libparted/tests/common.h b/libparted/tests/common.h
index 1b1c801..9d2ea1d 100644
--- a/libparted/tests/common.h
+++ b/libparted/tests/common.h
@@ -23,4 +23,5 @@ int _implemented_disk_label (const char* label) _GL_ATTRIBUTE_PURE;
 /* Test specific exception handler
  *
  */
-PedExceptionOption _test_exception_handler (PedException* e);
+PedExceptionOption _test_exception_handler (PedException* e)
+        __attribute__((__noreturn__));
diff --git a/parted/parted.c b/parted/parted.c
index a9426c4..2a88b75 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -117,6 +117,7 @@ static struct option const options[] = {
         {"script",      0, NULL, 's'},
         {"version",     0, NULL, 'v'},
         {"align",       required_argument, NULL, 'a'},
+        {"confirm-commit", 0, NULL, 'c'},
         {"-pretend-input-tty", 0, NULL, PRETEND_INPUT_TTY},
         {NULL,          0, NULL, 0}
 };
@@ -128,6 +129,7 @@ static const char *const options_help [][2] = {
         {"script",      N_("never prompts for user intervention")},
         {"version",     N_("displays the version")},
         {"align=[none|cyl|min|opt]", N_("alignment for new partitions")},
+        {"confirm-commit", N_("require explicit confirmation of commit to device")},
         {NULL,          NULL}
 };
 
@@ -137,6 +139,7 @@ int     opt_machine_mode = 0;
 int     disk_is_modified = 0;
 int     is_toggle_mode = 0;
 int     alignment = ALIGNMENT_OPTIMAL;
+int     confirm_commit_mode = 0;
 
 static const char* number_msg = N_(
 "NUMBER is the partition number used by Linux.  On MS-DOS disk labels, the "
@@ -535,8 +538,9 @@ do_mklabel (PedDevice** dev, PedDisk** diskp)
         if (!disk)
                 goto error;
 
-        if (!ped_disk_commit (disk))
-                goto error_destroy_disk;
+        if (!confirm_commit_mode)
+                if (!ped_disk_commit (disk))
+                        goto error_destroy_disk;
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
@@ -814,8 +818,9 @@ do_mkpart (PedDevice** dev, PedDisk** diskp)
         if (ped_partition_is_flag_available (part, PED_PARTITION_LBA))
                 ped_partition_set_flag (part, PED_PARTITION_LBA, 1);
 
-        if (!ped_disk_commit (disk))
-                goto error;
+        if (!confirm_commit_mode)
+                if (!ped_disk_commit (disk))
+                        goto error;
 
         /* clean up */
         if (range_start != NULL)
@@ -874,8 +879,10 @@ do_name (PedDevice** dev, PedDisk** diskp)
                 goto error_free_name;
         free (name);
 
-        if (!ped_disk_commit (*diskp))
-                goto error;
+        if (!confirm_commit_mode)
+                if (!ped_disk_commit (*diskp))
+                        goto error;
+
         return 1;
 
 error_free_name:
@@ -1309,8 +1316,26 @@ _print_list ()
 }
 
 static int
+do_commit_and_quit (PedDevice** dev, PedDisk **diskp)
+{
+        if (*diskp)
+                ped_disk_commit(*diskp);
+
+        _done (*dev, *diskp);
+        exit (EXIT_SUCCESS);
+}
+
+static int
 do_quit (PedDevice** dev, PedDisk **diskp)
 {
+        if (confirm_commit_mode && disk_is_modified)
+        {
+                if (ped_exception_throw (PED_EXCEPTION_WARNING, PED_EXCEPTION_YES_NO,
+                                         _("There are uncommited changes. Really quit?"))
+                        != PED_EXCEPTION_YES)
+                        return 1;
+        }
+
         _done (*dev, *diskp);
         exit (EXIT_SUCCESS);
 }
@@ -1328,7 +1353,7 @@ _disk_get_part_type_for_sector (PedDisk* disk, PedSector sector)
         return PED_PARTITION_LOGICAL;
 }
 
-/* This function checks if "part" contains a file system, and returs
+/* This function checks if "part" contains a file system, and returns
  *      0 if either no file system was found, or the user declined to add it.
  *      1 if a file system was found, and the user chose to add it.
  *      -1 if the user chose to cancel the entire search.
@@ -1383,7 +1408,10 @@ _rescue_add_partition (PedPartition* part)
         }
 
         ped_partition_set_system (part, fs_type);
-        ped_disk_commit (part->disk);
+
+        if (!confirm_commit_mode)
+                ped_disk_commit (part->disk);
+
         return 1;
 }
 
@@ -1558,7 +1586,9 @@ do_resizepart (PedDevice** dev, PedDisk** diskp)
                             _("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 (!confirm_commit_mode)
+                ped_disk_commit (disk);
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
@@ -1590,7 +1620,9 @@ do_rm (PedDevice** dev, PedDisk** diskp)
                 goto error;
 
         ped_disk_delete_partition (*diskp, part);
-        ped_disk_commit (*diskp);
+
+        if (!confirm_commit_mode)
+                ped_disk_commit (*diskp);
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
@@ -1698,8 +1730,10 @@ do_disk_set (PedDevice** dev, PedDisk** diskp)
 
     if (!ped_disk_set_flag (*diskp, flag, state))
         goto error;
-    if (!ped_disk_commit (*diskp))
-        goto error;
+
+    if (!confirm_commit_mode)
+        if (!ped_disk_commit (*diskp))
+            goto error;
 
     if ((*dev)->type != PED_DEVICE_FILE)
         disk_is_modified = 1;
@@ -1735,8 +1769,10 @@ do_set (PedDevice** dev, PedDisk **diskp)
 
         if (!ped_partition_set_flag (part, flag, state))
                 goto error;
-        if (!ped_disk_commit (*diskp))
-                goto error;
+
+        if (!confirm_commit_mode)
+                if (!ped_disk_commit (*diskp))
+                        goto error;
 
         if ((*dev)->type != PED_DEVICE_FILE)
                 disk_is_modified = 1;
@@ -1988,6 +2024,14 @@ NULL),
         NULL, 1));
 
 command_register (commands, command_create (
+        str_list_create_unique ("commit", _("commit"), NULL),
+        do_commit_and_quit,
+        str_list_create (
+_("commit                                   commit and exit program"),
+NULL),
+        NULL, 1));
+
+command_register (commands, command_create (
         str_list_create_unique ("rescue", _("rescue"), NULL),
         do_rescue,
         str_list_create (
@@ -2119,7 +2163,7 @@ int     opt, help = 0, list = 0, version = 0, wrong = 0;
 
 while (1)
 {
-        opt = getopt_long (*argc_ptr, *argv_ptr, "hlmsva:",
+        opt = getopt_long (*argc_ptr, *argv_ptr, "hlmsvca:",
                            options, NULL);
         if (opt == -1)
                 break;
@@ -2134,6 +2178,7 @@ while (1)
                   alignment = XARGMATCH ("--align", optarg,
                                          align_args, align_types);
                   break;
+                case 'c': confirm_commit_mode = 1; break;
                 case PRETEND_INPUT_TTY:
                   pretend_input_tty = 1;
                   break;
@@ -2145,7 +2190,7 @@ while (1)
 
 if (wrong == 1) {
         fprintf (stderr,
-                 _("Usage: %s [-hlmsv] [-a<align>] [DEVICE [COMMAND [PARAMETERS]]...]\n"),
+                 _("Usage: %s [-hlmsvc] [-a<align>] [DEVICE [COMMAND [PARAMETERS]]...]\n"),
                  program_name);
         return 0;
 }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 001b9de..e6dfe5c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -38,6 +38,7 @@ TESTS = \
   t0400-loop-clobber-infloop.sh \
   t0500-dup-clobber.sh \
   t0501-duplicate.sh \
+  t0600-confirm-commit.sh \
   t1100-busy-label.sh \
   t1101-busy-partition.sh \
   t1102-loop-label.sh \
diff --git a/tests/t0600-confirm-commit.sh b/tests/t0600-confirm-commit.sh
new file mode 100755
index 0000000..1505926
--- /dev/null
+++ b/tests/t0600-confirm-commit.sh
@@ -0,0 +1,55 @@
+#!/bin/sh -x
+# check --confirm-commit option
+
+# Copyright (C) 2016 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_
+
+# create memory-backed device
+scsi_debug_setup_ dev_size_mb=8 > dev-name ||
+  skip_ 'failed to create scsi_debug device'
+dev=$(cat dev-name)
+
+# create msdos partition table and primary partition
+parted -s $dev mklabel msdos mkpart primary ext4 1MiB 2MiB || fail=1
+
+# create gpt partition table but do not commit to disk
+parted --confirm-commit -s $dev mklabel gpt > out 2>&1 || fail=1
+
+# check that msdos partition table and primary partition are present
+cat <<EOF > exp || fail=1
+BYT;
+$dev:16384s:scsi:512:512:msdos:Linux scsi_debug:;
+1:2048s:4095s:2048s:::;
+EOF
+parted -m -s $dev unit s print > out 2>&1 || fail=1
+compare exp out || fail=1
+
+# create gpt partition table and commit to disk
+parted --confirm-commit -s $dev mklabel gpt commit > out 2>&1 || fail=1
+
+# check that gpt was written
+cat <<EOF > exp || fail=1
+BYT;
+$dev:16384s:scsi:512:512:gpt:Linux scsi_debug:;
+EOF
+parted -m -s $dev unit s print > out 2>&1 || fail=1
+compare exp out || fail=1
+
+Exit $fail
-- 
2.1.4



More information about the parted-devel mailing list