summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2010-04-03 16:11:07 +0200
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2010-04-03 16:11:07 +0200
commit7ba0df8974d8a7bba3949f38134eeb14de36ba0a (patch)
tree2d98dd73621df0c3e7e67d80015fc02f91b4c6b5
parent3396568982553a6547b4dca79d1258504c45ac41 (diff)
downloadtsnif-7ba0df8974d8a7bba3949f38134eeb14de36ba0a.tar.gz
tsnif-7ba0df8974d8a7bba3949f38134eeb14de36ba0a.tar.xz
tsnif-7ba0df8974d8a7bba3949f38134eeb14de36ba0a.zip
adding time for replay, few other fixies
-rw-r--r--include/linux/tsnif.h2
-rw-r--r--src/Makefile8
-rw-r--r--src/fsm.c6
-rw-r--r--src/intf.h2
-rw-r--r--src/misc.c19
-rw-r--r--src/misc.h6
-rw-r--r--src/storage-mmap.c30
-rw-r--r--src/storage-mmap.h4
-rw-r--r--src/storage.h3
-rw-r--r--src/trans-libnl.c16
-rw-r--r--src/trans.h4
-rw-r--r--src/tsnif-replay.c185
-rw-r--r--src/tsnif.c26
13 files changed, 263 insertions, 48 deletions
diff --git a/include/linux/tsnif.h b/include/linux/tsnif.h
index 86e49fd..c38073f 100644
--- a/include/linux/tsnif.h
+++ b/include/linux/tsnif.h
@@ -32,6 +32,8 @@ static struct nla_policy var[TSNIF_ATTR_MAX + 1] = { \
[TSNIF_ATTR_GROUP] = { .type = NLA_U32 }, \
[TSNIF_ATTR_FLAGS] = { .type = NLA_U32 }, \
[TSNIF_ATTR_DATA] = { .type = NLA_UNSPEC}, \
+ [TSNIF_ATTR_TIME] = { .type = NLA_UNSPEC}, \
+ [TSNIF_ATTR_WS] = { .type = NLA_UNSPEC}, \
};
enum {
diff --git a/src/Makefile b/src/Makefile
index db1703d..57b564c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,6 +7,9 @@ INTF_OBJS= \
STORAGE_OBJS= \
src/storage-mmap.o
+MISC_OBJS= \
+ src/misc.o
+
INTF_LIB=-lnl
@@ -15,14 +18,14 @@ TSNIF=tsnif
TSNIF_OBJS= \
src/tsnif.o
-$(TSNIF): $(TSNIF_OBJS) $(INTF_OBJS) $(STORAGE_OBJS)
+$(TSNIF): $(TSNIF_OBJS) $(INTF_OBJS) $(STORAGE_OBJS) $(MISC_OBJS)
$(QUIET_LD)$(CC) -o $@ $^ $(INTF_LIB)
TSNIF_REPLAY=tsnif-replay
TSNIF_REPLAY_OBJS= \
src/tsnif-replay.o
-$(TSNIF_REPLAY): $(TSNIF_REPLAY_OBJS) $(STORAGE_OBJS)
+$(TSNIF_REPLAY): $(TSNIF_REPLAY_OBJS) $(STORAGE_OBJS) $(MISC_OBJS)
$(QUIET_LD)$(CC) -o $@ $^
@@ -52,6 +55,7 @@ $(TEST): $(TEST_OBJS)
OBJS= \
$(INTF_OBJS) \
$(STORAGE_OBJS) \
+ $(MISC_OBJS) \
$(TSNIF_OBJS) \
$(TSNIF_REPLAY_OBJS) \
$(TSNIFD_OBJS) \
diff --git a/src/fsm.c b/src/fsm.c
index c8eebaf..9301918 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -47,9 +47,11 @@ static int process_data(struct tsnif_handle *h,
if (!h->ops || !h->ops->cb_data)
return -1;
- data.ptr = msg->data.ptr;
- data.len = msg->data.len;
+ data.ptr = msg->data.ptr;
+ data.len = msg->data.len;
data.flags = msg->data.flags;
+ data.time = msg->data.time;
+ data.ws = msg->data.ws;
return h->ops->cb_data(term, &data);
}
diff --git a/src/intf.h b/src/intf.h
index 6cabfde..4404b16 100644
--- a/src/intf.h
+++ b/src/intf.h
@@ -35,6 +35,8 @@ struct tsnif_data {
void *ptr;
int len;
uint flags;
+ struct timespec time;
+ struct winsize ws;
};
typedef int(*cb_data_t)(struct tsnif_term *term, struct tsnif_data *data);
diff --git a/src/misc.c b/src/misc.c
new file mode 100644
index 0000000..91d1266
--- /dev/null
+++ b/src/misc.c
@@ -0,0 +1,19 @@
+
+#include <termios.h>
+#include <unistd.h>
+
+int set_term(int set_init)
+{
+ struct termios new_settings;
+ static struct termios init_settings;
+
+ if (set_init)
+ return tcsetattr(0, TCSANOW, &init_settings);
+
+ tcgetattr(0, &init_settings);
+ new_settings = init_settings;
+ new_settings.c_lflag &= ~ICANON;
+ new_settings.c_lflag &= ~ECHO;
+
+ return tcsetattr(0, TCSANOW, &new_settings);
+}
diff --git a/src/misc.h b/src/misc.h
new file mode 100644
index 0000000..a0b6012
--- /dev/null
+++ b/src/misc.h
@@ -0,0 +1,6 @@
+#ifndef MISC_H
+#define MISC_H
+
+int set_term(int set_init);
+
+#endif /* !MISC_H */
diff --git a/src/storage-mmap.c b/src/storage-mmap.c
index f5e73ab..6fa4565 100644
--- a/src/storage-mmap.c
+++ b/src/storage-mmap.c
@@ -36,9 +36,13 @@ static int write_header(int fd, struct tsnif_storage_opts *opts)
static int map_header(struct tsnif_storage_handle *h)
{
void *ptr;
+ int flags = PROT_READ;
+
+ if (h->opts->flags & TSNIF_STORAGE_OPT_WRITE)
+ flags = PROT_WRITE;
ptr = mmap(NULL, sysconf(_SC_PAGESIZE),
- PROT_WRITE | PROT_READ,
+ flags,
MAP_SHARED, h->fd, 0);
if (MAP_FAILED == ptr)
return -1;
@@ -51,7 +55,7 @@ int tsnif_storage_init(struct tsnif_storage_handle *h,
struct tsnif_storage_opts *opts, char *name)
{
int fd, create, err;
- int flags = O_RDWR;
+ int flags = O_RDONLY;
if (!opts)
return -1;
@@ -65,9 +69,9 @@ int tsnif_storage_init(struct tsnif_storage_handle *h,
create = (opts->flags & TSNIF_STORAGE_OPT_WRITE);
if (create)
- flags |= O_CREAT | O_TRUNC;
+ flags |= O_CREAT | O_TRUNC | O_RDWR;
- fd = open(name, flags, S_IRUSR | S_IWUSR);
+ fd = open(name, flags);
if (fd < 0) {
TSNIF_DEBUG("open failed for '%s': %s\n",
name, strerror(errno));
@@ -165,7 +169,8 @@ static int map_chunk(struct tsnif_storage_handle *h,
{
void *ptr;
off_t offset = 0;
- int err;
+ int err, flags = PROT_READ;
+
TSNIF_DEBUG("what %d\n", what);
@@ -231,10 +236,12 @@ static int map_chunk(struct tsnif_storage_handle *h,
err = file_trunc(h, offset + h->opts->chunk_size);
if (err)
return err;
+
+ flags = PROT_WRITE;
}
ptr = mmap(NULL, h->opts->chunk_size,
- PROT_WRITE | PROT_READ,
+ flags,
MAP_SHARED, h->fd, offset);
if (MAP_FAILED == ptr)
return -1;
@@ -356,10 +363,13 @@ static int store_rec(struct tsnif_storage_handle *h,
TSNIF_DEBUG("chunk data %p\n", chunk->current_data);
TSNIF_DEBUG("chunk index %p\n", chunk->current_index);
+ TSNIF_DEBUG("time %ld\n", rec->time.tv_sec);
mrec = chunk->current_data;
- mrec->len = rec->len;
+ mrec->len = rec->len;
mrec->flags = rec->flags;
+ mrec->time = rec->time;
+ mrec->ws = rec->ws;
memcpy(mrec->data, rec->ptr, rec->len);
#define RECLEN (sizeof(struct tsnif_storage_rec_mmap) + rec->len)
@@ -414,9 +424,11 @@ static int read_rec(struct tsnif_storage_handle *h,
offset = *(chunk->current_index - chunk->read_index);
mrec = (void*) header + offset;
- rec->ptr = mrec->data;
- rec->len = mrec->len;
+ rec->ptr = mrec->data;
+ rec->len = mrec->len;
rec->flags = mrec->flags;
+ rec->time = mrec->time;
+ rec->ws = mrec->ws;
return 0;
}
diff --git a/src/storage-mmap.h b/src/storage-mmap.h
index db45cb0..8b00934 100644
--- a/src/storage-mmap.h
+++ b/src/storage-mmap.h
@@ -2,6 +2,8 @@
#ifndef STORAGE_MMAP_H
#define STORAGE_MMAP_H
+#include <sys/ioctl.h>
+
struct tsnif_storage_header_mmap {
struct tsnif_storage_header common;
/* max size of the file */
@@ -15,6 +17,8 @@ struct tsnif_storage_header_mmap {
struct tsnif_storage_rec_mmap {
uint32_t len;
uint32_t flags;
+ struct timespec time;
+ struct winsize ws;
unsigned char data[];
};
diff --git a/src/storage.h b/src/storage.h
index 54df8fa..2099059 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <stdint.h>
+#include <sys/ioctl.h>
struct tsnif_storage_handle;
struct tsnif_storage_opts;
@@ -33,6 +34,8 @@ struct tsnif_storage_rec {
void *ptr;
int len;
uint flags;
+ struct timespec time;
+ struct winsize ws;
};
int tsnif_storage_init(struct tsnif_storage_handle *h,
diff --git a/src/trans-libnl.c b/src/trans-libnl.c
index d4b814b..c6e3b90 100644
--- a/src/trans-libnl.c
+++ b/src/trans-libnl.c
@@ -45,6 +45,22 @@ static int process_cb(struct trans_handle *h, struct trans_msg *m,
m->data.len = nla_len(attrs[TSNIF_ATTR_DATA]);
}
+ if (attrs[TSNIF_ATTR_TIME]) {
+ struct timespec *time;
+
+ time = (struct timespec*) nla_data(attrs[TSNIF_ATTR_TIME]);
+ m->data.time = *(time);
+ TSNIF_DEBUG("time1 %ld %ld\n", time->tv_sec, time->tv_nsec);
+ TSNIF_DEBUG("time2 %ld\n", m->data.time.tv_sec);
+ }
+
+ if (attrs[TSNIF_ATTR_WS]) {
+ struct winsize *ws;
+
+ ws = (struct winsize*) nla_data(attrs[TSNIF_ATTR_WS]);
+ m->data.ws = *(ws);
+ }
+
if (attrs[TSNIF_ATTR_FLAGS])
m->data.flags = nla_get_u32(attrs[TSNIF_ATTR_FLAGS]);
diff --git a/src/trans.h b/src/trans.h
index 95b4457..e7c38bc 100644
--- a/src/trans.h
+++ b/src/trans.h
@@ -2,6 +2,8 @@
#ifndef TRANS_H
#define TRANS_H
+#include <sys/ioctl.h>
+
struct trans_handle;
struct trans_msg;
@@ -26,6 +28,8 @@ struct trans_msg {
void *ptr;
int len;
uint flags;
+ struct timespec time;
+ struct winsize ws;
} data;
/* notify message */
int action;
diff --git a/src/tsnif-replay.c b/src/tsnif-replay.c
index 0f1455f..a0ec61e 100644
--- a/src/tsnif-replay.c
+++ b/src/tsnif-replay.c
@@ -1,13 +1,20 @@
#include <stdio.h>
+#include <stdio_ext.h>
#include <unistd.h>
#include <getopt.h>
+#include <sys/select.h>
+#include <setjmp.h>
+#include <string.h>
+#include <signal.h>
#include "storage.h"
+#include "misc.h"
+#include "intf.h"
-
+static int killed;
static char *filename;
-struct tsnif_storage_handle storage_handle;
+static struct tsnif_storage_handle storage_handle;
static struct tsnif_storage_opts storage_opts = {
.flags = TSNIF_STORAGE_OPT_READ,
};
@@ -20,6 +27,12 @@ static void usage()
_exit(-1);
}
+static void sig_handler(int sig)
+{
+ printf("killed\n");
+ killed = 1;
+}
+
static int get_args(int argc, char **argv)
{
while (1) {
@@ -59,9 +72,153 @@ static int get_args(int argc, char **argv)
return 0;
}
+static struct timeval get_timeout(struct timespec *ts_new,
+ struct timespec *ts_old)
+{
+ static struct timeval tv;
+
+ tv.tv_sec = ts_new->tv_sec - ts_old->tv_sec;
+
+ TSNIF_DEBUG("time new %ld:%ld\n", ts_new->tv_sec, ts_new->tv_nsec);
+ TSNIF_DEBUG("time old %ld:%ld\n", ts_old->tv_sec, ts_old->tv_nsec);
+
+ if (ts_new->tv_nsec >= ts_old->tv_nsec)
+ tv.tv_usec = (ts_new->tv_nsec - ts_old->tv_nsec) / 1000;
+ else {
+ tv.tv_usec = (ts_new->tv_nsec + (1000000000 - ts_old->tv_nsec)) / 1000;
+ if (tv.tv_sec)
+ tv.tv_sec--;
+ }
+
+ TSNIF_DEBUG("time fin %ld %ld\n", tv.tv_sec, tv.tv_usec);
+ return tv;
+}
+
+enum {
+ ACTION_NEXT,
+ ACTION_PREV,
+ ACTION_FIRST,
+ ACTION_TIMEOUT,
+ ACTION_STOP,
+ ACTION_RUN,
+ ACTION_QUIT,
+ ACTION_SLAVE,
+ ACTION_MASTER,
+};
+
+static int display_slave = 1;
+static int display_master= 0;
+
+static int output(struct tsnif_storage_rec *rec)
+{
+ fwrite(rec->ptr, rec->len, 1, stdout);
+ fflush(NULL);
+ return 0;
+}
+
+static int get_action(struct timeval *tv)
+{
+ int c, ret;
+ jmp_buf env;
+ fd_set rfds;
+
+ setjmp(env);
+
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+
+ ret = select(1, &rfds, NULL, NULL, tv);
+
+ /* select failed - finish replay */
+ if (-1 == ret)
+ return ACTION_QUIT;
+
+ /* timeout - continue with next record */
+ if (!ret)
+ return ACTION_NEXT;
+
+ /* WTF??? */
+ if (!FD_ISSET(0, &rfds))
+ return ACTION_QUIT;
+
+ /* we got user input */
+ c = getchar();
+
+ if (c == '\033') {
+ __fpurge(stdin);
+ longjmp(env, 1);
+ }
+
+ switch(c) {
+ case 'p' : return ACTION_PREV;
+ case 'n' : return ACTION_NEXT;
+ case 'f' : return ACTION_FIRST;
+ case 'q' : return ACTION_QUIT;
+ case 't' : return ACTION_TIMEOUT;
+ case 's' : return ACTION_SLAVE;
+ case 'm' : return ACTION_MASTER;
+ }
+
+ longjmp(env, 1);
+ return -1;
+}
+
+static int process(void)
+{
+ struct tsnif_storage_rec rec;
+ int err, action;
+
+ err = tsnif_storage_read(&storage_handle,
+ TSNIF_STORAGE_READ_NEXT, &rec);
+ if (err < 0)
+ return err;
+
+ do {
+ struct timespec ts_prev;
+ struct timeval tv;
+
+ memset(&tv, 0x0, sizeof(tv));
+
+ if (err != TSNIF_STORAGE_READ_EOF) {
+ output(&rec);
+
+ ts_prev = rec.time;
+
+ err = tsnif_storage_read(&storage_handle,
+ TSNIF_STORAGE_READ_NEXT, &rec);
+ if (err < 0)
+ break;
+
+ tv = get_timeout(&rec.time, &ts_prev);
+ }
+
+ action = get_action(&tv);
+ switch(action) {
+ case ACTION_PREV:
+ err = tsnif_storage_read(&storage_handle,
+ TSNIF_STORAGE_READ_PREV, &rec);
+ if (err < 0)
+ return err;
+ break;
+
+ case ACTION_SLAVE:
+ display_slave = !display_slave;
+ break;
+
+ case ACTION_MASTER:
+ display_master = !display_master;
+ break;
+ }
+
+ } while(action != ACTION_QUIT);
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
- int err;
+ int err, ret;
+ jmp_buf env;
if (get_args(argc, argv))
usage();
@@ -70,20 +227,18 @@ int main(int argc, char **argv)
if (err)
return -1;
- do {
- struct tsnif_storage_rec rec;
-
- err = tsnif_storage_read(&storage_handle,
- TSNIF_STORAGE_READ_NEXT, &rec);
+ if ((ret = setjmp(env))) {
+ set_term(1);
+ tsnif_storage_close(&storage_handle);
- if (err)
- break;
+ printf("done err = %d\n", err);
+ return err;
+ }
- fwrite(rec.ptr, rec.len, 1, stdout);
- fflush(NULL);
+ set_term(0);
+ signal(SIGINT, sig_handler);
- } while(1);
+ err = process();
- tsnif_storage_close(&storage_handle);
- return 0;
+ longjmp(env, 1);
}
diff --git a/src/tsnif.c b/src/tsnif.c
index 57731f2..aca8e56 100644
--- a/src/tsnif.c
+++ b/src/tsnif.c
@@ -11,7 +11,7 @@
#include "autoconf.h"
#include "intf.h"
#include "storage.h"
-
+#include "misc.h"
static struct tsnif_handle handle;
static struct tsnif_term term;
@@ -46,9 +46,11 @@ static int display_pty(int flags)
static int store_data(struct tsnif_data *data)
{
struct tsnif_storage_rec rec = {
- .ptr = data->ptr,
- .len = data->len,
- .flags = data->flags,
+ .ptr = data->ptr,
+ .len = data->len,
+ .flags = data->flags,
+ .time = data->time,
+ .ws = data->ws,
};
return tsnif_storage_write(&storage_handle, &rec);
@@ -105,22 +107,6 @@ static void sig_handler(int sig)
killed = 1;
}
-int set_term(int set_init)
-{
- struct termios new_settings;
- static struct termios init_settings;
-
- if (set_init)
- return tcsetattr(0, TCSANOW, &init_settings);
-
- tcgetattr(0, &init_settings);
- new_settings = init_settings;
- new_settings.c_lflag &= ~ICANON;
- new_settings.c_lflag &= ~ECHO;
-
- return tcsetattr(0, TCSANOW, &new_settings);
-}
-
static int get_type(char *optarg)
{
int i;