[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#933511: partman-base: reformatting md raid 0.90 metadata does not delete metadata



Source: partman-base
Severity: normal
Tags: d-i patch

Dear Maintainer,

As reported in

    https://bugs.launchpad.net/ubuntu/+source/partman-base/+bug/1828558

installing over a drive previously used as a md raid can leave a system
that does not boot.  I tried and failed to convince parted upstream this
was their bug (https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36853) so
it probably makes sense to fix it in parted_server instead.

I'm attaching a WIP patch to this report. I'll probably upload something
like this to Ubuntu once I've tested it a bit.

Cheers,
mwh

-- System Information:
Debian Release: buster/sid
  APT prefers bionic-updates
  APT policy: (500, 'bionic-updates'), (500, 'bionic-security'), (500, 'bionic'), (400, 'bionic-proposed'), (100, 'bionic-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.15.0-55-generic (SMP w/4 CPU cores)
Locale: LANG=en_NZ.UTF-8, LC_CTYPE=en_NZ.UTF-8 (charmap=UTF-8), LANGUAGE=en_NZ.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
diff --git a/Makefile.am b/Makefile.am
index f93bf8e..e8027ba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,8 @@ bin_PROGRAMS = parted_server parted_devices partmap
 bin_SCRIPTS = partman partman-command partman-commit
 
 parted_server_SOURCES = parted_server.c
-parted_server_LDADD = $(libparted_fs_resize_LIBS) $(libparted_LIBS)
+parted_server_CPPFLAGS = $(blkid_CFLAGS)
+parted_server_LDADD = $(libparted_fs_resize_LIBS) $(libparted_LIBS) $(blkid_LIBS)
 
 parted_devices_SOURCES = parted_devices.c
 parted_devices_LDADD = $(libparted_LIBS)
diff --git a/configure.ac b/configure.ac
index 987cc4d..3d081ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,6 +7,7 @@ AC_DEFINE([_POSIX_C_SOURCE], [200809L], [Define the POSIX version])
 AC_PROG_CC
 
 PKG_CHECK_MODULES([libparted], [libparted])
+PKG_CHECK_MODULES([blkid], [blkid])
 
 AC_ARG_VAR([libparted_fs_resize_LIBS], [linker flags for libparted-fs-resize])
 AC_MSG_CHECKING([for libparted >= 3.1])
diff --git a/debian/changelog b/debian/changelog
index 51396e4..47c7341 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+partman-base (206ubuntu4~ppa4) eoan; urgency=medium
+
+  * parted_server.c: Wipe all known superblocks from device in
+    command_new_label. (LP: #1828558)
+
+ -- Michael Hudson-Doyle <michael.hudson@ubuntu.com>  Tue, 30 Jul 2019 10:18:37 +1200
+
 partman-base (206ubuntu3) eoan; urgency=medium
 
   * Revert previous upload, it is intentional to use non-part names, to
diff --git a/debian/control b/debian/control
index 2556d5d..e5d08a7 100644
--- a/debian/control
+++ b/debian/control
@@ -4,7 +4,7 @@ Priority: standard
 Maintainer: Ubuntu Installer Team <ubuntu-installer@lists.ubuntu.com>
 XSBC-Original-Maintainer: Debian Install System Team <debian-boot@lists.debian.org>
 Uploaders: Anton Zinoviev <zinoviev@debian.org>, Colin Watson <cjwatson@debian.org>, Christian Perrier <bubulle@debian.org>, Max Vozeler <xam@debian.org>
-Build-Depends: debhelper (>= 9), dh-autoreconf, dh-di (>= 2), pkg-config, po-debconf (>= 0.5.0), libparted-dev (>= 2.2)
+Build-Depends: debhelper (>= 9), dh-autoreconf, dh-di (>= 2), pkg-config, po-debconf (>= 0.5.0), libparted-dev (>= 2.2), libblkid-dev
 XS-Debian-Vcs-Browser: https://salsa.debian.org/installer-team/partman-base
 XS-Debian-Vcs-Git: https://salsa.debian.org/installer-team/partman-base.git
 
diff --git a/parted_server.c b/parted_server.c
index 41784b7..bfff500 100644
--- a/parted_server.c
+++ b/parted_server.c
@@ -15,6 +15,7 @@
 #include <ctype.h>
 #include <signal.h>
 #include <stdarg.h>
+#include <blkid.h>
 
 /**********************************************************************
    Logging
@@ -1864,6 +1865,57 @@ command_change_file_system()
         oprintf("OK\n");
 }
 
+/*
+ * wipe all superblocks libblkid knows about from a device
+ * (condensed from wipefs in util-linux)
+ */
+static int
+do_wipe(char *devname)
+{
+        blkid_probe pr = NULL;
+        int fd = -1;
+        int r = -1;
+
+        fd = open(devname, O_RDWR | O_EXCL);
+
+        log("do_wipe open(%s), %d", devname, fd);
+
+        if (fd < 0)
+                goto error;
+
+        pr = blkid_new_probe();
+        if (!pr || blkid_probe_set_device(pr, fd, 0, 0) != 0) {
+                log("setting up probe failed");
+                goto error;
+        }
+
+        blkid_probe_enable_superblocks(pr, 1);
+        blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_MAGIC |      /* return magic string and offset */
+                                          BLKID_SUBLKS_TYPE |           /* return superblock type */
+                                          BLKID_SUBLKS_BADCSUM);        /* accept bad checksums */
+
+        blkid_probe_enable_partitions(pr, 1);
+        blkid_probe_set_partitions_flags(pr, BLKID_PARTS_MAGIC |
+                                         BLKID_PARTS_FORCE_GPT);
+
+        while (blkid_do_probe(pr) == 0) {
+                char *type = "unknown";
+                blkid_probe_lookup_value(pr, "TYPE", &type, NULL);
+                log("wiping superblock of type %s", type);
+                if (blkid_do_wipe(pr, 0) != 0) {
+                        log("wiping failed");
+                }
+        }
+
+        fsync(fd);
+        r = 0;
+      error:
+        if (fd >= 0)
+                close(fd);
+        blkid_free_probe(pr);
+        return r;
+}
+
 void
 command_new_label()
 {
@@ -1887,6 +1939,12 @@ command_new_label()
            enough to change the partition table (i.e. `disk'). */
         set_disk_named(device_name, NULL);
         set_device_named(device_name, NULL);
+        log("command_new_label: wiping %s", device);
+        if (do_wipe(device) != 0) {
+                log("wiping superblocks from %s failed", device);
+        } else {
+                log("wiping superblocks from %s succeeded", device);
+        }
         dev = ped_device_get(device);
         free(device);
         if (NULL == dev)

Reply to: