ENV LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib
ENV C_INCLUDE_PATH=/usr/local/include
-RUN cd /playpen/src/; make -B mc_listener sender pipe_reader rdc_replay
+RUN cd /playpen/src/; make -B mc_listener sender pipe_reader rdc_replay rdc_extract
# ----- final, smaller image ----------------------------------
FROM ubuntu:18.04
+# bash doesn't cut it for run_replay so grab a real shell and clean up as much as we can
+RUN apt-get update; apt-get install -y ksh
+RUN rm -fr /var/lib/apt/lists
+
# obtusely this uses the previous value
ARG SRC
RUN mkdir -p /playpen/bin
COPY --from=buildenv /usr/local/lib/* /usr/local/lib/
-COPY --from=buildenv /playpen/src/mc_listener /playpen/src/sender /playpen/src/pipe_reader /playpen/src/rdc_replay /playpen/bin/
+COPY --from=buildenv /playpen/src/mc_listener /playpen/src/sender /playpen/src/pipe_reader /playpen/src/rdc_replay /playpen/src/rdc_extract /playpen/bin/
COPY ${SRC}/verify_replay.sh ${SRC}/verify.sh ${SRC}run_replay.sh ${SRC}/help /playpen/bin/
ENV PATH=/playpen/bin:$PATH
rdc_replay: rdc_replay.c libmcl.a
gcc $(coverage_opts) rdc_replay.c -o rdc_replay -L. -lmcl -lrmr_nng -lnng -lpthread -lm
+rdc_extract: rdc_extract.c libmcl.a
+ gcc $(coverage_opts) rdc_extract.c -o rdc_extract -L. -lmcl -lrmr_nng -lnng -lpthread -lm
+
# ---- housekeeping stuff -------------------------------------------------------------
# remove only intermediates
clean:
---
-tag: '1.3.0'
+tag: '1.3.1'
# this is used by CI jobs to apply a tag when it builds the image
above). If an alternate path must be used, it must be supplied using the -d path
command line option to run_replay.sh.
+The replay script supports pre-creating the FIFOs either from a list of known
+and/or expected message types, or by parsing the input file to determine the
+types contained. Use the '-p' option on the run_replay script command line to
+enable pre-creation, and -m "list" to supply a list of message types (e.g.
+-m 1,2,3,10002).
+
+If coordination with a FIFO reader is needed, there are two options to delay
+the start of the replay binary. The '-g file' will cause the run script to
+wait until the gate file "file" exists before starting the reader. This pause
+happens after FIFO creation if -p is given. Additionally, a delay in seconds
+can be given with the -D seconds command line option. After creating FIFOs,
+and optionally waiting for the gate file, the script will delay an additional
+number of seconds before starting the replay process.
endKat
--- /dev/null
+
+/*
+ Mnemonic: rdc_extract.c
+ Abstract: Read a raw data capture file from the mc-listener
+ and tease out one message type.
+
+ 0000000 40 52 44 43 << delim
+ 30 30 31 30 30 35 30 2a << mtype
+ 30 30 30 30 << msg len
+ 0000020 30 37 34 00
+ 40 4d 43 4c 30 30 30 30 30 34 36 00 << raw message
+ :
+ :
+
+ This is a very quick and dirty thing, so it might be flakey.
+
+ Parms from command line are file to read, and the msg type to extract.
+ If mtype given is 0, then message type of each record is written to
+ stdout (can be sorted -u for a list of messages in the file).
+
+ For capture mode, a file MT_<mtype> is created for the extracted
+ records.
+
+ Date: 11 October 2019
+ Author: E. Scott Daniels
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+int main( int argc, char** argv ) {
+ char rbuf[1024 * 5];
+ int fd;
+ int wfd = 1; // write file des; default to stdout
+ int mtype;
+ int mlen;
+ char* nxt;
+ int remain = 0;
+ int need = 20;
+ int desired;
+ int captured = 0;
+ int wlen = 0;
+
+ if( argc < 3 ) {
+ fprintf( stderr, "bad args.\nUsage: %s file mtype [output-file]\n", argv[0] );
+ exit( 1 ) ;
+ }
+
+ fd = open( argv[1], O_RDONLY );
+ if( fd < 0 ) {
+ fprintf( stderr, "bad open: %s\n", strerror(errno) );
+ exit( 1 );
+ }
+
+ desired = atoi( argv[2] );
+
+ if( argc > 3 ) {
+ wfd = open( argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0644 );
+ }
+
+ remain = read( fd, rbuf, sizeof( rbuf ) );
+ nxt = rbuf;
+ while( remain > 0 ) {
+ if( remain < 20 ) { // not enough stuff
+ memcpy( rbuf, nxt, remain ); // copy remaining up front
+ nxt = rbuf;
+ remain += read( fd, nxt + remain, sizeof( rbuf ) - remain );
+ }
+
+ if( remain < 20 ) { // truncated or a record > rbuf
+ fprintf( stderr, "abort: @header check, truncated file, or record > read buffer size\n" );
+ exit( 1 );
+ }
+
+ if( strncmp( nxt, "@RDC", 4 ) == 0 ) {
+ mtype = atoi( nxt+4 );
+ mlen = atoi( nxt+12 );
+ nxt += 20;
+ remain -= 20;
+
+ if( remain < mlen ) { // not enough stuff
+ memcpy( rbuf, nxt, remain ); // copy remaining up front
+ nxt = rbuf;
+ remain += read( fd, nxt + remain, sizeof( rbuf ) - remain );
+ }
+
+ if( remain < mlen ) { // truncated or a record > rbuf
+ fprintf( stderr, "abort: truncated file, or record > read buffer size\n" );
+ exit( 1 );
+ }
+
+ if( desired == 0 ) { // just dump mtypes
+ captured++;
+ fprintf( stdout, "%d\n", mtype );
+ } else {
+
+ if( mtype == desired ) {
+ wlen += mlen;
+ write( wfd, nxt, mlen );
+ captured++;
+ }
+ }
+
+ nxt += mlen;
+ remain -= mlen;
+ } else {
+ fprintf( stderr, "didn't find rdc header!?! @ %ld\n", (long) (nxt - rbuf) );
+ exit( 1 );
+ }
+ }
+
+ fprintf( stderr, "done, captured %d messages (%d bytes)\n", captured, wlen );
+ close( fd );
+}
+
fifo_dir=/var/lib/mc/listener
data="" # stdin by default
+pre_open=0
+mtype_list=""
+gate=""
+delay=0
while [[ $1 == -* ]]
do
case $1 in
- -f) data=$2; shift;;
+ -f) data="$2"; shift;;
-d) fifo_dir=$2; shift;;
+ -D) delay=$2; shift;;
+ -g) gate="$2"; shift;;
+ -m) mtype_list="$2"; shift;;
+ -p) pre_open=1;;
*) echo "$1 is not a recognised option"
- echo "usage: $0 [-d fifo-dir] [-f data-file]"
+ echo "usage: $0 [-d fifo-dir] [-D seconds] [-f data-file] [-g gate-file] [-m mtype-list] [-p]"
+ echo " -p causes FIFOs to be pre-allocated"
+ echo " -m supplies a comma separated list of message types to preopen FIFOs for"
+ echo " if -p is given and -m is omitted, the input file is examined to determine message types"
+ echo " -D seconds will cause a delay of the specified number of seconds before starting the replay"
+ echo " -g file will cause the script to wait for file to appear before starting the replay"
+ echo " if both -D and -g are used, the delay happens after the gate file is found"
exit 1
;;
esac
shift
done
+if (( pre_open ))
+then
+ if [[ -z $mtype_list ]]
+ then
+ if [[ -z $data ]]
+ then
+ echo "error: cannot determine a mtype list from stdin:"
+ echo " -p given with out a list (-m) and input file set to default to stdin (missing -f)"
+ exit 1
+ fi
+
+ rdc_extract $data 0 | sort -u | while read t
+ do
+ mtype_list="$mtype_list$t "
+ done
+ fi
+
+ (
+ cd $fifo_dir
+ count=0
+ for t in ${mtype_list//,/ }
+ do
+ name=$( printf "MT_%09d" t )
+ echo "making FIFO: $name"
+ mkfifo -m 664 $name 2>/dev/null # if these are there, don't natter on about them
+ (( count++ ))
+ done
+
+ ls MT_* | wc -l | read found
+ if (( count != found ))
+ then
+ echo "warn: after pre-create, expected $count FIFOs, but found only $found"
+ fi
+ )
+fi
+
if [[ -n $data ]]
then
if [[ ! -r $data ]]
echo "abort: cannot find data file: $data"
exit 1
fi
+
+ data="-f $data"
+fi
+
+if [[ -n $gate ]]
+then
+ echo "waiting for gate file to appear: $gate"
+ while true
+ do
+ if [[ -e $gate ]]
+ then
+ break
+ fi
+ sleep 1
+ done
+fi
+
+if (( delay ))
+then
+ echo "pausing $delay seconds before starting rdc_display..."
+ sleep $delay
fi
+echo "starting rdc_replay"
rdc_replay -d $fifo_dir $data