[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libguestfs] [PATCH 01/14] Enable running the daemon under valgrind.



From: "Richard W.M. Jones" <rjones redhat com>

This commit allows you to run the daemon under valgrind.  You have to
enable it at configure time:

  ./configure --enable-valgrind-daemon

This should *not* be done for production builds.

When this feature is enabled, valgrind is added to the appliance and
the daemon is run under valgrind.  Log messages from valgrind are
passed back over a virtio-serial channel into a file called
'valgrind.log.$PID' in the top build directory.

Running 'make check', 'make extra-tests' etc causes many
valgrind.log.* files to be created which must be examined by hand.
---
 .gitignore               |    1 +
 appliance/Makefile.am    |    9 +++++++--
 appliance/init           |   10 +++++++++-
 appliance/packagelist.in |    4 ++++
 configure.ac             |   15 +++++++++++++++
 src/guestfs.c            |    8 ++++++++
 src/launch.c             |   10 ++++++++++
 7 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index b75cafb..fc732bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -387,3 +387,4 @@ test-tool/libguestfs-test-tool-helper
 tools/test.img
 tools/virt-*.1
 tools/virt-*.pl
+/valgrind.log.*
diff --git a/appliance/Makefile.am b/appliance/Makefile.am
index e2e8b96..99896be 100644
--- a/appliance/Makefile.am
+++ b/appliance/Makefile.am
@@ -42,13 +42,18 @@ make.sh: make.sh.in
 	chmod +x $ -t
 	mv $ -t $@
 
+PACKAGELIST_CPP_FLAGS = -D$(DISTRO)=1
+if VALGRIND_DAEMON
+PACKAGELIST_CPP_FLAGS += -DVALGRIND_DAEMON=1
+endif
+
 packagelist: packagelist.in
-	cpp -undef -D$(DISTRO)=1 < $< | \
+	cpp -undef $(PACKAGELIST_CPP_FLAGS) < $< | \
 	grep -v '^[[:space:]]*$$' | grep -v '^#' > $ -t
 	mv $ -t $@
 
 excludelist: excludelist.in
-	cpp -undef -D$(DISTRO)=1 < $< | \
+	cpp -undef $(PACKAGELIST_CPP_FLAGS) < $< | \
 	grep -v '^[[:space:]]*$$' | grep -v '^#' > $ -t
 	mv $ -t $@
 
diff --git a/appliance/init b/appliance/init
index 0f32a55..1d69339 100755
--- a/appliance/init
+++ b/appliance/init
@@ -106,8 +106,16 @@ if grep -sq guestfs_verbose=1 /proc/cmdline; then
 fi
 
 if ! grep -sq guestfs_rescue=1 /proc/cmdline; then
+  # Run the daemon under valgrind if ./configure --enable-valgrind-daemon
+  vg_channel=/dev/virtio-ports/org.libguestfs.valgrind
+  if [ -w $vg_channel ]; then
+    exec 3>$vg_channel
+    vg="valgrind --leak-check=full --log-fd=3 --error-exitcode=119 --max-stackframe=8388608 --child-silent-after-fork=yes"
+    echo "enabling valgrind: $vg"
+  fi
+
   # The host will kill qemu abruptly if guestfsd shuts down normally
-  guestfsd
+  $vg guestfsd
 
   # Otherwise we try to clean up gracefully. For example, this ensures that a
   # core dump generated by the guest daemon will be written to disk.
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index 5735a5a..b42c510 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -130,3 +130,7 @@ tar
 xfsprogs
 #endif
 zerofree
+
+#ifdef VALGRIND_DAEMON
+valgrind
+#endif
diff --git a/configure.ac b/configure.ac
index 3e364b1..ebc20aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -264,8 +264,23 @@ if test "x$enable_daemon" = "xyes"; then
                 [],
                 [enable_install_daemon=no])
         AC_MSG_RESULT([$enable_install_daemon])
+
+        dnl Enable valgrind in the daemon.
+        AC_MSG_CHECKING([if we should run the daemon under valgrind])
+        AC_ARG_ENABLE([valgrind-daemon],
+                [AS_HELP_STRING([--enable-valgrind-daemon],
+                  [run the daemon under valgrind (developers only) @<:@default=no@:>@])],
+                  [],
+                  [enable_valgrind_daemon=no])
+        AC_MSG_RESULT([$enable_valgrind_daemon])
+
+        if test "x$enable_valgrind_daemon" = "xyes"; then
+            AC_DEFINE([VALGRIND_DAEMON],[1],[Define to 1 to run the daemon under valgrind])
+            AC_DEFINE_UNQUOTED([VALGRIND_LOG_PATH],["$(pwd)"],[Path to save valgrind log files])
+        fi
 fi
 AM_CONDITIONAL([INSTALL_DAEMON],[test "x$enable_install_daemon" = "xyes"])
+AM_CONDITIONAL([VALGRIND_DAEMON],[test "x$enable_valgrind_daemon" = "xyes"])
 
 dnl Build the appliance?
 AC_MSG_CHECKING([if we should build the appliance])
diff --git a/src/guestfs.c b/src/guestfs.c
index 31968e4..3607eaa 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -190,9 +190,17 @@ guestfs_close (guestfs_h *g)
   if (g->autosync && g->state == READY)
     guestfs_internal_autosync (g);
 
+  /* If we are valgrinding the daemon, then we *don't* want to kill
+   * the subprocess because we want the final valgrind messages sent
+   * when we close sockets below.  However for normal production use,
+   * killing the subprocess is the right thing to do (in case the
+   * daemon or qemu is not responding).
+   */
+#ifndef VALGRIND_DAEMON
   /* Kill the qemu subprocess. */
   if (g->state != CONFIG)
     guestfs_kill_subprocess (g);
+#endif
 
   /* Run user close callbacks. */
   guestfs___call_callbacks_void (g, GUESTFS_EVENT_CLOSE);
diff --git a/src/launch.c b/src/launch.c
index 1af74b9..4e2fba9 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -703,6 +703,16 @@ launch_appliance (guestfs_h *g)
     add_cmdline (g, "-device");
     add_cmdline (g, "virtserialport,chardev=channel0,name=org.libguestfs.channel.0");
 
+#ifdef VALGRIND_DAEMON
+    /* Set up virtio-serial channel for valgrind messages. */
+    add_cmdline (g, "-chardev");
+    snprintf (buf, sizeof buf, "file,path=%s/valgrind.log.%d,id=valgrind",
+              VALGRIND_LOG_PATH, getpid ());
+    add_cmdline (g, buf);
+    add_cmdline (g, "-device");
+    add_cmdline (g, "virtserialport,chardev=valgrind,name=org.libguestfs.valgrind");
+#endif
+
     /* Enable user networking. */
     if (g->enable_network) {
       add_cmdline (g, "-netdev");
-- 
1.7.6


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]