]> rtime.felk.cvut.cz Git - can-eth-gw.git/commitdiff
updated kernel module benchmark, added endianness conversion
authorRadek Matějka <radek.matejka@gmail.com>
Wed, 19 Dec 2012 21:06:55 +0000 (15:06 -0600)
committerRadek Matějka <radek.matejka@gmail.com>
Wed, 19 Dec 2012 21:06:55 +0000 (15:06 -0600)
bench/bench
bench/ncrcv
bench/novaboot [new file with mode: 0755]
bench/plotres.m
bench/result/2012-12-19-145516_bench.raw [new file with mode: 0644]
bench/result/2012-12-19-145516_bench.res [new file with mode: 0644]
kernel/canethgw.c
utils/cegwbench/Makefile
utils/cegwbench/cegwbench.c

index 15a003faa3d3c19d8fe558c9d0ac2dbc7cc42f8e..294b813c988b269dde61c0d629a943d603d372b1 100755 (executable)
@@ -15,20 +15,21 @@ fi
 # bench kernel
 #-----------------
 modprobe canethgw
+mkcegwdev
 
-cegw --listen udp@127.0.0.1:10501
-cegw --add -s can@vcan0 -d udp@127.0.0.1:10502
-cegw --add -s udp@127.0.0.1:10502 -d can@vcan0
+cegw vcan0 127.0.0.1:10501 127.0.0.1:10502 &
+JOB=$!
 
 sleep $SLEEP
-echo "#kernel udp->can" | tee -a result | cut -c 2-
+echo "#kernel udp->can" | tee -a result | cut -c 2-
 cegwbench -s udp@127.0.0.1:10501 -d can@vcan0 -n $N -m $MODE -t 1 >> $RESULTFILE
 
 sleep $SLEEP
-echo "#kernel can->udp" | tee -a result | cut -c 2-
+echo "#kernel can->udp" | tee -a result | cut -c 2-
 cegwbench -s can@vcan0 -d udp@127.0.0.1:10502 -n $N -m $MODE -t 1 >> $RESULTFILE
 
 sleep $SLEEP
+kill $JOB
 modprobe -r canethgw
 
 #-----------------
@@ -38,11 +39,11 @@ canethgw -s can@vcan0 -d udp@127.0.0.1:10502 -l udp@127.0.0.1:10501 &
 PID=$!
 sleep $SLEEP
 
-echo "#user udp->can" | tee -a result | cut -c 2-
+echo "#user udp->can" | tee -a result | cut -c 2-
 cegwbench -s udp@127.0.0.1:10501 -d can@vcan0 -n $N -m $MODE -t 1 >> $RESULTFILE
 
 sleep $SLEEP
-echo "#user can->udp" | tee -a result | cut -c 2-
+echo "#user can->udp" | tee -a result | cut -c 2-
 cegwbench -s can@vcan0 -d udp@127.0.0.1:10502 -n $N -m $MODE -t 1 >> $RESULTFILE
 
 sleep $SLEEP
index f9e39d5e63f9148672a4f3471dd0cb1b61833afb..34a7e030161ccbe9cb75b8f35afcfacc35ae9d8c 100755 (executable)
@@ -1,18 +1,11 @@
 #!/bin/bash
 PORT=10600
-ID=`ls -1 result | tail -1 | grep -o "[0-9]*\." | sed "s/\.//"`
-echo -n "nc listening on $PORT: "
-nc -l -p $PORT > res
+FILENAME=`date +%Y-%m-%d-%H%M%S`_bench
 
-if [ -z $ID ]; then
-       let id=1
-else
-       let id=ID+1
-fi;
+echo -n "nc listening on $PORT: "
+nc -l -p $PORT > result/$FILENAME.res
 
-FILENAME=result$id
-mv res result/$FILENAME.dat
 cd result
-sed /^#/d $FILENAME.dat > $FILENAME.raw
+sed /^#/d $FILENAME.res > $FILENAME.raw
 echo "done"
 
