Angus,

Didn't expect anyone to act this fast but..  Looks like we were up to
the same task...  I have an immediate need for it in the ckpt service
which is why I started on it.  

Attached is my version which is as of yet incomplete.  The general
concept is to allow very high performance event tracing with minimal
formatting overhead (formatting is done in a separate program after a
crash or to debug current program state).  I'd also like to get rid of
the critical section code in the current logsys as much as possible.

It uses a chunked circular word (32 bit) buffer of arbitrary length to
store data records.  It allows a variable length list of variable length
arguments.  It records the subsystem name, filename, function name, line
number, log identification used for replay output mapping, and record
number as well as the arguments and their lengths.  The implementation
only ever makes one copy of data at any time and copies/stores most
things in 1 word operations.  memcpy sucks on x86 for small memory
segments, which is why there is a C implementation of memcpy included.

My plan had been to change the actual log_printf logging code to create
records using log_rec and for the writing of the log messages to
files/syslog to come out of this flt data.

Anyway have a look.

The usage is: (arg1 = record identifier, arg2=argument, arg3=length,
terminated with a NULL).
 
log_rec (LOGREC_ID_CHECKPOINT_CREATE, "record1", 8, "record22", 9,
"record333", 10, "record444", 11, NULL);

test/locsysrec records a bunch of records
test/logsysbench compares throughput of function to sprintf
tools/fplay replays the data in the flight recorder data file fdata

after running apps in test cp fdata to tools and run fplay.  During a
segfault, the core file could be used to extract this flight data via
any symbol dumper such as gdb.

log_printf would turn into something like:

