#!/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