ia64/xen-unstable

changeset 16950:a6c037d8cba3

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>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 31 09:13:27 2008 +0000 (2008-01-31)
parents 32b898768217
children 0d70e01c0012
files tools/xenstore/Makefile tools/xenstore/xenstored_core.c tools/xenstore/xenstored_core.h tools/xenstore/xenstored_probes.d tools/xenstore/xenstored_solaris.c
line diff
     1.1 --- a/tools/xenstore/Makefile	Thu Jan 31 09:11:21 2008 +0000
     1.2 +++ b/tools/xenstore/Makefile	Thu Jan 31 09:13:27 2008 +0000
     1.3 @@ -24,7 +24,7 @@ CLIENTS_OBJS := $(patsubst xenstore-%,xe
     1.4  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
     1.5  
     1.6  XENSTORED_OBJS_$(CONFIG_Linux) = xenstored_linux.o
     1.7 -XENSTORED_OBJS_$(CONFIG_SunOS) = xenstored_solaris.o
     1.8 +XENSTORED_OBJS_$(CONFIG_SunOS) = xenstored_solaris.o xenstored_probes.o
     1.9  XENSTORED_OBJS_$(CONFIG_NetBSD) = xenstored_netbsd.o
    1.10  
    1.11  XENSTORED_OBJS += $(XENSTORED_OBJS_y)
    1.12 @@ -32,6 +32,18 @@ XENSTORED_OBJS += $(XENSTORED_OBJS_y)
    1.13  .PHONY: all
    1.14  all: libxenstore.so libxenstore.a xenstored $(CLIENTS) xs_tdb_dump xenstore-control xenstore-ls
    1.15  
    1.16 +ifeq ($(CONFIG_SunOS),y)
    1.17 +xenstored_probes.h: xenstored_probes.d
    1.18 +	dtrace -C -h -s xenstored_probes.d
    1.19 +
    1.20 +xenstored_solaris.o: xenstored_probes.h
    1.21 +
    1.22 +xenstored_probes.o: xenstored_solaris.o
    1.23 +	dtrace -C -G -s xenstored_probes.d xenstored_solaris.o 
    1.24 +
    1.25 +CFLAGS += -DHAVE_DTRACE=1
    1.26 +endif
    1.27 + 
    1.28  xenstored: $(XENSTORED_OBJS)
    1.29  	$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) $(LDFLAGS_libxenctrl) $(SOCKET_LIBS) -o $@
    1.30  
    1.31 @@ -63,7 +75,7 @@ libxenstore.a: xs.o xs_lib.o
    1.32  
    1.33  .PHONY: clean
    1.34  clean:
    1.35 -	rm -f *.a *.o *.opic *.so*
    1.36 +	rm -f *.a *.o *.opic *.so* xenstored_probes.h
    1.37  	rm -f xenstored xs_random xs_stress xs_crashme
    1.38  	rm -f xs_tdb_dump xenstore-control xenstore-ls
    1.39  	rm -f $(CLIENTS)
     2.1 --- a/tools/xenstore/xenstored_core.c	Thu Jan 31 09:11:21 2008 +0000
     2.2 +++ b/tools/xenstore/xenstored_core.c	Thu Jan 31 09:13:27 2008 +0000
     2.3 @@ -154,20 +154,25 @@ void trace(const char *fmt, ...)
     2.4  }
     2.5  
     2.6  static void trace_io(const struct connection *conn,
     2.7 -		     const char *prefix,
     2.8 -		     const struct buffered_data *data)
     2.9 +		     const struct buffered_data *data,
    2.10 +		     int out)
    2.11  {
    2.12  	unsigned int i;
    2.13  	time_t now;
    2.14  	struct tm *tm;
    2.15  
    2.16 +#ifdef HAVE_DTRACE
    2.17 +	dtrace_io(conn, data, out);
    2.18 +#endif
    2.19 +
    2.20  	if (tracefd < 0)
    2.21  		return;
    2.22  
    2.23  	now = time(NULL);
    2.24  	tm = localtime(&now);
    2.25  
    2.26 -	trace("%s %p %04d%02d%02d %02d:%02d:%02d %s (", prefix, conn,
    2.27 +	trace("%s %p %04d%02d%02d %02d:%02d:%02d %s (",
    2.28 +	      out ? "OUT" : "IN", conn,
    2.29  	      tm->tm_year + 1900, tm->tm_mon + 1,
    2.30  	      tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
    2.31  	      sockmsg_string(data->hdr.msg.type));
    2.32 @@ -257,7 +262,7 @@ static bool write_messages(struct connec
    2.33  	if (out->used != out->hdr.msg.len)
    2.34  		return true;
    2.35  
    2.36 -	trace_io(conn, "OUT", out);
    2.37 +	trace_io(conn, out, 1);
    2.38  
    2.39  	list_del(&out->list);
    2.40  	talloc_free(out);
    2.41 @@ -1316,7 +1321,7 @@ static void handle_input(struct connecti
    2.42  	if (in->used != in->hdr.msg.len)
    2.43  		return;
    2.44  
    2.45 -	trace_io(conn, "IN ", in);
    2.46 +	trace_io(conn, in, 0);
    2.47  	consider_message(conn);
    2.48  	return;
    2.49  
     3.1 --- a/tools/xenstore/xenstored_core.h	Thu Jan 31 09:11:21 2008 +0000
     3.2 +++ b/tools/xenstore/xenstored_core.h	Thu Jan 31 09:13:27 2008 +0000
     3.3 @@ -160,12 +160,12 @@ struct connection *new_connection(connwr
     3.4  /* Is this a valid node name? */
     3.5  bool is_valid_nodename(const char *node);
     3.6  
     3.7 -
     3.8  /* Tracing infrastructure. */
     3.9  void trace_create(const void *data, const char *type);
    3.10  void trace_destroy(const void *data, const char *type);
    3.11  void trace_watch_timeout(const struct connection *conn, const char *node, const char *token);
    3.12  void trace(const char *fmt, ...);
    3.13 +void dtrace_io(const struct connection *conn, const struct buffered_data *data, int out);
    3.14  
    3.15  extern int event_fd;
    3.16  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/xenstore/xenstored_probes.d	Thu Jan 31 09:13:27 2008 +0000
     4.3 @@ -0,0 +1,28 @@
     4.4 +/*
     4.5 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     4.6 + * Use is subject to license terms.
     4.7 + *
     4.8 + * This program is free software; you can redistribute it and/or modify
     4.9 + * it under the terms of the GNU General Public License as published by
    4.10 + * the Free Software Foundation, version 2 of the License.
    4.11 + */
    4.12 +
    4.13 +#include <sys/types.h>
    4.14 +
    4.15 +provider xenstore {
    4.16 +	/* tx id, dom id, pid, type, msg */
    4.17 +	probe msg(uint32_t, unsigned int, pid_t, int, const char *);
    4.18 +	/* tx id, dom id, pid, type, reply */
    4.19 +	probe reply(uint32_t, unsigned int, pid_t, int, const char *);
    4.20 +	/* tx id, dom id, pid, reply */
    4.21 +	probe error(uint32_t, unsigned int, pid_t, const char *);
    4.22 +	/* dom id, pid, watch details */
    4.23 +	probe watch_event(unsigned int, pid_t, const char *);
    4.24 +};
    4.25 +
    4.26 +#pragma D attributes Evolving/Evolving/Common provider xenstore provider
    4.27 +#pragma D attributes Private/Private/Unknown provider xenstore module
    4.28 +#pragma D attributes Private/Private/Unknown provider xenstore function
    4.29 +#pragma D attributes Evolving/Evolving/Common provider xenstore name
    4.30 +#pragma D attributes Evolving/Evolving/Common provider xenstore args
    4.31 +
     5.1 --- a/tools/xenstore/xenstored_solaris.c	Thu Jan 31 09:11:21 2008 +0000
     5.2 +++ b/tools/xenstore/xenstored_solaris.c	Thu Jan 31 09:13:27 2008 +0000
     5.3 @@ -15,9 +15,15 @@
     5.4  #include <unistd.h>
     5.5  #include <stdlib.h>
     5.6  #include <sys/mman.h>
     5.7 +#include <strings.h>
     5.8 +#include <ucred.h>
     5.9 +#include <stdio.h>
    5.10 +
    5.11  #include <xen/sys/xenbus.h>
    5.12  
    5.13 +#include "talloc.h"
    5.14  #include "xenstored_core.h"
    5.15 +#include "xenstored_probes.h"
    5.16  
    5.17  evtchn_port_t xenbus_evtchn(void)
    5.18  {
    5.19 @@ -64,3 +70,98 @@ void xenbus_notify_running(void)
    5.20  
    5.21  	close(fd);
    5.22  }
    5.23 +
    5.24 +static pid_t cred(const struct connection *conn)
    5.25 +{
    5.26 +	ucred_t *ucred = NULL;
    5.27 +	pid_t pid;
    5.28 +
    5.29 +	if (conn->domain)
    5.30 +		return (0);
    5.31 +
    5.32 +	if (getpeerucred(conn->fd, &ucred) == -1)
    5.33 +		return (0);
    5.34 +
    5.35 +	pid = ucred_getpid(ucred);
    5.36 +
    5.37 +	ucred_free(ucred);
    5.38 +	return (pid);
    5.39 +}
    5.40 +
    5.41 +/*
    5.42 + * The strings are often a number of nil-separated strings. We'll just
    5.43 + * replace the separators with spaces - not quite right, but good
    5.44 + * enough.
    5.45 + */
    5.46 +static char *
    5.47 +mangle(const struct connection *conn, const struct buffered_data *in)
    5.48 +{
    5.49 +	char *str;
    5.50 +	int i;
    5.51 +
    5.52 +	if (in->hdr.msg.len == 0)
    5.53 +		return (talloc_strdup(conn, ""));
    5.54 +
    5.55 +	if ((str = talloc_zero_size(conn, in->hdr.msg.len + 1)) == NULL)
    5.56 +		return (NULL);
    5.57 +
    5.58 +	memcpy(str, in->buffer, in->hdr.msg.len);
    5.59 +	
    5.60 +	/*
    5.61 +	 * The protocol is absurdly inconsistent in whether the length
    5.62 +	 * includes the terminating nil or not; replace all nils that
    5.63 +	 * aren't the last one.
    5.64 +	 */
    5.65 +	for (i = 0; i < (in->hdr.msg.len - 1); i++) {
    5.66 +		if (str[i] == '\0')
    5.67 +			str[i] = ' ';
    5.68 +	}
    5.69 +
    5.70 +	return (str);
    5.71 +}
    5.72 +
    5.73 +void
    5.74 +dtrace_io(const struct connection *conn, const struct buffered_data *in,
    5.75 +    int io_out)
    5.76 +{
    5.77 +	if (!io_out) {
    5.78 +		if (XENSTORE_MSG_ENABLED()) {
    5.79 +			char *mangled = mangle(conn, in);
    5.80 +			XENSTORE_MSG(in->hdr.msg.tx_id, conn->id, cred(conn),
    5.81 +			    in->hdr.msg.type, mangled);
    5.82 +		}
    5.83 +
    5.84 +		goto out;
    5.85 +	}
    5.86 +
    5.87 +	switch (in->hdr.msg.type) {
    5.88 +	case XS_ERROR:
    5.89 +		if (XENSTORE_ERROR_ENABLED()) {
    5.90 +			char *mangled = mangle(conn, in);
    5.91 +			XENSTORE_ERROR(in->hdr.msg.tx_id, conn->id,
    5.92 +			    cred(conn), mangled);
    5.93 +		}
    5.94 +		break;
    5.95 +
    5.96 +	case XS_WATCH_EVENT:
    5.97 +		if (XENSTORE_WATCH_EVENT_ENABLED()) {
    5.98 +			char *mangled = mangle(conn, in);
    5.99 +			XENSTORE_WATCH_EVENT(conn->id, cred(conn), mangled);
   5.100 +		}
   5.101 +		break;
   5.102 +
   5.103 +	default:
   5.104 +		if (XENSTORE_REPLY_ENABLED()) {
   5.105 +			char *mangled = mangle(conn, in);
   5.106 +			XENSTORE_REPLY(in->hdr.msg.tx_id, conn->id, cred(conn),
   5.107 +			    in->hdr.msg.type, mangled);
   5.108 +		}
   5.109 +		break;
   5.110 +	}
   5.111 +
   5.112 +out:
   5.113 +	/*
   5.114 +	 * 6589130 dtrace -G fails for certain tail-calls on x86
   5.115 +	 */
   5.116 +	asm("nop");
   5.117 +}