# 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
|