The patch attached to this mail is better. On Wed, 31 Jul 2019 at 14:12, Michael Hudson-Doyle < michael.hud...@ubuntu.com> wrote:
> 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/parted_server.c b/parted_server.c index 41784b7..5c75684 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 @@ -1360,6 +1361,61 @@ is_system_with_firmware_on_disk() return result; } +/* + * 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); + + if (fd < 0) { + log("open(%s) failed errno %d", devname, errno); + goto error; + } + + log("do_wipe open(%s), %d", devname, fd); + + + 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"; + if (blkid_probe_lookup_value(pr, "TYPE", &type, NULL) < 0) + blkid_probe_lookup_value(pr, "PTTYPE", &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_commit() { @@ -1382,8 +1438,25 @@ command_commit() } open_out(); - if (disk != NULL && named_is_changed(device_name)) - ped_disk_commit(disk); + if (disk != NULL) { + /* ped_disk_clobber does not remove all superblock information + * -- in particular it does not wipe mdraid 0.90 metadata, + * which can lead to an unbootable system as in + * https://bugs.launchpad.net/ubuntu/+source/partman-base/+bug/1828558. + * parted upstream didn't think this was a bug so here we give + * it a helping hand by using libblkid to wipe all superblocks. */ + if (disk->needs_clobber) { + log("command_commit: wiping superblocks from %s", dev->path); + if (do_wipe(dev->path) != 0) { + log("wiping superblocks from %s failed", dev->path); + } else { + log("wiping superblocks from %s succeeded", dev->path); + } + } + if (named_is_changed(device_name)) { + ped_disk_commit(disk); + } + } unchange_named(device_name); oprintf("OK\n"); }