debug: Arrange prototypes in alphabetical order.
[libguestfs.git] / daemon / debug.c
index 0867ccd..9df4dc2 100644 (file)
@@ -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"
  * to find out what you can do.
  *
  * Commands always output a freeform string.
+ *
+ * Since libguestfs 1.5.7, the debug command has been enabled
+ * by default for all builds (previously you had to enable it
+ * in configure).  This command is not part of the stable ABI
+ * and may change at any time.
  */
 
-#if ENABLE_DEBUG_COMMAND
 struct cmd {
   const char *cmd;
   char * (*f) (const char *subcmd, int argc, char *const *const argv);
 };
 
 static char *debug_help (const char *subcmd, int argc, char *const *const argv);
+static char *debug_core_pattern (const char *subcmd, int argc, char *const *const argv);
 static char *debug_env (const char *subcmd, int argc, char *const *const argv);
 static char *debug_fds (const char *subcmd, int argc, char *const *const argv);
 static char *debug_ls (const char *subcmd, int argc, char *const *const argv);
@@ -55,6 +61,7 @@ static char *debug_sh (const char *subcmd, int argc, char *const *const argv);
 
 static struct cmd cmds[] = {
   { "help", debug_help },
+  { "core_pattern", debug_core_pattern },
   { "env", debug_env },
   { "fds", debug_fds },
   { "ls", debug_ls },
@@ -63,18 +70,10 @@ static struct cmd cmds[] = {
   { "sh", debug_sh },
   { NULL, NULL }
 };
-#endif
-
-#if ! ENABLE_DEBUG_COMMAND
-# define MAYBE_UNUSED ATTRIBUTE_UNUSED
-#else
-# define MAYBE_UNUSED /* empty */
-#endif
 
 char *
-do_debug (const char *subcmd MAYBE_UNUSED, char *const *argv MAYBE_UNUSED)
+do_debug (const char *subcmd, char *const *argv)
 {
-#if ENABLE_DEBUG_COMMAND
   int argc, i;
 
   for (i = argc = 0; argv[i] != NULL; ++i)
@@ -87,13 +86,8 @@ do_debug (const char *subcmd MAYBE_UNUSED, char *const *argv MAYBE_UNUSED)
 
   reply_with_error ("use 'debug help' to list the supported commands");
   return NULL;
-#else
-  reply_with_error ("guestfsd was not configured with --enable-debug-command");
-  return NULL;
-#endif
 }
 
-#if ENABLE_DEBUG_COMMAND
 static char *
 debug_help (const char *subcmd, int argc, char *const *const argv)
 {
@@ -338,22 +332,67 @@ debug_ll (const char *subcmd, int argc, char *const *const argv)
   return out;
 }
 
-#endif /* ENABLE_DEBUG_COMMAND */
+/* 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");
+    return NULL;
+  }
+
+  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_perror ("open: " CORE_PATTERN);
+    return NULL;
+  }
+  if (write (fd, pattern, pattern_len) < (ssize_t) pattern_len) {
+    reply_with_perror ("write: " CORE_PATTERN);
+    return NULL;
+  }
+  if (close (fd) == -1) {
+    reply_with_perror ("close: " CORE_PATTERN);
+    return NULL;
+  }
+
+  struct rlimit limit = {
+    .rlim_cur = RLIM_INFINITY,
+    .rlim_max = RLIM_INFINITY
+  };
+  if (setrlimit (RLIMIT_CORE, &limit) == -1) {
+    reply_with_perror ("setrlimit (RLIMIT_CORE)");
+    return NULL;
+  }
+
+  char *ret = strdup ("ok");
+  if (NULL == ret) {
+    reply_with_perror ("strdup");
+    return NULL;
+  }
+
+  return ret;
+}
 
-#if ENABLE_DEBUG_COMMAND
 static int
 write_cb (void *fd_ptr, const void *buf, size_t len)
 {
   int fd = *(int *)fd_ptr;
   return xwrite (fd, buf, len);
 }
-#endif
 
 /* Has one FileIn parameter. */
 int
-do_debug_upload (const char *filename MAYBE_UNUSED, int mode MAYBE_UNUSED)
+do_debug_upload (const char *filename, int mode)
 {
-#if ENABLE_DEBUG_COMMAND
   /* Not chrooted - this command lets you upload a file to anywhere
    * in the appliance.
    */
@@ -392,8 +431,4 @@ do_debug_upload (const char *filename MAYBE_UNUSED, int mode MAYBE_UNUSED)
   }
 
   return 0;
-#else
-  reply_with_error ("guestfsd was not configured with --enable-debug-command");
-  return NULL;
-#endif
 }