summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/ChangeLog6
-rw-r--r--runtime/print.c16
-rw-r--r--runtime/probes/ChangeLog7
-rw-r--r--runtime/probes/shellsnoop/shellsnoop.c12
-rwxr-xr-xruntime/probes/shellsnoop/stp23
-rwxr-xr-xruntime/probes/tasklet/stp15
-rw-r--r--runtime/probes/tasklet/stp_tasklet.c14
-rwxr-xr-xruntime/probes/test4/stp15
-rw-r--r--runtime/probes/test4/test4.c12
-rw-r--r--runtime/probes/where_func/kprobe_where_funct.c12
-rwxr-xr-xruntime/probes/where_func/stp18
-rw-r--r--runtime/runtime.h12
-rw-r--r--runtime/stpd/ChangeLog17
-rw-r--r--runtime/stpd/librelay.c639
-rw-r--r--runtime/stpd/librelay.h12
-rw-r--r--runtime/stpd/stpd.c48
-rw-r--r--runtime/transport/ChangeLog14
-rw-r--r--runtime/transport/control.h1
-rw-r--r--runtime/transport/transport.c62
-rw-r--r--runtime/transport/transport.h41
20 files changed, 668 insertions, 328 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 6f8246b6..1114bb8a 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,9 @@
+2005-06-20 Tom Zanussi <zanussi@us.ibm.com>
+
+ * print.c: Made relayfs _stp_print_flush() use sequence counter.
+
+ * runtime.h: Added sequence counter, moved subbuf_size etc to probes.
+
2005-06-18 Martin Hunt <hunt@redhat.com>
* counter.c: New file. Counter aggregations.
diff --git a/runtime/print.c b/runtime/print.c
index 3c09e105..72846a24 100644
--- a/runtime/print.c
+++ b/runtime/print.c
@@ -56,8 +56,8 @@ void _stp_print_flush (void)
#else /* ! STP_NETLINK_ONLY */
/* size of timestamp, in bytes, including space */
-#define TIMESTAMP_SIZE 19
-#define STP_PRINT_BUF_START (TIMESTAMP_SIZE + 1)
+#define TIMESTAMP_SIZE 11
+#define STP_PRINT_BUF_START (TIMESTAMP_SIZE)
/** Size of buffer, not including terminating NULL */
#ifndef STP_PRINT_BUF_LEN
@@ -77,15 +77,15 @@ void _stp_print_flush (void)
int cpu = smp_processor_id();
char *buf = &_stp_pbuf[cpu][0];
char *ptr = buf + STP_PRINT_BUF_START;
- struct timeval tv;
+ int seq;
if (_stp_pbuf_len[cpu] == 0)
return;
-
- do_gettimeofday(&tv);
- scnprintf (buf, TIMESTAMP_SIZE+1, "[%li.%06li] ", tv.tv_sec, tv.tv_usec);
- buf[TIMESTAMP_SIZE] = ' ';
- _stp_transport_write(t, buf, _stp_pbuf_len[cpu] + TIMESTAMP_SIZE + 2);
+
+ seq = _stp_seq_inc();
+ scnprintf (buf, TIMESTAMP_SIZE, "%10d", seq);
+ buf[TIMESTAMP_SIZE - 1] = ' ';
+ _stp_transport_write(t, buf, _stp_pbuf_len[cpu] + TIMESTAMP_SIZE + 1);
_stp_pbuf_len[cpu] = 0;
*ptr = 0;
}
diff --git a/runtime/probes/ChangeLog b/runtime/probes/ChangeLog
index 2464a5c3..d4e31b88 100644
--- a/runtime/probes/ChangeLog
+++ b/runtime/probes/ChangeLog
@@ -1,3 +1,10 @@
+2005-06-20 Tom Zanussi <zanussi@us.ibm.com>
+
+ * added transport_mode, subbuf_size, n_subbufs to all
+ probes and changed _stp_transport_open() calls.
+
+ * removed all obsolete params from stp scripts.
+
2005-06-18 Martin Hunt <hunt@redhat.com>
* build: Modified to use build_probe.
diff --git a/runtime/probes/shellsnoop/shellsnoop.c b/runtime/probes/shellsnoop/shellsnoop.c
index 86d2e54d..21ad6b18 100644
--- a/runtime/probes/shellsnoop/shellsnoop.c
+++ b/runtime/probes/shellsnoop/shellsnoop.c
@@ -1,7 +1,17 @@
#define STP_NETLINK_ONLY
#define STP_NUM_STRINGS 1
+
+static unsigned n_subbufs = 4;
+static unsigned subbuf_size = 65536;
+
#include "runtime.h"
+#ifdef STP_NETLINK_ONLY
+static int transport_mode = STP_TRANSPORT_NETLINK;
+#else
+static int transport_mode = STP_TRANSPORT_RELAYFS;
+#endif
+
#define NEED_INT64_VALS
#define NEED_STRING_VALS
@@ -118,7 +128,7 @@ int init_module(void)
return -1;
}
- if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) {
+ if (_stp_transport_open(transport_mode, n_subbufs, subbuf_size, pid) < 0) {
printk("init_module: Couldn't open transport\n");
return -1;
}
diff --git a/runtime/probes/shellsnoop/stp b/runtime/probes/shellsnoop/stp
index ac5472f8..4baf70ff 100755
--- a/runtime/probes/shellsnoop/stp
+++ b/runtime/probes/shellsnoop/stp
@@ -7,8 +7,8 @@ else
exit
fi
-RELAYFS=`grep " relayfs_mmap" /proc/kallsyms`
-if [ "$RELAYFS" == "" ]
+RELAYFS=`lsmod | grep relayfs |awk '{print $1}'`
+if [ "$RELAYFS" != "relayfs" ]
then
/sbin/insmod ../../relayfs/relayfs.ko
fi
@@ -32,18 +32,11 @@ fi
#/sbin/insmod $modulename
-# print to screen only, 4 8K buffers
-#../../stpd/stpd -p -b 8192 -n 4
+# print to screen only
+#../../stpd/stpd -p $modulename
-# print to screen
-../../stpd/stpd -b 8192 -n 4 $modulename
-
-# log to files (relayfs), 4 8K buffers
-#../../stpd/stpd -r -b 65536 -n 4 $modulename
-
-# print to screen and log to files, 4 8K buffers
-#../../stpd/stpd -b 8192 -n 4
-
-# no screen or log
-#../../stpd/stpd -q -b 8192 -n 4
+# print to screen and log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+../../stpd/stpd $modulename
+# no screen, log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+#../../stpd/stpd -q $modulename
diff --git a/runtime/probes/tasklet/stp b/runtime/probes/tasklet/stp
index 185a5905..4baf70ff 100755
--- a/runtime/probes/tasklet/stp
+++ b/runtime/probes/tasklet/stp
@@ -32,14 +32,11 @@ fi
#/sbin/insmod $modulename
-# print to screen only, 4 8K buffers
-#../../stpd/stpd -p -b 8192 -n 4
+# print to screen only
+#../../stpd/stpd -p $modulename
-# print to screen and log to files, 4 8K buffers
-../../stpd/stpd -b 8192 -n 4 $modulename
+# print to screen and log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+../../stpd/stpd $modulename
-# no screen or log
-#../../stpd/stpd -q -b 8192 -n 4
-
-# stpd will remove module when it exits
-#/sbin/rmmod $modulename
+# no screen, log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+#../../stpd/stpd -q $modulename
diff --git a/runtime/probes/tasklet/stp_tasklet.c b/runtime/probes/tasklet/stp_tasklet.c
index 68569fb5..c6e7b132 100644
--- a/runtime/probes/tasklet/stp_tasklet.c
+++ b/runtime/probes/tasklet/stp_tasklet.c
@@ -4,9 +4,19 @@
#define STP_NETLINK_ONLY
#define STP_NUM_STRINGS 1
+
+static unsigned n_subbufs = 4;
+static unsigned subbuf_size = 65536;
+
#include "runtime.h"
-#include "probes.c"
+#ifdef STP_NETLINK_ONLY
+static int transport_mode = STP_TRANSPORT_NETLINK;
+#else
+static int transport_mode = STP_TRANSPORT_RELAYFS;
+#endif
+
+#include "probes.c"
MODULE_DESCRIPTION("test jprobes of tasklets");
MODULE_AUTHOR("Martin Hunt <hunt@redhat.com>");
@@ -42,7 +52,7 @@ int init_module(void)
return -1;
}
- if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) {
+ if (_stp_transport_open(transport_mode, n_subbufs, subbuf_size, pid) < 0) {
printk("init_dtr: Couldn't open transport\n");
return -1;
}
diff --git a/runtime/probes/test4/stp b/runtime/probes/test4/stp
index 185a5905..4baf70ff 100755
--- a/runtime/probes/test4/stp
+++ b/runtime/probes/test4/stp
@@ -32,14 +32,11 @@ fi
#/sbin/insmod $modulename
-# print to screen only, 4 8K buffers
-#../../stpd/stpd -p -b 8192 -n 4
+# print to screen only
+#../../stpd/stpd -p $modulename
-# print to screen and log to files, 4 8K buffers
-../../stpd/stpd -b 8192 -n 4 $modulename
+# print to screen and log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+../../stpd/stpd $modulename
-# no screen or log
-#../../stpd/stpd -q -b 8192 -n 4
-
-# stpd will remove module when it exits
-#/sbin/rmmod $modulename
+# no screen, log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+#../../stpd/stpd -q $modulename
diff --git a/runtime/probes/test4/test4.c b/runtime/probes/test4/test4.c
index 9867d8ef..ac446bbb 100644
--- a/runtime/probes/test4/test4.c
+++ b/runtime/probes/test4/test4.c
@@ -1,7 +1,17 @@
#define STP_NETLINK_ONLY
#define STP_NUM_STRINGS 1
+
+static unsigned n_subbufs = 4;
+static unsigned subbuf_size = 65536;
+
#include "runtime.h"
+#ifdef STP_NETLINK_ONLY
+static int transport_mode = STP_TRANSPORT_NETLINK;
+#else
+static int transport_mode = STP_TRANSPORT_RELAYFS;
+#endif
+
#define NEED_INT64_VALS
#define NEED_STAT_VALS
@@ -71,7 +81,7 @@ int init_module(void)
return -1;
}
- if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) {
+ if (_stp_transport_open(transport_mode, n_subbufs, subbuf_size, pid) < 0) {
printk("init: Couldn't open transport\n");
return -1;
}
diff --git a/runtime/probes/where_func/kprobe_where_funct.c b/runtime/probes/where_func/kprobe_where_funct.c
index e029a080..d0d720df 100644
--- a/runtime/probes/where_func/kprobe_where_funct.c
+++ b/runtime/probes/where_func/kprobe_where_funct.c
@@ -6,8 +6,18 @@
#define STP_NETLINK_ONLY
#define STP_NUM_STRINGS 1
+
+static unsigned n_subbufs = 4;
+static unsigned subbuf_size = 65536;
+
#include "runtime.h"
+#ifdef STP_NETLINK_ONLY
+static int transport_mode = STP_TRANSPORT_NETLINK;
+#else
+static int transport_mode = STP_TRANSPORT_RELAYFS;
+#endif
+
#define NEED_INT64_VALS
#define KEY1_TYPE INT64
@@ -59,7 +69,7 @@ int init_module(void)
return -1;
}
- if (_stp_transport_open(n_subbufs, subbuf_size, pid) < 0) {
+ if (_stp_transport_open(transport_mode, n_subbufs, subbuf_size, pid) < 0) {
printk("init_dtr: Couldn't open transport\n");
return -1;
}
diff --git a/runtime/probes/where_func/stp b/runtime/probes/where_func/stp
index ca0cb63c..4baf70ff 100755
--- a/runtime/probes/where_func/stp
+++ b/runtime/probes/where_func/stp
@@ -32,17 +32,11 @@ fi
#/sbin/insmod $modulename
-# print to screen only, 4 8K buffers
-#../../stpd/stpd -p -b 8192 -n 4
+# print to screen only
+#../../stpd/stpd -p $modulename
-# print to screen and log to files, 4 8K buffers
-../../stpd/stpd -b 8192 -n 4 $modulename
+# print to screen and log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+../../stpd/stpd $modulename
-# print to screen and log to files, 4 8K buffers
-#../../stpd/stpd -b 8192 -n 4
-
-# no screen or log
-#../../stpd/stpd -q -b 8192 -n 4
-
-# stpd will remove module when it exits
-#/sbin/rmmod $modulename
+# no screen, log to files (file logging only if #define STP_NETLINK_ONLY commented out in module)
+#../../stpd/stpd -q $modulename
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 5937ec5b..1a70da3f 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -25,12 +25,16 @@
/* atomic globals */
static atomic_t _stp_transport_failures = ATOMIC_INIT (0);
-/* some relayfs defaults that don't belong here */
-static unsigned n_subbufs = 4;
-static unsigned subbuf_size = 65536;
+#ifndef STP_NETLINK_ONLY
+static struct
+{
+ atomic_t ____cacheline_aligned_in_smp seq;
+} _stp_seq = { ATOMIC_INIT (0) };
+
+#define _stp_seq_inc() (atomic_inc_return(&_stp_seq.seq))
+#endif
#include "print.c"
#include "string.c"
-
#endif /* _RUNTIME_H_ */
diff --git a/runtime/stpd/ChangeLog b/runtime/stpd/ChangeLog
index 421b27c6..2d77c405 100644
--- a/runtime/stpd/ChangeLog
+++ b/runtime/stpd/ChangeLog
@@ -1,6 +1,21 @@
+2005-06-20 Tom Zanussi <zanussi@us.ibm.com>
+
+ * librelay.c: Large refactoring, important changes are
+ added transport_mode command, for relayfs transport
+ display results only when probe completes and/or write
+ output file, merge, sort and delete the per-cpu files
+ in postprocessing, refactor so that relayfs files aren't
+ created until transport command received, removed sigalrm,
+ read the final subbuffers on exit
+
+ * stpd.c: Remove all command-line args except for -p
+ and -q as well as all code related to buffer sizes.
+
+ * librelay.h: Add transport mode command and struct.
+
2005-05-16 Martin Hunt <hunt@redhat.com>
* librelay.c (sigproc): If STP_EXIT send fails, keep retrying
every 10ms.
(init_stp): Don't set n_subbufs and subbuf_size params.
-
+
diff --git a/runtime/stpd/librelay.c b/runtime/stpd/librelay.c
index a1e8562f..60a513b7 100644
--- a/runtime/stpd/librelay.c
+++ b/runtime/stpd/librelay.c
@@ -37,29 +37,48 @@
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/netlink.h>
+#include <linux/limits.h>
#include "librelay.h"
/* maximum number of CPUs we can handle - change if more */
#define NR_CPUS 256
- /* internal variables */
-static unsigned subbuf_size;
-static unsigned n_subbufs;
+ /* relayfs parameters */
+static struct params
+{
+ unsigned subbuf_size;
+ unsigned n_subbufs;
+ char relay_filebase[256];
+} params;
+
+/* temporary per-cpu output written here, filebase0...N */
+static char *percpu_tmpfilebase = "stpd_cpu";
+
+/* temporary merged/sorted output written here */
+static char *tmpfile_name = "sorted.tmp";
+
+/* probe output written here */
+static char *outfile_name = "probe.out";
+
+/* internal variables */
+static int transport_mode;
static int ncpus;
static int print_totals;
-static int logging;
+static int final_cpus_processed;
+static int exiting;
+/* per-cpu data */
static int relay_file[NR_CPUS];
-static int out_file[NR_CPUS];
+static int percpu_tmpfile[NR_CPUS];
static char *relay_buffer[NR_CPUS];
+static pthread_t reader[NR_CPUS];
- /* netlink control channel */
+/* netlink control channel */
static int control_channel;
/* flags */
extern int print_only;
extern int quiet;
-extern int streaming;
/* used to communicate with kernel over control channel */
@@ -76,12 +95,25 @@ struct consumed_info
unsigned consumed;
};
-struct app_msg
+struct transport_info
+{
+ int transport_mode;
+ unsigned subbuf_size;
+ unsigned n_subbufs;
+};
+
+struct buf_msg
{
struct nlmsghdr nlh;
struct buf_info info;
};
+struct transport_msg
+{
+ struct nlmsghdr nlh;
+ struct transport_info info;
+};
+
static char *recvbuf[8192];
/* per-cpu buffer info */
@@ -104,6 +136,19 @@ static char *color[] = {
};
/**
+ * streaming - is the current transport mode streaming or not?
+ *
+ * Returns 1 if in streaming mode, 0 otherwise.
+ */
+static int streaming(void)
+{
+ if (transport_mode == STP_TRANSPORT_NETLINK)
+ return 1;
+
+ return 0;
+}
+
+/**
* send_request - send request to kernel over control channel
* @type: the relay-app command id
* @data: pointer to the data to be sent
@@ -118,7 +163,7 @@ int send_request(int type, void *data, int len)
req = (struct nlmsghdr *)malloc(NLMSG_SPACE(len));
if (req == 0) {
- fprintf(stderr, "send_request malloc failed\n");
+ fprintf(stderr, "WARNING: send_request malloc failed\n");
return -1;
}
memset(req, 0, NLMSG_SPACE(len));
@@ -142,7 +187,7 @@ static int open_control_channel()
channel = socket(AF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
if (channel < 0) {
- printf("socket() failed\n");
+ fprintf(stderr, "ERROR: socket() failed\n");
return channel;
}
@@ -152,13 +197,159 @@ static int open_control_channel()
snl.nl_groups = 0;
if (bind (channel, (struct sockaddr *) &snl, sizeof snl))
- printf("bind() failed\n");
+ fprintf(stderr, "ERROR: bind() failed\n");
return channel;
}
/**
- * process_subbufs - write ready subbufs to disk and/or screen
+ * summarize - print a summary if applicable
+ */
+static void summarize(void)
+{
+ int i;
+
+ if (streaming())
+ return;
+
+ printf("summary:\n");
+ for (i = 0; i < ncpus; i++) {
+ printf("%s cpu %u:\n", color[i % 4], i);
+ printf(" %u sub-buffers processed\n",
+ status[i].info.consumed);
+ printf(" %u max backlog\n", status[i].max_backlog);
+ }
+}
+
+/**
+ * close_relayfs_files - close and munmap buffer and open output file
+ */
+static void close_relayfs_files(int cpu)
+{
+ size_t total_bufsize = params.subbuf_size * params.n_subbufs;
+
+ munmap(relay_buffer[cpu], total_bufsize);
+ close(relay_file[cpu]);
+ close(percpu_tmpfile[cpu]);
+}
+
+/**
+ * close_all_relayfs_files - close and munmap buffers and output files
+ */
+static void close_all_relayfs_files(void)
+{
+ int i;
+
+ if (!streaming()) {
+ for (i = 0; i < ncpus; i++)
+ close_relayfs_files(i);
+ }
+}
+
+/**
+ * open_relayfs_files - open and mmap buffer and open output file
+ */
+static int open_relayfs_files(int cpu, const char *relay_filebase)
+{
+ size_t total_bufsize;
+ char tmp[PATH_MAX];
+
+ memset(&status[cpu], 0, sizeof(struct buf_status));
+ pthread_mutex_init(&status[cpu].ready_mutex, NULL);
+ pthread_cond_init(&status[cpu].ready_cond, NULL);
+ status[cpu].info.cpu = cpu;
+
+ sprintf(tmp, "%s%d", relay_filebase, cpu);
+ relay_file[cpu] = open(tmp, O_RDONLY | O_NONBLOCK);
+ if (relay_file[cpu] < 0) {
+ fprintf(stderr, "ERROR: couldn't open relayfs file %s: errcode = %s\n", tmp, strerror(errno));
+ return -1;
+ }
+
+ sprintf(tmp, "%s%d", percpu_tmpfilebase, cpu);
+ if((percpu_tmpfile[cpu] = open(tmp, O_CREAT | O_RDWR | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
+ fprintf(stderr, "ERROR: Couldn't open output file %s: errcode = %s\n", tmp, strerror(errno));
+ close(relay_file[cpu]);
+ return -1;
+ }
+
+ total_bufsize = params.subbuf_size * params.n_subbufs;
+ relay_buffer[cpu] = mmap(NULL, total_bufsize, PROT_READ,
+ MAP_PRIVATE | MAP_POPULATE, relay_file[cpu],
+ 0);
+ if(relay_buffer[cpu] == MAP_FAILED)
+ {
+ fprintf(stderr, "ERROR: couldn't mmap relay file, total_bufsize (%d) = subbuf_size (%d) * n_subbufs(%d), error = %s \n", (int)total_bufsize, (int)params.subbuf_size, (int)params.n_subbufs, strerror(errno));
+ close(relay_file[cpu]);
+ close(percpu_tmpfile[cpu]);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * delete_percpu_files - delete temporary per-cpu output files
+ *
+ * Returns 0 if successful, -1 otherwise.
+ */
+static int delete_percpu_files(void)
+{
+ int i;
+ char tmp[PATH_MAX];
+
+ for (i = 0; i < ncpus; i++) {
+ sprintf(tmp, "%s%d", percpu_tmpfilebase, i);
+ if (unlink(tmp) < 0) {
+ fprintf(stderr, "ERROR: couldn't unlink percpu file %s: errcode = %s\n", tmp, strerror(errno));
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * kill_percpu_threads - kill per-cpu threads 0->n-1
+ * @n: number of threads to kill
+ *
+ * Returns number of threads killed.
+ */
+static int kill_percpu_threads(int n)
+{
+ int i, killed = 0;
+
+ for (i = 0; i < n; i++) {
+ if (pthread_cancel(reader[i]) == 0)
+ killed++;
+ }
+ if (killed != n)
+ fprintf(stderr, "WARNING: couldn't kill all per-cpu threads: %d killed, %d total\n", killed, n);
+
+ return killed;
+}
+
+/**
+ * request_last_buffers - request end-of-trace last buffer processing
+ *
+ * Returns 0 if successful, negative otherwise
+ */
+static int request_last_buffers(void)
+{
+ int i;
+
+ for (i = 0; i < ncpus; i++) {
+ if (send_request(STP_BUF_INFO, &status[i].info, sizeof(struct buf_info)) < 0) {
+ fprintf(stderr, "WARNING: couldn't request last buffers for cpu %d\n", i);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * process_subbufs - write ready subbufs to disk
*/
static int process_subbufs(struct buf_info *info)
{
@@ -169,31 +360,21 @@ static int process_subbufs(struct buf_info *info)
unsigned padding;
subbufs_ready = info->produced - info->consumed;
- start_subbuf = info->consumed % n_subbufs;
+ start_subbuf = info->consumed % params.n_subbufs;
end_subbuf = start_subbuf + subbufs_ready;
- if (!quiet)
- fputs ( color[cpu % 4], stdout);
-
for (i = start_subbuf; i < end_subbuf; i++) {
- subbuf_idx = i % n_subbufs;
- subbuf_ptr = relay_buffer[cpu] + subbuf_idx * subbuf_size;
+ subbuf_idx = i % params.n_subbufs;
+ subbuf_ptr = relay_buffer[cpu] + subbuf_idx * params.subbuf_size;
padding = *((unsigned *)subbuf_ptr);
subbuf_ptr += sizeof(padding);
- len = (subbuf_size - sizeof(padding)) - padding;
+ len = (params.subbuf_size - sizeof(padding)) - padding;
- if (!print_only)
+ if (write(percpu_tmpfile[cpu], subbuf_ptr, len) < 0)
{
- if (write(out_file[cpu], subbuf_ptr, len) < 0)
- {
- printf("Couldn't write to output file for cpu %d, exiting: errcode = %d: %s\n", cpu, errno, strerror(errno));
- exit(1);
- }
+ fprintf(stderr, "ERROR: couldn't write to output file for cpu %d, exiting: errcode = %d: %s\n", cpu, errno, strerror(errno));
+ exit(1);
}
-
- if (!quiet)
- fwrite (subbuf_ptr, len, 1, stdout);
-
subbufs_consumed++;
}
@@ -217,24 +398,24 @@ static void *reader_thread(void *data)
rc = poll(&pollfd, 1, -1);
if (rc < 0) {
if (errno != EINTR) {
- printf("poll error: %s\n",strerror(errno));
+ fprintf(stderr, "ERROR: poll error: %s\n",strerror(errno));
exit(1);
}
- printf("poll warning: %s\n",strerror(errno));
+ fprintf(stderr, "WARNING: poll warning: %s\n",strerror(errno));
rc = 0;
}
-
send_request(STP_BUF_INFO, &status[cpu].info,
sizeof(struct buf_info));
+
if (status[cpu].info.produced == status[cpu].info.consumed)
pthread_cond_wait(&status[cpu].ready_cond,
&status[cpu].ready_mutex);
pthread_mutex_unlock(&status[cpu].ready_mutex);
-
+
subbufs_consumed = process_subbufs(&status[cpu].info);
if (subbufs_consumed) {
- if (subbufs_consumed == n_subbufs)
- fprintf(stderr, "cpu %ld buffer full. Consider using a larger buffer size.\n", cpu);
+ if (subbufs_consumed == params.n_subbufs)
+ fprintf(stderr, "WARNING: cpu %ld buffer full. Consider using a larger buffer size.\n", cpu);
if (subbufs_consumed > status[cpu].max_backlog)
status[cpu].max_backlog = subbufs_consumed;
status[cpu].info.consumed += subbufs_consumed;
@@ -247,135 +428,62 @@ static void *reader_thread(void *data)
} while (1);
}
-static void summarize(void)
-{
- int i;
-
- if (streaming)
- return;
-
- printf("summary:\n");
- for (i = 0; i < ncpus; i++) {
- printf("%s cpu %u:\n", color[i % 4], i);
- printf(" %u sub-buffers processed\n",
- status[i].info.consumed);
- printf(" %u max backlog\n", status[i].max_backlog);
- }
-}
-
-/**
- * close_files - close and munmap buffer and open output file
- */
-static void close_files(int cpu)
-{
- size_t total_bufsize = subbuf_size * n_subbufs;
-
- munmap(relay_buffer[cpu], total_bufsize);
- close(relay_file[cpu]);
- if (!print_only) close(out_file[cpu]);
-}
-
-static void close_all_files(void)
-{
- int i;
- close(control_channel);
- for (i = 0; i < ncpus; i++)
- close_files(i);
-}
-
-static void sigalarm(int signum)
-{
- if (print_totals)
- summarize();
- close_all_files();
- exit(0);
-}
-
-static void sigproc(int signum)
-{
- while (send_request(STP_EXIT, NULL, 0) < 0)
- usleep (10000);
-}
-
/**
- * open_files - open and mmap buffer and open output file
+ * init_relayfs - create files and threads for relayfs processing
+ *
+ * Returns 0 if successful, negative otherwise
*/
-static int open_files(int cpu, const char *relay_filebase,
- const char *out_filebase)
+int init_relayfs(void)
{
- size_t total_bufsize;
- char tmp[4096];
-
- memset(&status[cpu], 0, sizeof(struct buf_status));
- pthread_mutex_init(&status[cpu].ready_mutex, NULL);
- pthread_cond_init(&status[cpu].ready_cond, NULL);
- status[cpu].info.cpu = cpu;
-
- sprintf(tmp, "%s%d", relay_filebase, cpu);
- relay_file[cpu] = open(tmp, O_RDONLY | O_NONBLOCK);
- if (relay_file[cpu] < 0) {
- printf("Couldn't open relayfs file %s: errcode = %s\n",
- tmp, strerror(errno));
- return -1;
- }
-
- if (!print_only) {
- sprintf(tmp, "%s%d", out_filebase, cpu);
- if((out_file[cpu] = open(tmp, O_CREAT | O_RDWR | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
- printf("Couldn't open output file %s: errcode = %s\n",
- tmp, strerror(errno));
- close(relay_file[cpu]);
- return -1;
+ int i, j;
+
+ for (i = 0; i < ncpus; i++) {
+ if (open_relayfs_files(i, params.relay_filebase) < 0) {
+ fprintf(stderr, "ERROR: couldn't open relayfs files, cpu = %d\n", i);
+ goto err;
+ }
+ /* create a thread for each per-cpu buffer */
+ if (pthread_create(&reader[i], NULL, reader_thread, (void *)i) < 0) {
+ close_relayfs_files(i);
+ fprintf(stderr, "ERROR: Couldn't create reader thread, cpu = %d\n", i);
+ goto err;
}
}
- total_bufsize = subbuf_size * n_subbufs;
- relay_buffer[cpu] = mmap(NULL, total_bufsize, PROT_READ,
- MAP_PRIVATE | MAP_POPULATE, relay_file[cpu],
- 0);
- if(relay_buffer[cpu] == MAP_FAILED)
- {
- printf("Couldn't mmap relay file, total_bufsize (%d) = subbuf_size (%d) * n_subbufs(%d), error = %s \n", (int)total_bufsize, (int)subbuf_size, (int)n_subbufs, strerror(errno));
- close(relay_file[cpu]);
- if (!print_only) close(out_file[cpu]);
- return -1;
- }
-
+ printf("Using channel with %u sub-buffers of size %u.\n",
+ params.n_subbufs, params.subbuf_size);
+
return 0;
+err:
+ for (j = 0; j < i; j++)
+ close_relayfs_files(j);
+ kill_percpu_threads(i);
+
+ return -1;
}
/**
* init_stp - initialize the app
+ * @modname: the name of the stp module to load
* @relay_filebase: full path of base name of the per-cpu relayfs files
- * @out_filebase: base name of the per-cpu files data will be written to
- * @sub_buf_size: relayfs sub-buffer size of channel to be created
- * @n_sub_bufs: relayfs number of sub-buffers of channel to be created
* @print_summary: boolean, print summary or not at end of run
*
* Returns 0 on success, negative otherwise.
*/
int init_stp(const char *modname,
const char *relay_filebase,
- const char *out_filebase,
- unsigned sub_buf_size,
- unsigned n_sub_bufs,
int print_summary)
{
- int i;
int daemon_pid;
char buf[1024];
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
- subbuf_size = sub_buf_size;
- n_subbufs = n_sub_bufs;
print_totals = print_summary;
-
daemon_pid = getpid();
sprintf(buf, "insmod %s pid=%d", modname, daemon_pid);
if (system(buf)) {
- printf("Couldn't insmod probe module %s\n", modname);
+ fprintf(stderr, "ERROR, couldn't insmod probe module %s\n", modname);
return -1;
}
@@ -383,48 +491,161 @@ int init_stp(const char *modname,
if (control_channel < 0)
return -1;
- if (streaming)
- return 0;
+ if (relay_filebase)
+ strcpy(params.relay_filebase, relay_filebase);
- for (i = 0; i < ncpus; i++) {
- if (open_files(i, relay_filebase, out_filebase) < 0) {
- printf("Couldn't open files\n");
- close (control_channel);
- return -1;
+ return 0;
+}
+
+/* length of timestamp in output field 0 - TODO: make binary, variable */
+#define TIMESTAMP_SIZE 11
+
+/**
+ * write_output - either to screen, outfile or both
+ */
+static int write_output(void)
+{
+ struct stat sbuf;
+ int i, len, err = 0;
+ const char *subbuf_ptr;
+ int tmpfile;
+ FILE *outfile = NULL;
+ char *tmpbuf;
+ const char *rec_txt = subbuf_ptr + i;
+ const char * rec_cnt;
+
+ tmpfile = open(tmpfile_name, O_RDONLY);
+ if (tmpfile < 0) {
+ fprintf(stderr, "ERROR: couldn't open tmp file %s: errcode = %s\n", tmpfile_name, strerror(errno));
+ return -1;
+ }
+
+ if (fstat(tmpfile, &sbuf)) {
+ fprintf(stderr, "ERROR: couldn't stat tmp file %s: errcode = %s\n", tmpfile_name, strerror(errno));
+ return -1;
+ }
+ len = sbuf.st_size;
+ if (len <= TIMESTAMP_SIZE)
+ goto rm_tmp;
+
+ tmpbuf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, tmpfile, 0);
+ if(tmpbuf == MAP_FAILED)
+ {
+ close(tmpfile);
+ fprintf(stderr, "ERROR: couldn't mmap tmp file %s: errcode = %s\n", tmpfile_name, strerror(errno));
+ err = -1;
+ goto rm_tmp;
+ }
+ subbuf_ptr = tmpbuf;
+ i = TIMESTAMP_SIZE;
+ rec_txt = subbuf_ptr + i;
+
+ if (!print_only) {
+ outfile = fopen(outfile_name, "w");
+ if (!outfile) {
+ fprintf(stderr, "ERROR: couldn't open output file %s: errcode = %s\n", outfile_name, strerror(errno));
+ err = -1;
+ goto unmap_rm_tmp;
+ }
+ }
+
+ while (i < len) {
+ if (subbuf_ptr[i] == '\0') {
+ rec_cnt = rec_txt - TIMESTAMP_SIZE;
+ if (!quiet) {
+#if 0
+ fwrite(rec_cnt, TIMESTAMP_SIZE, 1, stdout);
+#endif
+ fwrite(rec_txt, (subbuf_ptr + i) - rec_txt, 1, stdout);
+ }
+ if (!print_only) {
+#if 0
+ fwrite(rec_cnt, TIMESTAMP_SIZE, 1, outfile);
+#endif
+ fwrite(rec_txt, (subbuf_ptr + i) - rec_txt, 1, outfile);
+ }
+ rec_txt = subbuf_ptr + i + 1 + TIMESTAMP_SIZE;
+ i += TIMESTAMP_SIZE;
}
+ i++;
}
+ if (!print_only)
+ fclose(outfile);
+unmap_rm_tmp:
+ munmap(tmpbuf, len);
+rm_tmp:
+ close(tmpfile);
+ if (unlink(tmpfile_name) < 0) {
+ fprintf(stderr, "Couldn't unlink tmp file %s: errcode = %s\n",
+ tmpfile_name, strerror(errno));
+ err = -1;
+ }
+
+ return err;
+}
+
+/**
+ * sort_output - merge and sort per-cpu output
+ *
+ * TODO: replace this with our own sort
+ */
+static int sort_output(void)
+{
+ char tmpbuf[PATH_MAX];
+
+ sprintf(tmpbuf, "sort -z -b -n -o %s %s*", tmpfile_name, percpu_tmpfilebase);
+ system(tmpbuf);
+ if (system(tmpbuf)) {
+ fprintf(stderr, "ERROR: couldn't sort output: %s failed. No output will be written.\n", tmpbuf);
+ return -1;
+ }
+
return 0;
}
/**
+ * postprocess_and_exit - postprocess the output and exit
+ */
+static void postprocess_and_exit(void)
+{
+ if (print_totals)
+ summarize();
+
+ if (!streaming()) {
+ if (sort_output() == 0)
+ write_output();
+ close_all_relayfs_files();
+ delete_percpu_files();
+ }
+
+ exit(0);
+}
+
+static void sigproc(int signum)
+{
+ while (send_request(STP_EXIT, NULL, 0) < 0)
+ usleep (10000);
+}
+
+/**
* stp_main_loop - loop forever reading data
*/
int stp_main_loop(void)
{
- pthread_t thread;
- int cpu, nb;
- long i;
- struct app_msg *msg;
+ int cpu, nb, rc;
+ struct buf_msg *buf_msg;
+ struct transport_msg *transport_msg;
unsigned short *ptr;
+ unsigned subbufs_consumed;
char tmpbuf[128];
-
+
signal(SIGINT, sigproc);
signal(SIGTERM, sigproc);
- signal(SIGALRM, sigalarm);
-
- if (!streaming) {
- for (i = 0; i < ncpus; i++) {
- /* create a thread for each per-cpu buffer */
- if (pthread_create(&thread, NULL, reader_thread, (void *)i) < 0) {
- printf("Couldn't create thread\n");
- return -1;
- }
- }
- }
- logging = 1;
-
+ send_request(STP_TRANSPORT_MODE, &transport_mode,
+ sizeof(transport_mode));
+
while (1) { /* handle messages from control channel */
nb = recv(control_channel, recvbuf, sizeof(recvbuf), 0);
struct nlmsghdr *nlh = (struct nlmsghdr *)recvbuf;
@@ -432,46 +653,86 @@ int stp_main_loop(void)
if (nb < 0) {
if (errno == EINTR)
continue;
- printf("recv() failed\n");
+ fprintf(stderr, "WARNING: recv() failed\n");
} else if (nb == 0)
- printf("unexpected EOF on netlink socket\n");
+ fprintf(stderr, "WARNING: unexpected EOF on netlink socket\n");
if (!NLMSG_OK(nlh, nb)) {
- printf("netlink message not ok, nb = %d\n", nb);
+ fprintf(stderr, "WARNING: netlink message not ok, nb = %d\n", nb);
+ continue;
+ }
+ if (!transport_mode &&
+ nlh->nlmsg_type != STP_TRANSPORT_MODE &&
+ nlh->nlmsg_type != STP_EXIT)
+ {
+ fprintf(stderr, "WARNING: invalid stp command: no transport\n");
continue;
}
switch (nlh->nlmsg_type) {
case STP_BUF_INFO:
- msg = (struct app_msg *)nlh;
- cpu = msg->info.cpu;
- memcpy(&status[cpu].info, &msg->info, sizeof (struct buf_info));
- pthread_mutex_lock(&status[cpu].ready_mutex);
- if (status[cpu].info.produced > status[cpu].info.consumed)
- pthread_cond_signal(&status[cpu].ready_cond);
- pthread_mutex_unlock(&status[cpu].ready_mutex);
- break;
+ buf_msg = (struct buf_msg *)nlh;
+ cpu = buf_msg->info.cpu;
+ memcpy(&status[cpu].info, &buf_msg->info, sizeof (struct buf_info));
+ if (exiting) {
+ final_cpus_processed++;
+ subbufs_consumed = process_subbufs(&status[cpu].info);
+ status[cpu].info.consumed += subbufs_consumed;
+ if (final_cpus_processed >= ncpus)
+ postprocess_and_exit();
+ break;
+ }
+ pthread_mutex_lock(&status[cpu].ready_mutex);
+ if (status[cpu].info.produced > status[cpu].info.consumed)
+ pthread_cond_signal(&status[cpu].ready_cond);
+ pthread_mutex_unlock(&status[cpu].ready_mutex);
+ break;
+ case STP_TRANSPORT_MODE:
+ transport_msg = (struct transport_msg *)nlh;
+ transport_mode = transport_msg->info.transport_mode;
+ params.subbuf_size = transport_msg->info.subbuf_size;
+ params.n_subbufs = transport_msg->info.n_subbufs;
+ if (!streaming()) {
+ rc = init_relayfs();
+ if (rc < 0) {
+ close(control_channel);
+ fprintf(stderr, "ERROR: couldn't init relayfs, exiting\n");
+ exit(1);
+ }
+ }
+ break;
case STP_REALTIME_DATA:
- ptr = NLMSG_DATA(nlh);
- fputs ( color[5], stdout);
- fputs ((char *)ptr, stdout);
- break;
+ ptr = NLMSG_DATA(nlh);
+ fputs ( color[5], stdout);
+ fputs ((char *)ptr, stdout);
+ break;
case STP_EXIT:
- /* module asks us to unload it and exit */
- ptr = NLMSG_DATA(nlh);
- /* FIXME. overflow check */
- strcpy (tmpbuf, "/sbin/rmmod ");
- strcpy (tmpbuf + strlen(tmpbuf), (char *)ptr);
+ if (!streaming() && !exiting) {
+ exiting = 1;
+ kill_percpu_threads(ncpus);
+ if (request_last_buffers() < 0)
+ exit(1);
+ }
+ /* module asks us to unload it and exit */
+ ptr = NLMSG_DATA(nlh);
+ /* FIXME. overflow check */
+ strcpy (tmpbuf, "/sbin/rmmod ");
+ strcpy (tmpbuf + strlen(tmpbuf), (char *)ptr);
#if 0
- printf ("Executing \"system %s\"\n", tmpbuf);
+ printf ("Executing \"system %s\"\n", tmpbuf);
#endif
- system (tmpbuf);
- if (print_totals)
- summarize();
- if (!streaming)
- close_all_files();
- exit(0);
- break;
+ if (system(tmpbuf)) {
+ fprintf(stderr, "ERROR: couldn't rmmod probe module %s. No output will be written.\n", (char *)ptr);
+ close_all_relayfs_files();
+ delete_percpu_files();
+ exit(1);
+ }
+ if (!streaming() && (final_cpus_processed < ncpus))
+ break;
+
+ close(control_channel);
+ postprocess_and_exit();
+ break;
default:
- fprintf(stderr, "WARNING: ignored netlink message of type %d\n", (nlh->nlmsg_type));
+ fprintf(stderr, "WARNING: ignored netlink message of type %d\n", (nlh->nlmsg_type));
}
}
return 0;
diff --git a/runtime/stpd/librelay.h b/runtime/stpd/librelay.h
index 033976d9..59273d8e 100644
--- a/runtime/stpd/librelay.h
+++ b/runtime/stpd/librelay.h
@@ -4,18 +4,22 @@ enum
STP_BUF_INFO = 1,
STP_SUBBUFS_CONSUMED,
STP_REALTIME_DATA,
+ STP_TRANSPORT_MODE,
STP_EXIT,
};
+/* SystemTap transport options */
+enum
+{
+ STP_TRANSPORT_NETLINK = 1,
+ STP_TRANSPORT_RELAYFS
+};
+
/*
* stp external API functions
*/
extern int init_stp(const char *modname,
const char *relay_filebase,
- const char *out_filebase,
- unsigned sub_buf_size,
- unsigned n_sub_bufs,
int print_summary);
-
extern int stp_main_loop(void);
extern int send_request(int type, void *data, int len);
diff --git a/runtime/stpd/stpd.c b/runtime/stpd/stpd.c
index 881556cc..c31019d7 100644
--- a/runtime/stpd/stpd.c
+++ b/runtime/stpd/stpd.c
@@ -25,65 +25,39 @@
#include <unistd.h>
#include "librelay.h"
- /* packet logging output written here, filebase0...N */
-static char *stpd_outfilebase = "stpd_cpu";
-
-#define DEFAULT_SUBBUF_SIZE (262144)
-#define DEFAULT_N_SUBBUFS (4)
-static unsigned subbuf_size = DEFAULT_SUBBUF_SIZE;
-static unsigned n_subbufs = DEFAULT_N_SUBBUFS;
-
extern char *optarg;
extern int optopt;
extern int optind;
int print_only = 0;
int quiet = 0;
-int streaming = 1;
+int transport_mode = 0;
/* relayfs base file name */
static char stpd_filebase[1024];
static void usage(char *prog)
{
- fprintf(stderr, "%s [-p] [-q] [-b subbuf_size -n n_subbufs] kmod-name\n", prog);
+ fprintf(stderr, "%s [-p] [-q] kmod-name\n", prog);
fprintf(stderr, "-p Print only. Don't log to files.\n");
fprintf(stderr, "-q Quiet. Don't display trace to stdout.\n");
- fprintf(stderr, "-r Use relayfs for buffering i.e. non-streaming mode.\n");
- fprintf(stderr, "-b subbuf_size (default is %d)\n", DEFAULT_SUBBUF_SIZE);
- fprintf(stderr, "-n subbufs (default is %d)\n", DEFAULT_N_SUBBUFS);
exit(1);
}
int main(int argc, char **argv)
{
int c;
- unsigned opt_subbuf_size = 0;
- unsigned opt_n_subbufs = 0;
char *modname = NULL;
- while ((c = getopt(argc, argv, "b:n:pqr")) != EOF)
+ while ((c = getopt(argc, argv, "pq")) != EOF)
{
switch (c) {
- case 'b':
- opt_subbuf_size = (unsigned)atoi(optarg);
- if (!opt_subbuf_size)
- usage(argv[0]);
- break;
- case 'n':
- opt_n_subbufs = (unsigned)atoi(optarg);
- if (!opt_n_subbufs)
- usage(argv[0]);
- break;
case 'p':
print_only = 1;
break;
case 'q':
quiet = 1;
break;
- case 'r':
- streaming = 0;
- break;
default:
usage(argv[0]);
}
@@ -101,27 +75,13 @@ int main(int argc, char **argv)
fprintf (stderr, "Cannot do \"-p\" and \"-q\" both.\n");
usage(argv[0]);
}
-
- if ((opt_n_subbufs && !opt_subbuf_size) ||
- (!opt_n_subbufs && opt_subbuf_size))
- usage(argv[0]);
-
- if (opt_n_subbufs && opt_n_subbufs) {
- subbuf_size = opt_subbuf_size;
- n_subbufs = opt_n_subbufs;
- }
sprintf(stpd_filebase, "/mnt/relay/%d/cpu", getpid());
- if (init_stp(modname, stpd_filebase, stpd_outfilebase,
- subbuf_size, n_subbufs, 1)) {
+ if (init_stp(modname, stpd_filebase, 1)) {
fprintf(stderr, "Couldn't initialize stpd. Exiting.\n");
exit(1);
}
- if (!streaming)
- printf("Creating channel with %u sub-buffers of size %u.\n",
- n_subbufs, subbuf_size);
-
if (quiet)
printf("Logging... Press Control-C to stop.\n");
else
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 8f9cccfe..72a6e7ae 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,17 @@
+2005-06-20 Tom Zanussi <zanussi@us.ibm.com>
+
+ * control.h: Added STP_TRANSPORT_MODE command.
+
+ * transport.c: Lots of changes, most importantly
+ added transport mode command, which also sends buffer
+ sizes to daemon, added limit to number of attempts to
+ sending STP_EXIT (in case there is no daemon), moved
+ exit helper call.
+
+ * transport.h: Added transport type enum and transport
+ info struct for communication with userspace, changed and
+ moved a couple functions to transport.c.
+
2005-05-17 Martin Hunt <hunt@redhat.com>
* transport.c (_stp_transport_close): Call stp_exit_helper()
diff --git a/runtime/transport/control.h b/runtime/transport/control.h
index a614ecb7..f4e326da 100644
--- a/runtime/transport/control.h
+++ b/runtime/transport/control.h
@@ -22,6 +22,7 @@ enum
STP_BUF_INFO = 1,
STP_SUBBUFS_CONSUMED,
STP_REALTIME_DATA,
+ STP_TRANSPORT_MODE,
STP_EXIT,
};
diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c
index 8ce97bff..5645fe3b 100644
--- a/runtime/transport/transport.c
+++ b/runtime/transport/transport.c
@@ -38,6 +38,17 @@ struct stp_transport *t;
static void probe_exit(void);
/**
+ * _stp_streaming - boolean, are we using 'streaming' output?
+ */
+static inline int _stp_streaming(void)
+{
+ if (t->transport_mode == STP_TRANSPORT_NETLINK)
+ return 1;
+
+ return 0;
+}
+
+/**
* _stp_handle_buf_info - handle relayfs buffer info command
*/
static void _stp_handle_buf_info(int pid, struct buf_info *in)
@@ -61,16 +72,47 @@ static void _stp_handle_subbufs_consumed(int pid, struct consumed_info *info)
relay_subbufs_consumed(t->chan, info->cpu, info->consumed);
}
+/**
+ * _stp_handle_subbufs_consumed - handle relayfs subbufs consumed command
+ */
+static void _stp_handle_transport(int pid)
+{
+ struct transport_info out;
+ BUG_ON(!(t));
+
+ out.transport_mode = t->transport_mode;
+ if (t->transport_mode == STP_TRANSPORT_RELAYFS) {
+ out.subbuf_size = subbuf_size;
+ out.n_subbufs = n_subbufs;
+ }
+
+ _stp_ctrl_send(STP_TRANSPORT_MODE, &out, sizeof(out), pid);
+}
+
int _stp_exit_called = 0;
static int global_pid;
static void stp_exit_helper (void *data);
static DECLARE_WORK(stp_exit, stp_exit_helper, &global_pid);
+/**
+ * _stp_transport_flush - flush the transport, if applicable
+ */
+static inline void _stp_transport_flush(void)
+{
+ extern struct stp_transport *t;
+
+ if (t->transport_mode == STP_TRANSPORT_RELAYFS) {
+ BUG_ON(!t->chan);
+ relay_flush(t->chan);
+ ssleep(1); /* FIXME: time for data to be flushed */
+ }
+}
+
extern atomic_t _stp_transport_failures;
static void stp_exit_helper (void *data)
{
- int err, pid = *(int *)data;
+ int err, trylimit = 50, pid = *(int *)data;
if (_stp_exit_called == 0) {
_stp_exit_called = 1;
@@ -78,11 +120,12 @@ static void stp_exit_helper (void *data)
_stp_transport_flush();
}
- //printk("stp_handle_exit: sending STP_EXIT. pid=%d\n",(int)pid);
while ((err =_stp_ctrl_send(STP_EXIT, __this_module.name,
strlen(__this_module.name) + 1, pid)) < 0) {
//printk("stp_handle_exit: sent STP_EXIT. err=%d\n", err);
msleep (5);
+ if (!trylimit--) /* limit e.g. if user died */
+ break;
}
}
@@ -106,6 +149,9 @@ static int _stp_cmd_handler(int pid, int cmd, void *data)
case STP_SUBBUFS_CONSUMED:
_stp_handle_subbufs_consumed(pid, data);
break;
+ case STP_TRANSPORT_MODE:
+ _stp_handle_transport(pid);
+ break;
case STP_EXIT:
schedule_work (&stp_exit);
break;
@@ -128,11 +174,13 @@ void _stp_transport_close()
if (!t)
return;
+ stp_exit_helper (&t->pid);
+
_stp_ctrl_unregister(t->pid);
if (!_stp_streaming())
_stp_relayfs_close(t->chan, t->dir);
- stp_exit_helper (&t->pid);
+// stp_exit_helper (&t->pid);
kfree(t);
}
@@ -149,7 +197,10 @@ void _stp_transport_close()
* relayfs channel for it. This must be called before any I/O is
* done, probably at the start of module initialization.
*/
-int _stp_transport_open(unsigned n_subbufs, unsigned subbuf_size, int pid)
+int _stp_transport_open(int transport_mode,
+ unsigned n_subbufs,
+ unsigned subbuf_size,
+ int pid)
{
BUG_ON(!(n_subbufs && subbuf_size));
@@ -161,6 +212,8 @@ int _stp_transport_open(unsigned n_subbufs, unsigned subbuf_size, int pid)
global_pid = pid;
_stp_ctrl_register(t->pid, _stp_cmd_handler);
+ t->transport_mode = transport_mode;
+
if (_stp_streaming())
return 0;
@@ -185,5 +238,6 @@ int _stp_transport_send (int pid, void *data, int len)
}
return err;
}
+
/** @} */
#endif /* _TRANSPORT_C_ */
diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h
index a20ba8d8..9e98c894 100644
--- a/runtime/transport/transport.h
+++ b/runtime/transport/transport.h
@@ -9,11 +9,19 @@
#include "netlink.h"
#include "relayfs.h"
+/* SystemTap transport values */
+enum
+{
+ STP_TRANSPORT_NETLINK = 1,
+ STP_TRANSPORT_RELAYFS
+};
+
/* transport data structure */
struct stp_transport
{
struct rchan *chan;
struct dentry *dir;
+ int transport_mode;
int pid;
};
@@ -31,6 +39,12 @@ struct consumed_info
unsigned consumed;
};
+struct transport_info
+{
+ int transport_mode;
+ unsigned subbuf_size;
+ unsigned n_subbufs;
+};
/**
* _stp_transport_write - write data to the transport
@@ -44,30 +58,9 @@ struct consumed_info
#define _stp_transport_write(t, data, len) relay_write(t->chan, data, len)
#endif
-/**
- * _stp_streaming - boolean, are we using 'streaming' output?
- */
-#ifdef STP_NETLINK_ONLY
-#define _stp_streaming() (1)
-#else
-#define _stp_streaming() (0)
-#endif
-
-/**
- * _stp_transport_flush - flush the transport, if applicable
- */
-static inline void _stp_transport_flush(void)
-{
-#ifndef STP_NETLINK_ONLY
- extern struct stp_transport *t;
-
- BUG_ON(!t->chan);
- relay_flush(t->chan);
- ssleep(1); /* FIXME: time for data to be flushed */
-#endif
-}
-
-extern int _stp_transport_open(unsigned n_subbufs, unsigned subbuf_size,
+extern int _stp_transport_open(int transport_mode,
+ unsigned n_subbufs,
+ unsigned subbuf_size,
int pid);
extern void _stp_transport_close(void);
extern int _stp_transport_send (int pid, void *data, int len);