[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [OSSTEST PATCH 2/4] Building XEN and HVM Dom0 kernel for L1 guest VM



From: "longtao.pang" <longtaox.pang@xxxxxxxxx>

This patch is used for building XEN and HVM Dom0 kernel for L1 guest VM, 
and then reboot L1 guest into xen kernel.

---
 sg-run-job                        |    1 +
 ts-nested-L1-debian-install-part2 |  364 +++++++++++++++++++++++++++++++++++++
 2 files changed, 365 insertions(+)
 create mode 100755 ts-nested-L1-debian-install-part2

diff --git a/sg-run-job b/sg-run-job
index cd8b468..a4c0de1 100755
--- a/sg-run-job
+++ b/sg-run-job
@@ -291,6 +291,7 @@ proc run-job/test-pair {} {
 proc need-hosts/test-nested {} {return host}
 proc run-job/test-nested {} {
     run-ts . = ts-nested-L1-debian-install-part1
+    run-ts . = ts-nested-L1-debian-install-part2
 }
 
 proc test-guest-migr {g} {
diff --git a/ts-nested-L1-debian-install-part2 
b/ts-nested-L1-debian-install-part2
new file mode 100755
index 0000000..2f52edc
--- /dev/null
+++ b/ts-nested-L1-debian-install-part2
@@ -0,0 +1,364 @@
+#!/usr/bin/perl -w
+# This is part of "osstest", an automated testing framework for Xen.
+# Copyright (C) 2009-2013 Citrix Inc.
+# Copyright (C) 2014 Intel Inc.
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+# 
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+use strict qw(vars);
+use DBI;
+use Osstest;
+use Osstest::Debian;
+use Osstest::TestSupport;
+
+tsreadconfig();
+
+our ($whhost,$gn)= @ARGV;
+$whhost ||= 'host';
+$gn ||= 'nested';
+
+our $ho= selecthost($whhost);
+our $gho;
+our $nested_L2;
+
+my %distpath;
+sub guest_packages () {
+    target_install_packages($gho,
+                            qw(bridge-utils vncsnapshot libaio1 libpixman-1-0
+                               libsdl1.2debian libglib2.0-0 liblzma5 vim));
+    target_install_packages($gho,
+                           $ho->{Suite} =~ /squeeze/ ? "libyajl1" : 
"libyajl2");       #we always let L1 same as L0
+    if ($ho->{Suite} !~ m/lenny|squeeze/) {
+        target_install_packages($gho, 'libfdt1');
+    }
+    if ($r{arch} eq 'i386') {
+       target_install_packages($gho, 'libc6-xen');
+    }
+    target_install_packages($gho, @{toolstack()->{ExtraPackages}})
+        if toolstack()->{ExtraPackages};
+}
+
+sub guest_extract () {
+    my @parts = ('', 'kern', 'xen');
+    push @parts, 'libvirt' if $r{toolstack} eq "libvirt";
+
+    foreach my $part (@parts) {
+        target_extract_jobdistpath($gho, $part, "path_${part}dist",
+                                  $r{"${part}buildjob"}, \%distpath);
+    }
+    target_cmd_root($gho, '/sbin/ldconfig');
+}
+
+sub guest_adjustconfig () {
+    target_editfile_root($gho, "/etc/xen/xend-config.sxp",
+                        "xend-config.sxp", sub {
+       my (@domains) = (qw(localhost localhost.localdomain),
+                        ".".$c{DnsDomain}, ".".$c{TestHostDomain});
+       logm("relocation domains: @domains");
+       foreach (@domains) {
+           s/\./\\$&/g;
+           s/^/^/g;
+           s/$/\$/g;
+           s/^\^(\\\.)/.\*$1/;
+       }
+       $_= join ' ', @domains;
+       s/[\'\\]/\\$&/g;
+       my $extra= "(xend-relocation-hosts-allow '$_')";
+       logm("relocation setting: $extra");
+       $extra .= "\n";
+        while (<EI>) {
+           s/^\s*\(xend-relocation-hosts-allow/#$&/;
+           print EO or die $!;
+           if (m/^\#\(xend-relocation-hosts-allow/) {
+               print EO $extra or die $!;
+               $extra= '';
+           }
+       }
+       print EO $extra or die $!;
+    }) if toolstack()->{Name} eq "xend";
+
+    my $trace_config_file;
+    foreach my $try (qw(/etc/default/xencommons
+                        /etc/sysconfig/xencommons
+                        /etc/default/xend
+                        /etc/sysconfig/xend)) {
+        next unless target_file_exists_root($gho, $try);
+        $trace_config_file= $try;
+        last;
+    }
+    die unless defined $trace_config_file;
+
+    target_editfile_root($gho, $trace_config_file, sub {
+        my $prnow;
+        $prnow= sub {
+            print EO "XENCONSOLED_TRACE=guest\n" or die $!;
+            $prnow= sub { };
+        };
+        while (<EI>) {
+            print EO or die $! unless m/^XENCONSOLED_TRACE/;
+            $prnow->() if m/^#XENCONSOLED_TRACE/;
+        }
+        print EO "\n" or die $!;
+        $prnow->();
+    });
+
+    target_cmd_root($gho, 'mkdir -p /var/log/xen/console');
+
+}
+
+=begin
+sub guest_setupboot () {
+    my $xenhopt= "conswitch=x watchdog";
+
+    my $cons= get_host_property($gho, 'XenSerialConsole', 'com1');
+
+    if ( $cons eq "com1" ) {
+       $xenhopt .= " com1=$c{Baud},8n1 console=com1,vga gdb=com1";
+    } elsif ( $cons eq "dtuart" ) {
+       $xenhopt .= " console=dtuart";
+       my $dtuart= get_host_property($gho, 'XenDTUARTPath', undef);
+       $xenhopt .= " dtuart=$dtuart" if $dtuart;
+    } else {
+       logm("No Xen console device defined for L1 Xen");
+    }
+    if (toolstack()->{Dom0MemFixed}) {
+        $xenhopt .= " dom0_mem=1G,max:1G";
+    }
+    my $append= $r{xen_boot_append};
+    $xenhopt .= " $append" if defined $append;
+    $append = get_host_property($gho, 'xen-commandline-append', undef);
+    $xenhopt .= " $append" if defined $append;
+    my @hooks;
+                host_get_pcipassthrough_devs($ho);
+                logm("pci passthrough: hiding in dom0: $hide");
+                $$kopt .= $hide;
+            }
+        };
+    }
+
+    my $want_kernver = get_runvar('kernel_ver',$r{'kernbuildjob'});
+    debian_boot_setup($gho, $want_kernver, $xenhopt, \%distpath);
+
+    logm("ready to boot L1 Xen");
+}
+=end
+=cut
+
+sub setupboot_L1_grub ($$$) {
+    my ($ho,$want_kernver,$xenhopt,$xenkopt) = @_;
+    my $bl= { };
+    my $rmenu= '/boot/grub/grub.cfg';
+    my $kernkey= (defined $xenhopt ? 'KernDom0' : 'KernOnly');
+    my $parsemenu= sub {
+        my $f= bl_getmenu_open($ho, $rmenu, "$stash/$ho->{Name}--grub.cfg.1");
+    
+        my $count= 0;
+        my $entry;
+       my $submenu;
+        while (<$f>) {
+            next if m/^\s*\#/ || !m/\S/;
+            if (m/^\s*\}\s*$/) {
+                die unless $entry || $submenu;
+               if(!defined $entry && defined $submenu){
+                   logm("Met end of a submenu starting from 
$submenu->{StartLine}. Our want kern is $want_kernver");
+                   $submenu=undef;
+                   next;
+               }
+                my (@missing) =
+                    grep { !defined $entry->{$_} }  (defined $xenhopt ? 
qw(Title Hv KernDom0 KernVer) : qw(Title Hv KernOnly KernVer));
+               if (@missing) {
+                   logm("(skipping entry at $entry->{StartLine};".
+                        " no @missing)");
+               } elsif (defined $want_kernver &&
+                        $entry->{KernVer} ne $want_kernver) {
+                   logm("(skipping entry at $entry->{StartLine};".
+                        " kernel $entry->{KernVer}, not $want_kernver)");
+               } else {
+                   # yes!
+                   last;
+               }
+                $entry= undef;
+                next;
+            }
+            if (m/^function.*\{/) {
+                $entry= { StartLine => $. };
+            }
+            if (m/^menuentry\s+[\'\"](.*)[\'\"].*\{\s*$/) {
+                die $entry->{StartLine} if $entry;
+                $entry= { Title => $1, StartLine => $., Number => $count };
+                $count++;
+            }
+                       if(m/^submenu\s+[\'\"](.*)[\'\"].*\{\s*$/){
+                               $submenu={ StartLine =>$.};
+                       }
+            if (m/^\s*multiboot\s*(?:\/boot)*\/(xen\S+)/) {
+                die unless $entry;
+                $entry->{Hv}= $1;
+            }
+            if (m/^\s*multiboot\s*(?:\/boot)*\/(vmlinu[xz]-(\S+))/) {
+                die unless $entry;
+                $entry->{KernOnly}= $1;
+                $entry->{KernVer}= $2;
+            }
+            if (m/^\s*module\s*(?:\/boot)*\/(vmlinu[xz]-(\S+))/) {
+                die unless $entry;
+                $entry->{KernDom0}= $1;
+                $entry->{KernVer}= $2;
+            }
+            if (m/^\s*module\s*(?:\/boot)*\/(initrd\S+)/) {
+                $entry->{Initrd}= $1;
+            }
+        }
+        die 'grub 2 bootloader entry not found' unless $entry;
+
+        die unless $entry->{Title};
+
+        logm("boot check: grub2, found $entry->{Title}");
+
+       die unless $entry->{$kernkey};
+       if (defined $xenhopt) {
+           die unless $entry->{Hv};
+       }
+
+        return $entry;
+    };
+
+
+    $bl->{UpdateConfig}= sub {
+       my ( $ho ) = @_;
+       target_cmd_root($ho, "update-grub");
+    };
+
+    $bl->{GetBootKern}= sub { return $parsemenu->()->{$kernkey}; };
+
+    $bl->{PreFinalUpdate}= sub {
+        my $entry= $parsemenu->();
+        
+        target_editfile_root($ho, '/etc/default/grub', sub {
+            my %k;
+            while (<::EI>) {
+                next if m/^GRUB_DEFAULT/;
+                print ::EO;
+            }
+            print ::EO <<END or die $!;
+
+GRUB_DEFAULT=$entry->{Number}
+END
+        });
+    };
+
+    return $bl;
+}
+
+our $initscripts_nobridge;
+sub guest_setupinitd () {
+    my $ts= toolstack();
+    my $xencommons= '/etc/init.d/xencommons';
+    my $have_xencommons=
+        !!target_cmd_output_root($gho, <<END);
+   if test -f $xencommons && ! grep 'FOR USE WITH LIBXL' $xencommons >/dev/null
+   then
+   echo y
+   fi
+END
+    $initscripts_nobridge= !defined($ts->{OldDaemonInitd}) || $have_xencommons;
+    logm("init.d scripts ".
+         ($initscripts_nobridge
+          ? 'do not mess with bridge, doing it in interfaces(5)'
+          : '_do_ mess with bridge, letting them handle it'));
+    my $cmd= '';
+    my $updatercd= sub {
+        my ($script,$start) = @_;
+        $cmd .= "\n    update-rc.d $script start $start 2 .";
+    };
+    if ($initscripts_nobridge) {
+        my $script= $have_xencommons ? 'xencommons' : 'xenlightdaemons';
+        $updatercd->($script,92);
+        my $pri= 93;
+        foreach my $d (@{ $ts->{NewDaemons} }) {
+            $updatercd->("$d",$pri);
+            $pri++;
+        }
+    } else {
+        my $initd= $ts->{OldDaemonInitd};
+        $updatercd->($initd,93) if defined $initd;
+        $updatercd->('xenbridge',38) if $ts->{OldSeparateBridgeInitd};
+    }
+    target_cmd_root($gho, $cmd);
+}
+
+sub bl_getmenu_open ($$$) {
+    my ($ho, $rmenu, $lmenu) = @_;
+    target_getfile($ho, 60, $rmenu, $lmenu);
+    my $f= new IO::File $lmenu, 'r' or die "$lmenu $?";
+    return $f;
+}
+
+sub setup_l1_bridge($)
+{
+    my ($ho)=@_;
+    my $bridge_port;
+    my $route_output=target_cmd_output_root($ho,"route -n");
+    foreach my $line (split /\n/, $route_output){
+        if($line =~ m/^\s*(?:(?:0\.0\.0\.0)|default).*\s(\w+)\s*$/ai){
+            $bridge_port=$1;
+            logm("get L1 bridge phy port $bridge_port");
+            last;
+        }
+    }
+        die "cannot find L1 port for xenbr0 bridge" if !defined $bridge_port;
+
+    target_editfile_root($ho, "/etc/network/interfaces",
+                         "etc-network-interfaces",
+                        sub {
+                            while(<EI>){
+                                
s/^\s*iface\s*$bridge_port\s*inet.*dhcp\s*$/iface $bridge_port inet 
manual\nauto xenbr0\niface xenbr0 inet dhcp\n\tbridge_ports $bridge_port\n/;
+                                s/^\s*auto\s*$bridge_port/#auto\t$bridge_port/;
+                                print EO;
+                            }
+                         });
+    target_cmd_root($ho,"brctl addbr xenbr0; brctl addif xenbr0 $bridge_port; 
init 6");
+}
+
+
+$gho= selectguest($gn,$ho);
+store_runvar("$gho->{Guest}_kernkind",$r{'kernkind'});
+$gho->{Suite}=$ho->{Suite};
+
+guest_check_ip($gho);
+guest_packages();
+guest_extract();
+guest_adjustconfig();
+my $want_kernver = get_runvar('kernel_ver',$r{'kernbuildjob'});
+my $bootloader;
+$bootloader=setupboot_L1_grub($gho, $want_kernver, "");
+
+
+target_cmd_root($gho,
+                    "update-initramfs -k $want_kernver -c ||".
+                    " update-initramfs -k $want_kernver -u",
+                    200);
+$bootloader->{UpdateConfig}($gho); #so that /boot/grub/grub.cfg have new 
kernel and xen
+$bootloader->{PreFinalUpdate}();       #update /etc/default/grub, by setting 
default entry we want
+
+guest_setupinitd ();
+$bootloader->{UpdateConfig}($gho);     #use the default entry, apply it to 
/boot/grub/grub.cfg
+guest_editconfig($gho->{Host}, $gho, sub {
+        s/#nestedhvm/nestedhvm/;
+    });
+target_cmd_root($gho,"sync");
+setup_l1_bridge($gho);         #after setup L1 bridge, it will reboot for 
network settiings to take effect
+logm("ready to reboot L1 Xen");
+guest_await($gho, target_var($gho,'boot_timeout'));
+guest_check_up($gho);
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.