diff --git a/xCAT-server/lib/xcat/plugins/kvm.pm b/xCAT-server/lib/xcat/plugins/kvm.pm
index 77f750090..7f1d7ca4e 100644
--- a/xCAT-server/lib/xcat/plugins/kvm.pm
+++ b/xCAT-server/lib/xcat/plugins/kvm.pm
@@ -763,6 +763,7 @@ sub migrate {
s/=.*//;
get_storage_pool_by_url($_,$desthypconn,$targ);
}
+ #TODO: VMCLONE if vm.master is set, got to vmmaster.storage for that master and add it to prereq resolution here
}
my $sock = IO::Socket::INET->new(Proto=>'udp');
my $ipa=inet_aton($node);
@@ -857,6 +858,7 @@ sub makedom {
s/=.*//;
get_storage_pool_by_url($_);
}
+ #TODO: VMCLONE if vm.master is set, got to vmmaster.storage for that master and add it to prereq resolution here
}
$xml = $confdata->{kvmnodedata}->{$node}->[0]->{xml};
my $newxml = fixbootorder($node,$xml);
@@ -1063,6 +1065,22 @@ sub rinv {
invstorage($domain);
invnics($domain);
}
+sub get_pool_for_volume {
+#attempts to get pool for a volume, returns false on failure
+#TODO: build and use a total map of source paths to volume names. Then we could do more than just ones that end in uuid..
+ my $vol = shift;
+ my $file = $vol->get_path();
+ $file =~ m!/([^/]*)/($node\..*)\z!;
+ my $pooluuid=$1;
+ my $volname=$2;
+ my $pool;
+ my $vollocation=$file;
+ eval {
+ $pool = $hypconn->get_storage_pool_by_uuid($pooluuid);
+ };
+ return $pool;
+}
+
sub invstorage {
my $domain = shift;
my @disks = $domain->findnodes('/domain/devices/disk');
@@ -1446,6 +1464,7 @@ sub clonevm {
my $xml;
if ($dom) {
$xml = $dom->get_xml_description();
+ $detach=1; #can't rebase if vm is on
} else {
$xml = $confdata->{kvmnodedata}->{$node}->[0]->{xml};
}
@@ -1504,10 +1523,12 @@ sub clonevm {
foreach (keys %volclonemap) {
my $sourcevol = $volclonemap{$_}->[0];
my $targname = $volclonemap{$_}->[1];
+ my $format;
$targname =~ /([^\.]*)$/;
+ $format=$1;
my $newvol;
my %sourceinfo = %{$sourcevol->get_info()};
- my $targxml = "$targname".$sourceinfo{capacity}."";
+ my $targxml = "$targname".$sourceinfo{capacity}."";
xCAT::SvrUtils::sendmsg("Cloning ".$sourcevol->get_name()." (currently is ".($sourceinfo{allocation}/1048576)." MB and has a capacity of ".($sourceinfo{capacity}/1048576)."MB)",$callback,$node);
eval {
$newvol =$poolobj->clone_volume($targxml,$sourcevol);
@@ -1515,7 +1536,27 @@ sub clonevm {
if ($newvol) {
%sourceinfo = %{$newvol->get_info()};
xCAT::SvrUtils::sendmsg("Cloning of ".$sourcevol->get_name()." complete (clone uses ".($sourceinfo{allocation}/1048576)." for a disk size of ".($sourceinfo{capacity}/1048576)."MB)",$callback,$node);
- #TODO: rebase $sourcevol to have a backingStore of $newvol
+ unless ($detach) {
+ my $rebasepath = $sourcevol->get_path();
+ my $rebasename = $sourcevol->get_name();
+ my $rebasepool = get_pool_for_volume($sourcevol);
+ unless ($rebasepool) {
+ xCAT::SvrUtils::sendmsg([1,"Skipping rebase of $rebasename, unable to find correct storage pool"],$callback,$node);
+ next;
+ }
+ xCAT::SvrUtils::sendmsg("Rebasing $rebasename from master",$callback,$node);
+ $sourcevol->delete();
+ my $newbasexml="$rebasename".$sourceinfo{capacity}."".$newvol->get_path()."";
+ my $newbasevol;
+ eval {
+ $newbasevol = $rebasepool->create_volume($newbasexml);
+ };
+ if ($newbasevol) {
+ xCAT::SvrUtils::sendmsg("Rebased $rebasename from master",$callback,$node);
+ } else {
+ xCAT::SvrUtils::sendmsg([1,"Critical failure, rebasing process failed halfway through, source VM trashed"],$callback,$node);
+ }
+ }
} else {
xCAT::SvrUtils::sendmsg([1,"Cloning of ".$sourcevol->get_name()." failed due to ". $@],$callback,$node);
return;