diff options
author | Niklas Hambüchen <mail@nh2.me> | 2019-04-29 10:22:26 +0200 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2019-05-15 09:43:35 +0200 |
commit | 23aaa44614a02d2184951142125cb55b36cef40a (patch) | |
tree | e3cd3a4901cfe9a1a999f6a6aac2bfd49574a0bc | |
parent | eff53089523c331ac946df74ba365072a6fd1a95 (diff) | |
download | kexec-tools-23aaa44614a02d2184951142125cb55b36cef40a.tar.gz |
x86: Check /proc/mounts before mtab for mounts
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>
-rw-r--r-- | kexec/arch/i386/x86-linux-setup.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c index 8fad115d..74fb0c46 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)) { |