[Libguestfs] [PATCH v2] Enable coredumps to be captured from the appliance (RHBZ#619334).
Richard W.M. Jones
rjones at redhat.com
Mon Aug 2 11:12:55 UTC 2010
The last version omitted to implement LIBGUESTFS_COREDUMP. This
fixes that ...
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
-------------- next part --------------
>From 927fce62f13bf2201bc93e2cba88334a383268e5 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Sat, 31 Jul 2010 14:35:32 +0100
Subject: [PATCH] Enable coredumps to be captured from the appliance (RHBZ#619334).
---
daemon/guestfsd.c | 45 ++++++++++++++++++++++++++++++
fish/guestfish.pod | 6 ++++
src/generator.ml | 72 ++++++++++++++++++++++++++++++++++++++++++++++++
src/guestfs-internal.h | 1 +
src/guestfs.c | 36 ++++++++++++++++++++++++
src/guestfs.pod | 6 ++++
src/launch.c | 8 +++++
7 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
index 49aca08..91d59cc 100644
--- a/daemon/guestfsd.c
+++ b/daemon/guestfsd.c
@@ -42,6 +42,8 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#ifdef HAVE_PRINTF_H
# include <printf.h>
@@ -211,6 +213,49 @@ main (int argc, char *argv[])
}
#ifndef WIN32
+ /* Enable coredumps. */
+ if (cmdline) {
+ char *p = strstr (cmdline, "guestfs_coredump=");
+ if (p) {
+ p += 17;
+ size_t len = strcspn (p, " \t\n");
+ char *coredump = strndup (p, len);
+ if (!coredump) {
+ perror ("strndup");
+ exit (EXIT_FAILURE);
+ }
+
+#define CORE_PATTERN "/proc/sys/kernel/core_pattern"
+ int fd = open (CORE_PATTERN, O_WRONLY);
+ if (fd == -1) {
+ perror ("open: " CORE_PATTERN);
+ exit (EXIT_FAILURE);
+ }
+ if (write (fd, coredump, len) < (ssize_t) len) {
+ perror ("write: " CORE_PATTERN);
+ exit (EXIT_FAILURE);
+ }
+ if (close (fd) == -1) {
+ perror ("close: " CORE_PATTERN);
+ exit (EXIT_FAILURE);
+ }
+
+ struct rlimit limit = {
+ .rlim_cur = RLIM_INFINITY,
+ .rlim_max = RLIM_INFINITY
+ };
+ if (setrlimit (RLIMIT_CORE, &limit) == -1) {
+ perror ("setrlimit (RLIMIT_CORE)");
+ exit (EXIT_FAILURE);
+ }
+
+ if (verbose)
+ printf ("coredumps enabled to '%s'\n", coredump);
+ }
+ }
+#endif /* !WIN32 */
+
+#ifndef WIN32
/* Make sure SIGPIPE doesn't kill us. */
struct sigaction sa;
memset (&sa, 0, sizeof sa);
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
index bfcec5c..9aa01df 100644
--- a/fish/guestfish.pod
+++ b/fish/guestfish.pod
@@ -875,6 +875,12 @@ home directory can be used. See L</FILES>.
Pass additional options to the guest kernel.
+=item LIBGUESTFS_COREDUMP
+
+Capture coredump(s) which happen inside the libguestfs appliance.
+For further details of this option, see
+L<guestfs(3)/guestfs_set_coredump>.
+
=item LIBGUESTFS_DEBUG
Set C<LIBGUESTFS_DEBUG=1> to enable verbose messages. This has the
diff --git a/src/generator.ml b/src/generator.ml
index 52e7aba..fea771a 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -940,6 +940,78 @@ to specify the QEMU interface emulation to use at run time.");
This is the same as C<guestfs_add_drive_ro> but it allows you
to specify the QEMU interface emulation to use at run time.");
+ ("set_coredump", (RErr, [OptString "coredump"]), -1, [FishAlias "coredump"],
+ [],
+ "capture coredump to file or block device",
+ "\
+This option can be used to debug coredumps in the libguestfs
+appliance, in the daemon or in auxiliary programs that it
+runs. Set this to a string which is written verbatim to
+C</proc/sys/kernel/core_pattern> in the appliance during launch.
+Set this to NULL to disable coredumps.
+
+Useful values for this setting include:
+
+=over 4
+
+=item C</sysroot/core.%t.%p.%e>
+
+Coredump(s) are written to the root directory of the mounted
+guest disk. The name of the core file includes the current
+time (seconds since the epoch), PID, and the name of the
+executable.
+
+Note that the prefix C</sysroot> is an implementation detail
+of the current appliance and may change in future.
+
+This requires that a guest disk is mounted and writable
+at the time that the coredump is generated, otherwise
+the coredump will be discarded.
+
+=back
+
+The following are I<not> useful values for this setting:
+
+=over 4
+
+=item C</dev/vdb>
+
+The Linux kernel explicitly disallows writing coredumps to
+non-regular files. Therefore using a coredump capture device
+like this does not work.
+
+=item C</tmp/core>
+
+=item C<filename>
+
+If you use paths or filenames like these, then coredump(s) are written
+to the root disk in the appliance. This is not very useful, because
+the root disk is a ramdisk which is forgotten when the appliance
+shuts down.
+
+=back
+
+The default is C<NULL> unless overridden by setting the
+C<LIBGUESTFS_COREDUMP> environment variable.
+
+Note that you must set this before calling C<guestfs_launch>,
+otherwise it has no effect.
+
+This debugging feature is not part of the ABI and may be
+changed or removed in a future release.");
+
+ ("get_coredump", (RConstOptString "coredump", []), -1, [],
+ (* This cannot be tested with the current framework. The
+ * function can return NULL in normal operations, which the
+ * test framework interprets as an error.
+ *)
+ [],
+ "get the coredump debugging setting",
+ "\
+Return the coredump debugging setting.
+
+See C<guestfs_set_coredump>.");
+
]
(* daemon_functions are any functions which cause some action
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 12ca0ec..9f90904 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -110,6 +110,7 @@ struct guestfs_h
char *path; /* Path to kernel, initrd. */
char *qemu; /* Qemu binary. */
char *append; /* Append to kernel command line. */
+ char *coredump; /* Coredump path. */
int memsize; /* Size of RAM (megabytes). */
diff --git a/src/guestfs.c b/src/guestfs.c
index c54462d..10dd1e4 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -120,6 +120,12 @@ guestfs_create (void)
if (!g->append) goto error;
}
+ str = getenv ("LIBGUESTFS_COREDUMP");
+ if (str) {
+ g->coredump = strdup (str);
+ if (!g->coredump) goto error;
+ }
+
/* Choose a suitable memory size. Previously we tried to choose
* a minimal memory size, but this isn't really necessary since
* recent QEMU and KVM don't do anything nasty like locking
@@ -160,6 +166,7 @@ guestfs_create (void)
free (g->path);
free (g->qemu);
free (g->append);
+ free (g->coredump);
free (g);
return NULL;
}
@@ -509,6 +516,35 @@ guestfs__get_append (guestfs_h *g)
}
int
+guestfs__set_coredump (guestfs_h *g, const char *coredump)
+{
+ if (coredump != NULL) {
+ /* Because we pass this in the kernel command line, it will
+ * currently fail if it contains any whitespace. We ought to fix
+ * this by escaping spaces and unescaping them in the appliance. XXX
+ */
+ size_t i;
+ for (i = 0; i < strlen (coredump); ++i)
+ if (c_isspace (coredump[i])) {
+ error (g, "coredump parameter must not contain whitespace");
+ return -1;
+ }
+ }
+
+ free (g->coredump);
+ g->coredump = NULL;
+
+ g->coredump = coredump ? safe_strdup (g, coredump) : NULL;
+ return 0;
+}
+
+const char *
+guestfs__get_coredump (guestfs_h *g)
+{
+ return g->coredump;
+}
+
+int
guestfs__set_memsize (guestfs_h *g, int memsize)
{
g->memsize = memsize;
diff --git a/src/guestfs.pod b/src/guestfs.pod
index 5a2e7a5..0749da7 100644
--- a/src/guestfs.pod
+++ b/src/guestfs.pod
@@ -1478,6 +1478,12 @@ time.
Pass additional options to the guest kernel.
+=item LIBGUESTFS_COREDUMP
+
+Capture coredump(s) which happen inside the libguestfs appliance.
+For further details of this option, see
+L</guestfs_set_coredump>.
+
=item LIBGUESTFS_DEBUG
Set C<LIBGUESTFS_DEBUG=1> to enable verbose messages. This
diff --git a/src/launch.c b/src/launch.c
index 0d7a3f3..5d3c236 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -598,6 +598,12 @@ guestfs__launch (guestfs_h *g)
add_cmdline (g, "-net");
add_cmdline (g, "nic,model=" NET_IF ",vlan=0");
+ /* Coredump parameter for Linux command line. */
+ size_t len = g->coredump ? 32 + strlen (g->coredump) : 0;
+ char coredump[len];
+ if (g->coredump)
+ snprintf (coredump, len, "guestfs_coredump=%s", g->coredump);
+
#define LINUX_CMDLINE \
"panic=1 " /* force kernel to panic if daemon exits */ \
"console=ttyS0 " /* serial console */ \
@@ -613,11 +619,13 @@ guestfs__launch (guestfs_h *g)
"%s " /* (selinux) */
"%s " /* (vmchannel) */
"%s " /* (verbose) */
+ "%s " /* (coredump) */
"TERM=%s " /* (TERM environment variable) */
"%s", /* (append) */
g->selinux ? "selinux=1 enforcing=0" : "selinux=0",
vmchannel ? vmchannel : "",
g->verbose ? "guestfs_verbose=1" : "",
+ g->coredump ? coredump : "",
getenv ("TERM") ? : "linux",
g->append ? g->append : "");
--
1.7.1
More information about the Libguestfs
mailing list