This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[systemtap patch] Experimental systemtap integration of LTTng


This is a patch to the 0930 systemtap snapshot that adds the ability
to have systemtap log its data to LTTng (using the -l option).  It
adds a single LTTng event that all systemtap output is logged to.  To
use it, you need to apply the accompanying kernel patch to register
the systemtap facility, then reboot and start LTTng:

# rm -rf /tmp/trace/*
# modprobe ltt-control
# lttctl -n trace -d -l /debug/ltt -t /tmp/trace

Then run a systemtap probe and stop LTTng e.g.:

# stap -l transport1.stp
# lttctl -n trace -R

You should then be able to use the LTTng tools to view the systemtap
data in the LTTng trace.

I think that rather than having a single event for all systemtap data,
it would be much more useful to have it dynamically register and trace
binary data from real probes i.e. get LKET to log to it instead of to
the -b transport of systemtap.

Tom

For reference, here's the systemtap.xml file passed to genevent that
generates the logging code:

<?xml version="1.0"?>
<facility name="systemtap">
  <description>The systemtap facility contains events sourced from systemtap</description>

  <event name="probelog">
    <description>Each systemtap write is wrapped in one of these</description>
    <field name="probedata"> <description>Probe Data</description>
      <sequence>
        <uint/>
        <uchar/>
      </sequence>
    </field>
  </event>
</facility>


diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/main.cxx /usr/local/src/systemtap-20060930/src/main.cxx
--- /usr/local/src/systemtap-20060930/src-orig/main.cxx	2006-09-27 20:48:59.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/main.cxx	2006-10-05 00:29:58.000000000 -0500
@@ -68,6 +68,7 @@ usage (systemtap_session& s, int exitcod
     << "   -u         unoptimized translation" << (s.unoptimized ? " [set]" : "") << endl
     << "   -g         guru mode" << (s.guru_mode ? " [set]" : "") << endl
     << "   -b         bulk (relayfs) mode" << (s.bulk_mode ? " [set]" : "") << endl
+    << "   -l         bulk (LTT) mode" << (s.ltt_bulk_mode ? " [set]" : "") << endl
     << "   -M         Don't merge per-cpu files for bulk (relayfs) mode" << (s.merge ? "" : " [set]") << endl
     << "   -s NUM     buffer size in megabytes, instead of "
     << s.buffer_size << endl
@@ -130,6 +131,7 @@ main (int argc, char * const argv [])
   s.timing = 0;
   s.guru_mode = false;
   s.bulk_mode = false;
+  s.ltt_bulk_mode = false;
   s.unoptimized = false;
   s.buffer_size = 0;
   s.last_pass = 5;
@@ -161,7 +163,7 @@ main (int argc, char * const argv [])
 
   while (true)
     {
-      int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgc:x:D:bs:u");
+      int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgc:x:D:bls:u");
       if (grc < 0)
         break;
       switch (grc)
@@ -234,6 +236,10 @@ main (int argc, char * const argv [])
           s.bulk_mode = true;
           break;
 
+        case 'l':
+          s.ltt_bulk_mode = true;
+          break;
+
 	case 'u':
 	  s.unoptimized = true;
 	  break;
@@ -269,13 +275,13 @@ main (int argc, char * const argv [])
         }
     }
 
-  if(!s.bulk_mode && !s.merge)
+  if(!s.bulk_mode && !s.ltt_bulk_mode && !s.merge)
     {
-      cerr << "-M option is valid only for bulk (relayfs) mode." <<endl;
+      cerr << "-M option is valid only for bulk (relayfs or LTT) mode." <<endl;
       usage (s, 1);
     }
 
