diff options
author | Chris Leech <christopher.leech@linux.intel.com> | 2011-03-31 17:21:15 +0000 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2011-04-18 15:58:41 +0800 |
commit | e467cbaa6cfea50ce2a60de645af03a3c7580e20 (patch) | |
tree | dab4162c69633642a4cc949bd3f23c6302c357ed | |
parent | e3bb6ccd50e483d06bfeaca24c9107c31f1cf5d7 (diff) | |
download | kexec-tools-e467cbaa6cfea50ce2a60de645af03a3c7580e20.tar.gz |
kexec, x86: fix kexec when boot_params.hardware_subarch != 0
Simon Horman <horms@...> writes:
>
> On Tue, Mar 29, 2011 at 09:04:53AM +0000, WANG Cong wrote:
> > On Mon, 28 Mar 2011 14:50:11 -0700, Chris Leech wrote:
> >
> > > kexec needs to keep the subarch setting the same as the running kernel
> > > in the boot parameters, or the kernel will die in early setup. I ran
> > > into this with X86_SUBARCH_MRST, but it should apply to CE4100 and any
> > > future subarch that uses non-default early setup code.
> > >
> > > This patch requires debugfs mounted at /sys/kernel/debug, as that's the
> > > only way I know of to get at the running kernels boot_params. Without
> > > debugfs mounted it falls back to the current behavior of assuming
> > > subarch 0.
> > >
> > ...
> > >
> > > +#define BOOT_PARAMS_DBGFS "/sys/kernel/debug/boot_params/data"
> >
> > A minor issue here is that you are using a hard-coded debugfs path,
> > debugfs can be also mounted to /debug too, so it is better that if we can
> > search the path dynamically here.
>
> Do you think it would be better for the code to loop through
> a few common alternatives for the path?
>
Not fully tested, but instead of looping through possible mount points maybe
look through mtab in search of debugfs by fs type.
Something like this?
kexec, x86: search for debugfs mountpoint in /etc/mtab
From: Chris Leech <christopher.leech@linux.intel.com>
Signed-off-by: Chris Leech <christopher.leech@linux.intel.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | kexec/arch/i386/x86-linux-setup.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c index 50b32be0..0528ceaa 100644 --- a/kexec/arch/i386/x86-linux-setup.c +++ b/kexec/arch/i386/x86-linux-setup.c @@ -30,6 +30,7 @@ #include <linux/fb.h> #include <unistd.h> #include <dirent.h> +#include <mntent.h> #include <x86/x86-linux.h> #include "../../kexec.h" #include "kexec-x86.h" @@ -397,14 +398,44 @@ out: real_mode->eddbuf_entries); } -#define BOOT_PARAMS_DBGFS "/sys/kernel/debug/boot_params/data" +/* + * 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. + */ +char *find_mnt_by_fsname(char *fsname) +{ + FILE *mtab; + struct mntent *mnt; + char *mntdir; + + mtab = setmntent("/etc/mtab", "r"); + if (!mtab) + return NULL; + for(mnt = getmntent(mtab); mnt; mnt = getmntent(mtab)) { + if (strcmp(mnt->mnt_fsname, fsname) == 0) + break; + } + mntdir = mnt ? strdup(mnt->mnt_dir) : NULL; + endmntent(mtab); + return mntdir; +} void setup_subarch(struct x86_linux_param_header *real_mode) { int data_file; const off_t offset = offsetof(typeof(*real_mode), hardware_subarch); + char *debugfs_mnt; + char filename[PATH_MAX]; + + debugfs_mnt = find_mnt_by_fsname("debugfs"); + if (!debugfs_mnt) + return; + snprintf(filename, PATH_MAX, "%s/%s", debugfs_mnt, "boot_params/data"); + filename[PATH_MAX-1] = 0; + free(debugfs_mnt); - data_file = open(BOOT_PARAMS_DBGFS, O_RDONLY); + data_file = open(filename, O_RDONLY); if (data_file < 0) return; if (lseek(data_file, offset, SEEK_SET) < 0) |