[parted-devel] [PATCH] added option --wipesignatures

Arvin Schnell aschnell at suse.com
Wed Jul 28 11:37:34 BST 2021


Hi,

here is a patch for parted that adds an option to wipe signatures
during mkpart in the region parted is about to create the new
partition. The patch was developed at SUSE about five years
ago. I have now adapted it to master and added a test.

Without wiping signatures it can happen that old signatures cause
udev or other system parts to scan the new partition and
immediately make them busy, e.g. by start an old RAID.

Other tools have similar options, e.g. fdisk, sfdisk and
lvcreate.

Thanks,
  Arvin

---
 NEWS                          |  2 ++
 doc/C/parted.8                |  4 ++++
 include/parted/device.in.h    |  2 ++
 libparted/arch/linux.c        | 39 +++++++++++++++++++++++++++++++++++
 libparted/device.c            | 16 ++++++++++++++
 parted/parted.c               | 15 ++++++++++++++
 tests/Makefile.am             |  1 +
 tests/t1800-wipesignatures.sh | 36 ++++++++++++++++++++++++++++++++
 8 files changed, 115 insertions(+)
 create mode 100755 tests/t1800-wipesignatures.sh

diff --git a/NEWS b/NEWS
index 408a4f3..22462ba 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ GNU parted NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+  New option --wipesignatures makes mkpart wipe existing signatures
+  from the disk region where it is about to create the partition.
 
 * Noteworthy changes in release 3.4 (2021-01-27) [stable]
 
diff --git a/doc/C/parted.8 b/doc/C/parted.8
index d8e556e..797043d 100644
--- a/doc/C/parted.8
+++ b/doc/C/parted.8
@@ -33,6 +33,10 @@ automatically answer "fix" to exceptions in script mode
 .B -v, --version
 displays the version
 .TP
+.B --wipesignatures
+mkpart wipes the superblock signatures from the disk region where it is
+about to create the partition
+.TP
 .B -a \fIalignment-type\fP, --align \fIalignment-type\fP
 Set alignment for newly created partitions, valid alignment types are:
 .RS
diff --git a/include/parted/device.in.h b/include/parted/device.in.h
index 414f770..0fb3602 100644
--- a/include/parted/device.in.h
+++ b/include/parted/device.in.h
@@ -122,6 +122,7 @@ struct _PedDeviceArchOps {
         /* These functions are optional */
         PedAlignment *(*get_minimum_alignment)(const PedDevice *dev);
         PedAlignment *(*get_optimum_alignment)(const PedDevice *dev);
+        int (*wipe_signatures)(const PedDevice *dev, PedSector start, PedSector length);
 };
 
 #include <parted/constraint.h>
@@ -158,6 +159,7 @@ extern PedConstraint *ped_device_get_optimal_aligned_constraint(
 
 extern PedAlignment *ped_device_get_minimum_alignment(const PedDevice *dev);
 extern PedAlignment *ped_device_get_optimum_alignment(const PedDevice *dev);
+extern int ped_device_wipe_signatures(const PedDevice *dev, PedSector start, PedSector length);
 
 /* private stuff ;-) */
 
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index aacc94f..1efe101 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -3324,6 +3324,42 @@ linux_get_optimum_alignment(const PedDevice *dev)
                 blkid_topology_get_alignment_offset(tp) / dev->sector_size,
                 blkid_topology_get_optimal_io_size(tp) / dev->sector_size);
 }
+
+static int
+linux_wipe_signatures(const PedDevice *dev, PedSector start, PedSector length)
+{
+        PED_ASSERT (dev != NULL);
+        LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
+
+        blkid_loff_t wipe_offset = start * dev->sector_size;
+        blkid_loff_t wipe_size = length * dev->sector_size;
+
+        blkid_probe pr;
+        pr = blkid_new_probe();
+        if (!pr)
+                goto error;
+
+        if (blkid_probe_set_device(pr, arch_specific->fd, wipe_offset, wipe_size) == -1)
+                goto error_free_probe;
+        if (blkid_probe_enable_superblocks(pr, 1) == -1)
+                goto error_free_probe;
+        if (blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC) == -1)
+                goto error_free_probe;
+
+        while (blkid_do_probe(pr) == 0) {
+                if (blkid_do_wipe(pr, 0) == -1)
+                        goto error_free_probe;
+        }
+
+        blkid_free_probe(pr);
+        return 1;
+
+error_free_probe:
+        blkid_free_probe(pr);
+
+error:
+        return 0;
+}
 #endif
 
 #if defined __s390__ || defined __s390x__
