forked from pool/grub2
Accepting request 800577 from Base:System
OBS-URL: https://build.opensuse.org/request/show/800577 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=220
This commit is contained in:
commit
72fa4f7a10
199
grub-install-force-journal-draining-to-ensure-data-i.patch
Normal file
199
grub-install-force-journal-draining-to-ensure-data-i.patch
Normal file
@ -0,0 +1,199 @@
|
||||
From 3085db0922a1d803d4a9dfe54daae6fef20e4340 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 13 Apr 2020 16:08:59 +0800
|
||||
Subject: [PATCH] grub-install: force journal draining to ensure data integrity
|
||||
|
||||
In XFS, the system would end up in unbootable state if an abrupt power
|
||||
off after grub-install is occuring. It can be easily reproduced with.
|
||||
|
||||
grub-install /dev/vda; reboot -f
|
||||
|
||||
The grub error would show many different kinds of corruption in
|
||||
filesystem and the problem boils down to incompleted journal transaction
|
||||
which would leave pending writes behind in the on-disk journal. It is
|
||||
therefore necessary to recover the system via re-mounting the filesystem
|
||||
from linux system that all pending journal log can be replayed.
|
||||
|
||||
On the other hand if journal draining can be enforced by grub-install
|
||||
then it can bring more resilience to such abrupt power loss. The fsync
|
||||
is not enough here for XFS, because that only writes in-memory log to
|
||||
on-disk (ie makes sure broken state can be repaired). Unfortunately
|
||||
there's no designated system call to serve solely for the journal
|
||||
draining, so it can only be achieved via fsfreeze system call that the
|
||||
journal draining can happen as a byproduct during the process.
|
||||
|
||||
This patch adds fsfreeze/unfreeze at the end of grub-install to induce
|
||||
journal draining on journaled file system. However btrfs is excluded
|
||||
from the list as it is using fsync to drain journal and also is not
|
||||
desired as reportedly having negative side effect. With this patch
|
||||
applied, the boot falilure can no longer be reproduced with above
|
||||
procedure.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
grub-core/osdep/basic/journaled_fs.c | 26 +++++++++++++++++++
|
||||
grub-core/osdep/journaled_fs.c | 5 ++++
|
||||
grub-core/osdep/linux/journaled_fs.c | 48 ++++++++++++++++++++++++++++++++++++
|
||||
include/grub/util/install.h | 2 ++
|
||||
util/grub-install.c | 20 +++++++++++++++
|
||||
6 files changed, 102 insertions(+)
|
||||
create mode 100644 grub-core/osdep/basic/journaled_fs.c
|
||||
create mode 100644 grub-core/osdep/journaled_fs.c
|
||||
create mode 100644 grub-core/osdep/linux/journaled_fs.c
|
||||
|
||||
Index: grub-2.04/Makefile.util.def
|
||||
===================================================================
|
||||
--- grub-2.04.orig/Makefile.util.def
|
||||
+++ grub-2.04/Makefile.util.def
|
||||
@@ -645,6 +645,7 @@ program = {
|
||||
emu_condition = COND_s390x;
|
||||
common = grub-core/kern/emu/argp_common.c;
|
||||
common = grub-core/osdep/init.c;
|
||||
+ common = grub-core/osdep/journaled_fs.c;
|
||||
|
||||
ldadd = '$(LIBLZMA)';
|
||||
ldadd = libgrubmods.a;
|
||||
Index: grub-2.04/grub-core/osdep/basic/journaled_fs.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.04/grub-core/osdep/basic/journaled_fs.c
|
||||
@@ -0,0 +1,26 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB 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.
|
||||
+ *
|
||||
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/util/install.h>
|
||||
+
|
||||
+int
|
||||
+grub_install_sync_fs_journal (const char *path)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
Index: grub-2.04/grub-core/osdep/journaled_fs.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.04/grub-core/osdep/journaled_fs.c
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef __linux__
|
||||
+#include "linux/journaled_fs.c"
|
||||
+#else
|
||||
+#include "basic/journaled_fs.c"
|
||||
+#endif
|
||||
Index: grub-2.04/grub-core/osdep/linux/journaled_fs.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ grub-2.04/grub-core/osdep/linux/journaled_fs.c
|
||||
@@ -0,0 +1,48 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB 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.
|
||||
+ *
|
||||
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <fcntl.h>
|
||||
+#include <linux/fs.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <errno.h>
|
||||
+#include <grub/util/install.h>
|
||||
+
|
||||
+int
|
||||
+grub_install_sync_fs_journal (const char *path)
|
||||
+{
|
||||
+ int fd, ret;
|
||||
+
|
||||
+ fd = open (path, O_RDONLY);
|
||||
+
|
||||
+ if (fd == -1)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (ioctl (fd, FIFREEZE, 0) == 0)
|
||||
+ {
|
||||
+ ioctl(fd, FITHAW, 0);
|
||||
+ ret = 1;
|
||||
+ }
|
||||
+ else if (errno == EOPNOTSUPP)
|
||||
+ ret = 1;
|
||||
+ else
|
||||
+ ret = 0;
|
||||
+
|
||||
+ close (fd);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
Index: grub-2.04/include/grub/util/install.h
|
||||
===================================================================
|
||||
--- grub-2.04.orig/include/grub/util/install.h
|
||||
+++ grub-2.04/include/grub/util/install.h
|
||||
@@ -269,4 +269,6 @@ grub_util_get_target_name (const struct
|
||||
extern char *grub_install_copy_buffer;
|
||||
#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576
|
||||
|
||||
+int
|
||||
+grub_install_sync_fs_journal (const char *path);
|
||||
#endif
|
||||
Index: grub-2.04/util/grub-install.c
|
||||
===================================================================
|
||||
--- grub-2.04.orig/util/grub-install.c
|
||||
+++ grub-2.04/util/grub-install.c
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <grub/emu/config.h>
|
||||
#include <grub/util/ofpath.h>
|
||||
#include <grub/hfsplus.h>
|
||||
+#include <grub/time.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -1997,6 +1998,25 @@ main (int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
+ {
|
||||
+ const char *journaled_fs[] = {"xfs", "ext2", NULL};
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; journaled_fs[i]; ++i)
|
||||
+ if (grub_strcmp (grub_fs->name, journaled_fs[i]) == 0)
|
||||
+ {
|
||||
+ int retries = 10;
|
||||
+
|
||||
+ /* If the fs is already frozen at that point, we could generally
|
||||
+ * expected that it will be soon unfrozen again (assuming some other
|
||||
+ * process has frozen it for snapshotting or something), so we may
|
||||
+ * as well retry a few (limited) times in a delay loop. */
|
||||
+ while (retries-- && !grub_install_sync_fs_journal (grubdir))
|
||||
+ grub_sleep (1);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
fprintf (stderr, "%s\n", _("Installation finished. No error reported."));
|
||||
|
||||
/* Free resources. */
|
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue May 5 06:48:55 UTC 2020 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix boot failure as journaled data not get drained due to abrupt power
|
||||
off after grub-install (bsc#1167756)
|
||||
* grub-install-force-journal-draining-to-ensure-data-i.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Apr 16 13:35:10 UTC 2020 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
@ -224,6 +224,7 @@ Patch92: grub2-util-30_os-prober-multiple-initrd.patch
|
||||
Patch93: grub2-getroot-support-nvdimm.patch
|
||||
Patch94: grub2-install-fix-not-a-directory-error.patch
|
||||
Patch95: grub2-verifiers-fix-system-freeze-if-verify-failed.patch
|
||||
Patch96: grub-install-force-journal-draining-to-ensure-data-i.patch
|
||||
# Btrfs snapshot booting related patches
|
||||
Patch101: grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch
|
||||
Patch102: grub2-btrfs-02-export-subvolume-envvars.patch
|
||||
@ -546,6 +547,7 @@ swap partition while in resuming
|
||||
%patch93 -p1
|
||||
%patch94 -p1
|
||||
%patch95 -p1
|
||||
%patch96 -p1
|
||||
%patch101 -p1
|
||||
%patch102 -p1
|
||||
%patch103 -p1
|
||||
|
Loading…
x
Reference in New Issue
Block a user