3 # Copyright (C) 2010-2011 Red Hat Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 use Sys::Guestfs::Lib qw(feature_available);
24 use Fcntl qw(S_ISREG SEEK_SET);
29 use Locale::TextDomain 'libguestfs';
31 $Data::Dumper::Sortkeys = 1;
33 die __"virt-resize: sorry this program does not work on a 32 bit host\n"
42 virt-resize - Resize a virtual machine disk
46 virt-resize [--resize /dev/sdaN=[+/-]<size>[%]]
47 [--expand /dev/sdaN] [--shrink /dev/sdaN]
48 [--ignore /dev/sdaN] [--delete /dev/sdaN] [...] indisk outdisk
52 Virt-resize is a tool which can resize a virtual machine disk, making
53 it larger or smaller overall, and resizing or deleting any partitions
56 Virt-resize B<cannot> resize disk images in-place. Virt-resize
57 B<should not> be used on live virtual machines - for consistent
58 results, shut the virtual machine down before resizing it.
60 If you are not familiar with the associated tools:
61 L<virt-filesystems(1)> and L<virt-df(1)>, we recommend you go and read
62 those manual pages first.
66 Copy C<olddisk> to C<newdisk>, extending one of the guest's partitions
67 to fill the extra 5GB of space.
69 truncate -r olddisk newdisk; truncate -s +5G newdisk
70 virt-filesystems --long -h --all -a olddisk
71 # Note "/dev/sda2" is a partition inside the "olddisk" file.
72 virt-resize --expand /dev/sda2 olddisk newdisk
74 As above, but make the /boot partition 200MB bigger, while giving the
75 remaining space to /dev/sda2:
77 virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 olddisk newdisk
79 As above, but the output format will be uncompressed qcow2:
81 qemu-img create -f qcow2 newdisk.qcow2 15G
82 virt-resize --expand /dev/sda2 olddisk newdisk.qcow2
86 =head2 EXPANDING A VIRTUAL MACHINE DISK
90 =item 1. Shut down the virtual machine
92 =item 2. Locate input disk image
94 Locate the input disk image (ie. the file or device on the host
95 containing the guest's disk). If the guest is managed by libvirt, you
96 can use C<virsh dumpxml> like this to find the disk image name:
98 # virsh dumpxml guestname | xpath /domain/devices/disk/source
101 <source dev="/dev/vg/lv_guest" />
103 =item 3. Look at current sizing
105 Use L<virt-filesystems(1)> to display the current partitions and
108 # virt-filesystems --long --parts --blkdevs -h -a /dev/vg/lv_guest
109 Name Type Size Parent
110 /dev/sda1 partition 101M /dev/sda
111 /dev/sda2 partition 7.9G /dev/sda
112 /dev/sda device 8.0G -
114 (This example is a virtual machine with an 8 GB disk which we would
115 like to expand up to 10 GB).
117 =item 4. Create output disk
119 Virt-resize cannot do in-place disk modifications. You have to have
120 space to store the resized output disk.
122 To store the resized disk image in a file, create a file of a suitable
126 # truncate -s 10G outdisk
128 Or use L<lvcreate(1)> to create a logical volume:
130 # lvcreate -L 10G -n lv_name vg_name
132 Or use L<virsh(1)> vol-create-as to create a libvirt storage volume:
135 # virsh vol-create-as poolname newvol 10G
139 virt-resize takes two mandatory parameters, the input disk (eg. device
140 or file) and the output disk. The output disk is the one created in
143 # virt-resize indisk outdisk
145 This command just copies disk image C<indisk> to disk image C<outdisk>
146 I<without> resizing or changing any existing partitions. If
147 C<outdisk> is larger, then an extra, empty partition is created at the
148 end of the disk covering the extra space. If C<outdisk> is smaller,
149 then it will give an error.
151 More realistically you'd want to expand existing partitions in the
152 disk image by passing extra options (for the full list see the
153 L</OPTIONS> section below).
155 L</--expand> is the most useful option. It expands the named
156 partition within the disk to fill any extra space:
158 # virt-resize --expand /dev/sda2 indisk outdisk
160 (In this case, an extra partition is I<not> created at the end of the
161 disk, because there will be no unused space).
163 L</--resize> is the other commonly used option. The following would
164 increase the size of /dev/sda1 by 200M, and expand /dev/sda2
165 to fill the rest of the available space:
167 # virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 \
170 If the expanded partition in the image contains a filesystem or LVM
171 PV, then if virt-resize knows how, it will resize the contents, the
172 equivalent of calling a command such as L<pvresize(8)>,
173 L<resize2fs(8)> or L<ntfsresize(8)>. However virt-resize does not
174 know how to resize some filesystems, so you would have to online
175 resize them after booting the guest.
177 Other options are covered below.
181 Thoroughly test the new disk image I<before> discarding the old one.
183 If you are using libvirt, edit the XML to point at the new disk:
185 # virsh edit guestname
187 Change E<lt>source ...E<gt>, see
188 L<http://libvirt.org/formatdomain.html#elementsDisks>
190 Then start up the domain with the new, resized disk:
192 # virsh start guestname
194 and check that it still works. See also the L</NOTES> section below
195 for additional information.
197 =item 7. Resize LVs etc inside the guest
199 (This can also be done offline using L<guestfish(1)>)
201 Once the guest has booted you should see the new space available, at
202 least for filesystems that virt-resize knows how to resize, and for
203 PVs. The user may need to resize LVs inside PVs, and also resize
204 filesystem types that virt-resize does not know how to expand.
208 =head2 SHRINKING A VIRTUAL MACHINE DISK
210 Shrinking is somewhat more complex than expanding, and only an
211 overview is given here.
213 Firstly virt-resize will not attempt to shrink any partition content
214 (PVs, filesystems). The user has to shrink content before passing the
215 disk image to virt-resize, and virt-resize will check that the content
216 has been shrunk properly.
218 (Shrinking can also be done offline using L<guestfish(1)>)
220 After shrinking PVs and filesystems, shut down the guest, and proceed
221 with steps 3 and 4 above to allocate a new disk image.
223 Then run virt-resize with any of the C<--shrink> and/or C<--resize>
226 =head2 IGNORING OR DELETING PARTITIONS
228 virt-resize also gives a convenient way to ignore or delete partitions
229 when copying from the input disk to the output disk. Ignoring a
230 partition speeds up the copy where you don't care about the existing
231 contents of a partition. Deleting a partition removes it completely,
232 but note that it also renumbers any partitions after the one which is
233 deleted, which can leave some guests unbootable.
235 =head2 QCOW2 AND NON-SPARSE RAW FORMATS
237 If the input disk is in qcow2 format, then you may prefer that the
238 output is in qcow2 format as well. Alternately, virt-resize can
239 convert the format on the fly. The output format is simply determined
240 by the format of the empty output container that you provide. Thus to
241 create qcow2 output, use:
243 qemu-img create [-c] -f qcow2 outdisk [size]
245 instead of the truncate command (use C<-c> for a compressed disk).
247 Similarly, to get non-sparse raw output use:
249 fallocate -l size outdisk
251 (on older systems that don't have the L<fallocate(1)> command use
252 C<dd if=/dev/zero of=outdisk bs=1M count=..>)
272 Display version number and exit.
278 =item B<--resize part=size>
280 Resize the named partition (expanding or shrinking it) so that it has
283 C<size> can be expressed as an absolute number followed by
284 b/K/M/G/T/P/E to mean bytes, Kilobytes, Megabytes, Gigabytes,
285 Terabytes, Petabytes or Exabytes; or as a percentage of the current
286 size; or as a relative number or percentage. For example:
288 --resize /dev/sda2=10G
290 --resize /dev/sda4=90%
292 --resize /dev/sda2=+1G
294 --resize /dev/sda2=-200M
296 --resize /dev/sda1=+128K
298 --resize /dev/sda1=+10%
300 --resize /dev/sda1=-10%
302 You can increase the size of any partition. Virt-resize will expand
303 the direct content of the partition if it knows how (see C<--expand>
306 You can only I<decrease> the size of partitions that contain
307 filesystems or PVs which have already been shrunk. Virt-resize will
308 check this has been done before proceeding, or else will print an
309 error (see also C<--resize-force>).
311 You can give this option multiple times.
317 =item B<--resize-force part=size>
319 This is the same as C<--resize> except that it will let you decrease
320 the size of any partition. Generally this means you will lose any
321 data which was at the end of the partition you shrink, but you may not
322 care about that (eg. if shrinking an unused partition, or if you can
323 easily recreate it such as a swap partition).
325 See also the C<--ignore> option.
331 =item B<--expand part>
333 Expand the named partition so it uses up all extra space (space left
334 over after any other resize changes that you request have been done).
336 If virt-resize knows how, it will expand the direct content of the
337 partition. For example, if the partition is an LVM PV, it will expand
338 the PV to fit (like calling L<pvresize(8)>). Virt-resize leaves any
339 other content it doesn't know about alone.
341 Currently virt-resize can resize:
347 ext2, ext3 and ext4 filesystems when they are contained
348 directly inside a partition.
352 NTFS filesystems contained directly in a partition, if libguestfs was
353 compiled with support for NTFS.
355 The filesystem must have been shut down consistently last time it was
356 used. Additionally, L<ntfsresize(8)> marks the resized filesystem as
357 requiring a consistency check, so at the first boot after resizing
358 Windows will check the disk.
362 LVM PVs (physical volumes). virt-resize does not usually resize
363 anything inside the PV, but see the C<--LV-expand> option. The user
364 could also resize LVs as desired after boot.
368 Note that you cannot use C<--expand> and C<--shrink> together.
374 =item B<--shrink part>
376 Shrink the named partition until the overall disk image fits in the
377 destination. The named partition B<must> contain a filesystem or PV
378 which has already been shrunk using another tool (eg. L<guestfish(1)>
379 or other online tools). Virt-resize will check this and give an error
380 if it has not been done.
382 The amount by which the overall disk must be shrunk (after carrying
383 out all other operations requested by the user) is called the
384 "deficit". For example, a straight copy (assume no other operations)
385 from a 5GB disk image to a 4GB disk image results in a 1GB deficit.
386 In this case, virt-resize would give an error unless the user
387 specified a partition to shrink and that partition had more than a
388 gigabyte of free space.
390 Note that you cannot use C<--expand> and C<--shrink> together.
396 =item B<--ignore part>
398 Ignore the named partition. Effectively this means the partition is
399 allocated on the destination disk, but the content is not copied
400 across from the source disk. The content of the partition will be
401 blank (all zero bytes).
403 You can give this option multiple times.
409 =item B<--delete part>
411 Delete the named partition. It would be more accurate to describe
412 this as "don't copy it over", since virt-resize doesn't do in-place
413 changes and the original disk image is left intact.
415 Note that when you delete a partition, then anything contained in the
416 partition is also deleted. Furthermore, this causes any partitions
417 that come after to be I<renumbered>, which can easily make your guest
420 You can give this option multiple times.
426 =item B<--LV-expand logvol>
428 This takes the logical volume and, as a final step, expands it to fill
429 all the space available in its volume group. A typical usage,
430 assuming a Linux guest with a single PV C</dev/sda2> and a root device
431 called C</dev/vg_guest/lv_root> would be:
433 virt-resize indisk outdisk \
434 --expand /dev/sda2 --LV-expand /dev/vg_guest/lv_root
436 This would first expand the partition (and PV), and then expand the
437 root device to fill the extra space in the PV.
439 The contents of the LV are also resized if virt-resize knows how to do
440 that. You can stop virt-resize from trying to expand the content by
441 using the option C<--no-expand-content>.
443 Use L<virt-filesystems(1)> to list the filesystems in
446 You can give this option multiple times, I<but> it doesn't
447 make sense to do this unless the logical volumes you specify
448 are all in different volume groups.
452 my $copy_boot_loader = 1;
454 =item B<--no-copy-boot-loader>
456 By default, virt-resize copies over some sectors at the start of the
457 disk (up to the beginning of the first partition). Commonly these
458 sectors contain the Master Boot Record (MBR) and the boot loader, and
459 are required in order for the guest to boot correctly.
461 If you specify this flag, then this initial copy is not done. You may
462 need to reinstall the boot loader in this case.
466 my $extra_partition = 1;
467 my $min_extra_partition = 10 * 1024 * 1024; # see below
469 =item B<--no-extra-partition>
471 By default, virt-resize creates an extra partition if there is any
472 extra, unused space after all resizing has happened. Use this option
473 to prevent the extra partition from being created. If you do this
474 then the extra space will be inaccessible until you run fdisk, parted,
475 or some other partitioning tool in the guest.
477 Note that if the surplus space is smaller than 10 MB, no extra
478 partition will be created.
482 my $expand_content = 1;
484 =item B<--no-expand-content>
486 By default, virt-resize will try to expand the direct contents
487 of partitions, if it knows how (see C<--expand> option above).
489 If you give the C<--no-expand-content> option then virt-resize
490 will not attempt this.
496 =item B<-d> | B<--debug>
498 Enable debugging messages.
504 =item B<-n> | B<--dryrun>
506 Print a summary of what would be done, but don't do anything.
512 =item B<-q> | B<--quiet>
514 Don't print the summary.
520 =item B<--format> raw
522 Specify the format of the input disk image. If this flag is not
523 given then it is auto-detected from the image itself.
525 If working with untrusted raw-format guest disk images, you should
526 ensure the format is always specified.
528 Note that this option I<does not> affect the output format.
529 See L</QCOW2 AND NON-SPARSE RAW FORMATS>.
535 =item B<--output-format> raw
537 Specify the format of the output disk image. If this flag is not
538 given then it is auto-detected from the image itself.
540 If working with untrusted raw-format guest disk images, you should
541 ensure the format is always specified.
543 Note that you still need to create the output disk with the right
544 format. See L</QCOW2 AND NON-SPARSE RAW FORMATS>.
550 GetOptions ("help|?" => \$help,
551 "version" => \$version,
552 "resize=s" => \@resize,
553 "resize-force=s" => \@resize_force,
554 "expand=s" => \$expand,
555 "shrink=s" => \$shrink,
556 "ignore=s" => \@ignore,
557 "delete=s" => \@delete,
558 "lv-expand=s" => \@lv_expand,
559 "copy-boot-loader!" => \$copy_boot_loader,
560 "extra-partition!" => \$extra_partition,
561 "expand-content!" => \$expand_content,
562 "d|debug" => \$debug,
563 "n|dryrun|dry-run" => \$dryrun,
564 "q|quiet" => \$quiet,
565 "format=s" => \$format,
566 "output-format=s" => \$output_format,
568 pod2usage (1) if $help;
570 my $g = Sys::Guestfs->new ();
571 my %h = $g->version ();
572 print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
576 die "virt-resize [--options] indisk outdisk\n" unless @ARGV == 2;
578 # Check in and out images exist.
579 my $infile = $ARGV[0];
580 my $outfile = $ARGV[1];
581 die __x("virt-resize: {file}: does not exist or is not readable\n", file => $infile)
583 die __x("virt-resize: {file}: does not exist or is not writable\nYou have to create the destination disk before running this program.\nPlease read the virt-resize(1) manpage for more information.\n", file => $outfile)
586 # Add them to the handle and launch the appliance.
592 $g = Sys::Guestfs->new ();
593 $g->set_trace (1) if $debug;
594 my @args = ($infile);
595 push @args, readonly => 1;
596 push @args, format => $format if defined $format;
597 $g->add_drive_opts (@args);
599 push @args, format => $output_format if defined $output_format;
600 $g->add_drive_opts (@args);
601 $g->set_event_callback (\&progress_callback, $Sys::Guestfs::EVENT_PROGRESS)
606 my $sectsize = $g->blockdev_getss ("/dev/sdb");
608 # Get the size in bytes of each disk.
610 # Originally we computed this by looking at the same of the host file,
611 # but of course this failed for qcow2 images (RHBZ#633096). The right
612 # way to do it is with $g->blockdev_getsize64.
613 my $insize = $g->blockdev_getsize64 ("/dev/sda");
614 my $outsize = $g->blockdev_getsize64 ("/dev/sdb");
617 print "$infile size $insize bytes\n";
618 print "$outfile size $outsize bytes\n";
621 # Create a partition table.
623 # We *must* do this before copying the bootloader across, and copying
624 # the bootloader must be careful not to disturb this partition table
625 # (RHBZ#633766). There are two reasons for this:
627 # (1) The 'parted' library is stupid and broken. In many ways. In
628 # this particular instance the stupid and broken bit is that it
629 # overwrites the whole boot sector when initializating a partition
630 # table. (Upstream don't consider this obvious problem to be a bug).
632 # (2) GPT has a backup partition table located at the end of the disk.
633 # It's non-movable, because the primary GPT contains fixed references
634 # to both the size of the disk and the backup partition table at the
635 # end. This would be a problem for any resize that didn't either
636 # carefully move the backup GPT (and rewrite those references) or
637 # recreate the whole partition table from scratch.
640 create_partition_table ();
642 sub create_partition_table
646 $parttype = $g->part_get_parttype ("/dev/sda");
647 print "partition table type: $parttype\n" if $debug;
649 $g->part_init ("/dev/sdb", $parttype);
652 # In reality the number of sectors containing boot loader data will be
653 # less than this (although Windows 7 defaults to putting the first
654 # partition on sector 2048, and has quite a large boot loader).
656 # However make this large enough to be sure that we have copied over
657 # the boot loader. We could also do this by looking for the sector
658 # offset of the first partition.
660 # It doesn't matter if we copy too much.
661 my $max_bootloader = 4096 * 512;
663 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
664 file => $infile, sz => $insize)
665 if $insize < $max_bootloader;
666 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
667 file => $outfile, sz => $outsize)
668 if $outsize < $max_bootloader;
670 # Copy the boot loader across.
671 do_copy_boot_loader () if $copy_boot_loader;
673 sub do_copy_boot_loader
675 print "copying boot loader ...\n" if $debug;
677 # Don't disturb the partition table that we just wrote.
678 # https://secure.wikimedia.org/wikipedia/en/wiki/Master_Boot_Record
679 # https://secure.wikimedia.org/wikipedia/en/wiki/GUID_Partition_Table
681 my $bootsect = $g->pread_device ("/dev/sda", 446, 0);
682 die __"virt-resize: short read" if length ($bootsect) < 446;
684 $g->pwrite_device ("/dev/sdb", $bootsect, 0);
687 if ($parttype eq "gpt") {
688 # XXX With 4K sectors does GPT just fit more entries in a
689 # sector, or does it always use 34 sectors?
693 my $loader = $g->pread_device ("/dev/sda", $max_bootloader, $start);
694 die __"virt-resize: short read" if length ($loader) < $max_bootloader;
696 $g->pwrite_device ("/dev/sdb", $loader, $start);
699 my $to_be_expanded = 0;
701 # Get the partitions on the source disk.
704 check_source_disk ();
706 sub check_source_disk
710 # Partitions and PVs.
711 my @p = $g->part_list ("/dev/sda");
713 my $name = "/dev/sda" . $_->{part_num};
714 push @partitions, $name;
718 $h{bootable} = $g->part_get_bootable ("/dev/sda", $h{part_num});
719 eval { $h{mbr_id} = $g->part_get_mbr_id ("/dev/sda", $h{part_num}); };
720 $partitions{$name} = \%h;
724 # Examine each partition.
725 my @pvs_full = $g->pvs_full ();
726 examine_partition ($_) foreach @partitions;
728 sub examine_partition
734 my $type = "unknown";
736 $type = $g->vfs_type ($part);
738 $partitions{$part}->{type} = $type;
740 # Can we get the actual size of this object (ie. to find out if it
741 # is smaller than the container for shrinking)?
743 if ($type eq "LVM2_member") { # LVM PV
744 foreach (@pvs_full) {
745 $fssize = $_->{pv_size}
746 if canonicalize ($_->{pv_name}) eq $part;
748 } else { # Something mountable?
750 $g->mount_ro ($part, "/");
752 my %stat = $g->statvfs ("/");
753 $fssize = $stat{bsize} * $stat{blocks};
761 # This might be undef if we didn't successfully find the size. In
762 # that case user won't be allowed to shrink this partition except
764 $partitions{$part}->{fssize} = $fssize;
766 # Is it partition content that we know how to expand?
767 $partitions{$part}->{can_expand_content} = 0;
768 if ($expand_content) {
769 if ($type eq "LVM2_member") {
770 $partitions{$part}->{can_expand_content} = 1;
771 $partitions{$part}->{expand_content_method} = "pvresize";
772 } elsif ($type =~ /^ext[234]$/) {
773 $partitions{$part}->{can_expand_content} = 1;
774 $partitions{$part}->{expand_content_method} = "resize2fs";
775 } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
776 $partitions{$part}->{can_expand_content} = 1;
777 $partitions{$part}->{expand_content_method} = "ntfsresize";
783 print "partitions found: ", join (", ", @partitions), "\n";
784 foreach my $part (@partitions) {
786 foreach (sort keys %{$partitions{$part}}) {
787 print("\t", $_, " = ",
788 defined ($partitions{$part}->{$_})
789 ? $partitions{$part}->{$_} : "undef",
795 # Examine the LVs (for --lv-expand option).
796 my @lvs = $g->lvs ();
798 examine_lv ($_) foreach @lvs;
799 mark_lvs_to_expand ();
805 $lvs{$_}->{name} = $_;
807 my $type = "unknown";
809 $type = $g->vfs_type ($_);
811 $lvs{$_}->{type} = $type;
813 if ($expand_content) {
814 if ($type =~ /^ext[234]$/) {
815 $lvs{$_}->{can_expand_content} = 1;
816 $lvs{$_}->{expand_content_method} = "resize2fs";
817 } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
818 $lvs{$_}->{can_expand_content} = 1;
819 $lvs{$_}->{expand_content_method} = "ntfsresize";
824 sub mark_lvs_to_expand {
827 foreach (@lv_expand) {
828 die __x("virt-resize: no logical volume called {n}\n",
830 unless exists $lvs{$_};
832 if ($lvs{$_}->{can_expand_content}) {
833 $lvs{$_}->{will_expand_content} = 1;
844 $_ = "/dev/$_" unless $_ =~ m{^/dev};
845 $_ = canonicalize ($_);
847 unless (exists $partitions{$_}) {
848 die __x("{p}: partition not found in the source disk image, when using the '{opt}' command line option\n",
853 if ($partitions{$_}->{ignore}) {
854 die __x("{p}: partition ignored, you cannot use it in another command line argument\n",
857 if ($partitions{$_}->{delete}) {
858 die __x("{p}: partition deleted, you cannot use it in another command line argument\n",
866 do_ignore ($_) foreach @ignore;
871 $_ = find_partition ($_, "--ignore");
872 $partitions{$_}->{ignore} = 1;
876 do_delete ($_) foreach @delete;
881 $_ = find_partition ($_, "--delete");
882 $partitions{$_}->{delete} = 1;
885 # Handle --resize and --resize-force.
886 do_resize ($_, 0, "--resize") foreach @resize;
887 do_resize ($_, 1, "--resize-force") foreach @resize_force;
895 # Argument is "part=size" ...
896 my ($part, $sizefield) = split /=/, $_, 2;
897 $part = find_partition ($part, $option);
899 if (exists $partitions{$part}->{newsize}) {
900 die __x("{p}: this partition has already been marked for resizing\n",
904 # Parse the size field.
905 my $oldsize = $partitions{$part}->{part_size};
907 if (!defined ($sizefield) || $sizefield eq "") {
908 die __x("{p}: missing size field in {o} option\n",
909 p => $part, o => $option);
910 } elsif ($sizefield =~ /^([.\d]+)([bKMGTPE])$/) {
911 $newsize = sizebytes ($1, $2);
912 } elsif ($sizefield =~ /^\+([.\d]+)([bKMGTPE])$/) {
913 my $incr = sizebytes ($1, $2);
914 $newsize = $oldsize + $incr;
915 } elsif ($sizefield =~ /^-([.\d]+)([bKMGTPE])$/) {
916 my $decr = sizebytes ($1, $2);
917 $newsize = $oldsize - $decr;
918 } elsif ($sizefield =~ /^([.\d]+)%$/) {
919 $newsize = $oldsize * $1 / 100;
920 } elsif ($sizefield =~ /^\+([.\d]+)%$/) {
921 $newsize = $oldsize + $oldsize * $1 / 100;
922 } elsif ($sizefield =~ /^-([.\d]+)%$/) {
923 $newsize = $oldsize - $oldsize * $1 / 100;
925 die __x("{p}: {f}: cannot parse size field\n",
926 p => $part, f => $sizefield)
930 die __x("{p}: new size is zero or negative\n", p => $part);
932 mark_partition_for_resize ($part, $oldsize, $newsize, $force, $option);
935 sub mark_partition_for_resize
944 # Do nothing if the size is the same.
945 return if $oldsize == $newsize;
947 my $bigger = $newsize > $oldsize;
949 # Check there is space to shrink this.
950 unless ($bigger || $force) {
951 if (! $partitions{$part}->{fssize} ||
952 $partitions{$part}->{fssize} > $newsize) {
953 die __x("{p}: cannot make this partition smaller because it contains a\nfilesystem, physical volume or other content that is larger than the new size.\nYou have to resize the content first, see virt-resize(1).\n",
958 $partitions{$part}->{newsize} = $newsize;
960 if ($partitions{$part}->{can_expand_content} && $bigger) {
961 $partitions{$part}->{will_expand_content} = 1;
966 # Handle --expand and --shrink.
968 if (defined $expand && defined $shrink) {
969 die __"virt-resize: you cannot use options --expand and --shrink together\n"
971 if (defined $expand || defined $shrink) {
972 calculate_surplus ();
975 print "surplus before --expand or --shrink: $surplus (",
976 human_size ($surplus), ")\n";
979 do_expand () if $expand;
980 do_shrink () if $shrink;
983 # (Re-)calculate surplus after doing expand or shrink.
984 calculate_surplus ();
986 # Add up the total space required on the target so far, compared
987 # to the size of the target. We end up with a surplus or deficit.
988 sub calculate_surplus
992 # We need some overhead for partitioning. Worst case would be for
993 # EFI partitioning + massive per-partition alignment.
994 my $overhead = $sectsize * (
995 2 * 64 + # GPT start and end
996 (64 * (@partitions + 1)) # Maximum alignment
998 ($max_bootloader - 64 * 512); # boot loader
1001 foreach (@partitions) {
1002 if ($partitions{$_}->{newsize}) {
1003 $required += $partitions{$_}->{newsize}
1005 $required += $partitions{$_}->{part_size}
1009 # Compare that to the actual target disk.
1010 $surplus = $outsize - ($required + $overhead);
1017 unless ($surplus > 0) {
1018 die __x("virt-resize: error: cannot use --expand when there is no surplus space to\nexpand into. You need to make the target disk larger by at least {h}.\n",
1019 h => human_size (-$surplus));
1022 my $part = find_partition ($expand, "--expand");
1023 my $oldsize = $partitions{$part}->{part_size};
1024 mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
1032 unless ($surplus < 0) {
1033 die __"virt-resize: error: cannot use --shrink because there is no deficit\n(see 'deficit' in the virt-resize(1) man page)\n"
1036 my $part = find_partition ($shrink, "--shrink");
1037 my $oldsize = $partitions{$part}->{part_size};
1038 mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
1043 print_summary () unless $quiet;
1048 print __"Summary of changes:\n";
1050 foreach my $part (@partitions) {
1051 if ($partitions{$part}->{ignore}) {
1052 print __x("{p}: partition will be ignored\n", p => $part);
1053 } elsif ($partitions{$part}->{delete}) {
1054 print __x("{p}: partition will be deleted\n", p => $part);
1055 } elsif ($partitions{$part}->{newsize}) {
1056 print __x("{p}: partition will be resized from {oldsize} to {newsize}\n",
1058 oldsize => human_size ($partitions{$part}->{part_size}),
1059 newsize => human_size ($partitions{$part}->{newsize}));
1060 if ($partitions{$part}->{will_expand_content}) {
1061 print __x("{p}: content will be expanded using the '{meth}' method\n",
1063 meth => $partitions{$part}->{expand_content_method});
1066 print __x("{p}: partition will be left alone\n", p => $part);
1070 foreach my $lv (@lv_expand) {
1071 print __x("{n}: LV will be expanded to maximum size\n",
1075 foreach my $lv (@lvs) {
1076 if ($lvs{$lv}->{will_expand_content}) {
1077 print __x("{n}: content will be expanded using the '{meth}' method\n",
1079 meth => $lvs{$lv}->{expand_content_method});
1084 print __x("There is a surplus of {spl} bytes ({h}).\n",
1086 h => human_size ($surplus));
1087 if ($extra_partition) {
1088 if ($surplus >= $min_extra_partition) {
1089 print __"An extra partition will be created for the surplus.\n";
1091 print __"The surplus space is not large enough for an extra partition to be created\nand so it will just be ignored.\n";
1094 print __"The surplus space will be ignored. Run a partitioning program in the guest\nto partition this extra space if you want.\n";
1096 } elsif ($surplus < 0) {
1097 die __x("virt-resize: error: there is a deficit of {def} bytes ({h}).\nYou need to make the target disk larger by at least this amount,\nor adjust your resizing requests.\n",
1099 h => human_size (-$surplus));
1105 # Repartition the target disk.
1113 # Work out where to start the first partition.
1114 die __"virt-resize: source disk does not have a first partition\n"
1115 unless exists ($partitions{"/dev/sda1"});
1116 my $start = $partitions{"/dev/sda1"}->{part_start} / $sectsize;
1119 $start = ($start + 63) & ~63;
1121 print "starting to partition from $start\n" if $debug;
1123 # Create the new partitions.
1124 foreach my $part (@partitions) {
1125 unless ($partitions{$part}->{delete}) {
1128 if ($partitions{$part}->{newsize}) {
1129 $size = ($partitions{$part}->{newsize} + $sectsize - 1)
1132 $size = ($partitions{$part}->{part_size} + $sectsize - 1)
1137 my ($target, $end, $part_num) = add_partition ($start, $size);
1138 $partitions{$part}->{target} = $target;
1140 if ($partitions{$part}->{bootable}) {
1141 $g->part_set_bootable ("/dev/sdb", $part_num, 1);
1144 if ($partitions{$part}->{mbr_id}) {
1145 $g->part_set_mbr_id ("/dev/sdb", $part_num,
1146 $partitions{$part}->{mbr_id});
1149 # Start of next partition + alignment.
1151 $start = ($start + 63) & ~63;
1155 # Create surplus partition.
1156 if ($extra_partition && $surplus >= $min_extra_partition) {
1157 add_partition ($start, $outsize / $sectsize - 64 - $start);
1168 my ($target, $end, $part_num);
1170 if ($nextpart <= 3 || $parttype ne "msdos") {
1171 $target = "/dev/sdb$nextpart";
1172 $end = $start + $size - 1;
1173 $g->part_add ("/dev/sdb", "primary", $start, $end);
1174 $part_num = $nextpart++;
1176 if ($nextpart == 4) {
1177 $g->part_add ("/dev/sdb", "extended", $start, -1);
1178 $part_num = $nextpart++;
1181 $target = "/dev/sdb$nextpart";
1182 $end = $start + $size - 1;
1183 $g->part_add ("/dev/sdb", "logical", $start, $end);
1184 $part_num = $nextpart++;
1187 return ($target, $end, $part_num);
1190 # Copy over the data.
1195 foreach my $part (@partitions)
1197 unless ($partitions{$part}->{ignore}) {
1198 my $target = $partitions{$part}->{target};
1200 my $oldsize = $partitions{$part}->{part_size};
1202 if ($partitions{$part}->{newsize}) {
1203 $newsize = $partitions{$part}->{newsize};
1205 $newsize = $partitions{$part}->{part_size};
1208 if (!$quiet && !$debug) {
1209 print __x("Copying {p} ...\n", p => $part);
1212 $g->copy_size ($part, $target,
1213 $newsize < $oldsize ? $newsize : $oldsize);
1219 # After copying the data over we must shut down and restart the
1220 # appliance in order to expand the content. The reason for this may
1221 # not be obvious, but it's because otherwise we'll have duplicate VGs
1222 # (the old VG(s) and the new VG(s)) which breaks LVM.
1224 # The restart is only required if we're going to expand something.
1226 if ($to_be_expanded > 0) {
1227 restart_appliance ();
1228 expand_partitions ();
1230 expand_lvs_content ();
1233 sub restart_appliance
1235 # Sync disk and exit.
1240 $g = Sys::Guestfs->new ();
1241 $g->set_trace (1) if $debug;
1242 my @args = ($outfile);
1243 push @args, format => $output_format if defined $output_format;
1244 $g->add_drive_opts (@args);
1247 # Target partitions have changed from /dev/sdb to /dev/sda,
1249 foreach my $part (@partitions)
1251 my $target = $partitions{$part}->{target};
1253 if ($target =~ m{/dev/(.)db(.*)}) {
1254 $partitions{$part}->{target} = "/dev/$1da$2";
1256 die "internal error: unexpected partition target: $target";
1262 sub expand_partitions
1264 foreach my $part (@partitions)
1266 unless ($partitions{$part}->{ignore}) {
1267 my $target = $partitions{$part}->{target};
1269 # Expand if requested.
1270 if ($partitions{$part}->{will_expand_content}) {
1271 if (!$quiet && !$debug) {
1272 print __x("Expanding {p} using the '{meth}' method\n",
1274 meth => $partitions{$part}->{expand_content_method});
1276 expand_target_partition ($part)
1283 sub expand_target_partition
1290 die unless $partitions{$part}->{can_expand_content};
1291 die unless $partitions{$part}->{will_expand_content};
1292 die unless $partitions{$part}->{expand_content_method};
1293 die unless $partitions{$part}->{target};
1294 die unless $expand_content;
1296 my $target = $partitions{$part}->{target};
1297 my $method = $partitions{$part}->{expand_content_method};
1298 if ($method eq "pvresize") {
1299 $g->pvresize ($target);
1301 elsif ($method eq "resize2fs") {
1302 $g->e2fsck_f ($target);
1303 $g->resize2fs ($target);
1305 elsif ($method eq "ntfsresize") {
1306 $g->ntfsresize ($target);
1309 die "internal error: unknown method: $method";
1317 foreach (@lv_expand) {
1318 $g->lvresize_free ($_, 100);
1322 sub expand_lvs_content
1327 if ($lvs{$_}->{will_expand_content}) {
1328 my $method = $lvs{$_}->{expand_content_method};
1329 if (!$quiet && !$debug) {
1330 print __x("Expanding {p} using the '{meth}' method\n",
1331 p => $_, meth => $method);
1333 if ($method eq "resize2fs") {
1336 } elsif ($method eq "ntfsresize") {
1337 $g->ntfsresize ($_);
1339 die "internal error: unknown method: $method";
1345 # Sync disk and exit.
1357 $_ *= 1024 if $unit =~ /[KMGTPE]/;
1358 $_ *= 1024 if $unit =~ /[MGTPE]/;
1359 $_ *= 1024 if $unit =~ /[GTPE]/;
1360 $_ *= 1024 if $unit =~ /[TPE]/;
1361 $_ *= 1024 if $unit =~ /[PE]/;
1362 $_ *= 1024 if $unit =~ /[E]/;
1367 # Convert a number of bytes to a human-readable number.
1381 sprintf "%s%dK", $sgn, $_;
1382 } elsif ($_ < 1024 * 1024) {
1383 sprintf "%s%.1fM", $sgn, ($_ / 1024);
1385 sprintf "%s%.1fG", $sgn, ($_ / 1024 / 1024);
1389 # The reverse of device name translation, see
1390 # BLOCK DEVICE NAMING in guestfs(3).
1395 if (m{^/dev/[hv]d([a-z]\d*)$}) {
1401 # Not as sophisticated as the guestfish progress bar, because
1402 # I intend to use an external library for this at some point (XXX).
1403 sub progress_callback
1406 my $event_handle = shift;
1410 my $proc_nr = $array->[0];
1411 my $serial = $array->[1];
1412 my $position = $array->[2];
1413 my $total = $array->[3];
1415 my $ratio = $position / $total;
1416 if ($ratio < 0) { $ratio = 0 }
1417 elsif ($ratio > 1) { $ratio = 1 }
1419 my $dots = int ($ratio * 76);
1421 print "[", "#"x$dots, "-"x(76-$dots), "]\r";
1422 print "\n" if $ratio == 1;
1427 =head2 "Partition 1 does not end on cylinder boundary."
1429 Virt-resize aligns partitions to multiples of 64 sectors. Usually
1430 this means the partitions will not be aligned to the ancient CHS
1431 geometry. However CHS geometry is meaningless for disks manufactured
1432 since the early 1990s, and doubly so for virtual hard drives.
1433 Alignment of partitions to cylinders is not required by any modern
1436 =head2 RESIZING WINDOWS VIRTUAL MACHINES
1438 In Windows Vista and later versions, Microsoft switched to using a
1439 separate boot partition. In these VMs, typically C</dev/sda1> is the
1440 boot partition and C</dev/sda2> is the main (C:) drive. We have not
1441 had any luck resizing the boot partition. Doing so seems to break the
1442 guest completely. However expanding the second partition (ie. C:
1445 Windows may initiate a lengthy "chkdsk" on first boot after a resize,
1446 if NTFS partitions have been expanded. This is just a safety check
1447 and (unless it find errors) is nothing to worry about.
1449 =head2 GUEST BOOT STUCK AT "GRUB"
1451 If a Linux guest does not boot after resizing, and the boot is stuck
1452 after printing C<GRUB> on the console, try reinstalling grub. This
1453 sometimes happens on older (RHEL 5-era) guests, for reasons we don't
1454 fully understand, although we think is to do with partition alignment.
1456 guestfish -i -a newdisk
1457 ><fs> cat /boot/grub/device.map
1458 # check the contents of this file are sensible or
1459 # edit the file if necessary
1460 ><fs> grub-install / /dev/vda
1463 For more flexible guest reconfiguration, including if you need to
1464 specify other parameters to grub-install, use L<virt-rescue(1)>.
1466 =head1 ALTERNATIVE TOOLS
1468 There are several proprietary tools for resizing partitions. We
1469 won't mention any here.
1471 L<parted(8)> and its graphical shell gparted can do some types of
1472 resizing operations on disk images. They can resize and move
1473 partitions, but I don't think they can do anything with the contents,
1474 and they certainly don't understand LVM.
1476 L<guestfish(1)> can do everything that virt-resize can do and a lot
1477 more, but at a much lower level. You will probably end up
1478 hand-calculating sector offsets, which is something that virt-resize
1479 was designed to avoid. If you want to see the guestfish-equivalent
1480 commands that virt-resize runs, use the C<--debug> flag.
1482 =head1 SHELL QUOTING
1484 Libvirt guest names can contain arbitrary characters, some of which
1485 have meaning to the shell such as C<#> and space. You may need to
1486 quote or escape these characters on the command line. See the shell
1487 manual page L<sh(1)> for details.
1491 L<virt-filesystems(1)>,
1508 L<http://libguestfs.org/>.
1512 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
1516 Copyright (C) 2010 Red Hat Inc.
1518 This program is free software; you can redistribute it and/or modify
1519 it under the terms of the GNU General Public License as published by
1520 the Free Software Foundation; either version 2 of the License, or
1521 (at your option) any later version.
1523 This program is distributed in the hope that it will be useful,
1524 but WITHOUT ANY WARRANTY; without even the implied warranty of
1525 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1526 GNU General Public License for more details.
1528 You should have received a copy of the GNU General Public License
1529 along with this program; if not, write to the Free Software
1530 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.