john.levon@sun.com
2008-Jan-30 17:47 UTC
[Xen-devel] [PATCH] Add DTrace support to xenstored
# HG changeset patch # User john.levon@sun.com # 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@sun.com> 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@lists.xensource.com http://lists.xensource.com/xen-devel