This adds a new debug command, core_pattern, which writes a new pattern for
coredump files to the appliance kernel, and sets the daemon's hard and soft core
limits to infinity.
---
daemon/debug.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/daemon/debug.c b/daemon/debug.c
index 0867ccd..d9863b8 100644
--- a/daemon/debug.c
+++ b/daemon/debug.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
+#include <sys/resource.h>
#include "../src/guestfs_protocol.h"
#include "daemon.h"
@@ -52,6 +53,7 @@ static char *debug_ls (const char *subcmd, int argc, char *const *const
argv);
static char *debug_ll (const char *subcmd, int argc, char *const *const argv);
static char *debug_segv (const char *subcmd, int argc, char *const *const argv);
static char *debug_sh (const char *subcmd, int argc, char *const *const argv);
+static char *debug_core_pattern (const char *subcmd, int argc, char *const *const argv);
static struct cmd cmds[] = {
{ "help", debug_help },
@@ -61,6 +63,7 @@ static struct cmd cmds[] = {
{ "ll", debug_ll },
{ "segv", debug_segv },
{ "sh", debug_sh },
+ { "core_pattern", debug_core_pattern },
{ NULL, NULL }
};
#endif
@@ -338,6 +341,45 @@ debug_ll (const char *subcmd, int argc, char *const *const argv)
return out;
}
+/* Enable core dumping to the given core pattern.
+ * Note that this pattern is relative to any chroot of the process which
+ * crashes. This means that if you want to write the core file to the guest's
+ * storage the pattern must start with /sysroot only if the command which
+ * crashes doesn't chroot.
+ */
+static char *
+debug_core_pattern (const char *subcmd, int argc, char *const *const argv)
+{
+ if (argc < 1) {
+ reply_with_error ("core_pattern: expecting a core pattern");
+ }
+
+ const char *pattern = argv[0];
+ const size_t pattern_len = strlen(pattern);
+
+#define CORE_PATTERN "/proc/sys/kernel/core_pattern"
+ int fd = open (CORE_PATTERN, O_WRONLY);
+ if (fd == -1) {
+ reply_with_error ("open: " CORE_PATTERN);
+ }
+ if (write (fd, pattern, pattern_len) < (ssize_t) pattern_len) {
+ reply_with_error ("write: " CORE_PATTERN);
+ }
+ if (close (fd) == -1) {
+ reply_with_error ("close: " CORE_PATTERN);
+ }
+
+ struct rlimit limit = {
+ .rlim_cur = RLIM_INFINITY,
+ .rlim_max = RLIM_INFINITY
+ };
+ if (setrlimit (RLIMIT_CORE, &limit) == -1) {
+ reply_with_error ("setrlimit (RLIMIT_CORE)");
+ }
+
+ return strdup("ok");
+}
+
#endif /* ENABLE_DEBUG_COMMAND */
#if ENABLE_DEBUG_COMMAND
--
1.7.2