#!/usr/bin/env perl
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
## Initialization
use strict;
use warnings;
use warnings (exists $ENV{NOVABOOT_TEST} ?
(FATAL => 'all') :
(FATAL => qw(inplace))); # Open warnings in <<>> are fatal
use Getopt::Long qw(GetOptionsFromString GetOptionsFromArray);
use Pod::Usage;
use File::Basename;
use File::Spec;
use File::Path qw(make_path);
use IO::Handle;
use Time::HiRes("usleep");
use Socket;
use FileHandle;
use IPC::Open2;
use POSIX qw(:errno_h sysconf);
use Cwd qw(getcwd abs_path);
use Expect;
# always flush
$| = 1;
my $invocation_dir = $ENV{PWD} || getcwd();
# We prefer using PWD, to use nicer paths names with symbolic links.
# However, when executed from 'make -C dir', PWD may contain the make
# invocation path, not the real invocation path with dir at the end.
# We fix that here.
if (abs_path($ENV{PWD}) ne abs_path(getcwd())) {
$invocation_dir = getcwd();
}
## Configuration file handling
# Default configuration
$CFG::hypervisor = "";
$CFG::hypervisor_params = "serial";
$CFG::genisoimage = "genisoimage";
$CFG::qemu = 'qemu-system-i386 -cpu coreduo -smp 2';
$CFG::default_target = '';
$CFG::netif = 'eth0';
%CFG::targets = (
'qemu' => '--qemu',
"tud" => '--copy=erwin.inf.tu-dresden.de:~sojka/boot/novaboot --rsync-flags="--chmod=Dg+s,ug+w,o-w,+rX --rsync-path=\"umask 002 && rsync\"" --grub --grub-prefix=(nd)/tftpboot/sojka/novaboot --grub-preamble="timeout 0" --concat --iprelay=141.76.48.80:2324 --scriptmod=s/\\\\bhostserial\\\\b/hostserialpci/g',
"novabox" => '--ssh=novabox@rtime.felk.cvut.cz',
"localhost" => '--scriptmod=s/console=tty[A-Z0-9,]+// --copy=/boot/novaboot/$NAME --grub2 --grub-prefix=/boot/novaboot/$NAME --grub2-prolog=" set root=\'(hd0,msdos1)\'"',
"ryu" => '--uboot --uboot-init="mw f0000b00 \${psc_cfg}; sleep 1" --uboot-addr kernel=800000 --uboot-addr ramdisk=b00000 --uboot-addr fdt=7f0000',
"ryuglab" => '--target ryu --ssh=ryu@pc-sojkam.felk.cvut.cz',
"ryulocal" => '--target ryu --dhcp-tftp --serial --reset-cmd="if which dtrrts; then dtrrts $NB_SERIAL 0 1; sleep 0.1; dtrrts $NB_SERIAL 1 1; fi"',
);
{
my %const;
$const{linux}->{_SC_NPROCESSORS_CONF} = 83;
my $nproc = sysconf($const{$^O}->{_SC_NPROCESSORS_CONF});
$CFG::scons = "scons -j$nproc";
$CFG::make = "make -j$nproc";
}
my $builddir;
sub read_config($) {
my ($cfg) = @_;
{
package CFG; # Put config data into a separate namespace
my $rc = do($cfg);
# Check for errors
if ($@) {
die("ERROR: Failure compiling '$cfg' - $@");
} elsif (! defined($rc)) {
die("ERROR: Failure reading '$cfg' - $!");
} elsif (! $rc) {
die("ERROR: Failure processing '$cfg'");
}
}
$builddir = File::Spec->rel2abs($CFG::builddir, dirname($cfg)) if defined $CFG::builddir;
print STDERR "novaboot: Read $cfg\n";
}
my @cfgs;
{
# We don't use $0 here, because it points to the novaboot itself and
# not to the novaboot script. The problem with this approach is that
# when a script is run as "novaboot