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

[Xen-devel] [PATCH] Add DTrace support to xenstored



# HG changeset patch
# User john.levon@xxxxxxx
# Date 1201715263 28800
# Node ID 60778396cfaebd9b2ca651333033b9a6dbbf2566
# Parent  95f312d690357bc6aa2fc476572dd1919f3b5624
Add DTrace support to xenstored

Add USDT probes for significant xenstore operations to allow dynamic
tracing.

Signed-off-by: John Levon <john.levon@xxxxxxx>

diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile
--- a/tools/xenstore/Makefile
+++ b/tools/xenstore/Makefile
@@ -24,7 +24,7 @@ XENSTORED_OBJS = xenstored_core.o xensto
 XENSTORED_OBJS = xenstored_core.o xenstored_watch.o xenstored_domain.o 
xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o hashtable.o
 
 XENSTORED_OBJS_$(CONFIG_Linux) = xenstored_linux.o
-XENSTORED_OBJS_$(CONFIG_SunOS) = xenstored_solaris.o
+XENSTORED_OBJS_$(CONFIG_SunOS) = xenstored_solaris.o xenstored_probes.o
 XENSTORED_OBJS_$(CONFIG_NetBSD) = xenstored_netbsd.o
 
 XENSTORED_OBJS += $(XENSTORED_OBJS_y)
@@ -32,6 +32,18 @@ XENSTORED_OBJS += $(XENSTORED_OBJS_y)
 .PHONY: all
 all: libxenstore.so libxenstore.a xenstored $(CLIENTS) xs_tdb_dump 
xenstore-control xenstore-ls
 
+ifeq ($(CONFIG_SunOS),y)
+xenstored_probes.h: xenstored_probes.d
+       dtrace -C -h -s xenstored_probes.d
+
+xenstored_solaris.o: xenstored_probes.h
+
+xenstored_probes.o: xenstored_solaris.o
+       dtrace -C -G -s xenstored_probes.d xenstored_solaris.o 
+
+CFLAGS += -DHAVE_DTRACE=1
+endif
+ 
 xenstored: $(XENSTORED_OBJS)
        $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) 
$(LDFLAGS_libxenctrl) $(SOCKET_LIBS) -o $@
 
@@ -63,7 +75,7 @@ libxenstore.a: xs.o xs_lib.o
 
 .PHONY: clean
 clean:
