summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2011-10-10 13:26:15 +0100
committerRichard W.M. Jones <rjones@redhat.com>2011-10-10 13:26:15 +0100
commitc155330f04f933d13298d5cddab6b7f3dc9d218f (patch)
tree61d18967a14806cc8c60c4043cb5554b27372816
parentd6622d7636d592eb1c01fbcb8b8ad52c2b20615b (diff)
downloadlibguestfs-c155330f04f933d13298d5cddab6b7f3dc9d218f.tar.gz
libguestfs-c155330f04f933d13298d5cddab6b7f3dc9d218f.tar.xz
libguestfs-c155330f04f933d13298d5cddab6b7f3dc9d218f.zip
Add systemtap/DTrace probes.
Mainly this is a documentation change. However a sample of DTrace-compatible userspace probes are also added.
-rw-r--r--README3
-rw-r--r--configure.ac5
-rw-r--r--src/guestfs-internal.h20
-rw-r--r--src/guestfs.pod72
-rw-r--r--src/launch.c10
5 files changed, 110 insertions, 0 deletions
diff --git a/README b/README
index 6b2078e5..396c8bb2 100644
--- a/README
+++ b/README
@@ -77,6 +77,9 @@ For basic functionality and the C tools:
- Berkeley DB 'db_dump' and 'db_load' utilities
(db4-utils or db4.X-util or similar) (optional)
+- systemtap/DTrace userspace probes (optional)
+ http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps
+
- perldoc (pod2man, pod2text, pod2html) to generate the manual pages
and other documentation.
diff --git a/configure.ac b/configure.ac
index 2bd98c67..e0fd7de1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -346,6 +346,11 @@ if test "x$have_libselinux" = "xyes"; then
fi
AC_SUBST([SELINUX_LIB])
+dnl Check for systemtap/DTrace userspace probes (optional).
+dnl http://sourceware.org/systemtap/wiki/AddingUserSpaceProbingToApps
+AC_CHECK_HEADERS([sys/sdt.h])
+dnl AC_CHECK_PROG([DTRACE],[dtrace],[dtrace],[no])
+
dnl Check for cpio which isn't in the default Pardus install amazingly.
AC_CHECK_PROG([CPIO],[cpio],[cpio],[no])
test "x$CPIO" = "xno" &&
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 494003ef..64cf6960 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -43,6 +43,26 @@
#define N_(str) str
#endif
+#ifdef HAVE_SYS_SDT_H
+#include <sys/sdt.h>
+/* NB: The 'name' parameter is a literal identifier, NOT a string! */
+#define TRACE0(name) DTRACE_PROBE(guestfs, name)
+#define TRACE1(name, arg1) \
+ DTRACE_PROBE(guestfs, name, (arg1))
+#define TRACE2(name, arg1, arg2) \
+ DTRACE_PROBE(guestfs, name, (arg1), (arg2))
+#define TRACE3(name, arg1, arg2, arg3) \
+ DTRACE_PROBE(guestfs, name, (arg1), (arg2), (arg3))
+#define TRACE4(name, arg1, arg2, arg3, arg4) \
+ DTRACE_PROBE(guestfs, name, (arg1), (arg2), (arg3), (arg4))
+#else
+#define TRACE0(name)
+#define TRACE1(name, arg1)
+#define TRACE2(name, arg1, arg2)
+#define TRACE3(name, arg1, arg2, arg3)
+#define TRACE4(name, arg1, arg2, arg3, arg4)
+#endif
+
#define TMP_TEMPLATE_ON_STACK(var) \
const char *ttos_tmpdir = guestfs_tmpdir (); \
char var[strlen (ttos_tmpdir) + 32]; \
diff --git a/src/guestfs.pod b/src/guestfs.pod
index 1a5abc65..ada9f1e5 100644
--- a/src/guestfs.pod
+++ b/src/guestfs.pod
@@ -2165,6 +2165,77 @@ are being deleted, but other manipulations of keys within the loop
might not terminate unless you also maintain an indication of which
keys have been visited.
+=head1 SYSTEMTAP
+
+The libguestfs C library can be probed using systemtap or DTrace.
+This is true of any library, not just libguestfs. However libguestfs
+also contains static markers to help in probing internal operations.
+
+You can list all the static markers by doing:
+
+ stap -l 'process("/usr/lib*/libguestfs.so.0")
+ .provider("guestfs").mark("*")'
+
+B<Note:> These static markers are I<not> part of the stable API and
+may change in future versions.
+
+=head2 SYSTEMTAP SCRIPT EXAMPLE
+
+This script contains examples of displaying both the static markers
+and some ordinary C entry points:
+
+ global last;
+
+ function display_time () {
+ now = gettimeofday_us ();
+ delta = 0;
+ if (last > 0)
+ delta = now - last;
+ last = now;
+
+ printf ("%d (+%d):", now, delta);
+ }
+
+ probe begin {
+ last = 0;
+ printf ("ready\n");
+ }
+
+ /* Display all calls to static markers. */
+ probe process("/usr/lib*/libguestfs.so.0")
+ .provider("guestfs").mark("*") ? {
+ display_time();
+ printf ("\t%s %s\n", $$name, $$parms);
+ }
+
+ /* Display all calls to guestfs_mkfs* functions. */
+ probe process("/usr/lib*/libguestfs.so.0")
+ .function("guestfs_mkfs*") ? {
+ display_time();
+ printf ("\t%s %s\n", probefunc(), $$parms);
+ }
+
+The script above can be saved to C<test.stap> and run using the
+L<stap(1)> program. Note that you either have to be root, or you have
+to add yourself to several special stap groups. Consult the systemtap
+documentation for more information.
+
+ # stap /tmp/test.stap
+ ready
+
+In another terminal, run a guestfish command such as this:
+
+ guestfish -N fs
+
+In the first terminal, stap trace output similar to this is shown:
+
+ 1318248056692655 (+0): launch_start
+ 1318248056692850 (+195): launch_build_appliance_start
+ 1318248056818285 (+125435): launch_build_appliance_end
+ 1318248056838059 (+19774): launch_run_qemu
+ 1318248061071167 (+4233108): launch_end
+ 1318248061280324 (+209157): guestfs_mkfs g=0x1024ab0 fstype=0x46116f device=0x1024e60
+
=begin html
<!-- old anchor for the next section -->
@@ -3216,6 +3287,7 @@ L<qemu(1)>,
L<febootstrap(1)>,
L<febootstrap-supermin-helper(8)>,
L<hivex(3)>,
+L<stap(1)>,
L<http://libguestfs.org/>.
Tools with a similar purpose:
diff --git a/src/launch.c b/src/launch.c
index b0f5b394..8e171f7b 100644
--- a/src/launch.c
+++ b/src/launch.c
@@ -389,6 +389,8 @@ guestfs__launch (guestfs_h *g)
return -1;
}
+ TRACE0 (launch_start);
+
/* Make the temporary directory. */
if (!g->tmpdir) {
TMP_TEMPLATE_ON_STACK (dir_template);
@@ -439,11 +441,15 @@ launch_appliance (guestfs_h *g)
gettimeofday (&g->launch_t, NULL);
guestfs___launch_send_progress (g, 0);
+ TRACE0 (launch_build_appliance_start);
+
/* Locate and/or build the appliance. */
char *kernel = NULL, *initrd = NULL, *appliance = NULL;
if (guestfs___build_appliance (g, &kernel, &initrd, &appliance) == -1)
return -1;
+ TRACE0 (launch_build_appliance_end);
+
guestfs___launch_send_progress (g, 3);
if (g->verbose)
@@ -696,6 +702,8 @@ launch_appliance (guestfs_h *g)
setenv ("LC_ALL", "C", 1);
+ TRACE0 (launch_run_qemu);
+
execv (g->qemu, g->cmdline); /* Run qemu. */
perror (g->qemu);
_exit (EXIT_FAILURE);
@@ -825,6 +833,8 @@ launch_appliance (guestfs_h *g)
goto cleanup1;
}
+ TRACE0 (launch_end);
+
guestfs___launch_send_progress (g, 12);
return 0;