Commit 1c8032c7 authored by Leigh B Stoller's avatar Leigh B Stoller

Changes to use pygrub as boot loader.

We were using pygrub to suck the kernel and ramdisk out before
booting the guest, but doing that makes it impossible for for
the guest to change its kernel and reboot.

Other minor fixes.
parent d6db3a93
...@@ -234,7 +234,7 @@ sub restartDHCP(); ...@@ -234,7 +234,7 @@ sub restartDHCP();
sub formatDHCP($$$); sub formatDHCP($$$);
sub fixupMac($); sub fixupMac($);
sub createControlNetworkScript($$$); sub createControlNetworkScript($$$);
sub createExpNetworkScript($$$$$$$); sub createExpNetworkScript($$$$$$$$);
sub createTunnelScript($$$$); sub createTunnelScript($$$$);
sub createExpBridges($$$); sub createExpBridges($$$);
sub destroyExpBridges($$); sub destroyExpBridges($$);
...@@ -947,9 +947,8 @@ sub vnodeCreate($$$$) ...@@ -947,9 +947,8 @@ sub vnodeCreate($$$$)
ExtractKernelFromLinuxImage($vnode_id, "$VMDIR/$vnode_id"); ExtractKernelFromLinuxImage($vnode_id, "$VMDIR/$vnode_id");
if (defined($kernel)) { if (defined($kernel)) {
$image{'kernel'} = $kernel; my $usebootloader = 1;
$image{'ramdisk'} = $ramdisk;
# #
# If this is an Ubuntu ramdisk, we have to make sure it # If this is an Ubuntu ramdisk, we have to make sure it
# will boot as a XEN guest, by changing the ramdisk. YUCK! # will boot as a XEN guest, by changing the ramdisk. YUCK!
...@@ -957,9 +956,21 @@ sub vnodeCreate($$$$) ...@@ -957,9 +956,21 @@ sub vnodeCreate($$$$)
if ($imagemetadata->{'PARTOS'} =~ /ubuntu/i || if ($imagemetadata->{'PARTOS'} =~ /ubuntu/i ||
$imagename =~ /ubuntu/i || $imagename =~ /ubuntu/i ||
system("strings $kernel | grep -q -i ubuntu") == 0) { system("strings $kernel | grep -q -i ubuntu") == 0) {
if (FixRamFs($vnode_id, $ramdisk)) { my $ramres = FixRamFs($vnode_id, $ramdisk);
if ($ramres < 0) {
fatal("xen_vnodeCreate: Failed to fix ramdisk"); fatal("xen_vnodeCreate: Failed to fix ramdisk");
} }
elsif ($ramres == 0) {
# Ramfs needed to be changed, so cannot use pygrub.
$usebootloader = 0;
}
}
if ($usebootloader) {
$image{'bootloader'} = 'pygrub';
}
else {
$image{'kernel'} = $kernel;
$image{'ramdisk'} = $ramdisk;
} }
} }
# Use the booted kernel. Works sometimes. # Use the booted kernel. Works sometimes.
...@@ -1029,12 +1040,18 @@ sub vnodeCreate($$$$) ...@@ -1029,12 +1040,18 @@ sub vnodeCreate($$$$)
my $kernel = $image{'kernel'}; my $kernel = $image{'kernel'};
my $ramdisk = $image{'ramdisk'}; my $ramdisk = $image{'ramdisk'};
my $bootloader = $image{'bootloader'};
addConfig($vninfo, "# Xen configuration script for $os vnode $vnode_id", 2); addConfig($vninfo, "# Xen configuration script for $os vnode $vnode_id", 2);
addConfig($vninfo, "name = '$vnode_id'", 2); addConfig($vninfo, "name = '$vnode_id'", 2);
addConfig($vninfo, "kernel = '$kernel'", 2); if (defined($bootloader)) {
addConfig($vninfo, "ramdisk = '$ramdisk'", 2) addConfig($vninfo, "bootloader = 'pygrub'", 2);
if (defined($ramdisk)); }
else {
addConfig($vninfo, "kernel = '$kernel'", 2);
addConfig($vninfo, "ramdisk = '$ramdisk'", 2)
if (defined($ramdisk));
}
addConfig($vninfo, "disk = [" . join(",", @alldisks) . "]", 2); addConfig($vninfo, "disk = [" . join(",", @alldisks) . "]", 2);
if ($os eq "FreeBSD") { if ($os eq "FreeBSD") {
...@@ -1054,6 +1071,20 @@ sub vnodeCreate($$$$) ...@@ -1054,6 +1071,20 @@ sub vnodeCreate($$$$)
if (exists($attributes->{'VM_VCPUS'}) && $attributes->{'VM_VCPUS'} > 1) { if (exists($attributes->{'VM_VCPUS'}) && $attributes->{'VM_VCPUS'} > 1) {
addConfig($vninfo, "vcpus = " . $attributes->{'VM_VCPUS'}, 2); addConfig($vninfo, "vcpus = " . $attributes->{'VM_VCPUS'}, 2);
} }
#
# VNC console setup. Not very useful since on shared nodes there
# is no local account for the users to log in and connect to
# the port, and we definitely do not want export it since there
# is no password and no encryption. So, leave out for now.
#
if (0) {
addConfig($vninfo, "vfb = ['vnc=1,vncdisplay=$vmid,vncunused=0']", 2);
addConfig($vninfo,
"device_model_version = 'qemu-xen-traditional'", 2);
addConfig($vninfo,
"device_model_override = '/usr/lib/xen-4.3/bin/qemu-dm'",2);
}
# #
# Finish off the state transitions as necessary. # Finish off the state transitions as necessary.
...@@ -1364,7 +1395,7 @@ sub vnodePreConfigExpNetwork($$$$) ...@@ -1364,7 +1395,7 @@ sub vnodePreConfigExpNetwork($$$$)
my $tag = "$vnode_id:" . $ldinfo->{'LINKNAME'}; my $tag = "$vnode_id:" . $ldinfo->{'LINKNAME'};
my $ifb = pop(@$ifbs); my $ifb = pop(@$ifbs);
createExpNetworkScript($vmid, $interface, createExpNetworkScript($vmid, $interface, $brname,
$ldinfo, "ifb$ifb", $script, $sh, $log); $ldinfo, "ifb$ifb", $script, $sh, $log);
} }
} }
...@@ -1505,6 +1536,21 @@ sub vnodeConfigResources($$$$){ ...@@ -1505,6 +1536,21 @@ sub vnodeConfigResources($$$$){
sub vnodeConfigDevices($$$$) sub vnodeConfigDevices($$$$)
{ {
my ($vnode_id, $vmid, $vnconfig, $private) = @_; my ($vnode_id, $vmid, $vnconfig, $private) = @_;
my $vninfo = $private;
# DHCP entry...
if (exists($vninfo->{'dhcp'})) {
my $name = $vninfo->{'dhcp'}->{'name'};
my $ip = $vninfo->{'dhcp'}->{'ip'};
my $mac = $vninfo->{'dhcp'}->{'mac'};
addDHCP($name, $ip, $mac, 1) == 0
or die("libvnode_xen: vnodeBoot $vnode_id: dhcp setup error!");
}
# physical bridge devices...
if (createExpBridges($vmid, $vninfo->{'links'}, $private)) {
die("libvnode_xen: vnodeBoot $vnode_id: could not create bridges");
}
return 0; return 0;
} }
...@@ -1533,7 +1579,8 @@ sub vnodeBoot($$$$) ...@@ -1533,7 +1579,8 @@ sub vnodeBoot($$$$)
my $vninfo = $private; my $vninfo = $private;
if (!exists($vninfo->{'cffile'})) { if (!exists($vninfo->{'cffile'})) {
die("libvnode_xen: vnodeBoot $vnode_id: no essential state!?"); print STDERR "vnodeBoot $vnode_id: no essential state!\n";
return -1;
} }
# #
...@@ -1543,24 +1590,12 @@ sub vnodeBoot($$$$) ...@@ -1543,24 +1590,12 @@ sub vnodeBoot($$$$)
my $config = configFile($vnode_id); my $config = configFile($vnode_id);
if ($vninfo->{'cfchanged'}) { if ($vninfo->{'cfchanged'}) {
if (createXenConfig($config, $vninfo->{'cffile'})) { if (createXenConfig($config, $vninfo->{'cffile'})) {
die("libvnode_xen: vnodeBoot $vnode_id: could not create $config"); print STDERR "vnodeBoot $vnode_id: could not create $config\n";
return -1;
} }
} elsif (! -e $config) { } elsif (! -e $config) {
die("libvnode_xen: vnodeBoot $vnode_id: $config file does not exist!"); print STDERR "vnodeBoot $vnode_id: $config file does not exist!\n";
} return -1;
# DHCP entry...
if (exists($vninfo->{'dhcp'})) {
my $name = $vninfo->{'dhcp'}->{'name'};
my $ip = $vninfo->{'dhcp'}->{'ip'};
my $mac = $vninfo->{'dhcp'}->{'mac'};
addDHCP($name, $ip, $mac, 1) == 0
or die("libvnode_xen: vnodeBoot $vnode_id: dhcp setup error!");
}
# physical bridge devices...
if (createExpBridges($vmid, $vninfo->{'links'}, $private)) {
die("libvnode_xen: vnodeBoot $vnode_id: could not create bridges");
} }
# notify stated that we are about to boot # notify stated that we are about to boot
...@@ -1568,13 +1603,6 @@ sub vnodeBoot($$$$) ...@@ -1568,13 +1603,6 @@ sub vnodeBoot($$$$)
# and finally, create the VM # and finally, create the VM
my $status = RunWithLock("xmtool", "$XM create $config"); my $status = RunWithLock("xmtool", "$XM create $config");
# We have a problem with intermittent failures.
if ($status) {
print "Guest failure: retrying after a short wait.\n";
sleep(20);
$status = RunWithLock("xmtool", "$XM create $config");
}
if ($status) { if ($status) {
print STDERR "$XM create failed: $status\n"; print STDERR "$XM create failed: $status\n";
return -1; return -1;
...@@ -2669,9 +2697,9 @@ sub createTunnelScript($$$$) ...@@ -2669,9 +2697,9 @@ sub createTunnelScript($$$$)
return 0; return 0;
} }
sub createExpNetworkScript($$$$$$$) sub createExpNetworkScript($$$$$$$$)
{ {
my ($vmid,$ifc,$info,$ifb,$wrapper,$file,$lfile) = @_; my ($vmid,$ifc,$bridge,$info,$ifb,$wrapper,$file,$lfile) = @_;
my $TC = "/sbin/tc"; my $TC = "/sbin/tc";
if (! open(FILE, ">$wrapper")) { if (! open(FILE, ">$wrapper")) {
...@@ -2691,6 +2719,7 @@ sub createExpNetworkScript($$$$$$$) ...@@ -2691,6 +2719,7 @@ sub createExpNetworkScript($$$$$$$)
} }
print FILE "#!/bin/sh\n"; print FILE "#!/bin/sh\n";
print FILE "OP=\$1\n"; print FILE "OP=\$1\n";
print FILE "export bridge=$bridge\n";
print FILE "/etc/xen/scripts/vif-bridge \$*\n"; print FILE "/etc/xen/scripts/vif-bridge \$*\n";
print FILE "STAT=\$?\n"; print FILE "STAT=\$?\n";
print FILE "if [ \$STAT -ne 0 -o \"\$OP\" != \"online\" ]; then\n"; print FILE "if [ \$STAT -ne 0 -o \"\$OP\" != \"online\" ]; then\n";
...@@ -3726,6 +3755,7 @@ sub FixRamFs($$) ...@@ -3726,6 +3755,7 @@ sub FixRamFs($$)
my ($vnode_id, $ramfspath) = @_; my ($vnode_id, $ramfspath) = @_;
my $tempdir = "$EXTRAFS/$vnode_id/ramfs"; my $tempdir = "$EXTRAFS/$vnode_id/ramfs";
my $modules = "$EXTRAFS/$vnode_id/ramfs/conf/modules"; my $modules = "$EXTRAFS/$vnode_id/ramfs/conf/modules";
my $rval = 0;
return -1 return -1
if (-e $tempdir && mysystem2("/bin/rm -rf $tempdir")); if (-e $tempdir && mysystem2("/bin/rm -rf $tempdir"));
...@@ -3743,6 +3773,8 @@ sub FixRamFs($$) ...@@ -3743,6 +3773,8 @@ sub FixRamFs($$)
# #
if (-e $modules) { if (-e $modules) {
if (mysystem2("grep -q xen-blkfront $modules") == 0) { if (mysystem2("grep -q xen-blkfront $modules") == 0) {
# Tell caller ramfs was okay.
$rval = 1;
goto done; goto done;
} }
} }
...@@ -3752,7 +3784,7 @@ sub FixRamFs($$) ...@@ -3752,7 +3784,7 @@ sub FixRamFs($$)
if ($?); if ($?);
done: done:
mysystem2("/bin/rm -rf $tempdir"); mysystem2("/bin/rm -rf $tempdir");
return 0; return $rval;
} }
# #
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment