diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-01-31 09:13:27 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-01-31 09:13:27 +0000 |
commit | d66e065f7f5e8ded336a4ad42a99ab98b00d1083 (patch) | |
tree | fe8a8def386d2661928bc9566cf490a17d755581 /tools/xenstore | |
parent | 87fdf3231c5f7998037b1962506dd1bb81cd4ac3 (diff) | |
download | xen-d66e065f7f5e8ded336a4ad42a99ab98b00d1083.tar.gz xen-d66e065f7f5e8ded336a4ad42a99ab98b00d1083.tar.bz2 xen-d66e065f7f5e8ded336a4ad42a99ab98b00d1083.zip |
Add DTrace support to xenstored
Add USDT probes for significant xenstore operations to allow dynamic
tracing.
Signed-off-by: John Levon <john.levon@sun.com>
Diffstat (limited to 'tools/xenstore')
-rw-r--r-- | tools/xenstore/Makefile | 16 | ||||
-rw-r--r-- | tools/xenstore/xenstored_core.c | 15 | ||||
-rw-r--r-- | tools/xenstore/xenstored_core.h | 2 | ||||
-rw-r--r-- | tools/xenstore/xenstored_probes.d | 28 | ||||
-rw-r--r-- | tools/xenstore/xenstored_solaris.c | 101 |
5 files changed, 154 insertions, 8 deletions
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 3d6700c0b8..bf0ae4ed64 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -24,7 +24,7 @@ CLIENTS_OBJS := $(patsubst xenstore-%,xenstore_%.o,$(CLIENTS)) 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 index 7f20e30ca0..a643f2d969 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -154,20 +154,25 @@ 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; 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 connection *conn) 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 connection *conn) 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 index 975a97226f..c487089c2f 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -160,12 +160,12 @@ struct connection *new_connection(connwritefn_t *write, connreadfn_t *read); /* 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 index 0000000000..f72d38f935 --- /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 index 376a00081b..ef6b51533c 100644 --- 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"); +} |