From 60f54f7fb2addb0bdf24defcadca42d31990c12f Mon Sep 17 00:00:00 2001 From: Mark Gurevich Date: Tue, 16 Aug 2016 20:34:15 -0400 Subject: [PATCH] Support --resize option for chvm (#1598) * Support --resize option for chvm * Handle generic error from libvirt when resizing VM * Improve finding the disk to resize --- .../admin-guides/references/man1/chvm.1.rst | 18 ++++-- xCAT-client/pods/man1/chvm.1.pod | 14 +++-- xCAT-server/lib/xcat/plugins/kvm.pm | 60 ++++++++++++++++++- 3 files changed, 80 insertions(+), 12 deletions(-) diff --git a/docs/source/guides/admin-guides/references/man1/chvm.1.rst b/docs/source/guides/admin-guides/references/man1/chvm.1.rst index 056aa31e3..bd81a7f17 100644 --- a/docs/source/guides/admin-guides/references/man1/chvm.1.rst +++ b/docs/source/guides/admin-guides/references/man1/chvm.1.rst @@ -62,7 +62,7 @@ VMware/KVM specific: ==================== -\ **chvm**\ \ *noderange*\ [\ **-a**\ \ *size*\ ] [\ **-d**\ \ *disk*\ ] [\ **-p**\ \ *disk*\ ] [\ **-**\ **-resize**\ \ **disk**\ =\ *size*\ ] [\ **-**\ **-cpus**\ \ *count*\ ] [\ **-**\ **-mem**\ \ *memory*\ ] +\ **chvm**\ \ *noderange*\ [\ **-a**\ \ *size*\ ] [\ **-d**\ \ *disk*\ ] [\ **-p**\ \ *disk*\ ] [\ **-**\ **-resize**\ \ *disk*\ =\ *size*\ ] [\ **-**\ **-cpus**\ \ *count*\ ] [\ **-**\ **-mem**\ \ *memory*\ ] zVM specific: @@ -318,7 +318,7 @@ VMware/KVM specific: \ **-d**\ \ *disk*\ - Deregister the Hard disk but leave the backing files. Multiple can be done with comma separated values. The disks are specified by SCSI id. Size defaults to GB. + Deregister the Hard disk but leave the backing files. Multiple can be done with comma separated values. The disks are specified by SCSI id. @@ -330,13 +330,13 @@ VMware/KVM specific: \ **-p**\ \ *disk*\ - Purge the Hard disk. Deregisters and deletes the files. Multiple can be done with comma separated values. The disks are specified by SCSI id. Size defaults to GB. + Purge the Hard disk. Deregisters and deletes the files. Multiple can be done with comma separated values. The disks are specified by SCSI id. -\ **-**\ **-resize**\ \ **disk**\ =\ *size*\ +\ **-**\ **-resize**\ \ *disk*\ =\ *size*\ - Change the size of the Hard disk. The disk can never be set to less than it's current size. Multiple disks can be resized to \ *size*\ by using comma separated values on the left side of \ **=**\ . The disks are specified by SCSI id. Size defaults to GB. + Change the size of the Hard disk. The disk in \ *qcow2*\ format can not be set to less than it's current size. The disk in \ *raw*\ format can be resized smaller, please use caution. Multiple disks can be resized by using comma separated \ *disk*\ \ **=**\ \ *size*\ pairs. The disks are specified by SCSI id. Size defaults to GB. @@ -976,6 +976,14 @@ Output is similar to: gpok3: Replacing user entry of LNX3... Done +8. To resize virtual machine's disk sdb to 10G and sdc to 15G: + + +.. code-block:: perl + + chvm gpok3 --resize sdb=10G,sdc=15G + + ***** diff --git a/xCAT-client/pods/man1/chvm.1.pod b/xCAT-client/pods/man1/chvm.1.pod index 4a52a7a38..615ec1fca 100644 --- a/xCAT-client/pods/man1/chvm.1.pod +++ b/xCAT-client/pods/man1/chvm.1.pod @@ -38,7 +38,7 @@ B I [B<--devdetach> I...] =head2 VMware/KVM specific: -B I [B<-a> I] [B<-d> I] [B<-p> I] [B<--resize> B=I] [B<--cpus> I] [B<--mem> I] +B I [B<-a> I] [B<-d> I] [B<-p> I] [B<--resize> I=I] [B<--cpus> I] [B<--mem> I] =head2 zVM specific: @@ -236,7 +236,7 @@ Set the number of CPUs. =item B<-d> I -Deregister the Hard disk but leave the backing files. Multiple can be done with comma separated values. The disks are specified by SCSI id. Size defaults to GB. +Deregister the Hard disk but leave the backing files. Multiple can be done with comma separated values. The disks are specified by SCSI id. =item B<--mem> I @@ -244,11 +244,11 @@ Set the memory, defaults to MB. =item B<-p> I -Purge the Hard disk. Deregisters and deletes the files. Multiple can be done with comma separated values. The disks are specified by SCSI id. Size defaults to GB. +Purge the Hard disk. Deregisters and deletes the files. Multiple can be done with comma separated values. The disks are specified by SCSI id. -=item B<--resize> B=I +=item B<--resize> I=I -Change the size of the Hard disk. The disk can never be set to less than it's current size. Multiple disks can be resized to I by using comma separated values on the left side of B<=>. The disks are specified by SCSI id. Size defaults to GB. +Change the size of the Hard disk. The disk in I format can not be set to less than it's current size. The disk in I format can be resized smaller, please use caution. Multiple disks can be resized by using comma separated IB<=>I pairs. The disks are specified by SCSI id. Size defaults to GB. =back @@ -640,6 +640,10 @@ Output is similar to: gpok3: Replacing user entry of LNX3... Done +8. To resize virtual machine's disk sdb to 10G and sdc to 15G: + + chvm gpok3 --resize sdb=10G,sdc=15G + =head1 FILES /opt/xcat/bin/chvm diff --git a/xCAT-server/lib/xcat/plugins/kvm.pm b/xCAT-server/lib/xcat/plugins/kvm.pm index d0d8eab11..32b73c72a 100755 --- a/xCAT-server/lib/xcat/plugins/kvm.pm +++ b/xCAT-server/lib/xcat/plugins/kvm.pm @@ -1807,7 +1807,7 @@ sub rmvm { sub chvm { shift; my @addsizes; - my %resize; + my $resize; my $cpucount; my @purge; my @derefdisks; @@ -1831,7 +1831,7 @@ sub chvm { "eject" => \$eject, "cpus|cpu=s" => \$cpucount, "p=s" => \@purge, - "resize=s%" => \%resize, + "resize=s" => \$resize, "cpupin=s" => \$pcpuset, "membind=s" => \$numanodeset, "devpassthru=s" => \$passthrudevices, @@ -2096,6 +2096,62 @@ sub chvm { $updatetable->{kvm_nodedata}->{$node}->{xml} = $vmxml; } } + if ($resize) { + my $shrinking_not_supported = "qcow2 doesn't support shrinking images yet"; + # Get a list of disk=size pairs + my @resize_disks = split(/,/, $resize); + for my $single_disk (@resize_disks) { + # For each comma separated disk, get disk name and the size to change it to + my ($disk_to_resize, $value) = split(/=/, $single_disk); + if ($disk_to_resize) { + unless (exists $useddisks{$disk_to_resize}) { + # Disk name given does not match any disks for this vm + xCAT::SvrUtils::sendmsg([ 1, "Disk $disk_to_resize does not exist" ], $callback, $node); + next; + } + # Get desired (new) disk size + $value = getUnits($value, "G", 1); + # Now search kvm_nodedata table to find the volume for this disk + my $myxml = $parser->parse_string($vmxml); + my @alldisks = $myxml->findnodes("/domain/devices/disk"); + # Look through all the disk entries + foreach my $disknode (@alldisks) { + my $devicetype = $disknode->getAttribute("device"); + # Skip cdrom devices + if ($devicetype eq "cdrom") { next; } + # Get name of the disk + my $diskname = $disknode->findnodes('./target')->[0]->getAttribute('dev'); + # Is this a disk we were looking for to resize ? + if ($diskname eq $disk_to_resize) { + my $file = $disknode->findnodes('./source')->[0]->getAttribute('file'); + my $vol = $hypconn->get_storage_volume_by_path($file); + if ($vol) { + # Always pass RESIZE_SHRINK flag to resize(). It is required when shrinking + # the volume size and is ignored when growing volume size + eval { + $vol->resize($value, &Sys::Virt::StorageVol::RESIZE_SHRINK); + }; + if ($@) { + if ($@ =~ /$shrinking_not_supported/) { + # qcow2 does not support shrinking volumes, display more readable error + xCAT::SvrUtils::sendmsg([ 1, "Resizing disk $disk_to_resize failed, $shrinking_not_supported" ], $callback, $node); + } + else { + # some other resize error from libvirt, just display it + xCAT::SvrUtils::sendmsg([ 1, "Resizing disk $disk_to_resize failed, $@" ], $callback, $node); + } + } + else { + # success + xCAT::SvrUtils::sendmsg([ 0, "Resized disk $disk_to_resize" ], $callback, $node); + } + } + last; # Found the disk we were looking for. Go to the next disk. + } + } + } + } + } if ($cpucount or $memory) { if ($currstate eq 'on') { if ($cpucount) { xCAT::SvrUtils::sendmsg([ 1, "Hot add of cpus not supported (VM must be powered down to successfuly change)" ], $callback, $node); }