SHA256
1
0
forked from pool/kdump

Accepting request 225921 from Kernel:kdump

Add Xen detection code (forwarded request 225920 from ptesarik)

OBS-URL: https://build.opensuse.org/request/show/225921
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/kdump?expand=0&rev=64
This commit is contained in:
Stephan Kulow 2014-03-14 14:16:32 +00:00 committed by Git OBS Bridge
commit cc463ed1fe
5 changed files with 402 additions and 0 deletions

View File

@ -0,0 +1,309 @@
From: Petr Tesarik <ptesarik@suse.cz>
Subject: Add '-X' to makedumpfile when dumping a Xen host
References: bnc#864910
Patch-mainline: 0.8.10
When dumping a Xen virtualization host, kdump should dump only Dom0 and
hypervisor pages, i.e. it should exclude all DomU pages.
A kdumptool flag is introduced to override this default behaviour.
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
---
NEWS | 4 +
doc/man/kdump.5.txt.in | 7 +-
kdumptool/savedump.cc | 9 ++
kdumptool/util.cc | 166 +++++++++++++++++++++++++++++++++++++++++++++++++
kdumptool/util.h | 20 +++++
sysconfig.kdump.in | 3
6 files changed, 206 insertions(+), 3 deletions(-)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+0.8.10
+------
+ * Filter out DomU pages, when dumping a Xen virtualization host
+
0.8.9
-----
* Fixed dracut hook install
--- a/doc/man/kdump.5.txt.in
+++ b/doc/man/kdump.5.txt.in
@@ -481,7 +481,7 @@ KDUMPTOOL_FLAGS
~~~~~~~~~~~~~~~
This is a space-separated list of flags to tweak the run-time behaviour of
-*kdumptool*(8). Currently, only one flag is supported:
+*kdumptool*(8). These flags are recognized:
*NOSPARSE*::
Disable the creation of sparse-files. This flag is for debugging purposes,
@@ -495,6 +495,11 @@ This is a space-separated list of flags
You can specify this flag to force the use of only one dumping process,
regardless of the value of KDUMP_CPUS.
+*XENALLDOMAINS*::
+ When dumping a Xen virtualization host, *makedumpfile*(8) is normally
+ invoked with the _-X_ option to exclude DomU pages. This flag can be
+ used to include all pages in the dump.
+
Default: ""
KDUMP_NETCONFIG
--- a/kdumptool/savedump.cc
+++ b/kdumptool/savedump.cc
@@ -275,7 +275,12 @@ void SaveDump::saveDump(const RootDirURL
cerr << "Splitting ELF dumps is not supported." << endl;
}
- if (useElf && dumplevel == 0) {
+ bool excludeDomU = false;
+ if (!config->kdumptoolContainsFlag("XENALLDOMAINS") &&
+ Util::isXenCoreDump(m_dump.c_str()))
+ excludeDomU = true;
+
+ if (useElf && dumplevel == 0 && !excludeDomU) {
// use file source?
provider = new FileDataProvider(m_dump.c_str());
m_useMakedumpfile = false;
@@ -287,6 +292,8 @@ void SaveDump::saveDump(const RootDirURL
cmdline << "--split ";
cmdline << config->MAKEDUMPFILE_OPTIONS.value() << " ";
cmdline << "-d " << config->KDUMP_DUMPLEVEL.value() << " ";
+ if (excludeDomU)
+ cmdline << "-X ";
if (useElf)
cmdline << "-E ";
if (useCompressed)
--- a/kdumptool/util.cc
+++ b/kdumptool/util.cc
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/utsname.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include <libelf.h>
#include <gelf.h>
@@ -162,6 +163,171 @@ bool Util::isElfFile(const string &file)
} catch (...) {
close(fd);
throw;
+ }
+
+ return ret;
+}
+
+// -----------------------------------------------------------------------------
+static off_t FindElfNoteByName(int fd, off_t offset, size_t sz,
+ const char *name)
+ throw (KError)
+{
+ char *buf, *p;
+ size_t to_read;
+ size_t nlen;
+ off_t ret = (off_t)-1;
+
+ Debug::debug()->trace("FindElfNoteByName(%d, %lu, %lu, %s)",
+ fd, (unsigned long)offset, (unsigned long)sz, name);
+
+ if (lseek(fd, offset, SEEK_SET) == (off_t)-1)
+ throw KSystemError("Cannot seek to ELF notes", errno);
+
+ buf = new char[sz];
+ try {
+ to_read = sz;
+ p = buf;
+ while (to_read) {
+ ssize_t bytes_read = read(fd, p, to_read);
+ if (bytes_read < 0)
+ throw KSystemError("Cannot read ELF note", errno);
+ else if (!bytes_read)
+ throw KError("Unexpected EOF while reading ELF note");
+
+ to_read -= bytes_read;
+ p += bytes_read;
+ }
+
+ nlen = strlen(name);
+ to_read = sz;
+ p = buf;
+ while (to_read) {
+ Elf64_Nhdr *hdr = reinterpret_cast<Elf64_Nhdr*>(p);
+ if (to_read < sizeof(*hdr))
+ break;
+ to_read -= sizeof(*hdr);
+ p += sizeof(*hdr);
+
+ size_t notesz =
+ ((hdr->n_namesz + 3) & (-(Elf64_Word)4)) +
+ ((hdr->n_descsz + 3) & (-(Elf64_Word)4));
+ if (to_read < notesz)
+ break;
+
+ if ((hdr->n_namesz == nlen && !memcmp(p, name, nlen)) ||
+ (hdr->n_namesz == nlen+1 && !memcmp(p, name, nlen+1))) {
+ ret = offset + (p - buf) - sizeof(*hdr);
+ break;
+ }
+
+ to_read -= notesz;
+ p += notesz;
+ }
+ } catch (...) {
+ delete buf;
+ throw;
+ }
+
+ return ret;
+}
+
+// -----------------------------------------------------------------------------
+#define ELF_HEADER_MAPSIZE (128*1024)
+
+bool Util::isXenCoreDump(int fd)
+ throw (KError)
+{
+ void *map = MAP_FAILED;
+ Elf *elf = (Elf*)0;
+ bool ret;
+
+ Debug::debug()->trace("isXenCoreDump(%d)", fd);
+
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ throw KError("libelf is out of date.");
+
+ try {
+ map = mmap(NULL, ELF_HEADER_MAPSIZE, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (map == MAP_FAILED) {
+ map = mmap(NULL, ELF_HEADER_MAPSIZE, PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (map == MAP_FAILED)
+ throw KSystemError("Cannot allocate ELF headers", errno);
+
+ size_t to_read = ELF_HEADER_MAPSIZE;
+ char *p = reinterpret_cast<char *>(map);
+ while (to_read) {
+ ssize_t bytes_read = read(fd, p, to_read);
+ if (bytes_read < 0)
+ throw KSystemError("ELF read error", errno);
+ else if (!bytes_read)
+ break;
+
+ to_read -= bytes_read;
+ p += bytes_read;
+ }
+ }
+ elf = elf_memory(reinterpret_cast<char *>(map), ELF_HEADER_MAPSIZE);
+ if (!elf)
+ throw KELFError("elf_memory() failed", elf_errno());
+
+ if (elf_kind(elf) != ELF_K_ELF)
+ return false;
+
+ switch (gelf_getclass(elf)) {
+ case ELFCLASS32:
+ case ELFCLASS64:
+ break;
+ default:
+ throw KError("Unrecognized ELF class");
+ }
+
+ size_t phnum, i;
+ if (elf_getphdrnum(elf, &phnum))
+ throw KELFError("Cannot count ELF program headers", elf_errno());
+
+ for (i = 0; i < phnum; ++i) {
+ GElf_Phdr phdr;
+
+ if (gelf_getphdr(elf, i, &phdr) != &phdr)
+ throw KELFError("getphdr() failed.", elf_errno());
+
+ if (phdr.p_type == PT_NOTE &&
+ FindElfNoteByName(fd, phdr.p_offset, phdr.p_filesz, "Xen")
+ != (off_t)-1) {
+ ret = true;
+ break;
+ }
+ }
+ } catch (...) {
+ if (elf)
+ elf_end(elf);
+ if (map != MAP_FAILED)
+ munmap(map, ELF_HEADER_MAPSIZE);
+ throw;
+ }
+
+ munmap(map, ELF_HEADER_MAPSIZE);
+ elf_end(elf);
+ return ret;
+}
+
+// -----------------------------------------------------------------------------
+bool Util::isXenCoreDump(const string &file)
+ throw (KError)
+{
+ int fd = open(file.c_str(), O_RDONLY);
+ if (fd < 0) {
+ throw KSystemError("Opening of " + file + " failed.", errno);
+ }
+
+ bool ret;
+ try {
+ ret = isXenCoreDump(fd);
+ } catch (...) {
+ close(fd);
+ throw;
}
return ret;
--- a/kdumptool/util.h
+++ b/kdumptool/util.h
@@ -94,6 +94,26 @@ class Util {
throw (KError);
/**
+ * Checks if @p filename is a Xen core dump.
+ *
+ * @param[in] filename the file to check
+ * @return @c true if it's a Xen core dump, @c false otherwise
+ * @exception KError if opening the file failed
+ */
+ static bool isXenCoreDump(const std::string &filename)
+ throw (KError);
+
+ /**
+ * Checks if @p filename is a Xen core dump.
+ *
+ * @param[in] fd a file descriptor
+ * @return @c true if it's a Xen core dump, @c false otherwise
+ * @exception KError if opening the file failed
+ */
+ static bool isXenCoreDump(int fd)
+ throw (KError);
+
+ /**
* Frees a vector.
*/
template <typename T>
--- a/sysconfig.kdump.in
+++ b/sysconfig.kdump.in
@@ -260,7 +260,7 @@ KDUMP_POSTSCRIPT=""
#
KDUMP_COPY_KERNEL="yes"
-## Type: string(NOSPARSE,NOSPLIT)
+## Type: string(NOSPARSE,NOSPLIT,XENALLDOMAINS)
## Default: ""
## ServiceRestart: kdump
#
@@ -268,6 +268,7 @@ KDUMP_COPY_KERNEL="yes"
#
# NOSPARSE disable creation of sparse files.
# NOSPLIT do not pass "--split" to makedumpfile even if KDUMP_CPUS > 1
+# XENALLDOMAINS do not filter out Xen DomU pages
#
# See also: kdump(5).
#

View File

@ -0,0 +1,39 @@
From: Julian Wolf <juwolf@suse.com>
Subject: Added dracut network activation in initrd to mkdumprd
Patch-mainline: not yet
Acked-by: Petr Tesarik <ptesarik@suse.cz>
---
init/mkdumprd | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--- a/init/mkdumprd
+++ b/init/mkdumprd
@@ -123,6 +123,26 @@ function run_dracut()
DRACUT_ARGS="--force --hostonly --omit 'systemd plymouth resume usrmount'"
+ # network configuration
+ if [ "$KDUMP_NETCONFIG" = "auto" ] ; then
+ status_message "Network: auto"
+ DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1'"
+ elif [ -z "$KDUMP_NETCONFIG" ] ; then
+ status_message "Network: none"
+ else
+ interface=$(echo "$KDUMP_NETCONFIG" | cut -d ':' -f 1)
+ mode=$(echo "$KDUMP_NETCONFIG" | cut -d ':' -f 2)
+
+ status_message "Network interface: $interface"
+ if [ "$mode" = "static" ] ; then
+ status_message "Network mode: Static IP"
+ DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1'"
+ else
+ status_message "Network mode: Automatic IP (DHCP)"
+ DRACUT_ARGS+=" --kernel-cmdline 'rd.neednet=1 ip=${interface}:dhcp'"
+ fi
+ fi
+
# add mount points
kdump_get_mountpoints || return 1
i=0

View File

@ -0,0 +1,25 @@
From: Julian Wolf <juwolf@suse.com>
Subject: Fixed wrong argument for ledblink.
Patch-mainline: not yet
There is no --background option for kdumptool ledblink.
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
---
init/save_dump.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/init/save_dump.sh
+++ b/init/save_dump.sh
@@ -143,8 +143,8 @@ FADUMP_ENABLED=/sys/kernel/fadump_enable
FADUMP_RELEASE_MEM=/sys/kernel/fadump_release_mem
#
-# start LED blinking in background
-kdumptool ledblink --background
+# start LED blinking
+kdumptool ledblink &
#
# create core dumps by default here for kdumptool debugging

View File

@ -1,3 +1,26 @@
-------------------------------------------------------------------
Fri Mar 14 11:03:35 UTC 2014 - ptesarik@suse.cz
- kdump-0.8.9-detect-xen-dumps.patch: Add '-X' to makedumpfile when
dumping a Xen host (bnc#864910).
-------------------------------------------------------------------
Fri Mar 14 07:21:41 UTC 2014 - ptesarik@suse.cz
- kdump-ledblink-background.patch: Run kdumptool in the background.
-------------------------------------------------------------------
Wed Mar 5 16:58:02 UTC 2014 - juwolf@suse.com
- kdump-initrd-network.patch: Added dracut network activation in
initrd to mkdumprd.
-------------------------------------------------------------------
Tue Mar 4 12:19:24 UTC 2014 - juwolf@suse.com
- kdump-ledblink-background.patch: Fixed wrong argument for
ledblink.
------------------------------------------------------------------- -------------------------------------------------------------------
Sun Mar 2 15:35:11 UTC 2014 - ptesarik@suse.cz Sun Mar 2 15:35:11 UTC 2014 - ptesarik@suse.cz

View File

@ -49,6 +49,9 @@ PreReq: %insserv_prereq %fillup_prereq mkinitrd
Source: %{name}-%{version}.tar.bz2 Source: %{name}-%{version}.tar.bz2
Source2: %{name}-%{version}-rpmlintrc Source2: %{name}-%{version}-rpmlintrc
Source3: kdump.service Source3: kdump.service
Patch1: %{name}-ledblink-background.patch
Patch2: %{name}-initrd-network.patch
Patch3: %{name}-%{version}-detect-xen-dumps.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build
# rename "kdump-helpers" (10.3) -> "kdump" (11.0/SP2) # rename "kdump-helpers" (10.3) -> "kdump" (11.0/SP2)
Provides: kdump-helpers = %{version} Provides: kdump-helpers = %{version}
@ -86,6 +89,9 @@ Authors:
%prep %prep
%setup %setup
%patch1 -p1
%patch2 -p1
%patch3 -p1
%build %build
export CFLAGS="%optflags" export CFLAGS="%optflags"