sprintf (buf, ##args);
log_rec (LOGREC_ID_PRINTF, buf, strlen (buf), NULL);
do_some_kind_of_signal_to_logging_thread()

The current buffer size is hardcoded to 7321 (4 byte words) but this
could of course be parametrized.  If you change it in logsys.h, change
it in fplay.c as well.

timestamping is expensive cpu wise reducing throughput to 8-10%.

Regards
-steve

On Thu, 2008-10-09 at 12:00 +1300, angus salkeld wrote:
> Hi
> 
> Here is a REALLY simple blackbox.
> 
> Qu: Do we need to store the timestamp?  I don't have one in there
> yet as I didn't want to use up memory more than I had to.
> 
> To extract the blackbox load your core file in gdb and:
> 
> set print array on
> print blackbox
> 
> Simple.
> 
> The next thing I want to do is separately keep info on the last X (100) 
> messages sent or received.
> -Info like where it came from, where it's going and it's size.
> From this we could also keep counters like:
> -number of TX/RX messages per service
> -number of resent/dropped messages, etc...
> 
> Any other ideas?
> 
> Regards
> Angus
> 
> diff --git a/exec/logsys.c b/exec/logsys.c
> index c919d6f..14e0cf8 100644
> --- a/exec/logsys.c
> +++ b/exec/logsys.c
> @@ -86,12 +86,21 @@ struct logsys_logger logsys_loggers[MAX_LOGGERS];
>  
>  int logsys_single_id = 0;
>  
> +#define MAX_LOG_LENGTH 128
> +
> +#ifndef MAX_BLACKBOX_LOGS
> +#define MAX_BLACKBOX_LOGS 1024
> +#endif /* MAX_BLACKBOX_LOG */
> +
> +static int blackbox_pos = 0;
> +static char blackbox[MAX_BLACKBOX_LOGS][MAX_LOG_LENGTH];
> +
>  
>  struct log_entry {
>       char *file;
>       int line;
>       int priority;
> -     char str[128];
> +     char str[MAX_LOG_LENGTH];
>       struct log_entry *next;
>  };
>  
> @@ -402,6 +411,46 @@ drop_log_msg:
>       }
>  }
>  
> +/*
> + * save the log to the blackbox
> + */
> +static void _blackbox_printf (
> +     enum logsys_config_mutex_state config_mutex_state,
> +     char *file,
> +     int line,
> +     char *format,
> +     va_list ap)
> +{
> +     char *p = NULL;
> +     char newfmt[MAX_LOG_LENGTH];
> +
> +     if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) {
> +             pthread_mutex_lock (&logsys_config_mutex);
> +     }
> +     pthread_mutex_lock (&logsys_new_log_mutex);
> +
> +     p = strrchr(file, '/');
> +     if (p) 
> +             file = ++p;
> +
> +     snprintf (newfmt, MAX_LOG_LENGTH, "[%s:%04u] %s", file, line, format);
> +     vsnprintf (&blackbox[blackbox_pos], MAX_LOG_LENGTH, newfmt, ap);
> +
> +     if (blackbox_pos >= (MAX_BLACKBOX_LOGS - 1)) {
> +             blackbox_pos = 0;
> +     } else {
> +             blackbox_pos++;
> +     }
> +     sprintf(&blackbox[blackbox_pos], "*** END OF BLACK BOX ***");
> +
> +     pthread_mutex_unlock (&logsys_new_log_mutex);
> +     if (config_mutex_state == LOGSYS_CONFIG_MUTEX_UNLOCKED) {
> +             pthread_mutex_unlock (&logsys_config_mutex);
> +     }
> +     return;
> +
> +}
> +
>  unsigned int _logsys_subsys_create (
>       const char *subsys,
>       unsigned int priority)
> @@ -532,6 +581,10 @@ void logsys_log_printf (
>  
>       assert (id < MAX_LOGGERS);
>  
> +     va_start (ap, format);
> +     _blackbox_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, format, ap);
> +     va_end(ap);
> +     
>       if (LOG_LEVEL(priority) > logsys_loggers[id].priority) {
>               return;
>       }
> @@ -555,6 +608,10 @@ static void logsys_log_printf_locked (
>  
>       assert (id < MAX_LOGGERS);
>  
> +     va_start (ap, format);
> +     _blackbox_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line, format, ap);
> +     va_end(ap);
> +
>       if (LOG_LEVEL(priority) > logsys_loggers[id].priority) {
>               return;
>       }
> @@ -577,6 +634,7 @@ void _logsys_log_printf2 (
>       assert (id < MAX_LOGGERS);
>  
>       va_start (ap, format);
> +     _blackbox_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, format, ap);
>       _log_printf (LOGSYS_CONFIG_MUTEX_UNLOCKED, file, line, priority, id,
>               format, ap);
>       va_end(ap);
> @@ -584,13 +642,16 @@ void _logsys_log_printf2 (
>  
>  void _logsys_trace (char *file, int line, int tag, int id, char *format, ...)
>  {
> +     va_list ap;
>       assert (id < MAX_LOGGERS);
>  
>       pthread_mutex_lock (&logsys_config_mutex);
>  
> -     if (tag & logsys_loggers[id].tags) {
> -             va_list ap;
> +     va_start (ap, format);
> +     _blackbox_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line, format, ap);
> +     va_end(ap);
>  
> +     if (tag & logsys_loggers[id].tags) {
>               va_start (ap, format);
>               _log_printf (LOGSYS_CONFIG_MUTEX_LOCKED, file, line,
>                       LOG_LEVEL_DEBUG, id, format, ap);
> 
> _______________________________________________
> Openais mailing list
> Openais@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/openais
Index: test/Makefile
===================================================================
--- test/Makefile	(revision 1670)
+++ test/Makefile	(working copy)
@@ -44,13 +44,13 @@
 
 LIBRARIES= ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a ../lib/libconfdb.a
 LIBS = $(LIBRARIES) 
-BINARIES= testevs evsbench evsverify testcpg testcpg2 cpgbench testconfdb
+BINARIES= testevs evsbench evsverify testcpg testcpg2 cpgbench testconfdb logsysrec logsysbench
 
 override CFLAGS += -I../include
 override LDFLAGS += -L../lib
 
 EXTRA_CFLAGS = -I$(srcdir)include
-TEST_SRC = sa_error.c logsys_s1.c logsys_s2.c logsys_s.c logsys_t1.c logsys_t2.c
+TEST_SRC = sa_error.c logsys_s1.c logsys_s2.c logsys_s.c logsys_t1.c logsys_t2.c logsysrec.c logsysbench.c
 
 all: $(BINARIES)
 
@@ -90,6 +90,12 @@
 logsys_t2: logsys_t2.o ../exec/liblogsys.a
 	$(CC) -o logsys_t2 logsys_t2.o ../exec/liblogsys.a $(LDFLAGS)
 
+logsysrec: logsysrec.o ../exec/liblogsys.a
+	$(CC) -o logsysrec logsysrec.o ../exec/liblogsys.a $(LDFLAGS)
+
+logsysbench: logsysbench.o ../exec/liblogsys.a
+	$(CC) -o logsysbench logsysbench.o ../exec/liblogsys.a $(LDFLAGS)
+
 clean:
 	rm -f *.o $(LIBRARIES) $(BINARIES)
 
Index: include/corosync/engine/logsys.h
===================================================================
--- include/corosync/engine/logsys.h	(revision 1670)
+++ include/corosync/engine/logsys.h	(working copy)
@@ -102,6 +102,9 @@
 
 extern inline int logsys_mkpri (int priority, int id);
 
+extern int logsys_rec_init (
+	unsigned int size);
+
 extern void logsys_config_mode_set (
 	unsigned int mode);
 
@@ -151,6 +154,16 @@
 
 extern int _logsys_wthread_create (void);
 
+extern void _logsys_log_rec (
+	int subsys,
+	char *function_name,
+	char *file_name,
+	int file_line,
+	unsigned int rec_ident,
+	...);
+
+void logsys_log_rec_store (char *filename);
+
 extern void logsys_log_printf (char *file, int line, int priority,
 	char *format, ...) __attribute__((format(printf, 4, 5)));
 
@@ -168,6 +181,7 @@
 {									\
 	char *error_string;						\
 									\
+	logsys_rec_init (7321);					\
 	logsys_config_mode_set (mode);					\
 	logsys_config_file_set (&error_string, (file));			\
 	logsys_config_facility_set (name, (facility));			\
@@ -206,6 +220,11 @@
 			_logsys_subsys_create ((subsys), (priority));	\
 }
 
+#define log_rec(rec_ident, args...) do {				\
+	_logsys_log_rec (logsys_subsys_id, (char *) __FUNCTION__,	\
+		__FILE__,  __LINE__, rec_ident, ##args);		\
+} while(0)
+
 #define log_printf(lvl, format, args...) do {				\
 	if (logsys_single_id)						\
 		logsys_subsys_id = 0;					\
Index: exec/Makefile
===================================================================
--- exec/Makefile	(revision 1670)
+++ exec/Makefile	(working copy)
@@ -110,6 +110,7 @@
 
 libtotem_pg.a: $(TOTEM_OBJS)
 	$(AR) -rc libtotem_pg.a $(TOTEM_OBJS)
+	echo $(CFLAGS)
 
 liblogsys.a: $(LOGSYS_OBJS)
 	$(AR) -rc liblogsys.a $(LOGSYS_OBJS)
@@ -151,6 +152,9 @@
 coroparse.o: coroparse.c
 	$(CC) $(CFLAGS) -c -o $@ $<
 
+logsys.o: logsys.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
 # -fPIC rules required for lib totem
 coropoll.o: coropoll.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $<
Index: exec/logsys.c
===================================================================
--- exec/logsys.c	(revision 1670)
+++ exec/logsys.c	(working copy)
@@ -1,6 +1,12 @@
+int *flt_data;
+int flt_data_size;
+
+#define FDHEAD_INDEX	(flt_data_size)
+#define FDTAIL_INDEX 	(flt_data_size + 1)
+
 /*
  * Copyright (c) 2002-2004 MontaVista Software, Inc.
- * Copyright (c) 2006-2007 Red Hat, Inc.
+ * Copyright (c) 2006-2008 Red Hat, Inc.
  *
  * Author: Steven Dake ([EMAIL PROTECTED])
  * Author: Lon Hohberger ([EMAIL PROTECTED])
@@ -38,10 +44,13 @@
 #include <string.h>
 #include <stdarg.h>
 #include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <time.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <unistd.h>
 #if defined(COROSYNC_LINUX)
 #include <linux/un.h>
 #endif
@@ -507,7 +516,7 @@
 	logsys_flush();
 
 	atexit (logsys_atexit);
-	pthread_atfork(NULL, NULL, child_cleanup);
+//	pthread_atfork(NULL, NULL, child_cleanup);
 
 	if (logsys_mode & LOG_MODE_OUTPUT_SYSLOG_THREADED && logsys_name != NULL) {
 		openlog (logsys_name, LOG_CONS|LOG_PID, logsys_facility);
@@ -564,6 +573,240 @@
 	va_end(ap);
 }
 
+/*
+ * u32 RECORD SIZE
+ * u32 record ident
+ * u32 arg count
+ * u32 file line
+ * u32 filename length
+ * buffer terminated filename
+ * u32 arg1 length
+ * buffer arg1
+ */
+
+void logsys_log_rec_store (char *filename)
+{
+	int fd;
+	int size;
+
+	fd = open (filename, O_CREAT|O_RDWR, 0700);
+printf ("fd is %d\n", fd);
+	size = write (fd, flt_data, (flt_data_size + 2) * sizeof (unsigned int));
+printf ("size %d\n", size);
+}
+
+static inline void my_memcpy_32bit (int *dest, int *src, unsigned int words)
+{
+	unsigned int word_idx;
+	for (word_idx = 0; word_idx < words; word_idx++) {
+		dest[word_idx] = src[word_idx];
+	}
+}
+
+static inline void my_memcpy_8bit (char *dest, char *src, unsigned int bytes)
+{
+	unsigned int byte_idx;
+
+	for (byte_idx = 0; byte_idx < bytes; byte_idx++) {
+		dest[byte_idx] = src[byte_idx];
+	}
+}
+
+static int logsys_buffer_full = 0;
+
+/*
+ * Before any write operation, a reclaim on the buffer area must be executed
+ */
+static inline void records_reclaim (unsigned int idx, unsigned int words)
+{
+	int words_needed = 0;
+
+	if ((idx + words) >= flt_data_size) {
+		logsys_buffer_full = 1;
+	}
+	if (logsys_buffer_full == 0) {
+		return;
+	}
+
+	words_needed = words + 1;
+	if (flt_data[FDTAIL_INDEX] > flt_data[FDHEAD_INDEX]) {
+		if (idx + words >= flt_data[FDTAIL_INDEX]) {
+			do {
+				words_needed -= flt_data[flt_data[FDTAIL_INDEX]];
+				flt_data[FDTAIL_INDEX] = 
+					(flt_data[FDTAIL_INDEX] + 
+						flt_data[flt_data[FDTAIL_INDEX]]) % (flt_data_size);
+			} while (words_needed > 0);
+		}
+	} else {
+		if ((idx + words) >= (flt_data[FDTAIL_INDEX] + flt_data_size)) {
+			do {
+				words_needed -= flt_data[flt_data[FDTAIL_INDEX]];
+				flt_data[FDTAIL_INDEX] = 
+					(flt_data[FDTAIL_INDEX] + 
+						flt_data[flt_data[FDTAIL_INDEX]]) % (flt_data_size);
+			} while (words_needed > 0);
+		}
+	}
+}
+
+#define idx_word_step(idx)						\
+do {									\
+	if (idx > (flt_data_size - 1)) {				\
+		idx = 0;						\
+	}								\
+} while (0);
+
+#define idx_buffer_step(idx)						\
+do {									\
+	if (idx > (flt_data_size - 1)) {				\
+		idx = ((idx) % (flt_data_size));			\
+	}								\
+} while (0);
+
+unsigned int run_once = 0;
+unsigned int records_written = 1;
+
+void _logsys_log_rec (
+	int subsys,
+	char *function_name,
+	char *file_name,
+	int file_line,
+	unsigned int rec_ident,
+	...)
+{
+	va_list ap;
+	void *buf_args[64];
+	unsigned int buf_len[64];
+	unsigned int i;
+	unsigned int idx;
+	unsigned int arguments = 0;
+	unsigned int record_reclaim_size;
+	unsigned int index_start;
+	int words_written;
+
+	record_reclaim_size = 0;
+		
+	/*
+	 * Decode VA Args
+	 */
+	va_start (ap, rec_ident);
+	arguments = 3;
+	for (;;) {
+		assert (arguments < 64);
+		buf_args[arguments] = va_arg (ap, void *);
+		if (buf_args[arguments] == NULL) {
+			break;
+		}
+		buf_len[arguments] = va_arg (ap, int);
+		record_reclaim_size += ((buf_len[arguments] + 3) >> 2) + 1;
+		arguments++;
+	}
+	va_end (ap);
+
+	/*
+	 * Encode logsys subsystem identity, filename, and function
+	 */
+	buf_args[0] = logsys_loggers[subsys].subsys;
+	buf_len[0] = strlen (logsys_loggers[subsys].subsys) + 1;
+	buf_args[1] = file_name;
+	buf_len[1] = strlen (file_name) + 1;
+	buf_args[2] = function_name;
+	buf_len[2] = strlen (function_name) + 1;
+	for (i = 0; i < 3; i++) {
+		record_reclaim_size += ((buf_len[i] + 3) >> 2) + 1;
+	}
+
+	idx = flt_data[FDHEAD_INDEX];
+	index_start = idx;
+
+	/*
+	 * Reclaim data needed for record including 3 words for the header
+	 */
+	records_reclaim (idx, record_reclaim_size + 3);
+
+	/*
+	 * Write record size of zero and rest of header information
+	 */
+	flt_data[idx++] = 0;
+	idx_word_step(idx);
+
+	flt_data[idx++] = rec_ident;
+	idx_word_step(idx);
+
+	flt_data[idx++] = file_line;
+	idx_word_step(idx);
+
+	flt_data[idx++] = records_written;
+	idx_word_step(idx);
+	/*
+	 * Encode all of the arguments into the log message
+	 */
+	for (i = 0; i < arguments; i++) {
+		unsigned int bytes;
+		unsigned int full_words;
+		unsigned int total_words;
+
+		bytes = buf_len[i];
+		full_words = bytes >> 2;
+		total_words = (bytes + 3) >> 2;
+
+		flt_data[idx++] = total_words;
+		idx_word_step(idx);
+
+		/*
+		 * determine if this is a wrapped write or normal write
+		 */
+		if (idx + total_words < flt_data_size) {
+			/*
+			 * dont need to wrap buffer
+			 */
+			my_memcpy_32bit (&flt_data[idx], buf_args[i], full_words);
+			if (bytes % 4) {
+				my_memcpy_8bit ((char *)&flt_data[idx + full_words],
+					((char *)buf_args[i]) + (full_words << 2), bytes % 4);
+			}
+		} else {
+			/*
+			 * need to wrap buffer
+			 */
+			unsigned int first;
+			unsigned int second;
+
+			first = flt_data_size - idx;
+			if (first > full_words) {
+				first = full_words;
+			}
+			second = full_words - first;
+			my_memcpy_32bit (&flt_data[idx], (int *)buf_args[i], first);
+			my_memcpy_32bit (&flt_data[0],
+				(int *)(((unsigned char *)buf_args[i]) + (first << 2)),
+				second);
+			if (bytes % 4) {
+				my_memcpy_8bit ((char *)&flt_data[0 + second],
+					((char *)buf_args[i]) + (full_words << 2), bytes % 4);
+			}
+		}
+		idx += total_words;
+		idx_buffer_step (idx);
+	}
+	words_written = idx - index_start;
+	if (words_written < 0) {
+		words_written += flt_data_size;
+	}
+	/*
+	 * Commit the write of the record size now that the full record
+	 * is in the memory buffer
+	 */
+	flt_data[index_start] = words_written;
+
+	/*
+	 * Commit the new head index
+	 */
+	flt_data[FDHEAD_INDEX] = idx;
+	records_written++;
+}
+
 void _logsys_log_printf2 (
 	char *file,
 	int line,
@@ -636,10 +879,27 @@
 	worker_thread_group_wait (&log_thread_group);
 }
 
+int logsys_rec_init (unsigned int size)
+{
+	/*
+	 * First record starts at zero
+	 * Last record ends at zero
+	 */
+	flt_data = malloc ((size + 2) * sizeof (unsigned int));
+	assert (flt_data);
+	flt_data_size = size;
+	assert (flt_data);
+	flt_data[FDHEAD_INDEX] = 0;
+	flt_data[FDTAIL_INDEX] = 0;
+
+	return (0);
+}
+
 int logsys_init (char *name, int mode, int facility, int priority, char *file)
 {
 	char *errstr;
 
+
 	/* logsys_subsys_id will be 0 */
 	logsys_single_id = 1;
 
Index: tools/fplay.c
===================================================================
--- tools/fplay.c	(revision 0)
+++ tools/fplay.c	(revision 0)
@@ -0,0 +1,164 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+unsigned int flt_data_size = 7321;
+
+unsigned int *flt_data;
+#define FDHEAD_INDEX		(flt_data_size)
+#define FDTAIL_INDEX		(flt_data_size + 1)
+
+#ifdef COMPILE_OUT
+struct logsys_print_fn {
+	char *(*print_fn) (void *);
+	unsigned int arg_no;
+};
+
+char *string_print_fn (void *arg) 
+{
+	static char buf_ret[1024];
+
+	sprintf (buf_ret, "%s", arg);
+	return (buf_ret);
+}
+
+char *uint64t_print_fn (void *arg)
+{
+	static char buf_ret[64];
+
+	sprintf (buf_ret, "%lld", *(unsigned long long)arg);
+	return (buf_ret);
+}
+	
+struct logsys_printer {
+	unsigned int rec_ident;
+	char *format;
+	struct logsys_print_fn print_fn[32];
+	unsigned int print_fn_count;
+}
+	
+struct logsys_printer logsys_printers[32];
+
+int logsys_printer_index = 0;
+	
+
+void logsys_printer_fn_register (
+	unsigned int rec_ident,
+	unsigned int arg_no,
+	char *(*)print_fn)
+{
+	logsys_printers[0].print_fn[print_fn_count].arg_no = arg_no
+	logsys_printers[0].print_fn[print_fn_count].print_fn = print_fn;
+}
+
+void logsys_printer_format_register (
+	unsigned int rec_ident,
+	char *format)
+{
+	logsys_printers[logsys_printer_index].rec_ident = rec_ident;
+	logsys_printers[logsys_printer_index].format = format;
+	logsys_printer_index += 1;
+	print_fn_count = 0;
+}
+
+void logsys_ckpt_register (void)
+{
+	logsys_printer_format_register (LOGREC_ID_CHECKPOINT_CREATE,
+		"subsys %s filename %fn pos %fp record %a1 size %a2");
+	logsys_printer_fn_register (LOGREC_ID_CHECKPOINT_CREATE, 0, string_print_fn);
+	logsys_printer_fn_register (LOGREC_ID_CHECKPOINT_CREATE, 1, uint64t_print_fn);
+{
+#endif
+
+unsigned int records_printed = 1;
+
+unsigned int record[10000];
+
+/*
+ * Copy record, dealing with wrapping
+ */
+int logsys_rec_get (int rec_idx) {
+	unsigned int rec_size;
+	int firstcopy, secondcopy;
+
+	rec_size = flt_data[rec_idx];
+
+	firstcopy = rec_size;
+	secondcopy = 0;
+	if (firstcopy + rec_idx > flt_data_size) {
+		firstcopy = flt_data_size - rec_idx; 
+		secondcopy -= firstcopy - rec_size;
+	}
+	memcpy (&record[0], &flt_data[rec_idx], firstcopy<<2);
+	if (secondcopy) {
+		memcpy (&record[firstcopy], &flt_data[0], secondcopy<<2);
+	}
+	return ((rec_idx + rec_size) % flt_data_size);
+}
+
+void logsys_rec_print (void *record)
+{
+	unsigned int *buf_uint32t = (unsigned int *)record;
+	unsigned int rec_size;
+	unsigned int rec_ident;
+	unsigned int line;
+	unsigned int arg_size_idx;
+	unsigned int i;
+	unsigned int words_processed;
+	unsigned int rec_idx = 0;
+	unsigned int record_number;
+
+	rec_size = buf_uint32t[rec_idx];
+	rec_ident = buf_uint32t[rec_idx+1];
+	line = buf_uint32t[rec_idx+2];
+	record_number = buf_uint32t[rec_idx+3];
+
+	printf ("rec size %d rec ident %d line %d\n",
+		rec_size, rec_ident, line);
+	arg_size_idx = rec_idx + 4;
+	words_processed = 4;
+	for (i = 0; words_processed < rec_size; i++) {
+		printf ("argument [%d]=[%s] ", i,
+			(char *)&buf_uint32t[arg_size_idx + 1]);
+		words_processed += buf_uint32t[arg_size_idx] + 1;
+		arg_size_idx += buf_uint32t[arg_size_idx] + 1;
+		
+	}
+printf ("\n");
+}
+
+int main (void)
+{
+	unsigned int fd;
+	int rec_idx;
+	int end_rec;
+	unsigned int rec_count = 1;
+	int i;
+
+	flt_data = malloc ((flt_data_size + 2) * sizeof (unsigned int));
+//	logsys_ckpt_register ();
+	fd = open ("fdata", O_RDONLY);
+	read (fd, flt_data, (flt_data_size + 2) * sizeof (unsigned int));
+
+printf ("head %d\n",
+	flt_data[FDHEAD_INDEX]);
+printf ("tail %d\n",
+	flt_data[FDTAIL_INDEX]);
+	rec_idx = flt_data[FDTAIL_INDEX];
+	end_rec = flt_data[FDHEAD_INDEX];
+printf ("rec idx tail %d head %d\n", rec_idx, end_rec);
+	for (;;) {
+printf ("found %d records rec_idx %d\n", rec_count++, rec_idx);
+		rec_idx = logsys_rec_get (rec_idx);
+		if (rec_idx == end_rec) {
+			break;
+		}
+		logsys_rec_print (record);
+	}
+printf ("rec idx %d\n", rec_idx);
+}
Index: tools/Makefile
===================================================================
--- tools/Makefile	(revision 1670)
+++ tools/Makefile	(working copy)
@@ -42,7 +42,7 @@
 endif
 
 LIBS = ../lib/libconfdb.a ../lib/libcfg.a
-BINARIES=corosync-objctl corosync-cfgtool corosync-keygen
+BINARIES=corosync-objctl corosync-cfgtool corosync-keygen fplay
 APPS_SRC=$(addsuffix .c,$(BINARIES))
 EXTRA_CFLAGS = -I$(srcdir)include
 
@@ -57,11 +57,14 @@
 corosync-keygen: corosync-keygen.o
 	$(CC) $(LDFLAGS) -o $@ $<
 
+fplay: fplay.o
+	$(CC) $(LDFLAGS) -g -o $@ $<
+
 clean:
 	rm -f *.o $(BINARIES)
 
 %.o: %.c
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) -g -c -o $@ $<
 
 depend:
 	makedepend -Y -- $(CFLAGS) $(CPPFLAGS) $(APPS_SRC) > /dev/null 2>&1
_______________________________________________
Openais mailing list
Openais@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to