diff --git a/bench/novaboot b/bench/novaboot
new file mode 100755 (executable)
index 0000000..bc52ee3
--- /dev/null
@@ -0,0 +1,1077 @@
+#!/usr/bin/perl -w\r
+\r
+use strict;\r
+use warnings;\r
+use Getopt::Long qw(GetOptionsFromString);\r
+use Pod::Usage;\r
+use File::Basename;\r
+use File::Spec;\r
+use IO::Handle;\r
+use Time::HiRes("usleep");\r
+use Socket;\r
+use FileHandle;\r
+use IPC::Open2;\r
+use POSIX qw(:errno_h);\r
+use Cwd;\r
+\r
+# always flush\r
+$| = 1;\r
+\r
+my $invocation_dir = getcwd();\r
+\r
+chomp(my $gittop = `git rev-parse --show-toplevel 2>/dev/null`);\r
+\r
+# Default configuration\r
+$CFG::hypervisor = "bin/apps/hypervisor";\r
+$CFG::hypervisor_params = "serial";\r
+$CFG::server = "erwin.inf.tu-dresden.de:boot/novaboot/\$NAME";\r
+$CFG::server_grub_prefix = "(nd)/tftpboot/sojka/novaboot/\$NAME";\r
+$CFG::grub_keys = ''; #"/novaboot\n\n/\$NAME\n\n";\r
+$CFG::grub2_prolog = "  set root='(hd0,msdos1)'";\r
+$CFG::genisoimage = "genisoimage";\r
+$CFG::iprelay_addr = '141.76.48.80:2324'; #'141.76.48.252';\r
+$CFG::qemu = 'qemu';\r
+$CFG::script_modifier = ''; # Depricated, use --scriptmod commandline option or custom_options.\r
+@CFG::chainloaders = (); #('bin/boot/bender promisc');\r
+$CFG::pulsar_root = '';\r
+$CFG::pulsar_mac = '52-54-00-12-34-56';\r
+%CFG::custom_options = ('I' => '--server=erwin.inf.tu-dresden.de:~passive/boot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --grub-prefix=(nd)/tftpboot/passive/ --iprelay=141.76.48.80:2324 --scriptmod=s/\\\\bhostserial\\\\b/hostserialpci/g',\r
+                       'J' => '--server=rtime.felk.cvut.cz:/srv/tftp/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --pulsar=novaboot --iprelay=147.32.86.92:2324');\r
+$CFG::scons = "scons -j2";\r
+\r
+my @qemu_flags = qw(-cpu coreduo -smp 2);\r
+sub read_config($) {\r
+    my ($cfg) = @_;\r
+    {\r
+       package CFG; # Put config data into a separate namespace\r
+       my $rc = do($cfg);\r
+\r
+       # Check for errors\r
+       if ($@) {\r
+           die("ERROR: Failure compiling '$cfg' - $@");\r
+       } elsif (! defined($rc)) {\r
+           die("ERROR: Failure reading '$cfg' - $!");\r
+       } elsif (! $rc) {\r
+           die("ERROR: Failure processing '$cfg'");\r
+       }\r
+    }\r
+}\r
+\r
+my $cfg = $ENV{'NOVABOOT_CONFIG'} || $ENV{'HOME'}."/.novaboot";\r
+Getopt::Long::Configure(qw/no_ignore_case pass_through/);\r
+GetOptions ("config|c=s" => \$cfg);\r
+if (-s $cfg) { read_config($cfg); }\r
+\r
+# Command line\r
+my ($append, $bender, $builddir, $config_name_opt, $dhcp_tftp, $dump_opt, $dump_config, $grub_config, $grub_prefix, $grub2_config, $help, $iprelay, $iso_image, $man, $no_file_gen, $off_opt, $on_opt, $pulsar, $qemu, $qemu_append, $qemu_flags_cmd, $rsync_flags, @scriptmod, $scons, $serial, $server);\r
+\r
+$rsync_flags = '';\r
+\r
+Getopt::Long::Configure(qw/no_ignore_case no_pass_through/);\r
+my %opt_spec = (\r
+    "append|a=s"     => \$append,\r
+    "bender|b"       => \$bender,\r
+    "build-dir=s"    => \$builddir,\r
+    "dhcp-tftp|d"    => \$dhcp_tftp,\r
+    "dump"          => \$dump_opt,\r
+    "dump-config"    => \$dump_config,\r
+    "grub|g:s"              => \$grub_config,\r
+    "grub-prefix=s"  => \$grub_prefix,\r
+    "grub2:s"       => \$grub2_config,\r
+    "iprelay:s"             => \$iprelay,\r
+    "iso|i:s"       => \$iso_image,\r
+    "name=s"        => \$config_name_opt,\r
+    "no-file-gen"    => \$no_file_gen,\r
+    "off"           => \$off_opt,\r
+    "on"            => \$on_opt,\r
+    "pulsar|p:s"     => \$pulsar,\r
+    "qemu|Q=s"              => \$qemu,\r
+    "qemu-append=s"  => \$qemu_append,\r
+    "qemu-flags|q=s" => \$qemu_flags_cmd,\r
+    "rsync-flags=s"  => \$rsync_flags,\r
+    "scons:s"       => \$scons,\r
+    "scriptmod=s"    => \@scriptmod,\r
+    "serial|s:s"     => \$serial,\r
+    "server:s"              => \$server,\r
+    "h"             => \$help,\r
+    "help"          => \$man,\r
+    );\r
+foreach my $opt(keys(%CFG::custom_options)) {\r
+    $opt_spec{$opt} = sub { GetOptionsFromString($CFG::custom_options{$opt}, %opt_spec); };\r
+}\r
+GetOptions %opt_spec or pod2usage(2);\r
+pod2usage(1) if $help;\r
+pod2usage(-exitstatus => 0, -verbose => 2) if $man;\r
+\r
+$CFG::iprelay_addr = $ENV{'NOVABOOT_IPRELAY'} if $ENV{'NOVABOOT_IPRELAY'};\r
+if ($iprelay && $iprelay ne "on" && $iprelay ne "off") { $CFG::iprelay_addr = $iprelay; }\r
+\r
+if (defined $config_name_opt && scalar(@ARGV) > 1) { die "You cannot use --name with multiple scripts"; }\r
+\r
+if ($server) { $CFG::server = $server; }\r
+if ($qemu) { $CFG::qemu = $qemu; }\r
+$qemu_append ||= '';\r
+\r
+if (defined $pulsar) {\r
+    $CFG::pulsar_mac = $pulsar;\r
+}\r
+\r
+if ($scons) { $CFG::scons = $scons; }\r
+if (!@scriptmod && $CFG::script_modifier) { @scriptmod = ( $CFG::script_modifier ); }\r
+if (defined $grub_prefix) { $CFG::server_grub_prefix = $grub_prefix; }\r
+\r
+if ($dump_config) {\r
+    use Data::Dumper;\r
+    $Data::Dumper::Indent=0;\r
+    print "# This file is in perl syntax.\n";\r
+    foreach my $key(sort(keys(%CFG::))) { # See "Symbol Tables" in perlmod(1)\r
+       if (defined ${$CFG::{$key}}) { print Data::Dumper->Dump([${$CFG::{$key}}], ["*$key"]); }\r
+       if (defined @{$CFG::{$key}}) { print Data::Dumper->Dump([\@{$CFG::{$key}}], ["*$key"]); }\r
+       if (        %{$CFG::{$key}}) { print Data::Dumper->Dump([\%{$CFG::{$key}}], ["*$key"]); }\r
+       print "\n";\r
+    }\r
+    print "1;\n";\r
+    exit;\r
+}\r
+\r
+if (defined $serial) {\r
+    $serial ||= "/dev/ttyUSB0";\r
+}\r
+\r
+if (defined $grub_config) {\r
+    $grub_config ||= "menu.lst";\r
+}\r
+\r
+if (defined $grub2_config) {\r
+    $grub2_config ||= "grub.cfg";\r
+}\r
+\r
+if ($on_opt) { $iprelay="on"; }\r
+if ($off_opt) { $iprelay="off"; }\r
+\r
+# Parse the config(s)\r
+my @scripts;\r
+my $file;\r
+my $line;\r
+my $EOF;\r
+my $last_fn = '';\r
+my ($modules, $variables, $generated, $continuation);\r
+while (<>) {\r
+    if ($ARGV ne $last_fn) { # New script\r
+       die "Missing EOF in $last_fn" if $file;\r
+       die "Unfinished line in $last_fn" if $line;\r
+       $last_fn = $ARGV;\r
+       push @scripts, { 'filename' => $ARGV,\r
+                        'modules' => $modules = [],\r
+                        'variables' => $variables = {},\r
+                        'generated' => $generated = []};\r
+\r
+    }\r
+    chomp();\r
+    next if /^#/ || /^\s*$/;   # Skip comments and empty lines\r
+\r
+    foreach my $mod(@scriptmod) { eval $mod; }\r
+\r
+    print "$_\n" if $dump_opt;\r
+\r
+    if (/^([A-Z_]+)=(.*)$/) {  # Internal variable\r
+       $$variables{$1} = $2;\r
+       next;\r
+    }\r
+    if (/^([^ ]*)(.*?)[[:space:]]*<<([^ ]*)$/) { # Heredoc start\r
+       push @$modules, "$1$2";\r
+       $file = [];\r
+       push @$generated, {filename => $1, content => $file};\r
+       $EOF = $3;\r
+       next;\r
+    }\r
+    if ($file && $_ eq $EOF) { # Heredoc end\r
+       undef $file;\r
+       next;\r
+    }\r
+    if ($file) {               # Heredoc content\r
+       push @{$file}, "$_\n";\r
+       next;\r
+    }\r
+    $_ =~ s/^[[:space:]]*// if ($continuation);\r
+    if (/\\$/) {               # Line continuation\r
+       $line .= substr($_, 0, length($_)-1);\r
+       $continuation = 1;\r
+       next;\r
+    }\r
+    $continuation = 0;\r
+    $line .= $_;\r
+    $line .= " $append" if ($append && scalar(@$modules) == 0);\r
+\r
+    if ($line =~ /^([^ ]*)(.*?)[[:space:]]*< ?(.*)$/) { # Command substitution\r
+       push @$modules, "$1$2";\r
+       push @$generated, {filename => $1, command => $3};\r
+       $line = '';\r
+       next;\r
+    }\r
+    push @$modules, $line;\r
+    $line = '';\r
+}\r
+#use Data::Dumper;\r
+#print Dumper(\@scripts);\r
+\r
+exit if $dump_opt;\r
+\r
+sub generate_configs($$$) {\r
+    my ($base, $generated, $filename) = @_;\r
+    if ($base) { $base = "$base/"; };\r
+    foreach my $g(@$generated) {\r
+      if (exists $$g{content}) {\r
+       my $config = $$g{content};\r
+       my $fn = $$g{filename};\r
+       open(my $f, '>', $fn) || die("$fn: $!");\r
+       map { s|\brom://([^ ]*)|rom://$base$1|g; print $f "$_"; } @{$config};\r
+       close($f);\r
+       print "novaboot: Created $fn\n";\r
+      } elsif (exists $$g{command} && ! $no_file_gen) {\r
+       $ENV{SRCDIR} = dirname(File::Spec->rel2abs( $filename, $invocation_dir ));\r
+       system_verbose("( $$g{command} ) > $$g{filename}");\r
+      }\r
+    }\r
+}\r
+\r
+sub generate_grub_config($$$$;$)\r
+{\r
+    my ($filename, $title, $base, $modules_ref, $prepend) = @_;\r
+    if ($base) { $base = "$base/"; };\r
+    open(my $fg, '>', $filename) or die "$filename: $!";\r
+    print $fg "$prepend\n" if $prepend;\r
+    my $endmark = ($serial || defined $iprelay) ? ';' : '';\r
+    print $fg "title $title$endmark\n" if $title;\r
+    #print $fg "root $base\n"; # root doesn't really work for (nd)\r
+    my $first = 1;\r
+    foreach (@$modules_ref) {\r
+       if ($first) {\r
+           $first = 0;\r
+           my ($kbin, $kcmd) = split(' ', $_, 2);\r
+           $kcmd = '' if !defined $kcmd;\r
+           print $fg "kernel ${base}$kbin $kcmd\n";\r
+       } else {\r
+           s|\brom://([^ ]*)|rom://$base$1|g; # Translate rom:// files - needed for vdisk parameter of sigma0\r
+           print $fg "module $base$_\n";\r
+       }\r
+    }\r
+    close($fg);\r
+}\r
+\r
+sub generate_grub2_config($$$$;$)\r
+{\r
+    my ($filename, $title, $base, $modules_ref, $prepend) = @_;\r
+    if ($base && substr($base,-1,1) ne '/') { $base = "$base/"; };\r
+    open(my $fg, '>', $filename) or die "$filename: $!";\r
+    print $fg "$prepend\n" if $prepend;\r
+    my $endmark = ($serial || defined $iprelay) ? ';' : '';\r
+    $title ||= 'novaboot';\r
+    print $fg "menuentry $title$endmark {\n";\r
+    print $fg "$CFG::grub2_prolog\n";\r
+    my $first = 1;\r
+    foreach (@$modules_ref) {\r
+       if ($first) {\r
+           $first = 0;\r
+           my ($kbin, $kcmd) = split(' ', $_, 2);\r
+           $kcmd = '' if !defined $kcmd;\r
+           print $fg "  multiboot ${base}$kbin $kcmd\n";\r
+       } else {\r
+           my @args = split;\r
+           # GRUB2 doesn't pass filename in multiboot info so we have to duplicate it here\r
+           $_ = join(' ', ($args[0], @args));\r
+           #s|\brom://([^ ]*)|rom://$base$1|g; # Translate rom:// files - needed for vdisk parameter of sigma0\r
+           print $fg "  module $base$_\n";\r
+       }\r
+    }\r
+    print $fg "}\n";\r
+    close($fg);\r
+}\r
+\r
+sub generate_pulsar_config($$)\r
+{\r
+    my ($filename, $modules_ref) = @_;\r
+    open(my $fg, '>', $filename) or die "$filename: $!";\r
+    print $fg "root $CFG::pulsar_root\n" if $CFG::pulsar_root;\r
+    my $first = 1;\r
+    my ($kbin, $kcmd);\r
+    foreach (@$modules_ref) {\r
+       if ($first) {\r
+           $first = 0;\r
+           ($kbin, $kcmd) = split(' ', $_, 2);\r
+           $kcmd = '' if !defined $kcmd;\r
+       } else {\r
+           my @args = split;\r
+           print $fg "load $_\n";\r
+       }\r
+    }\r
+    # Put kernel as last - this is needed for booting Linux and has no influence on non-Linux OSes\r
+    print $fg "exec $kbin $kcmd\n";\r
+    close($fg);\r
+}\r
+\r
+sub exec_verbose(@)\r
+{\r
+    print "novaboot: Running: ".join(' ', map("'$_'", @_))."\n";\r
+    exec(@_);\r
+}\r
+\r
+sub system_verbose($)\r
+{\r
+    my $cmd = shift;\r
+    print "novaboot: Running: $cmd\n";\r
+    my $ret = system($cmd);\r
+    if ($ret & 0x007f) { die("Command terminated by a signal"); }\r
+    if ($ret & 0xff00) {die("Command exit with non-zero exit code"); }\r
+    if ($ret) { die("Command failure $ret"); }\r
+}\r
+\r
+if (exists $variables->{WVDESC}) {\r
+    print "Testing \"$variables->{WVDESC}\" in $last_fn:\n";\r
+} elsif ($last_fn =~ /\.wv$/) {\r
+    print "Testing \"all\" in $last_fn:\n";\r
+}\r
+\r
+my $IPRELAY;\r
+if (defined $iprelay) {\r
+    $CFG::iprelay_addr =~ /([.0-9]+)(:([0-9]+))?/;\r
+    my $addr = $1;\r
+    my $port = $3 || 23;\r
+    my $paddr   = sockaddr_in($port, inet_aton($addr));\r
+    my $proto   = getprotobyname('tcp');\r
+    socket($IPRELAY, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";\r
+    print "novaboot: Connecting to IP relay... ";\r
+    connect($IPRELAY, $paddr)    || die "connect: $!";\r
+    print "done\n";\r
+    $IPRELAY->autoflush(1);\r
+\r
+    while (1) {\r
+       print $IPRELAY "\xFF\xF6";\r
+       alarm(20);\r
+       local $SIG{ALRM} = sub { die "Relay AYT timeout"; };\r
+       my $ayt_reponse = "";\r
+       my $read = sysread($IPRELAY, $ayt_reponse, 100);\r
+       alarm(0);\r
+\r
+       chomp($ayt_reponse);\r
+       print "$ayt_reponse\n";\r
+       if ($ayt_reponse =~ /<iprelayd: not connected/) {\r
+           sleep(10);\r
+           next;\r
+       }\r
+       last;\r
+    }\r
+\r
+    sub relaycmd($$) {\r
+       my ($relay, $onoff) = @_;\r
+       die unless ($relay == 1 || $relay == 2);\r
+\r
+       my $cmd = ($relay == 1 ? 0x5 : 0x6) | ($onoff ? 0x20 : 0x10);\r
+       return "\xFF\xFA\x2C\x32".chr($cmd)."\xFF\xF0";\r
+    }\r
+\r
+    sub relayconf($$) {\r
+       my ($relay, $onoff) = @_;\r
+       die unless ($relay == 1 || $relay == 2);\r
+       my $cmd = ($relay == 1 ? 0xdf : 0xbf) | ($onoff ? 0x00 : 0xff);\r
+       return "\xFF\xFA\x2C\x97".chr($cmd)."\xFF\xF0";\r
+    }\r
+\r
+    sub relay($$;$) {\r
+       my ($relay, $onoff, $can_giveup) = @_;\r
+       my $confirmation = '';\r
+       print $IPRELAY relaycmd($relay, $onoff);\r
+\r
+       # We use non-blocking I/O and polling here because for some\r
+       # reason read() on blocking FD returns only after all\r
+       # requested data is available. If we get during the first\r
+       # read() only a part of confirmation, we may get the rest\r
+       # after the system boots and print someting, which may be too\r
+       # long.\r
+       $IPRELAY->blocking(0);\r
+\r
+       alarm(20); # Timeout in seconds\r
+       my $giveup = 0;\r
+        local $SIG{ALRM} = sub {\r
+           if ($can_giveup) { print("Relay confirmation timeout - ignoring\n"); $giveup = 1;}\r
+           else {die "Relay confirmation timeout";}\r
+       };\r
+       my $index;\r
+       while (($index=index($confirmation, relayconf($relay, $onoff))) < 0 && !$giveup) {\r
+           my $read = read($IPRELAY, $confirmation, 70, length($confirmation));\r
+           if (!defined($read)) {\r
+               die("IP relay: $!") unless $! == EAGAIN;\r
+               usleep(10000);\r
+               next;\r
+           }\r
+           #use MIME::QuotedPrint;\r
+           #print "confirmation = ".encode_qp($confirmation)."\n";\r
+       }\r
+       alarm(0);\r
+       $IPRELAY->blocking(1);\r
+    }\r
+}\r
+\r
+if ($iprelay && ($iprelay eq "on" || $iprelay eq "off")) {\r
+     relay(1, 1); # Press power button\r
+    if ($iprelay eq "on") {\r
+       usleep(100000);         # Short press\r
+    } else {\r
+       usleep(6000000);        # Long press to switch off\r
+    }\r
+    print $IPRELAY relay(1, 0);\r
+    exit;\r
+}\r
+\r
+if ($builddir) {\r
+    $CFG::builddir = $builddir;\r
+} else {\r
+    if (! defined $CFG::builddir) {\r
+       $CFG::builddir = ( $gittop || $ENV{'HOME'}."/nul" ) . "/build";\r
+       if (! -d $CFG::builddir) {\r
+           $CFG::builddir = $ENV{SRCDIR} = dirname(File::Spec->rel2abs( ${$scripts[0]}{filename}, $invocation_dir ));\r
+       }\r
+    }\r
+}\r
+\r
+chdir($CFG::builddir) or die "Can't change directory to $CFG::builddir: $!";\r
+print "novaboot: Entering directory `$CFG::builddir'\n";\r
+\r
+my (%files_iso, $menu_iso, $config_name, $filename);\r
+\r
+foreach my $script (@scripts) {\r
+    $filename = $$script{filename};\r
+    $modules = $$script{modules};\r
+    $generated = $$script{generated};\r
+    $variables = $$script{variables};\r
+    my ($server_grub_prefix);\r
+\r
+    if (defined $config_name_opt) {\r
+       $config_name = $config_name_opt;\r
+    } else {\r
+       ($config_name = $filename) =~ s#.*/##;\r
+    }\r
+\r
+    my $kernel;\r
+    if (exists $variables->{KERNEL}) {\r
+       $kernel = $variables->{KERNEL};\r
+    } else {\r
+       $kernel = $CFG::hypervisor . " ";\r
+       if (exists $variables->{HYPERVISOR_PARAMS}) {\r
+           $kernel .= $variables->{HYPERVISOR_PARAMS};\r
+       } else {\r
+           $kernel .= $CFG::hypervisor_params;\r
+       }\r
+    }\r
+    @$modules = ($kernel, @$modules);\r
+    @$modules = (@CFG::chainloaders, @$modules);\r
+    @$modules = ("bin/boot/bender", @$modules) if ($bender || defined $ENV{'NOVABOOT_BENDER'});\r
+\r
+    if (defined $grub_config) {\r
+       generate_configs("", $generated, $filename);\r
+       generate_grub_config($grub_config, $config_name, "", $modules);\r
+       print("GRUB menu created: $CFG::builddir/$grub_config\n");\r
+       exit;\r
+    }\r
+\r
+    if (defined $grub2_config && !defined $server) {\r
+       generate_configs('', $generated, $filename);\r
+       generate_grub2_config($grub2_config, $config_name, $CFG::builddir, $modules);\r
+       print("GRUB2 configuration created: $CFG::builddir/$grub2_config\n");\r
+       exit;\r
+    }\r
+\r
+    my $pulsar_config;\r
+    if (defined $pulsar) {\r
+       $pulsar_config = "config-$CFG::pulsar_mac";\r
+       generate_configs('', $generated, $filename);\r
+       generate_pulsar_config($pulsar_config, $modules);\r
+       if (!defined $server) {\r
+           print("Pulsar configuration created: $CFG::builddir/$pulsar_config\n");\r
+           exit;\r
+       }\r
+    }\r
+\r
+    if (defined $scons) {\r
+       my @files = map({ ($file) = m/([^ ]*)/; $file; } @$modules);\r
+       # Filter-out generated files\r
+       my @to_build = grep({ my $file = $_; !scalar(grep($file eq $$_{filename}, @$generated)) } @files);\r
+       system_verbose($CFG::scons." ".join(" ", @to_build));\r
+    }\r
+\r
+    if (defined $server) {\r
+       ($server_grub_prefix = $CFG::server_grub_prefix) =~ s/\$NAME/$config_name/;\r
+       ($server = $CFG::server)                         =~ s/\$NAME/$config_name/;\r
+       my $bootloader_config;\r
+       if ($grub2_config) {\r
+           generate_configs('', $generated, $filename);\r
+           $bootloader_config ||= "grub.cfg";\r
+           generate_grub2_config($grub2_config, $config_name, $server_grub_prefix, $modules);\r
+       } elsif (defined $pulsar) {\r
+           $bootloader_config = $pulsar_config;\r
+       } else {\r
+           generate_configs($server_grub_prefix, $generated, $filename);\r
+           $bootloader_config ||= "menu.lst";\r
+           if (!grep { $_ eq $bootloader_config } @$modules) {\r
+               generate_grub_config($bootloader_config, $config_name, $server_grub_prefix, $modules,\r
+                                    $server_grub_prefix eq $CFG::server_grub_prefix ? "timeout 0" : undef);\r
+           }\r
+       }\r
+       my ($hostname, $path) = split(":", $server, 2);\r
+       if (! defined $path) {\r
+           $path = $hostname;\r
+           $hostname = "";\r
+       }\r
+       my $files = "$bootloader_config " . join(" ", map({ ($file) = m/([^ ]*)/; $file; } @$modules));\r
+       my $combined_menu_lst = ($CFG::server =~ m|/\$NAME$|);\r
+       map({ my $file = (split)[0]; die "$file: $!" if ! -f $file; } @$modules);\r
+       my $istty = -t STDOUT && $ENV{'TERM'} ne "dumb";\r
+       my $progress = $istty ? "--progress" : "";\r
+       system_verbose("rsync $progress -RLp $rsync_flags $files $server");\r
+       my $cmd = "cd $path/.. && cat */menu.lst > menu.lst";\r
+       if ($combined_menu_lst) { system_verbose($hostname ? "ssh $hostname '$cmd'" : $cmd); }\r
+    }\r
+\r
+    if (defined $iso_image) {\r
+       generate_configs("(cd)", $generated, $filename);\r
+       my $menu;\r
+       generate_grub_config(\$menu, $config_name, "(cd)", $modules);\r
+       $menu_iso .= "$menu\n";\r
+       map { ($file,undef) = split; $files_iso{$file} = 1; } @$modules;\r
+    }\r
+}\r
+\r
+if (defined $iso_image) {\r
+    open(my $fh, ">menu-iso.lst");\r
+    print $fh "timeout 5\n\n$menu_iso";\r
+    close($fh);\r
+    my $files = "boot/grub/menu.lst=menu-iso.lst " . join(" ", map("$_=$_", keys(%files_iso)));\r
+    $iso_image ||= "$config_name.iso";\r
+    system_verbose("$CFG::genisoimage -R -b stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -hide-rr-moved -J -joliet-long -o $iso_image -graft-points bin/boot/grub/ $files");\r
+    print("ISO image created: $CFG::builddir/$iso_image\n");\r
+}\r
+\r
+######################################################################\r
+# Boot NOVA using various methods and send serial output to stdout\r
+######################################################################\r
+\r
+if (scalar(@scripts) > 1 && ( defined $dhcp_tftp || defined $serial || defined $iprelay)) {\r
+    die "You cannot do this with multiple scripts simultaneously";\r
+}\r
+\r
+if ($variables->{WVTEST_TIMEOUT}) {\r
+    print "wvtest: timeout ", $variables->{WVTEST_TIMEOUT}, "\n";\r
+}\r
+\r
+if (!(defined $dhcp_tftp || defined $serial || defined $iprelay || defined $server || defined $iso_image)) {\r
+    # Qemu\r
+    @qemu_flags = split(/ /, $variables->{QEMU_FLAGS}) if exists $variables->{QEMU_FLAGS};\r
+    @qemu_flags = split(/ /, $qemu_flags_cmd) if $qemu_flags_cmd;\r
+    push(@qemu_flags, split(/ /, $qemu_append));\r
+\r
+    if (defined $iso_image) {\r
+       # Boot NOVA with grub (and test the iso image)\r
+       push(@qemu_flags, ('-cdrom', "$config_name.iso"));\r
+    } else {\r
+       # Boot NOVA without GRUB\r
+\r
+       # Non-patched qemu doesn't like commas, but NUL can live with pluses instead of commans\r
+       foreach (@$modules) {s/,/+/g;}\r
+       generate_configs("", $generated, $filename);\r
+\r
+       my ($kbin, $kcmd) = split(' ', shift(@$modules), 2);\r
+       $kcmd = '' if !defined $kcmd;\r
+       my $initrd = join ",", @$modules;\r
+\r
+       push(@qemu_flags, ('-kernel', $kbin, '-append', $kcmd));\r
+       push(@qemu_flags, ('-initrd', $initrd)) if $initrd;\r
+    }\r
+    push(@qemu_flags,  qw(-serial stdio)); # Redirect serial output (for collecting test restuls)\r
+    exec_verbose(($CFG::qemu,  '-name', $config_name, @qemu_flags));\r
+}\r
+\r
+my ($dhcpd_pid, $tftpd_pid);\r
+\r
+if (defined $dhcp_tftp)\r
+{\r
+    generate_configs("(nd)", $generated, $filename);\r
+    system_verbose('mkdir -p tftpboot');\r
+    generate_grub_config("tftpboot/os-menu.lst", $config_name, "(nd)", \@$modules, "timeout 0");\r
+    open(my $fh, '>', 'dhcpd.conf');\r
+    my $mac = `cat /sys/class/net/eth0/address`;\r
+    chomp $mac;\r
+    print $fh "subnet 10.23.23.0 netmask 255.255.255.0 {\r
+                     range 10.23.23.10 10.23.23.100;\r
+                     filename \"bin/boot/grub/pxegrub.pxe\";\r
+                     next-server 10.23.23.1;\r
+}\r
+host server {\r
+       hardware ethernet $mac;\r
+       fixed-address 10.23.23.1;\r
+}";\r
+    close($fh);\r
+    system_verbose("sudo ip a add 10.23.23.1/24 dev eth0;\r
+           sudo ip l set dev eth0 up;\r
+           sudo touch dhcpd.leases");\r
+\r
+    $dhcpd_pid = fork();\r
+    if ($dhcpd_pid == 0) {\r
+       # This way, the spawned server are killed when this script is killed.\r
+       exec_verbose("sudo dhcpd -d -cf dhcpd.conf -lf dhcpd.leases -pf dhcpd.pid");\r
+    }\r
+    $tftpd_pid = fork();\r
+    if ($tftpd_pid == 0) {\r
+       exec_verbose("sudo in.tftpd --foreground --secure -v -v -v $CFG::builddir");\r
+    }\r
+    $SIG{TERM} = sub { print "CHILDS KILLED\n"; kill 15, $dhcpd_pid, $tftpd_pid; };\r
+}\r
+\r
+if ($serial || defined $iprelay) {\r
+    my $CONN;\r
+    if (defined $iprelay) {\r
+       print "novaboot: Reseting the test box... ";\r
+       relay(2, 1, 1); # Reset the machine\r
+       usleep(100000);\r
+       relay(2, 0);\r
+       print "done\n";\r
+\r
+       $CONN = $IPRELAY;\r
+    } elsif ($serial) {\r
+       system("stty -F $serial raw -crtscts -onlcr 115200");\r
+       open($CONN, "+<", $serial) || die "open $serial: $!";\r
+       $CONN->autoflush(1);\r
+    }\r
+    if (!defined $dhcp_tftp && $CFG::grub_keys) {\r
+       # Control grub via serial line\r
+       print "Waiting for GRUB's serial output... ";\r
+       while (<$CONN>) {\r
+           if (/Press any key to continue/) { print $CONN "\n"; last; }\r
+       }\r
+       $CFG::grub_keys =~ s/\$NAME/$config_name;/;\r
+       my @characters = split(//, $CFG::grub_keys);\r
+       foreach (@characters) {\r
+           print $CONN $_;\r
+           usleep($_ eq "\n" ? 100000 : 10000);\r
+       }\r
+       print $CONN "\n";\r
+       print "done\n";\r
+    }\r
+    # Pass the NOVA output to stdout.\r
+    while (<$CONN>) {\r
+       print;\r
+    }\r
+    kill 15, $dhcpd_pid, $tftpd_pid if ($dhcp_tftp);\r
+    exit;\r
+}\r
+\r
+if (defined $dhcp_tftp) {\r
+    my $pid = wait();\r
+    if ($pid == $dhcpd_pid) { print "dhcpd exited!\n"; }\r
+    elsif ($pid == $tftpd_pid) { print "tftpd exited!\n"; }\r
+    else { print "wait returned: $pid\n"; }\r
+    kill(15, 0); # Kill current process group i.e. all remaining children\r
+}\r
+\r
+=head1 NAME\r
+\r
+novaboot - NOVA boot script interpreter\r
+\r
+=head1 SYNOPSIS\r
+\r
+B<novaboot> [ options ] [--] script...\r
+\r
+B<./script> [ options ]\r
+\r
+B<novaboot> --help\r
+\r
+=head1 DESCRIPTION\r
+\r
+This program makes it easier to boot NOVA or other operating system\r
+(OS) in different environments. It reads a so called novaboot script\r
+and uses it either to boot the OS in an emulator (e.g. in qemu) or to\r
+generate the configuration for a specific bootloader and optionally to\r
+copy the necessary binaries and other needed files to proper\r
+locations, perhaps on a remote server. In case the system is actually\r
+booted, its serial output is redirected to standard output if that is\r
+possible.\r
+\r
+A typical way of using novaboot is to make the novaboot script\r
+executable and set its first line to I<#!/usr/bin/env novaboot>. Then,\r
+booting a particular OS configuration becomes the same as executing a\r
+local program - the novaboot script.\r
+\r
+With C<novaboot> you can:\r
+\r
+=over 3\r
+\r
+=item 1.\r
+\r
+Run NOVA in Qemu. This is the default action when no other action is\r
+specified by command line switches. Thus running C<novaboot ./script>\r
+(or C<./script> as described above) will run Qemu with configuration\r
+specified in the I<script>.\r
+\r
+=item 2.\r
+\r
+Create a bootloader configuration file (currently supported\r
+bootloaders are GRUB, GRUB2 and Pulsar) and copy it with all files\r
+needed for booting another, perhaps remote, location.\r
+\r
+ ./script --server --iprelay\r
+\r
+This command copies files to a TFTP server specified in the\r
+configuration file and uses TCP/IP-controlled relay to reset the test\r
+box and receive its serial output.\r
+\r
+=item 3.\r
+\r
+Run DHCP and TFTP server on developer's machine to PXE-boot NOVA from\r
+it. E.g.\r
+\r
+ ./script --dhcp-tftp\r
+\r
+When a PXE-bootable machine is connected via Ethernet to developer's\r
+machine, it will boot the configuration described in I<script>.\r
+\r
+=item 4.\r
+\r
+Create bootable ISO images. E.g.\r
+\r
+ novaboot --iso -- script1 script2\r
+\r
+The created ISO image will have GRUB bootloader installed on it and\r
+the boot menu will allow selecting between I<script1> and I<script2>\r
+configurations.\r
+\r
+=back\r
+\r
+=head1 OPTIONS\r
+\r
+=over 8\r
+\r
+=item -a, --append=<parameters>\r
+\r
+Appends a string to the root task's command line.\r
+\r
+=item -b, --bender\r
+\r
+Boot bender tool before the kernel to find PCI serial ports.\r
+\r
+=item --build-dir=<directory>\r
+\r
+Overrides the default build directory location.\r
+\r
+The default build directory location is determined as follows:\r
+\r
+If there is a configuration file, the value specified in I<$builddir>\r
+variable is used. Otherwise, if the current working directory is\r
+inside git work tree and there is F<build> directory at the top of\r
+that tree, it is used. Otherwise, if directory F<~/nul/build> exists,\r
+it is used. Otherwise, it is the directory that contains the first\r
+processed novaboot script.\r
+\r
+=item -c, --config=<filename>\r
+\r
+Use a different configuration file than the default one (i.e.\r
+F<~/.novaboot>).\r
+\r
+=item -d, --dhcp-tftp\r
+\r
+Turns your workstation into a DHCP and TFTP server so that NOVA\r
+can be booted via PXE BIOS on a test machine directly connected by\r
+a plain Ethernet cable to your workstation.\r
+\r
+The DHCP and TFTP servers require root privileges and C<novaboot>\r
+uses C<sudo> command to obtain those. You can put the following to\r
+I</etc/sudoers> to allow running the necessary commands without\r
+asking for password.\r
+\r
+ Cmnd_Alias NOVABOOT = /bin/ip a add 10.23.23.1/24 dev eth0, /bin/ip l set dev eth0 up, /usr/sbin/dhcpd -d -cf dhcpd.conf -lf dhcpd.leases -pf dhcpd.pid, /usr/sbin/in.tftpd --foreground --secure -v -v -v *, /usr/bin/touch dhcpd.leases\r
+ your_login ALL=NOPASSWD: NOVABOOT\r
+\r
+=item --dump\r
+\r
+Prints the content of the novaboot script after removing comments and\r
+evaluating all I<--scriptmod> expressions.\r
+\r
+=item --dump-config\r
+\r
+Dumps current configuration to stdout end exits. Useful as an initial\r
+template for a configuration file.\r
+\r
+=item -g, --grub[=I<filename>]\r
+\r
+Generates grub menu file. If the I<filename> is not specified,\r
+F<menu.lst> is used. The I<filename> is relative to NUL build\r
+directory.\r
+\r
+=item --grub-prefix=I<prefix>\r
+\r
+Specifies I<prefix> that is put before every file in GRUB's menu.lst.\r
+This overrides the value of I<$server_grub_prefix> from the\r
+configuration file.\r
+\r
+=item --grub2[=I<filename>]\r
+\r
+Generate GRUB2 menuentry in I<filename>. If I<filename> is not\r
+specified grub.cfg is used. The content of the menuentry can be\r
+customized by I<$grub2_prolog> and I<$server_grub_prefix>\r
+configuration variables.\r
+\r
+In order to use the the generated menuentry on your development\r
+machine that uses GRUB2, append the following snippet to\r
+F</etc/grub.d/40_custom> file and regenerate your grub configuration,\r
+i.e. run update-grub on Debian/Ubuntu.\r
+\r
+  if [ -f /path/to/nul/build/grub.cfg ]; then\r
+    source /path/to/nul/build/grub.cfg\r
+  fi\r
+\r
+\r
+=item -h, --help\r
+\r
+Print short (B<-h>) or long (B<--help>) help.\r
+\r
+=item --iprelay[=addr or cmd]\r
+\r
+If no I<cmd> is given, use IP relay to reset the machine and to get\r
+the serial output. The IP address of the relay is given by I<addr>\r
+parameter if specified or by $iprelay_addr variable in the\r
+configuration file.\r
+\r
+If I<cmd> is one of "on" or "off", the IP relay is used to press power\r
+button for a short (in case of "on") or long (in case of "off") time.\r
+Then, novaboot exits.\r
+\r
+Note: This option is expected to work with HWG-ER02a IP relays.\r
+\r
+=item -i, --iso[=filename]\r
+\r
+Generates the ISO image that boots NOVA system via GRUB. If no filename\r
+is given, the image is stored under I<NAME>.iso, where I<NAME> is the name\r
+of novaboot script (see also B<--name>).\r
+\r
+=item -I\r
+\r
+This is an alias (see C<%custom_options> below) defined in the default\r
+configuration. When used, it causes novaboot to use Michal's remotely\r
+controllable test bed.\r
+\r
+=item -J\r
+\r
+This is an alias (see C<%custom_options> below) defined in the default\r
+configuration. When used, it causes novaboot to use another remotely\r
+controllable test bed.\r
+\r
+=item --on, --off\r
+\r
+Synonym for --iprelay=on/off.\r
+\r
+=item --name=I<string>\r
+\r
+Use the name I<string> instead of the name of the novaboot script.\r
+This name is used for things like a title of grub menu or for the\r
+server directory where the boot files are copied to.\r
+\r
+=item --no-file-gen\r
+\r
+Do not generate files on the fly (i.e. "<" syntax) except for the\r
+files generated via "<<WORD" syntax.\r
+\r
+=item -p, --pulsar[=mac]\r
+\r
+Generates pulsar bootloader configuration file whose name is based on\r
+the MAC address specified either on the command line or taken from\r
+I<.novaboot> configuration file.\r
+\r
+=item -Q, --qemu=I<qemu-binary>\r
+\r
+Use specific version of qemu binary. The default is 'qemu'.\r
+\r
+=item --qemu-append=I<flags>\r
+\r
+Append I<flags> to the default qemu flags (QEMU_FLAGS variable or\r
+C<-cpu coreduo -smp 2>).\r
+\r
+=item -q, --qemu-flags=I<flags>\r
+\r
+Replace the default qemu flags (QEMU_FLAGS variable or C<-cpu coreduo\r
+-smp 2>) with I<flags> specified here.\r
+\r
+=item --rsync-flags=I<flags>\r
+\r
+Specifies which I<flags> are appended to F<rsync> command line when\r
+copying files as a result of I<--server> option.\r
+\r
+=item --scons[=scons command]\r
+\r
+Runs I<scons> to build files that are not generated by novaboot\r
+itself.\r
+\r
+=item --scriptmod=I<perl expression>\r
+\r
+When novaboot script is read, I<perl expression> is executed for every\r
+line (in $_ variable). For example, C<novaboot\r
+--scriptmod=s/sigma0/omega6/g> replaces every occurrence of I<sigma0>\r
+in the script with I<omega6>.\r
+\r
+When this option is present, it overrides I<$script_modifier> variable\r
+from the configuration file, which has the same effect. If this option\r
+is given multiple times all expressions are evaluated in the command\r
+line order.\r
+\r
+=item --server[=[[user@]server:]path]\r
+\r
+Copy all files needed for booting to a server (implies B<-g> unless\r
+B<--grub2> is given). The files will be copied to the directory\r
+I<path>. If the I<path> contains string $NAME, it will be replaced\r
+with the name of the novaboot script (see also B<--name>).\r
+\r
+Additionally, if $NAME is the last component of the I<path>, a file\r
+named I<path>/menu.lst (with $NAME removed from the I<path>) will be\r
+created on the server by concatenating all I<path>/*/menu.lst (with\r
+$NAME removed from the I<path>) files found on the server.\r
+\r
+=item -s, --serial[=device]\r
+\r
+Use serial line to control GRUB bootloader and to get the serial\r
+output of the machine. The default value is /dev/ttyUSB0.\r
+\r
+=back\r
+\r
+=head1 NOVABOOT SCRIPT SYNTAX\r
+\r
+The syntax tries to mimic POSIX shell syntax. The syntax is defined with the following rules.\r
+\r
+Lines starting with "#" are ignored.\r
+\r
+Lines that end with "\" are concatenated with the following line after\r
+removal of the final "\" and leading whitespace of the following line.\r
+\r
+Lines in the form I<VARIABLE=...> (i.e. matching '^[A-Z_]+=' regular\r
+expression) assign values to internal variables. See VARIABLES\r
+section.\r
+\r
+Otherwise, the first word on the line represents the filename\r
+(relative to the build directory (see I<--build-dir>) of the module to\r
+load and the remaining words are passed as the command line\r
+parameters.\r
+\r
+When the line ends with "<<WORD" then the subsequent lines until the\r
+line containing only WORD are copied literally to the file named on\r
+that line.\r
+\r
+When the line ends with "< CMD" the command CMD is executed with\r
+C</bin/sh> and its standard output is stored in the file named on that\r
+line. The SRCDIR variable in CMD's environment is set to the absolute\r
+path of the directory containing the interpreted novaboot script.\r
+\r
+Example:\r
+  #!/usr/bin/env novaboot\r
+  WVDESC=Example program\r
+  bin/apps/sigma0.nul S0_DEFAULT script_start:1,1 \\r
+    verbose hostkeyb:0,0x60,1,12,2\r
+  bin/apps/hello.nul\r
+  hello.nulconfig <<EOF\r
+  sigma0::mem:16 name::/s0/log name::/s0/timer name::/s0/fs/rom ||\r
+  rom://bin/apps/hello.nul\r
+  EOF\r
+\r
+This example will load three modules: sigma0.nul, hello.nul and\r
+hello.nulconfig. sigma0 gets some command line parameters and\r
+hello.nulconfig file is generated on the fly from the lines between\r
+<<EOF and EOF.\r
+\r
+=head2 VARIABLES\r
+\r
+The following variables are interpreted in the novaboot script:\r
+\r
+=over 8\r
+\r
+=item WVDESC\r
+\r
+Description of the wvtest-compliant program.\r
+\r
+=item WVTEST_TIMEOUT\r
+\r
+The timeout in seconds for WvTest harness. If no complete line appears\r
+in the test output within the time specified here, the test fails. It\r
+is necessary to specify this for long running tests that produce no\r
+intermediate output.\r
+\r
+=item QEMU_FLAGS\r
+\r
+Use specific qemu flags (can be overriden by B<-q>).\r
+\r
+=item HYPERVISOR_PARAMS\r
+\r
+Parameters passed to hypervisor. The default value is "serial", unless\r
+overriden in configuration file.\r
+\r
+=item KERNEL\r
+\r
+The kernel to use instead of NOVA hypervisor specified in the\r
+configuration file. The value should contain the name of the kernel\r
+image as well as its command line parameters. If this variable is\r
+defined and non-empty, the variable HYPERVISOR_PARAMS is not used.\r
+\r
+=back\r
+\r
+=head1 CONFIGURATION FILE\r
+\r
+novaboot can read its configuration from ~/.novaboot file (or another\r
+file specified with B<-c> parameter or NOVABOOT_CONFIG environment\r
+variable). It is a file with perl syntax, which sets values of certain\r
+variables. The current configuration can be dumped with\r
+B<--dump-config> switch. Use\r
+\r
+    novaboot --dump-config > ~/.novaboot\r
+\r
+to create a default configuration file and modify it to your needs.\r
+Some configuration variables can be overriden by environment variables\r
+(see below) or by command line switches.\r
+\r
+Documentation of some configuration variables follows:\r
+\r
+=over 8\r
+\r
+=item @chainloaders\r
+\r
+Custom chainloaders to load before hypervisor and files specified in\r
+novaboot script. E.g. ('bin/boot/bender promisc', 'bin/boot/zapp').\r
+\r
+=item %custom_options\r
+\r
+Defines custom command line options that can serve as aliases for\r
+other options. E.g. 'S' => '--server=boot:/tftproot\r
+--serial=/dev/ttyUSB0'.\r
+\r
+=back\r
+\r
+=head1 ENVIRONMENT VARIABLES\r
+\r
+Some options can be specified not only via config file or command line\r
+but also through environment variables. Environment variables override\r
+the values from configuration file and command line parameters\r
+override the environment variables.\r
+\r
+=over 8\r
+\r
+=item NOVABOOT_CONFIG\r
+\r
+A name of default novaboot configuration file.\r
+\r
+=item NOVABOOT_BENDER\r
+\r
+Defining this variable has the same meaning as B<--bender> option.\r
+\r
+=item NOVABOOT_IPRELAY\r
+\r
+The IP address (and optionally the port) of the IP relay. This\r
+overrides $iprelay_addr variable from the configuration file.\r
+\r
+=back\r
+\r
+=head1 AUTHORS\r
+\r
+Michal Sojka <sojka@os.inf.tu-dresden.de>\r
index 40310f0c0dd43e8426ea75c4e24d9f914d856b22..0b18e31ff8aaed969e7a748c13103153de7db0f3 100644 (file)
@@ -1,6 +1,6 @@
 function [] = plotres( filename )
 % plots canethgw benchmark data
-data = dlmread( ["result/" filename ".raw"] );
+data = dlmread( filename );
 
 figure;
 hold on;
diff --git a/bench/result/2012-12-19-145516_bench.raw b/bench/result/2012-12-19-145516_bench.raw
new file mode 100644 (file)
index 0000000..0168fca
--- /dev/null
@@ -0,0 +1,4 @@
+59547.000000   9065.000000     7422.000000     7032.000000     6971.000000     6605.000000     6601.000000     6554.000000     6597.000000     6450.000000     6487.000000     6363.000000     6393.000000     6350.000000     9850.000000     6721.000000     6496.000000     6422.000000     6436.000000     6405.000000     6560.000000     6464.000000     6429.000000     6350.000000     6417.000000     6349.000000     6418.000000     6328.000000     6354.000000     6447.000000     6372.000000     6378.000000     6377.000000     6202.000000     6373.000000     6325.000000     6429.000000     6277.000000     6469.000000     6262.000000     6560.000000     6355.000000     6437.000000     6291.000000     6528.000000     6287.000000     6433.000000     6335.000000     6411.000000     6299.000000     6443.000000     6316.000000     6373.000000     6387.000000     6458.000000     6388.000000     6485.000000     6408.000000     6315.000000     6391.000000     6501.000000     6348.000000     6444.000000     6325.000000     6419.000000     6387.000000     6499.000000     6340.000000     6494.000000     6494.000000     6345.000000     6318.000000     6366.000000     6381.000000     6547.000000     6320.000000     6347.000000     6277.000000     6436.000000     6297.000000     6521.000000     6412.000000     6369.000000     6351.000000     6424.000000     6370.000000     6474.000000     6395.000000     6363.000000     6427.000000     6540.000000     6449.000000     6357.000000     6327.000000     6384.000000     6244.000000     6461.000000     6294.000000     6461.000000     6362.000000     
+69080.000000   63520.000000    63814.000000    37757.000000    9887.000000     8232.000000     8300.000000     7652.000000     6789.000000     6652.000000     6698.000000     6529.000000     6267.000000     6321.000000     6790.000000     6442.000000     6528.000000     6416.000000     6547.000000     6435.000000     6405.000000     6425.000000     6468.000000     6403.000000     6361.000000     6357.000000     6553.000000     6431.000000     6645.000000     8057.000000     6912.000000     6387.000000     6464.000000     6346.000000     6367.000000     6329.000000     6335.000000     6302.000000     6535.000000     6334.000000     6347.000000     6395.000000     6663.000000     6372.000000     6424.000000     6343.000000     6372.000000     6269.000000     6281.000000     6331.000000     6479.000000     6320.000000     6422.000000     6354.000000     6385.000000     6356.000000     6701.000000     6375.000000     6415.000000     6342.000000     6413.000000     6387.000000     18412.000000    6437.000000     6334.000000     6411.000000     6500.000000     6394.000000     6427.000000     6266.000000     6720.000000     6337.000000     6309.000000     6356.000000     6475.000000     6365.000000     6355.000000     6312.000000     6413.000000     6361.000000     6371.000000     6262.000000     6387.000000     6274.000000     6582.000000     6443.000000     6562.000000     6401.000000     6441.000000     6366.000000     6474.000000     6390.000000     6435.000000     6353.000000     6466.000000     6379.000000     6335.000000     6398.000000     6765.000000     6376.000000     
+41618.000000   36407.000000    35293.000000    9200.000000     24647.000000    7293.000000     7353.000000     7318.000000     7175.000000     7214.000000     7120.000000     7211.000000     7200.000000     7197.000000     7195.000000     7391.000000     7075.000000     7117.000000     7262.000000     7077.000000     7144.000000     7051.000000     7236.000000     7079.000000     7216.000000     7115.000000     7127.000000     7072.000000     15639.000000    7442.000000     7379.000000     7152.000000     7062.000000     7123.000000     7272.000000     7211.000000     7214.000000     7180.000000     7124.000000     7087.000000     7101.000000     7105.000000     7155.000000     7230.000000     7116.000000     7299.000000     7159.000000     7150.000000     7169.000000     7093.000000     7231.000000     7080.000000     7147.000000     7113.000000     7173.000000     7100.000000     7195.000000     7086.000000     7086.000000     7132.000000     7350.000000     7216.000000     7202.000000     7111.000000     7100.000000     7100.000000     7259.000000     7066.000000     7113.000000     7064.000000     7129.000000     7056.000000     7125.000000     7108.000000     7048.000000     7293.000000     7104.000000     7170.000000     7222.000000     7090.000000     7088.000000     7104.000000     7218.000000     7065.000000     7185.000000     7044.000000     7145.000000     7052.000000     7116.000000     7141.000000     7296.000000     7144.000000     7093.000000     7092.000000     7193.000000     7065.000000     7151.000000     7083.000000     7192.000000     7073.000000     
+88044.000000   85226.000000    84115.000000    41538.000000    20492.000000    19123.000000    7781.000000     7336.000000     7294.000000     7539.000000     7289.000000     7289.000000     7244.000000     7452.000000     7492.000000     7360.000000     7263.000000     7424.000000     10021.000000    7598.000000     7299.000000     7467.000000     7424.000000     7229.000000     7266.000000     7230.000000     7304.000000     7296.000000     7545.000000     7363.000000     7274.000000     7195.000000     7213.000000     7330.000000     7260.000000     7205.000000     7205.000000     7313.000000     7289.000000     7285.000000     7233.000000     7334.000000     7385.000000     7249.000000     7250.000000     7304.000000     7274.000000     7209.000000     7229.000000     7272.000000     7217.000000     7234.000000     7186.000000     7319.000000     7301.000000     7284.000000     7398.000000     7309.000000     7201.000000     7223.000000     7189.000000     7333.000000     7300.000000     7164.000000     7272.000000     7297.000000     7181.000000     7191.000000     7196.000000     7279.000000     7418.000000     7180.000000     7215.000000     7431.000000     7153.000000     7198.000000     7138.000000     7241.000000     7244.000000     7129.000000     7176.000000     7245.000000     7182.000000     7157.000000     7399.000000     7316.000000     7280.000000     7172.000000     7155.000000     7315.000000     7147.000000     7178.000000     7136.000000     7295.000000     7209.000000     7197.000000     7194.000000     7244.000000     7352.000000     7193.000000     
diff --git a/bench/result/2012-12-19-145516_bench.res b/bench/result/2012-12-19-145516_bench.res
new file mode 100644 (file)
index 0000000..4edde57
--- /dev/null
@@ -0,0 +1,12 @@
+#kernel udp->can
+#cegwbench -s udp@127.0.0.1:10501 -d can@vcan0 -n 100 -m oneattime -t 1 
+59547.000000   9065.000000     7422.000000     7032.000000     6971.000000     6605.000000     6601.000000     6554.000000     6597.000000     6450.000000     6487.000000     6363.000000     6393.000000     6350.000000     9850.000000     6721.000000     6496.000000     6422.000000     6436.000000     6405.000000     6560.000000     6464.000000     6429.000000     6350.000000     6417.000000     6349.000000     6418.000000     6328.000000     6354.000000     6447.000000     6372.000000     6378.000000     6377.000000     6202.000000     6373.000000     6325.000000     6429.000000     6277.000000     6469.000000     6262.000000     6560.000000     6355.000000     6437.000000     6291.000000     6528.000000     6287.000000     6433.000000     6335.000000     6411.000000     6299.000000     6443.000000     6316.000000     6373.000000     6387.000000     6458.000000     6388.000000     6485.000000     6408.000000     6315.000000     6391.000000     6501.000000     6348.000000     6444.000000     6325.000000     6419.000000     6387.000000     6499.000000     6340.000000     6494.000000     6494.000000     6345.000000     6318.000000     6366.000000     6381.000000     6547.000000     6320.000000     6347.000000     6277.000000     6436.000000     6297.000000     6521.000000     6412.000000     6369.000000     6351.000000     6424.000000     6370.000000     6474.000000     6395.000000     6363.000000     6427.000000     6540.000000     6449.000000     6357.000000     6327.000000     6384.000000     6244.000000     6461.000000     6294.000000     6461.000000     6362.000000     
+#kernel can->udp
+#cegwbench -s can@vcan0 -d udp@127.0.0.1:10502 -n 100 -m oneattime -t 1 
+69080.000000   63520.000000    63814.000000    37757.000000    9887.000000     8232.000000     8300.000000     7652.000000     6789.000000     6652.000000     6698.000000     6529.000000     6267.000000     6321.000000     6790.000000     6442.000000     6528.000000     6416.000000     6547.000000     6435.000000     6405.000000     6425.000000     6468.000000     6403.000000     6361.000000     6357.000000     6553.000000     6431.000000     6645.000000     8057.000000     6912.000000     6387.000000     6464.000000     6346.000000     6367.000000     6329.000000     6335.000000     6302.000000     6535.000000     6334.000000     6347.000000     6395.000000     6663.000000     6372.000000     6424.000000     6343.000000     6372.000000     6269.000000     6281.000000     6331.000000     6479.000000     6320.000000     6422.000000     6354.000000     6385.000000     6356.000000     6701.000000     6375.000000     6415.000000     6342.000000     6413.000000     6387.000000     18412.000000    6437.000000     6334.000000     6411.000000     6500.000000     6394.000000     6427.000000     6266.000000     6720.000000     6337.000000     6309.000000     6356.000000     6475.000000     6365.000000     6355.000000     6312.000000     6413.000000     6361.000000     6371.000000     6262.000000     6387.000000     6274.000000     6582.000000     6443.000000     6562.000000     6401.000000     6441.000000     6366.000000     6474.000000     6390.000000     6435.000000     6353.000000     6466.000000     6379.000000     6335.000000     6398.000000     6765.000000     6376.000000     
+#user udp->can
+#cegwbench -s udp@127.0.0.1:10501 -d can@vcan0 -n 100 -m oneattime -t 1 
+41618.000000   36407.000000    35293.000000    9200.000000     24647.000000    7293.000000     7353.000000     7318.000000     7175.000000     7214.000000     7120.000000     7211.000000     7200.000000     7197.000000     7195.000000     7391.000000     7075.000000     7117.000000     7262.000000     7077.000000     7144.000000     7051.000000     7236.000000     7079.000000     7216.000000     7115.000000     7127.000000     7072.000000     15639.000000    7442.000000     7379.000000     7152.000000     7062.000000     7123.000000     7272.000000     7211.000000     7214.000000     7180.000000     7124.000000     7087.000000     7101.000000     7105.000000     7155.000000     7230.000000     7116.000000     7299.000000     7159.000000     7150.000000     7169.000000     7093.000000     7231.000000     7080.000000     7147.000000     7113.000000     7173.000000     7100.000000     7195.000000     7086.000000     7086.000000     7132.000000     7350.000000     7216.000000     7202.000000     7111.000000     7100.000000     7100.000000     7259.000000     7066.000000     7113.000000     7064.000000     7129.000000     7056.000000     7125.000000     7108.000000     7048.000000     7293.000000     7104.000000     7170.000000     7222.000000     7090.000000     7088.000000     7104.000000     7218.000000     7065.000000     7185.000000     7044.000000     7145.000000     7052.000000     7116.000000     7141.000000     7296.000000     7144.000000     7093.000000     7092.000000     7193.000000     7065.000000     7151.000000     7083.000000     7192.000000     7073.000000     
+#user can->udp
+#cegwbench -s can@vcan0 -d udp@127.0.0.1:10502 -n 100 -m oneattime -t 1 
+88044.000000   85226.000000    84115.000000    41538.000000    20492.000000    19123.000000    7781.000000     7336.000000     7294.000000     7539.000000     7289.000000     7289.000000     7244.000000     7452.000000     7492.000000     7360.000000     7263.000000     7424.000000     10021.000000    7598.000000     7299.000000     7467.000000     7424.000000     7229.000000     7266.000000     7230.000000     7304.000000     7296.000000     7545.000000     7363.000000     7274.000000     7195.000000     7213.000000     7330.000000     7260.000000     7205.000000     7205.000000     7313.000000     7289.000000     7285.000000     7233.000000     7334.000000     7385.000000     7249.000000     7250.000000     7304.000000     7274.000000     7209.000000     7229.000000     7272.000000     7217.000000     7234.000000     7186.000000     7319.000000     7301.000000     7284.000000     7398.000000     7309.000000     7201.000000     7223.000000     7189.000000     7333.000000     7300.000000     7164.000000     7272.000000     7297.000000     7181.000000     7191.000000     7196.000000     7279.000000     7418.000000     7180.000000     7215.000000     7431.000000     7153.000000     7198.000000     7138.000000     7241.000000     7244.000000     7129.000000     7176.000000     7245.000000     7182.000000     7157.000000     7399.000000     7316.000000     7280.000000     7172.000000     7155.000000     7315.000000     7147.000000     7178.000000     7136.000000     7295.000000     7209.000000     7197.000000     7194.000000     7244.000000     7352.000000     7193.000000     
index fc660d7438d26e143402cc885ea922d32d882343..c1782a5a04747d352b6acaacf0037c4661b17f28 100644 (file)
@@ -33,7 +33,6 @@ static int cegw_udp_send(struct socket *udp_sock, struct can_frame *cf, struct s
        vec.iov_base = cf;
        vec.iov_len = sizeof(*cf);
 
-       /* FIXME: Convert endianing of cf->can_id */
        err = kernel_sendmsg(udp_sock, &mh, &vec, 1, sizeof(*cf));
 
        return err;
@@ -85,7 +84,7 @@ static int cegw_udp2can(void *data)
                if (ret < 1)
                        break;
 
-               /* FIXME: Convert endianing of cf.can_id */
+               cf.can_id = be32_to_cpu(cf.can_id);
                cegw_can_send(can_sock, &cf);
        }
 
@@ -121,6 +120,7 @@ static int cegw_can2udp(void* data)
                if (ret < 1)
                        break;
 
+               cf.can_id = cpu_to_be32(cf.can_id);
                for (i=0; i<job->udp_dstcnt; i++) {
                        cegw_udp_send(udp_sock, &cf, &job->udp_dst[i]);
                }
index 07a7030ee264fd11701a2a173f7830b0ce1383cb..51de5ca6d24bf07464ee59a05ab52b23cca72445 100644 (file)
@@ -1,3 +1,5 @@
 all:
        gcc -Wall -ocegwbench -I../common/include -lrt cegwbench.c ../common/readif.c ../common/cegwerr.c
+debug:
+       gcc -Wall -ocegwbench -DBENCH_DEBUG -I../common/include -lrt cegwbench.c ../common/readif.c ../common/cegwerr.c
 
index 61fde292f03689f768ef1a3a613d3ada26727054..5785d4094873e9cb65fcda106ac4f9bc9e4835ca 100644 (file)
@@ -84,7 +84,9 @@ void* thr_recv( void* arg )
                        puts( "cegwbench: recv timed out\n" );
                        return (void*)1;
                }
-               seq = *((int*)cf.data);
+               memcpy( &seq, cf.data, sizeof(seq) );
+               printdbg( "recv can_data=%i", seq );
+
                clock_gettime( CLOCK_REALTIME, &rx_time[ seq ] );
                printdbg( "recv: cf.data=%d\n", seq );
                if( d.mode == BENCH_MODE_ONEATTIME )
@@ -158,7 +160,7 @@ int can_sock_create( int ifindex )
 
        addr_can.can_family = AF_CAN;
        addr_can.can_ifindex = ifindex;
-       
+
        can_sock = socket( PF_CAN, SOCK_RAW, CAN_RAW );
        if( can_sock < 0 )
        {
@@ -184,7 +186,7 @@ void dump_arg( int argc, char* argv[] )
        {
                printf( "%s ", argv[i] );
        }
-       putchar( '\n' );        
+       putchar( '\n' );
 }
 
 int read_mode( char* in )
@@ -339,7 +341,7 @@ int main( int argc, char* argv[] )
        /* send  */
        for( i=0; i<d.n; i++ )
        {
-               cf.can_id = i;
+               cf.can_id = 0;
                cf.can_dlc = sizeof(i);
                memcpy( cf.data, &i, sizeof(i) );