-       rm -f *.a *.o *.opic *.so*
+       rm -f *.a *.o *.opic *.so* xenstored_probes.h
        rm -f xenstored xs_random xs_stress xs_crashme
        rm -f xs_tdb_dump xenstore-control xenstore-ls
        rm -f $(CLIENTS)
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -154,12 +154,16 @@ void trace(const char *fmt, ...)
 }
 
 static void trace_io(const struct connection *conn,
-                    const char *prefix,
-                    const struct buffered_data *data)
+                    const struct buffered_data *data,
+                    int out)
 {
        unsigned int i;
        time_t now;
        struct tm *tm;
+
+#ifdef HAVE_DTRACE
+       dtrace_io(conn, data, out);
+#endif
 
        if (tracefd < 0)
                return;
@@ -167,7 +171,8 @@ static void trace_io(const struct connec
        now = time(NULL);
        tm = localtime(&now);
 
-       trace("%s %p %04d%02d%02d %02d:%02d:%02d %s (", prefix, conn,
+       trace("%s %p %04d%02d%02d %02d:%02d:%02d %s (",
+             out ? "OUT" : "IN", conn,
              tm->tm_year + 1900, tm->tm_mon + 1,
              tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
              sockmsg_string(data->hdr.msg.type));
@@ -257,7 +262,7 @@ static bool write_messages(struct connec
        if (out->used != out->hdr.msg.len)
                return true;
 
-       trace_io(conn, "OUT", out);
+       trace_io(conn, out, 1);
 
        list_del(&out->list);
        talloc_free(out);
@@ -1316,7 +1321,7 @@ static void handle_input(struct connecti
        if (in->used != in->hdr.msg.len)
                return;
 
-       trace_io(conn, "IN ", in);
+       trace_io(conn, in, 0);
        consider_message(conn);
        return;
 
diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
--- a/tools/xenstore/xenstored_core.h
+++ b/tools/xenstore/xenstored_core.h
@@ -160,12 +160,12 @@ struct connection *new_connection(connwr
 /* Is this a valid node name? */
 bool is_valid_nodename(const char *node);
 
-
 /* Tracing infrastructure. */
 void trace_create(const void *data, const char *type);
 void trace_destroy(const void *data, const char *type);
 void trace_watch_timeout(const struct connection *conn, const char *node, 
const char *token);
 void trace(const char *fmt, ...);
+void dtrace_io(const struct connection *conn, const struct buffered_data 
*data, int out);
 
 extern int event_fd;
 
diff --git a/tools/xenstore/xenstored_probes.d 
b/tools/xenstore/xenstored_probes.d
new file mode 100644
--- /dev/null
+++ b/tools/xenstore/xenstored_probes.d
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include <sys/types.h>
+
+provider xenstore {
+       /* tx id, dom id, pid, type, msg */
+       probe msg(uint32_t, unsigned int, pid_t, int, const char *);
+       /* tx id, dom id, pid, type, reply */
+       probe reply(uint32_t, unsigned int, pid_t, int, const char *);
+       /* tx id, dom id, pid, reply */
+       probe error(uint32_t, unsigned int, pid_t, const char *);
+       /* dom id, pid, watch details */
+       probe watch_event(unsigned int, pid_t, const char *);
+};
+
+#pragma D attributes Evolving/Evolving/Common provider xenstore provider
+#pragma D attributes Private/Private/Unknown provider xenstore module
+#pragma D attributes Private/Private/Unknown provider xenstore function
+#pragma D attributes Evolving/Evolving/Common provider xenstore name
+#pragma D attributes Evolving/Evolving/Common provider xenstore args
+
diff --git a/tools/xenstore/xenstored_solaris.c 
b/tools/xenstore/xenstored_solaris.c
--- a/tools/xenstore/xenstored_solaris.c
+++ b/tools/xenstore/xenstored_solaris.c
@@ -15,9 +15,15 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/mman.h>
+#include <strings.h>
+#include <ucred.h>
+#include <stdio.h>
+
 #include <xen/sys/xenbus.h>
 
+#include "talloc.h"
 #include "xenstored_core.h"
+#include "xenstored_probes.h"
 
 evtchn_port_t xenbus_evtchn(void)
 {
@@ -64,3 +70,98 @@ void xenbus_notify_running(void)
 
        close(fd);
 }
+
+static pid_t cred(const struct connection *conn)
+{
+       ucred_t *ucred = NULL;
+       pid_t pid;
+
+       if (conn->domain)
+               return (0);
+
+       if (getpeerucred(conn->fd, &ucred) == -1)
+               return (0);
+
+       pid = ucred_getpid(ucred);
+
+       ucred_free(ucred);
+       return (pid);
+}
+
+/*
+ * The strings are often a number of nil-separated strings. We'll just
+ * replace the separators with spaces - not quite right, but good
+ * enough.
+ */
+static char *
+mangle(const struct connection *conn, const struct buffered_data *in)
+{
+       char *str;
+       int i;
+
+       if (in->hdr.msg.len == 0)
+               return (talloc_strdup(conn, ""));
+
+       if ((str = talloc_zero_size(conn, in->hdr.msg.len + 1)) == NULL)
+               return (NULL);
+
+       memcpy(str, in->buffer, in->hdr.msg.len);
+       
+       /*
+        * The protocol is absurdly inconsistent in whether the length
+        * includes the terminating nil or not; replace all nils that
+        * aren't the last one.
+        */
+       for (i = 0; i < (in->hdr.msg.len - 1); i++) {
+               if (str[i] == '\0')
+                       str[i] = ' ';
+       }
+
+       return (str);
+}
+
+void
+dtrace_io(const struct connection *conn, const struct buffered_data *in,
+    int io_out)
+{
+       if (!io_out) {
+               if (XENSTORE_MSG_ENABLED()) {
+                       char *mangled = mangle(conn, in);
+                       XENSTORE_MSG(in->hdr.msg.tx_id, conn->id, cred(conn),
+                           in->hdr.msg.type, mangled);
+               }
+
+               goto out;
+       }
+
+       switch (in->hdr.msg.type) {
+       case XS_ERROR:
+               if (XENSTORE_ERROR_ENABLED()) {
+                       char *mangled = mangle(conn, in);
+                       XENSTORE_ERROR(in->hdr.msg.tx_id, conn->id,
+                           cred(conn), mangled);
+               }
+               break;
+
+       case XS_WATCH_EVENT:
+               if (XENSTORE_WATCH_EVENT_ENABLED()) {
+                       char *mangled = mangle(conn, in);
+                       XENSTORE_WATCH_EVENT(conn->id, cred(conn), mangled);
+               }
+               break;
+
+       default:
+               if (XENSTORE_REPLY_ENABLED()) {
+                       char *mangled = mangle(conn, in);
+                       XENSTORE_REPLY(in->hdr.msg.tx_id, conn->id, cred(conn),
+                           in->hdr.msg.type, mangled);
+               }
+               break;
+       }
+
+out:
+       /*
+        * 6589130 dtrace -G fails for certain tail-calls on x86
+        */
+       asm("nop");
+}

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.