fixes xen HVM creation (this was broken by new libvirt, perhaps?)

adds xen paravirtualized guest support (requires modified pypxeboot, and modified udhcpc to work.  see forthcoming docs)


git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4661 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
cridye 2009-11-24 00:03:45 +00:00
parent 25138a3e6b
commit 20a3572b06

View File

@ -12,7 +12,6 @@ use xCAT_monitoring::monitorctrl;
use xCAT::Table;
use XML::Simple qw(XMLout);
use Thread qw(yield);
use IO::Socket;
use IO::Select;
use strict;
@ -21,6 +20,8 @@ my %vm_comm_pids;
my @destblacklist;
my $vmhash;
my $hmhash;
my $bptab;
my $bphash;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER='XML::Parser';
@ -29,7 +30,7 @@ use POSIX "WNOHANG";
use Storable qw(freeze thaw);
use IO::Select;
use IO::Handle;
use Time::HiRes qw(gettimeofday sleep);
use Time::HiRes qw(gettimeofday sleep usleep);
use xCAT::DBobjUtils;
use Getopt::Long;
use xCAT::SvrUtils;
@ -59,6 +60,7 @@ sub handled_commands {
#rspconfig => 'nodehm:mgt',
#rbootseq => 'nodehm:mgt',
#reventlog => 'nodehm:mgt',
mkinstall => 'nodehm:mgt=(xen)',
};
}
@ -71,6 +73,8 @@ my %hyphash;
my $node;
my $hmtab;
my $vmtab;
my $chaintab;
my $chainhash;
sub waitforack {
my $sock = shift;
@ -86,29 +90,37 @@ sub waitforack {
}
sub build_oshash {
my $node=shift;
my %rethash;
$rethash{type}->{content}='hvm';
$rethash{loader}->{content}='/usr/lib/xen/boot/hvmloader';
if (defined $vmhash->{$node}->[0]->{bootorder}) {
my $bootorder = $vmhash->{$node}->[0]->{bootorder};
my @bootdevs = split(/[:,]/,$bootorder);
my $bootnum = 0;
foreach (@bootdevs) {
$rethash{boot}->[$bootnum]->{dev}=$_;
$bootnum++;
}
my $is_pv = $vmhash->{$node}->[0]->{'virtflags'} =~ 'paravirt' ? 1:0;
if ( $is_pv ) {
$rethash{type}->{content}= 'linux';
} else {
$rethash{boot}->[0]->{dev}='network';
$rethash{boot}->[1]->{dev}='hd';
$rethash{type}->{content}='hvm';
$rethash{loader}->{content}='/usr/lib/xen/boot/hvmloader';
if (defined $vmhash->{$node}->[0]->{bootorder}) {
my $bootorder = $vmhash->{$node}->[0]->{bootorder};
my @bootdevs = split(/[:,]/,$bootorder);
my $bootnum = 0;
foreach (@bootdevs) {
$rethash{boot}->[$bootnum]->{dev}=$_;
$bootnum++;
}
} else {
$rethash{boot}->[0]->{dev}='network';
$rethash{boot}->[1]->{dev}='hd';
}
}
return \%rethash;
}
sub build_diskstruct {
my $node = shift;
my @returns=();
my $currdev;
my @suffixes=('a'..'z');
my $suffidx=0;
my $is_pv = $vmhash->{$node}->[0]->{'virtflags'} =~ 'paravirt' ? 1:0;
if (defined $vmhash->{$node}->[0]->{storage}) {
my $disklocs=$vmhash->{$node}->[0]->{storage};
my @locations=split /\|/,$disklocs;
@ -117,7 +129,11 @@ sub build_diskstruct {
my $diskhash;
$diskhash->{type} = 'file';
$diskhash->{device} = 'disk';
$diskhash->{target}->{dev} = 'hd'.$suffixes[$suffidx];
if ( $is_pv ) {
$diskhash->{target}->{dev} = 'xvd'.$suffixes[$suffidx];
} else {
$diskhash->{target}->{dev} = 'hd'.$suffixes[$suffidx];
}
my @disk_parts = split(/,/, $disk);
#Find host file and determine if it is a file or a block device.
@ -217,10 +233,14 @@ sub getUnits {
sub build_xmldesc {
my $node = shift;
my %xtree=();
my $is_pv = $vmhash->{$node}->[0]->{'virtflags'} =~ 'paravirt' ? 1:0;
$xtree{type}='xen';
if (! $is_pv) {
$xtree{image}='hvm';
}
$xtree{name}->{content}=$node;
$xtree{uuid}->{content}=getNodeUUID($node);
$xtree{os} = build_oshash();
$xtree{os} = build_oshash($node);
if (defined $vmhash->{$node}->[0]->{memory}) {
$xtree{memory}->{content}=getUnits($vmhash->{$node}->[0]->{memory},"M",1024);
} else {
@ -231,13 +251,22 @@ sub build_xmldesc {
$xtree{features}->{acpi}={};
$xtree{features}->{apic}={};
$xtree{features}->{content}="\n";
$xtree{devices}->{emulator}->{content}='/usr/lib64/xen/bin/qemu-dm';
$xtree{devices}->{disk}=build_diskstruct();
unless ( $is_pv ) {
$xtree{devices}->{emulator}->{content}='/usr/lib64/xen/bin/qemu-dm';
}
$xtree{devices}->{disk}=build_diskstruct($node);
$xtree{devices}->{interface}=build_nicstruct($node);
$xtree{devices}->{graphics}->{type}='vnc';
$xtree{devices}->{graphics}->{'listen'}='0.0.0.0';
$xtree{devices}->{console}->{type}='pty';
$xtree{devices}->{console}->{target}->{port}='1';
return XMLout(\%xtree,RootName=>"domain");
if ( $is_pv ) {
$xtree{bootloader}{content} = '/usr/bin/pypxeboot';
$xtree{bootloader_args}{content} = 'mac=' . $xtree{devices}{interface}[0]{mac}{address};
}
$xtree{on_poweroff}{content} = 'destroy';
$xtree{on_reboot}{content} = 'restart';
return XMLout(\%xtree,RootName=>"domain", KeyAttr=>{} );
}
sub refresh_vm {
@ -497,6 +526,7 @@ sub power {
} elsif ($subcommand eq 'off') {
if ($dom) {
$dom->destroy();
undef $dom;
} else { $retstring .= " $status_noop"; }
} elsif ($subcommand eq 'softoff') {
if ($dom) {
@ -609,7 +639,7 @@ sub preprocess_request {
my $reqcopy = {%$request};
$reqcopy->{node} = $sn->{$snkey};
$reqcopy->{'_xcatdest'} = $snkey;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
push @requests, $reqcopy;
}
@ -638,6 +668,10 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes
$mactab = xCAT::Table->new("mac",-create=>1);
$nrtab= xCAT::Table->new("noderes",-create=>1);
$machash = $mactab->getNodesAttribs($noderange,['mac']);
$chaintab = xCAT::Table->new("chain",-create=>1);
$chainhash = $chaintab->getNodesAttribs($noderange,['currstate']);
$bptab = xCAT::Table->new("bootparams",-create=>1);
$bphash = $bptab->getNodesAttribs($noderange,['kernel', 'initrd']);
}
sub process_request {
@ -703,6 +737,28 @@ sub process_request {
}
grab_table_data($noderange,$callback);
if ($command eq 'mkinstall') {
$DB::single=1;
eval {
require xCAT_plugin::anaconda;
xCAT_plugin::anaconda::mkinstall($request, $callback, $doreq);
for my $node ( @{$request->{node}} ) {
my $is_pv = $vmhash->{$node}->[0]->{'virtflags'} =~ 'paravirt' ? 1:0;
if ( $is_pv ) {
my $kernel = $bphash->{$node}[0]{kernel};
my $initrd = $bphash->{$node}[0]{initrd};
$kernel =~ s|vmlinuz|xen/vmlinuz|;
$initrd =~ s|initrd\.img|xen/initrd\.img|;
$bptab->setNodeAttribs( $node, { kernel=>$kernel, initrd=>$initrd } );
}
}
};
if ($@) {
$callback->({error=>$@,errorcode=>[1]});
}
return;
}
if ($command eq 'revacuate' or $command eq 'rmigrate') {
$vmmaxp=1; #for now throttle concurrent migrations, requires more sophisticated heuristics to ensure sanity
@ -929,7 +985,7 @@ sub forward_data {
close($rfh);
}
}
yield(); #Try to avoid useless iterations as much as possible
usleep(0); # yield
return $rc;
}
@ -960,7 +1016,7 @@ sub dohyp {
}
print $out freeze([\%err]);
print $out "\nENDOFFREEZE6sK4ci\n";
yield();
usleep(0); # yield
waitforack($out);
return 1,"General error establishing libvirt communication";
}
@ -972,7 +1028,7 @@ sub dohyp {
if (ref($_)) {
print $out freeze([$_]);
print $out "\nENDOFFREEZE6sK4ci\n";
yield();
usleep(0); # yield
waitforack($out);
next;
}
@ -992,12 +1048,13 @@ sub dohyp {
$output{node}->[0]->{errorcode} = $rc;
$output{node}->[0]->{name}->[0]=$node;
$output{node}->[0]->{data}->[0]->{contents}->[0]=$text;
$output{node}->[0]->{error} = $text unless $rc == 0;
print $out freeze([\%output]);
print $out "\nENDOFFREEZE6sK4ci\n";
yield();
usleep(0); # yield
waitforack($out);
}
yield();
usleep(0); # yield
}
#my $msgtoparent=freeze(\@outhashes); # = XMLout(\%output,RootName => 'xcatresponse');
#print $out $msgtoparent; #$node.": $_\n";