-  if(!s.output_file.empty() && s.bulk_mode && !s.merge)
+  if(!s.output_file.empty() && (s.bulk_mode || s.ltt_bulk_mode) && !s.merge)
     {
       cerr << "You can't specify -M, -b and -o options together." <<endl;
       usage (s, 1);
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/runtime/print.c /usr/local/src/systemtap-20060930/src/runtime/print.c
--- /usr/local/src/systemtap-20060930/src-orig/runtime/print.c	2006-09-26 16:39:52.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/runtime/print.c	2006-10-05 00:30:19.000000000 -0500
@@ -111,6 +111,15 @@ static void * _stp_reserve_bytes (int nu
 	_stp_print_flush();
 	return relay_reserve(_stp_chan, numbytes);
 }
+#elif defined(STP_LTT)
+static void * _stp_reserve_bytes (int numbytes)
+{
+	// LTTng has a reserve function, but I don't know how to
+	// easily or correctly use it from here.  There doesn't seem
+	// to be a simple API function outside of the trace management
+	// stuff for writing directly into a trace channel.
+	return NULL;
+}
 #else
 static void * _stp_reserve_bytes (int numbytes)
 {
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/runtime/stpd/librelay.c /usr/local/src/systemtap-20060930/src/runtime/stpd/librelay.c
--- /usr/local/src/systemtap-20060930/src-orig/runtime/stpd/librelay.c	2006-09-26 16:38:35.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/runtime/stpd/librelay.c	2006-10-05 00:30:27.000000000 -0500
@@ -781,11 +781,15 @@ int stp_main_loop(void)
 					params.subbuf_size);
 				if (params.merge)
 					fprintf(stderr,"Merge output\n");
-			} else
+			} else if (tranport_mode == STP_TRANSPORT_LTT)
+				fprintf(stderr,"TRANSPORT_INFO recvd: LTT %d bufs of %d bytes (buf sizes not yet used).\n", 
+					params.n_subbufs, 
+					params.subbuf_size);
+			} else if (tranport_mode == STP_TRANSPORT_PROC)
 				fprintf(stderr,"TRANSPORT_INFO recvd: PROC with %d Mbyte buffers.\n", 
 					 info->buf_size); 
 #endif