@@ -3400,6 +3436,9 @@ static PedDeviceArchOps linux_dev_ops = {
         get_minimum_alignment:	linux_get_minimum_alignment,
         get_optimum_alignment:	linux_get_optimum_alignment,
 #endif
+#if USE_BLKID
+	wipe_signatures: linux_wipe_signatures,
+#endif
 };
 
 PedDiskArchOps linux_disk_ops =  {
diff --git a/libparted/device.c b/libparted/device.c
index 36fecd2..a670a2f 100644
--- a/libparted/device.c
+++ b/libparted/device.c
@@ -559,4 +559,20 @@ ped_device_get_optimum_alignment(const PedDevice *dev)
         return align;
 }
 
+/**
+ * Wipe superblock signatures from the specified region on the device.
+ *
+ * \return zero on failure
+ */
+int
+ped_device_wipe_signatures(const PedDevice *dev, PedSector start, PedSector length)
+{
+        int ret = 0;
+
+        if (ped_architecture->dev_ops->wipe_signatures)
+                ret = ped_architecture->dev_ops->wipe_signatures(dev, start, length);
+
+        return ret;
+}
+
 /** @} */
diff --git a/parted/parted.c b/parted/parted.c
index 22b5818..0a0049d 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -77,6 +77,7 @@ static int MEGABYTE_SECTORS (PedDevice* dev)
 enum
 {
   PRETEND_INPUT_TTY = CHAR_MAX + 1,
+  WIPESIGNATURES = CHAR_MAX + 2,
 };
 
 enum
@@ -119,6 +120,7 @@ static struct option const options[] = {
         {"fix",         0, NULL, 'f'},
         {"version",     0, NULL, 'v'},
         {"align",       required_argument, NULL, 'a'},
+        {"wipesignatures", 0, NULL, WIPESIGNATURES},
         {"-pretend-input-tty", 0, NULL, PRETEND_INPUT_TTY},
         {NULL,          0, NULL, 0}
 };
@@ -131,12 +133,14 @@ static const char *const options_help [][2] = {
         {"fix",         N_("in script mode, fix instead of abort when asked")},
         {"version",     N_("displays the version")},
         {"align=[none|cyl|min|opt]", N_("alignment for new partitions")},
+        {"wipesignatures", N_("wipe superblock signatures when creating partition")},
         {NULL,          NULL}
 };
 
 int     opt_script_mode = 0;
 int     opt_fix_mode = 0;
 int     pretend_input_tty = 0;
+int     wipesignatures = 0;
 int     opt_machine_mode = 0;
 int     disk_is_modified = 0;
 int     is_toggle_mode = 0;
@@ -825,6 +829,14 @@ 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 (wipesignatures) {
+                if (!ped_device_wipe_signatures(*dev, part->geom.start, part->geom.length))
+                        ped_exception_throw (
+                                        PED_EXCEPTION_WARNING,
+                                        PED_EXCEPTION_OK,
+                                        _("Wiping the superblock signatures has failed."));
+        }
+
         if (!ped_disk_commit (disk))
                 goto error_remove_part;
 
@@ -2217,6 +2229,9 @@ while (1)
                 case PRETEND_INPUT_TTY:
                   pretend_input_tty = 1;
                   break;
+                case WIPESIGNATURES:
+                  wipesignatures = 1;
+                  break;
                 default:
                   wrong = 1;
                   break;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3473e6b..2584941 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -45,6 +45,7 @@ TESTS = \
   t1104-remove-and-add-partition.sh \
   t1700-probe-fs.sh \
   t1701-rescue-fs.sh \
+  t1800-wipesignatures.sh \
   t2200-dos-label-recog.sh \
   t2201-pc98-label-recog.sh \
   t2300-dos-label-extended-bootcode.sh \
diff --git a/tests/t1800-wipesignatures.sh b/tests/t1800-wipesignatures.sh
new file mode 100755
index 0000000..bb8f426
--- /dev/null
+++ b/tests/t1800-wipesignatures.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Test --wipesignatures option
+
+# 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
+
+dev=loop-file
+
+# create device
+truncate --size 50MiB "$dev" || fail=1
+
+# create ext2 with 1 MiB offset and 48 MiB size
+mkfs.ext2 -E offset=$((1 * 1024*1024)) "$dev" $((48 * 1024*1024)) || fail=1
+
+# create partition that contains the ext2 and tell parted to wipe signatures
+parted --script --wipesignature "$dev" mklabel gpt mkpart test ext4 1MiB 49MiB > out 2>&1 || fail=1
+
+# check that parted does not detect the ext2
+parted --script --machine "$dev" print > out 2>&1 || fail=1
+grep ':ext2:' out && fail=1
+
+Exit $fail
-- 
Arvin Schnell, <aschnell at suse.com>
Senior Software Engineer, Research & Development

SUSE Software Solutions Germany GmbH
Maxfeldstraße 5
90409 Nürnberg
Germany

(HRB 36809, AG Nürnberg)

Geschäftsführer: Felix Imendörffer



More information about the parted-devel mailing list