71 lines
2.4 KiB
Diff
71 lines
2.4 KiB
Diff
|
|
From 23aaa44614a02d2184951142125cb55b36cef40a Mon Sep 17 00:00:00 2001
|
||
|
|
From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= <mail@nh2.me>
|
||
|
|
Date: Mon, 29 Apr 2019 10:22:26 +0200
|
||
|
|
Subject: [PATCH 04/20] x86: Check /proc/mounts before mtab for mounts
|
||
|
|
MIME-Version: 1.0
|
||
|
|
Content-Type: text/plain; charset=UTF-8
|
||
|
|
Content-Transfer-Encoding: 8bit
|
||
|
|
|
||
|
|
https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=23aaa44614a02d2184951142125cb55b36cef40a
|
||
|
|
|
||
|
|
In many situations, especially on read-only file systems
|
||
|
|
and initial ramdisks (intramfs/initrd), /etc/mtab does not exist.
|
||
|
|
|
||
|
|
Before this commit, kexec would fail to read mounts on such systems
|
||
|
|
in `find_mnt_by_fsname()`, such that `get_bootparam()` would not
|
||
|
|
`boot_params/data`, which would then lead to e.g. `setup_efi_data()`
|
||
|
|
not being called in `setup_efi_info()`.
|
||
|
|
|
||
|
|
As a result, kexec'ed kernels would not obtain EFI data,
|
||
|
|
subsequentially lack an `ACPI RSDP` entry, emitting:
|
||
|
|
|
||
|
|
ACPI BIOS Error (bug): A valid RSDP was not found (20180810/tbxfroot-210)
|
||
|
|
|
||
|
|
and thus fail to turn off the machine on poweroff, instead printing only:
|
||
|
|
|
||
|
|
reboot: System halted
|
||
|
|
|
||
|
|
This problem had to be worked around by passing `acpi_rsdp=` manually
|
||
|
|
before. This commit obviates this workaround.
|
||
|
|
|
||
|
|
See also:
|
||
|
|
|
||
|
|
* https://github.com/coreos/bugs/issues/167#issuecomment-487320879
|
||
|
|
* http://lists.infradead.org/pipermail/kexec/2012-October/006924.html
|
||
|
|
|
||
|
|
Signed-off-by: Niklas Hambüchen <mail@nh2.me>
|
||
|
|
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||
|
|
---
|
||
|
|
kexec/arch/i386/x86-linux-setup.c | 8 ++++++--
|
||
|
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
|
||
|
|
index 8fad115..74fb0c4 100644
|
||
|
|
--- a/kexec/arch/i386/x86-linux-setup.c
|
||
|
|
+++ b/kexec/arch/i386/x86-linux-setup.c
|
||
|
|
@@ -432,7 +432,7 @@ out:
|
||
|
|
/*
|
||
|
|
* This really only makes sense for virtual filesystems that are only expected
|
||
|
|
* to be mounted once (sysfs, debugsfs, proc), as it will return the first
|
||
|
|
- * instance listed in mtab.
|
||
|
|
+ * instance listed in /proc/mounts, falling back to mtab if absent.
|
||
|
|
*/
|
||
|
|
char *find_mnt_by_fsname(char *fsname)
|
||
|
|
{
|
||
|
|
@@ -440,7 +440,11 @@ char *find_mnt_by_fsname(char *fsname)
|
||
|
|
struct mntent *mnt;
|
||
|
|
char *mntdir;
|
||
|
|
|
||
|
|
- mtab = setmntent("/etc/mtab", "r");
|
||
|
|
+ mtab = setmntent("/proc/mounts", "r");
|
||
|
|
+ if (!mtab) {
|
||
|
|
+ // Fall back to mtab
|
||
|
|
+ mtab = setmntent("/etc/mtab", "r");
|
||
|
|
+ }
|
||
|
|
if (!mtab)
|
||
|
|
return NULL;
|
||
|
|
for(mnt = getmntent(mtab); mnt; mnt = getmntent(mtab)) {
|
||
|
|
--
|
||
|
|
1.8.3.1
|
||
|
|
|