-			if (!streaming()) {
+			if (transport_mode == STP_TRANSPORT_RELAYFS) {
 				rc = init_relayfs();
 				if (rc < 0) {
 					fprintf(stderr, "ERROR: couldn't init relayfs, exiting\n");
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/runtime/transport/relayfs.h /usr/local/src/systemtap-20060930/src/runtime/transport/relayfs.h
--- /usr/local/src/systemtap-20060930/src-orig/runtime/transport/relayfs.h	2006-09-19 14:18:26.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/runtime/transport/relayfs.h	2006-10-05 00:30:30.000000000 -0500
@@ -14,6 +14,10 @@
 #  undef STP_RELAYFS
 #endif
 
+#if !defined(CONFIG_LTT)
+#  undef STP_LTT
+#endif
+
 #  include <linux/namei.h>
 
 struct rchan *_stp_relayfs_open(unsigned n_subbufs,
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/runtime/transport/transport.c /usr/local/src/systemtap-20060930/src/runtime/transport/transport.c
--- /usr/local/src/systemtap-20060930/src-orig/runtime/transport/transport.c	2006-09-26 16:38:05.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/runtime/transport/transport.c	2006-10-05 00:30:35.000000000 -0500
@@ -57,7 +57,7 @@ int _stp_transport_send (int type, void 
 	return err;
 }
 
-#ifndef STP_RELAYFS
+#if !defined(STP_RELAYFS) && !defined(STP_LTT)
 int _stp_transport_write (void *data, int len)  
 {
 	/* when _stp_exit_called is set, we are in probe_exit() and we can sleep */
@@ -234,7 +234,7 @@ int _stp_transport_open(struct transport
 	_stp_target = info->target;
 
 #ifdef STP_RELAYFS
-	if (_stp_transport_mode == STP_TRANSPORT_RELAYFS) {
+	if (_stp_transport_mode == STP_TRANSPORT_RELAYFS || _stp_transport_mode == STP_TRANSPORT_LTT) {
 		if (info->buf_size) {
 			unsigned size = info->buf_size * 1024 * 1024;
 			subbuf_size = ((size >> 2) + 1) * 65536;
@@ -243,7 +243,7 @@ int _stp_transport_open(struct transport
 		info->n_subbufs = n_subbufs;
 		info->subbuf_size = subbuf_size;
 
-#ifdef STP_RELAYFS_MERGE
+#if defined(STP_RELAYFS_MERGE) || defined(STP_LTT_MERGE)
 		info->merge = 1;
 #endif
 
@@ -291,7 +291,22 @@ int _stp_transport_init(void)
 	return 0;
 }
 
+#if defined (CONFIG_LTT) && defined(STP_LTT)
+#include <linux/ltt/ltt-facility-systemtap.h>
+/* like relay_write except returns an error code */
+
+static int _stp_ltt_write (const void *data, unsigned length)
+{
+	lttng_sequence_systemtap_probelog_probedata probedata;
+	
+	probedata.len = length;
+	probedata.array = data;
 
+	trace_systemtap_probelog(&probedata);
+	
+	return length; // trace call has no retval
+}
+#else
 /* like relay_write except returns an error code */
 
 #ifdef STP_RELAYFS
@@ -317,5 +332,6 @@ static int _stp_relay_write (const void 
 	return length;
 }
 #endif
+#endif
 
 #endif /* _TRANSPORT_C_ */
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/runtime/transport/transport.h /usr/local/src/systemtap-20060930/src/runtime/transport/transport.h
--- /usr/local/src/systemtap-20060930/src-orig/runtime/transport/transport.h	2006-09-21 20:34:42.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/runtime/transport/transport.h	2006-10-05 00:30:40.000000000 -0500
@@ -15,11 +15,14 @@ void _stp_warn (const char *fmt, ...);
 /* how often the work queue wakes up and checks buffers */
 #define STP_WORK_TIMER (HZ/100)
 
-#ifdef STP_RELAYFS
+#if defined STP_RELAYFS
 static unsigned n_subbufs = 16;
 static unsigned subbuf_size = 65536;
 #define _stp_transport_write(data, len)  _stp_relay_write(data, len)
 static int _stp_transport_mode = STP_TRANSPORT_RELAYFS;
+#elif defined STP_LTT
+#define _stp_transport_write(data, len)  _stp_ltt_write(data, len)
+static int _stp_transport_mode = STP_TRANSPORT_LTT;
 #else
 static int _stp_transport_mode = STP_TRANSPORT_PROC;
 #endif
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/runtime/transport/transport_msgs.h /usr/local/src/systemtap-20060930/src/runtime/transport/transport_msgs.h
--- /usr/local/src/systemtap-20060930/src-orig/runtime/transport/transport_msgs.h	2006-09-25 17:37:21.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/runtime/transport/transport_msgs.h	2006-10-05 00:30:43.000000000 -0500
@@ -2,7 +2,8 @@
 enum
 {
 	STP_TRANSPORT_PROC = 1,
-	STP_TRANSPORT_RELAYFS
+	STP_TRANSPORT_RELAYFS,
+	STP_TRANSPORT_LTT
 };
 
 /* stp control channel command values */
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/session.h /usr/local/src/systemtap-20060930/src/session.h
--- /usr/local/src/systemtap-20060930/src-orig/session.h	2006-09-27 20:48:59.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/session.h	2006-10-05 00:30:03.000000000 -0500
@@ -76,6 +76,7 @@ struct systemtap_session
   bool keep_tmpdir;
   bool guru_mode;
   bool bulk_mode;
+  bool ltt_bulk_mode;
   bool unoptimized;
   bool merge;
   int buffer_size;
diff -urpN -X /usr/local/src/dontdiff.systemtap /usr/local/src/systemtap-20060930/src-orig/translate.cxx /usr/local/src/systemtap-20060930/src/translate.cxx
--- /usr/local/src/systemtap-20060930/src-orig/translate.cxx	2006-09-18 11:55:01.000000000 -0500
+++ /usr/local/src/systemtap-20060930/src/translate.cxx	2006-10-05 00:30:10.000000000 -0500
@@ -3792,6 +3792,14 @@ translate_pass (systemtap_session& s)
 	    s.op->newline() << "#define STP_RELAYFS_MERGE";
 	}
 
+      if (s.ltt_bulk_mode)
+	{
+	  s.op->newline() << "#define STP_LTT";
+	  
+	  if (s.merge)
+	    s.op->newline() << "#define STP_LTT_MERGE";
+	}
+
       if (s.timing)
 	s.op->newline() << "#define STP_TIMING" << " " << s.timing ;
 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]