3 # Copyright (C) 2010 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-list-partitions(1)>,
62 L<virt-list-filesystems(1)> and
64 we recommend you go and read those manual pages first.
68 Copy C<olddisk> to C<newdisk>, extending one of the guest's partitions
69 to fill the extra 5GB of space.
71 truncate -r olddisk newdisk; truncate -s +5G newdisk
72 virt-list-partitions -lht olddisk
73 # Note "/dev/sda2" is a partition inside the "olddisk" file.
74 virt-resize --expand /dev/sda2 olddisk newdisk
76 As above, but make the /boot partition 200MB bigger, while giving the
77 remaining space to /dev/sda2:
79 virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 olddisk newdisk
83 =head2 EXPANDING A VIRTUAL MACHINE DISK
87 =item 1. Shut down the virtual machine
89 =item 2. Locate input disk image
91 Locate the input disk image (ie. the file or device on the host
92 containing the guest's disk). If the guest is managed by libvirt, you
93 can use C<virsh dumpxml> like this to find the disk image name:
95 # virsh dumpxml guestname | xpath /domain/devices/disk/source
98 <source dev="/dev/vg/lv_guest" />
100 =item 3. Look at current sizing
102 Use L<virt-list-partitions(1)> to display the current partitions and
105 # virt-list-partitions -lht /dev/vg/lv_guest
106 /dev/sda1 ext3 101.9M
110 (This example is a virtual machine with an 8 GB disk which we would
111 like to expand up to 10 GB).
113 =item 4. Create output disk
115 Virt-resize cannot do in-place disk modifications. You have to have
116 space to store the resized output disk.
118 To store the resized disk image in a file, create a file of a suitable
122 # truncate -s 10G outdisk
124 Or use L<lvcreate(1)> to create a logical volume:
126 # lvcreate -L 10G -n lv_name vg_name
128 Or use L<virsh(1)> vol-create-as to create a libvirt storage volume:
131 # virsh vol-create-as poolname newvol 10G
135 virt-resize takes two mandatory parameters, the input disk (eg. device
136 or file) and the output disk. The output disk is the one created in
139 # virt-resize indisk outdisk
141 This command just copies disk image C<indisk> to disk image C<outdisk>
142 I<without> resizing or changing any existing partitions. If
143 C<outdisk> is larger, then an extra, empty partition is created at the
144 end of the disk covering the extra space. If C<outdisk> is smaller,
145 then it will give an error.
147 More realistically you'd want to expand existing partitions in the
148 disk image by passing extra options (for the full list see the
149 L</OPTIONS> section below).
151 L</--expand> is the most useful option. It expands the named
152 partition within the disk to fill any extra space:
154 # virt-resize --expand /dev/sda2 indisk outdisk
156 (In this case, an extra partition is I<not> created at the end of the
157 disk, because there will be no unused space).
159 L</--resize> is the other commonly used option. The following would
160 increase the size of /dev/sda1 by 200M, and expand /dev/sda2
161 to fill the rest of the available space:
163 # virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 \
166 If the expanded partition in the image contains a filesystem or LVM
167 PV, then if virt-resize knows how, it will resize the contents, the
168 equivalent of calling a command such as L<pvresize(8)>,
169 L<resize2fs(8)> or L<ntfsresize(8)>. However virt-resize does not
170 know how to resize some filesystems, so you would have to online
171 resize them after booting the guest. And virt-resize also does not
172 resize anything inside an LVM PV, it just resizes the PV itself and
173 leaves the user to resize any LVs inside that PV as desired.
175 Other options are covered below.
179 Thoroughly test the new disk image I<before> discarding the old one.
181 If you are using libvirt, edit the XML to point at the new disk:
183 # virsh edit guestname
185 Change E<lt>source ...E<gt>, see
186 L<http://libvirt.org/formatdomain.html#elementsDisks>
188 Then start up the domain with the new, resized disk:
190 # virsh start guestname
192 and check that it still works. See also the L</NOTES> section below
193 for additional information.
195 =item 7. Resize LVs etc inside the guest
197 (This can also be done offline using L<guestfish(1)>)
199 Once the guest has booted you should see the new space available, at
200 least for filesystems that virt-resize knows how to resize, and for
201 PVs. The user may need to resize LVs inside PVs, and also resize
202 filesystem types that virt-resize does not know how to expand.
206 =head2 SHRINKING A VIRTUAL MACHINE DISK
208 Shrinking is somewhat more complex than expanding, and only an
209 overview is given here.
211 Firstly virt-resize will not attempt to shrink any partition content
212 (PVs, filesystems). The user has to shrink content before passing the
213 disk image to virt-resize, and virt-resize will check that the content
214 has been shrunk properly.
216 (Shrinking can also be done offline using L<guestfish(1)>)
218 After shrinking PVs and filesystems, shut down the guest, and proceed
219 with steps 3 and 4 above to allocate a new disk image.
221 Then run virt-resize with any of the C<--shrink> and/or C<--resize>
224 =head2 IGNORING OR DELETING PARTITIONS
226 virt-resize also gives a convenient way to ignore or delete partitions
227 when copying from the input disk to the output disk. Ignoring a
228 partition speeds up the copy where you don't care about the existing
229 contents of a partition. Deleting a partition removes it completely,
230 but note that it also renumbers any partitions after the one which is
231 deleted, which can leave some guests unbootable.
251 Display version number and exit.
257 =item B<--resize part=size>
259 Resize the named partition (expanding or shrinking it) so that it has
262 C<size> can be expressed as an absolute number followed by
263 b/K/M/G/T/P/E to mean bytes, Kilobytes, Megabytes, Gigabytes,
264 Terabytes, Petabytes or Exabytes; or as a percentage of the current
265 size; or as a relative number or percentage. For example:
267 --resize /dev/sda2=10G
269 --resize /dev/sda4=90%
271 --resize /dev/sda2=+1G
273 --resize /dev/sda2=-200M
275 --resize /dev/sda1=+128K
277 --resize /dev/sda1=+10%
279 --resize /dev/sda1=-10%
281 You can increase the size of any partition. Virt-resize will expand
282 the direct content of the partition if it knows how (see C<--expand>
285 You can only I<decrease> the size of partitions that contain
286 filesystems or PVs which have already been shrunk. Virt-resize will
287 check this has been done before proceeding, or else will print an
288 error (see also C<--resize-force>).
290 You can give this option multiple times.
296 =item B<--resize-force part=size>
298 This is the same as C<--resize> except that it will let you decrease
299 the size of any partition. Generally this means you will lose any
300 data which was at the end of the partition you shrink, but you may not
301 care about that (eg. if shrinking an unused partition, or if you can
302 easily recreate it such as a swap partition).
304 See also the C<--ignore> option.
310 =item B<--expand part>
312 Expand the named partition so it uses up all extra space (space left
313 over after any other resize changes that you request have been done).
315 If virt-resize knows how, it will expand the direct content of the
316 partition. For example, if the partition is an LVM PV, it will expand
317 the PV to fit (like calling L<pvresize(8)>). Virt-resize leaves any
318 other content it doesn't know about alone.
320 Currently virt-resize can resize:
326 ext2, ext3 and ext4 filesystems when they are contained
327 directly inside a partition.
331 NTFS filesystems contained directly in a partition, if libguestfs was
332 compiled with support for NTFS.
334 The filesystem must have been shut down consistently last time it was
335 used. Additionally, L<ntfsresize(8)> marks the resized filesystem as
336 requiring a consistency check, so at the first boot after resizing
337 Windows will check the disk.
341 LVM PVs (physical volumes). However virt-resize does I<not>
342 resize anything inside the PV. The user will have to resize
347 Note that you cannot use C<--expand> and C<--shrink> together.
353 =item B<--shrink part>
355 Shrink the named partition until the overall disk image fits in the
356 destination. The named partition B<must> contain a filesystem or PV
357 which has already been shrunk using another tool (eg. L<guestfish(1)>
358 or other online tools). Virt-resize will check this and give an error
359 if it has not been done.
361 The amount by which the overall disk must be shrunk (after carrying
362 out all other operations requested by the user) is called the
363 "deficit". For example, a straight copy (assume no other operations)
364 from a 5GB disk image to a 4GB disk image results in a 1GB deficit.
365 In this case, virt-resize would give an error unless the user
366 specified a partition to shrink and that partition had more than a
367 gigabyte of free space.
369 Note that you cannot use C<--expand> and C<--shrink> together.
375 =item B<--ignore part>
377 Ignore the named partition. Effectively this means the partition is
378 allocated on the destination disk, but the content is not copied
379 across from the source disk. The content of the partition will be
380 blank (all zero bytes).
382 You can give this option multiple times.
388 =item B<--delete part>
390 Delete the named partition. It would be more accurate to describe
391 this as "don't copy it over", since virt-resize doesn't do in-place
392 changes and the original disk image is left intact.
394 Note that when you delete a partition, then anything contained in the
395 partition is also deleted. Furthermore, this causes any partitions
396 that come after to be I<renumbered>, which can easily make your guest
399 You can give this option multiple times.
405 =item B<--LV-expand logvol>
407 This takes the logical volume and, as a final step, expands it to fill
408 all the space available in its volume group. A typical usage,
409 assuming a Linux guest with a single PV C</dev/sda2> and a root device
410 called C</dev/vg_guest/lv_root> would be:
412 virt-resize indisk outdisk \
413 --expand /dev/sda2 --LV-expand /dev/vg_guest/lv_root
415 This would first expand the partition (and PV), and then expand the
416 root device to fill the extra space in the PV.
418 The contents of the LV are also resized if virt-resize knows how to do
419 that. You can stop virt-resize from trying to expand the content by
420 using the option C<--no-expand-content>.
422 Use L<virt-list-filesystems(1)> to list the filesystems in
425 You can give this option multiple times, I<but> it doesn't
426 make sense to do this unless the logical volumes you specify
427 are all in different volume groups.
431 my $copy_boot_loader = 1;
433 =item B<--no-copy-boot-loader>
435 By default, virt-resize copies over some sectors at the start of the
436 disk (up to the beginning of the first partition). Commonly these
437 sectors contain the Master Boot Record (MBR) and the boot loader, and
438 are required in order for the guest to boot correctly.
440 If you specify this flag, then this initial copy is not done. You may
441 need to reinstall the boot loader in this case.
445 my $extra_partition = 1;
446 my $min_extra_partition = 10 * 1024 * 1024; # see below
448 =item B<--no-extra-partition>
450 By default, virt-resize creates an extra partition if there is any
451 extra, unused space after all resizing has happened. Use this option
452 to prevent the extra partition from being created. If you do this
453 then the extra space will be inaccessible until you run fdisk, parted,
454 or some other partitioning tool in the guest.
456 Note that if the surplus space is smaller than 10 MB, no extra
457 partition will be created.
461 my $expand_content = 1;
463 =item B<--no-expand-content>
465 By default, virt-resize will try to expand the direct contents
466 of partitions, if it knows how (see C<--expand> option above).
468 If you give the C<--no-expand-content> option then virt-resize
469 will not attempt this.
475 =item B<-d> | B<--debug>
477 Enable debugging messages.
483 =item B<-n> | B<--dryrun>
485 Print a summary of what would be done, but don't do anything.
491 =item B<-q> | B<--quiet>
493 Don't print the summary.
499 GetOptions ("help|?" => \$help,
500 "version" => \$version,
501 "resize=s" => \@resize,
502 "resize-force=s" => \@resize_force,
503 "expand=s" => \$expand,
504 "shrink=s" => \$shrink,
505 "ignore=s" => \@ignore,
506 "delete=s" => \@delete,
507 "lv-expand=s" => \@lv_expand,
508 "copy-boot-loader!" => \$copy_boot_loader,
509 "extra-partition!" => \$extra_partition,
510 "expand-content!" => \$expand_content,
511 "d|debug" => \$debug,
512 "n|dryrun|dry-run" => \$dryrun,
513 "q|quiet" => \$quiet,
515 pod2usage (1) if $help;
517 my $g = Sys::Guestfs->new ();
518 my %h = $g->version ();
519 print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
523 die "virt-resize [--options] indisk outdisk\n" unless @ARGV == 2;
525 # Check in and out images exist.
526 my $infile = $ARGV[0];
527 my $outfile = $ARGV[1];
528 die __x("virt-resize: {file}: does not exist or is not readable\n", file => $infile)
530 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)
535 my $insize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($infile);
537 my $outsize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($outfile);
540 print "$infile size $insize bytes\n";
541 print "$outfile size $outsize bytes\n";
544 # In reality the number of sectors containing boot loader data will be
545 # less than this (although Windows 7 defaults to putting the first
546 # partition on sector 2048, and has quite a large boot loader).
548 # However make this large enough to be sure that we have copied over
549 # the boot loader. We could also do this by looking for the sector
550 # offset of the first partition.
552 # It doesn't matter if we copy too much.
553 my $boot_sectors = 4096;
555 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
556 file => $infile, sz => $insize)
557 if $insize < $boot_sectors * 512;
558 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
559 file => $outfile, sz => $outsize)
560 if $outsize < $boot_sectors * 512;
562 # Copy the boot loader across.
563 do_copy_boot_loader () if $copy_boot_loader;
565 sub do_copy_boot_loader
567 print "copying boot loader ...\n" if $debug;
568 open IFILE, $infile or die "$infile: $!";
570 my $r = sysread (IFILE, $s, $boot_sectors * 512) or die "$infile: $!";
571 die "$infile: short read" if $r < $boot_sectors * 512;
572 open OFILE, "+<$outfile" or die "$outfile: $!";
573 sysseek OFILE, 0, SEEK_SET or die "$outfile: seek: $!";
574 $r = syswrite (OFILE, $s, $boot_sectors * 512) or die "$outfile: $!";
575 die "$outfile: short write" if $r < $boot_sectors * 512;
578 # Add them to the handle and launch the appliance.
584 $g = Sys::Guestfs->new ();
585 $g->set_trace (1) if $debug;
586 $g->add_drive_ro ($infile);
587 $g->add_drive ($outfile);
588 $g->set_progress_callback (\&progress_callback) unless $quiet;
592 my $sectsize = $g->blockdev_getss ("/dev/sdb");
594 my $to_be_expanded = 0;
596 # Get the partitions on the source disk.
599 check_source_disk ();
601 sub check_source_disk
605 # Partitions and PVs.
606 my @p = $g->part_list ("/dev/sda");
608 my $name = "/dev/sda" . $_->{part_num};
609 push @partitions, $name;
613 $h{bootable} = $g->part_get_bootable ("/dev/sda", $h{part_num});
614 eval { $h{mbr_id} = $g->part_get_mbr_id ("/dev/sda", $h{part_num}); };
615 $partitions{$name} = \%h;
619 # Examine each partition.
620 my @pvs_full = $g->pvs_full ();
621 examine_partition ($_) foreach @partitions;
623 sub examine_partition
629 my $type = "unknown";
631 $type = $g->vfs_type ($part);
633 $partitions{$part}->{type} = $type;
635 # Can we get the actual size of this object (ie. to find out if it
636 # is smaller than the container for shrinking)?
638 if ($type eq "LVM2_member") { # LVM PV
639 foreach (@pvs_full) {
640 $fssize = $_->{pv_size}
641 if canonicalize ($_->{pv_name}) eq $part;
643 } else { # Something mountable?
645 $g->mount_ro ($part, "/");
647 my %stat = $g->statvfs ("/");
648 $fssize = $stat{bsize} * $stat{blocks};
656 # This might be undef if we didn't successfully find the size. In
657 # that case user won't be allowed to shrink this partition except
659 $partitions{$part}->{fssize} = $fssize;
661 # Is it partition content that we know how to expand?
662 $partitions{$part}->{can_expand_content} = 0;
663 if ($expand_content) {
664 if ($type eq "LVM2_member") {
665 $partitions{$part}->{can_expand_content} = 1;
666 $partitions{$part}->{expand_content_method} = "pvresize";
667 } elsif ($type =~ /^ext[234]$/) {
668 $partitions{$part}->{can_expand_content} = 1;
669 $partitions{$part}->{expand_content_method} = "resize2fs";
670 } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
671 $partitions{$part}->{can_expand_content} = 1;
672 $partitions{$part}->{expand_content_method} = "ntfsresize";
678 print "partitions found: ", join (", ", @partitions), "\n";
679 foreach my $part (@partitions) {
681 foreach (sort keys %{$partitions{$part}}) {
682 print("\t", $_, " = ",
683 defined ($partitions{$part}->{$_})
684 ? $partitions{$part}->{$_} : "undef",
690 # Examine the LVs (for --lv-expand option).
691 my @lvs = $g->lvs ();
693 examine_lv ($_) foreach @lvs;
694 mark_lvs_to_expand ();
700 $lvs{$_}->{name} = $_;
702 my $type = "unknown";
704 $type = $g->vfs_type ($_);
706 $lvs{$_}->{type} = $type;
708 if ($expand_content) {
709 if ($type =~ /^ext[234]$/) {
710 $lvs{$_}->{can_expand_content} = 1;
711 $lvs{$_}->{expand_content_method} = "resize2fs";
712 } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
713 $lvs{$_}->{can_expand_content} = 1;
714 $lvs{$_}->{expand_content_method} = "ntfsresize";
719 sub mark_lvs_to_expand {
722 foreach (@lv_expand) {
723 die __x("virt-resize: no logical volume called {n}\n",
725 unless exists $lvs{$_};
727 if ($lvs{$_}->{can_expand_content}) {
728 $lvs{$_}->{will_expand_content} = 1;
739 $_ = "/dev/$_" unless $_ =~ m{^/dev};
740 $_ = canonicalize ($_);
742 unless (exists $partitions{$_}) {
743 die __x("{p}: partition not found in the source disk image, when using the '{opt}' command line option\n",
748 if ($partitions{$_}->{ignore}) {
749 die __x("{p}: partition ignored, you cannot use it in another command line argument\n",
752 if ($partitions{$_}->{delete}) {
753 die __x("{p}: partition deleted, you cannot use it in another command line argument\n",
761 do_ignore ($_) foreach @ignore;
766 $_ = find_partition ($_, "--ignore");
767 $partitions{$_}->{ignore} = 1;
771 do_delete ($_) foreach @delete;
776 $_ = find_partition ($_, "--delete");
777 $partitions{$_}->{delete} = 1;
780 # Handle --resize and --resize-force.
781 do_resize ($_, 0, "--resize") foreach @resize;
782 do_resize ($_, 1, "--resize-force") foreach @resize_force;
790 # Argument is "part=size" ...
791 my ($part, $sizefield) = split /=/, $_, 2;
792 $part = find_partition ($part, $option);
794 if (exists $partitions{$part}->{newsize}) {
795 die __x("{p}: this partition has already been marked for resizing\n",
799 # Parse the size field.
800 my $oldsize = $partitions{$part}->{part_size};
802 if (!defined ($sizefield) || $sizefield eq "") {
803 die __x("{p}: missing size field in {o} option\n",
804 p => $part, o => $option);
805 } elsif ($sizefield =~ /^([.\d]+)([bKMGTPE])$/) {
806 $newsize = sizebytes ($1, $2);
807 } elsif ($sizefield =~ /^\+([.\d]+)([bKMGTPE])$/) {
808 my $incr = sizebytes ($1, $2);
809 $newsize = $oldsize + $incr;
810 } elsif ($sizefield =~ /^-([.\d]+)([bKMGTPE])$/) {
811 my $decr = sizebytes ($1, $2);
812 $newsize = $oldsize - $decr;
813 } elsif ($sizefield =~ /^([.\d]+)%$/) {
814 $newsize = $oldsize * $1 / 100;
815 } elsif ($sizefield =~ /^\+([.\d]+)%$/) {
816 $newsize = $oldsize + $oldsize * $1 / 100;
817 } elsif ($sizefield =~ /^-([.\d]+)%$/) {
818 $newsize = $oldsize - $oldsize * $1 / 100;
820 die __x("{p}: {f}: cannot parse size field\n",
821 p => $part, f => $sizefield)
825 die __x("{p}: new size is zero or negative\n", p => $part);
827 mark_partition_for_resize ($part, $oldsize, $newsize, $force, $option);
830 sub mark_partition_for_resize
839 # Do nothing if the size is the same.
840 return if $oldsize == $newsize;
842 my $bigger = $newsize > $oldsize;
844 # Check there is space to shrink this.
845 unless ($bigger || $force) {
846 if (! $partitions{$part}->{fssize} ||
847 $partitions{$part}->{fssize} > $newsize) {
848 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",
853 $partitions{$part}->{newsize} = $newsize;
855 if ($partitions{$part}->{can_expand_content} && $bigger) {
856 $partitions{$part}->{will_expand_content} = 1;
861 # Handle --expand and --shrink.
863 if (defined $expand && defined $shrink) {
864 die __"virt-resize: you cannot use options --expand and --shrink together\n"
866 if (defined $expand || defined $shrink) {
867 calculate_surplus ();
870 print "surplus before --expand or --shrink: $surplus (",
871 human_size ($surplus), ")\n";
874 do_expand () if $expand;
875 do_shrink () if $shrink;
878 # (Re-)calculate surplus after doing expand or shrink.
879 calculate_surplus ();
881 # Add up the total space required on the target so far, compared
882 # to the size of the target. We end up with a surplus or deficit.
883 sub calculate_surplus
887 # We need some overhead for partitioning. Worst case would be for
888 # EFI partitioning + massive per-partition alignment.
889 my $overhead = $sectsize * (
890 2 * 64 + # GPT start and end
891 (64 * (@partitions + 1)) + # Maximum alignment
892 ($boot_sectors - 64) # Boot loader
896 foreach (@partitions) {
897 if ($partitions{$_}->{newsize}) {
898 $required += $partitions{$_}->{newsize}
900 $required += $partitions{$_}->{part_size}
904 # Compare that to the actual target disk.
905 $surplus = $outsize - ($required + $overhead);
912 unless ($surplus > 0) {
913 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",
914 h => human_size (-$surplus));
917 my $part = find_partition ($expand, "--expand");
918 my $oldsize = $partitions{$part}->{part_size};
919 mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
927 unless ($surplus < 0) {
928 die __"virt-resize: error: cannot use --shrink because there is no deficit\n(see 'deficit' in the virt-resize(1) man page)\n"
931 my $part = find_partition ($shrink, "--shrink");
932 my $oldsize = $partitions{$part}->{part_size};
933 mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
938 print_summary () unless $quiet;
943 print __"Summary of changes:\n";
945 foreach my $part (@partitions) {
946 if ($partitions{$part}->{ignore}) {
947 print __x("{p}: partition will be ignored\n", p => $part);
948 } elsif ($partitions{$part}->{delete}) {
949 print __x("{p}: partition will be deleted\n", p => $part);
950 } elsif ($partitions{$part}->{newsize}) {
951 print __x("{p}: partition will be resized from {oldsize} to {newsize}\n",
953 oldsize => human_size ($partitions{$part}->{part_size}),
954 newsize => human_size ($partitions{$part}->{newsize}));
955 if ($partitions{$part}->{will_expand_content}) {
956 print __x("{p}: content will be expanded using the '{meth}' method\n",
958 meth => $partitions{$part}->{expand_content_method});
961 print __x("{p}: partition will be left alone\n", p => $part);
965 foreach my $lv (@lv_expand) {
966 print __x("{n}: LV will be expanded to maximum size\n",
970 foreach my $lv (@lvs) {
971 if ($lvs{$lv}->{will_expand_content}) {
972 print __x("{n}: content will be expanded using the '{meth}' method\n",
974 meth => $lvs{$lv}->{expand_content_method});
979 print __x("There is a surplus of {spl} bytes ({h}).\n",
981 h => human_size ($surplus));
982 if ($extra_partition) {
983 if ($surplus >= $min_extra_partition) {
984 print __"An extra partition will be created for the surplus.\n";
986 print __"The surplus space is not large enough for an extra partition to be created\nand so it will just be ignored.\n";
989 print __"The surplus space will be ignored. Run a partitioning program in the guest\nto partition this extra space if you want.\n";
991 } elsif ($surplus < 0) {
992 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",
994 h => human_size (-$surplus));
1000 # Repartition the target disk.
1009 if ($copy_boot_loader) {
1010 $parttype = $g->part_get_parttype ("/dev/sdb");
1014 print "partition table type: $parttype\n" if $debug;
1016 # Delete any existing partitions on the destination disk,
1017 # but leave the bootloader that we copied over intact.
1018 if ($copy_boot_loader) {
1019 # Delete in reverse as an easy way to deal with extended
1021 foreach (sort { $b cmp $a } $g->list_partitions ()) {
1022 if (m{^/dev/.db(\d+)$}) {
1023 $g->part_del ("/dev/sdb", $1);
1027 # Didn't copy over the initial boot loader, so we need
1028 # to make a new partition table here.
1029 $g->part_init ("/dev/sdb", $parttype);
1032 # Work out where to start the first partition.
1033 die __"virt-resize: source disk does not have a first partition\n"
1034 unless exists ($partitions{"/dev/sda1"});
1035 my $start = $partitions{"/dev/sda1"}->{part_start} / $sectsize;
1038 $start = ($start + 63) & ~63;
1040 print "starting to partition from $start\n" if $debug;
1042 # Create the new partitions.
1043 foreach my $part (@partitions) {
1044 unless ($partitions{$part}->{delete}) {
1047 if ($partitions{$part}->{newsize}) {
1048 $size = ($partitions{$part}->{newsize} + $sectsize - 1)
1051 $size = ($partitions{$part}->{part_size} + $sectsize - 1)
1056 my ($target, $end, $part_num) = add_partition ($start, $size);
1057 $partitions{$part}->{target} = $target;
1059 if ($partitions{$part}->{bootable}) {
1060 $g->part_set_bootable ("/dev/sdb", $part_num, 1);
1063 if ($partitions{$part}->{mbr_id}) {
1064 $g->part_set_mbr_id ("/dev/sdb", $part_num,
1065 $partitions{$part}->{mbr_id});
1068 # Start of next partition + alignment.
1070 $start = ($start + 63) & ~63;
1074 # Create surplus partition.
1075 if ($extra_partition && $surplus >= $min_extra_partition) {
1076 add_partition ($start, $outsize / $sectsize - 64 - $start);
1087 my ($target, $end, $part_num);
1089 if ($nextpart <= 3 || $parttype ne "msdos") {
1090 $target = "/dev/sdb$nextpart";
1091 $end = $start + $size - 1;
1092 $g->part_add ("/dev/sdb", "primary", $start, $end);
1093 $part_num = $nextpart++;
1095 if ($nextpart == 4) {
1096 $g->part_add ("/dev/sdb", "extended", $start, -1);
1097 $part_num = $nextpart++;
1100 $target = "/dev/sdb$nextpart";
1101 $end = $start + $size - 1;
1102 $g->part_add ("/dev/sdb", "logical", $start, $end);
1103 $part_num = $nextpart++;
1106 return ($target, $end, $part_num);
1109 # Copy over the data.
1114 foreach my $part (@partitions)
1116 unless ($partitions{$part}->{ignore}) {
1117 my $target = $partitions{$part}->{target};
1119 my $oldsize = $partitions{$part}->{part_size};
1121 if ($partitions{$part}->{newsize}) {
1122 $newsize = $partitions{$part}->{newsize};
1124 $newsize = $partitions{$part}->{part_size};
1127 if (!$quiet && !$debug) {
1128 print __x("Copying {p} ...\n", p => $part);
1131 $g->copy_size ($part, $target,
1132 $newsize < $oldsize ? $newsize : $oldsize);
1138 # After copying the data over we must shut down and restart the
1139 # appliance in order to expand the content. The reason for this may
1140 # not be obvious, but it's because otherwise we'll have duplicate VGs
1141 # (the old VG(s) and the new VG(s)) which breaks LVM.
1143 # The restart is only required if we're going to expand something.
1145 if ($to_be_expanded > 0) {
1146 restart_appliance ();
1147 expand_partitions ();
1149 expand_lvs_content ();
1152 sub restart_appliance
1154 # Sync disk and exit.
1159 $g = Sys::Guestfs->new ();
1160 $g->set_trace (1) if $debug;
1161 $g->add_drive ($outfile);
1164 # Target partitions have changed from /dev/sdb to /dev/sda,
1166 foreach my $part (@partitions)
1168 my $target = $partitions{$part}->{target};
1170 if ($target =~ m{/dev/(.)db(.*)}) {
1171 $partitions{$part}->{target} = "/dev/$1da$2";
1173 die "internal error: unexpected partition target: $target";
1179 sub expand_partitions
1181 foreach my $part (@partitions)
1183 unless ($partitions{$part}->{ignore}) {
1184 my $target = $partitions{$part}->{target};
1186 # Expand if requested.
1187 if ($partitions{$part}->{will_expand_content}) {
1188 if (!$quiet && !$debug) {
1189 print __x("Expanding {p} using the '{meth}' method\n",
1191 meth => $partitions{$part}->{expand_content_method});
1193 expand_target_partition ($part)
1200 sub expand_target_partition
1207 die unless $partitions{$part}->{can_expand_content};
1208 die unless $partitions{$part}->{will_expand_content};
1209 die unless $partitions{$part}->{expand_content_method};
1210 die unless $partitions{$part}->{target};
1211 die unless $expand_content;
1213 my $target = $partitions{$part}->{target};
1214 my $method = $partitions{$part}->{expand_content_method};
1215 if ($method eq "pvresize") {
1216 $g->pvresize ($target);
1218 elsif ($method eq "resize2fs") {
1219 $g->e2fsck_f ($target);
1220 $g->resize2fs ($target);
1222 elsif ($method eq "ntfsresize") {
1223 $g->ntfsresize ($target);
1226 die "internal error: unknown method: $method";
1234 foreach (@lv_expand) {
1235 $g->lvresize_free ($_, 100);
1239 sub expand_lvs_content
1244 if ($lvs{$_}->{will_expand_content}) {
1245 my $method = $lvs{$_}->{expand_content_method};
1246 if (!$quiet && !$debug) {
1247 print __x("Expanding {p} using the '{meth}' method\n",
1248 p => $_, meth => $method);
1250 if ($method eq "resize2fs") {
1253 } elsif ($method eq "ntfsresize") {
1254 $g->ntfsresize ($_);
1256 die "internal error: unknown method: $method";
1262 # Sync disk and exit.
1274 $_ *= 1024 if $unit =~ /[KMGTPE]/;
1275 $_ *= 1024 if $unit =~ /[MGTPE]/;
1276 $_ *= 1024 if $unit =~ /[GTPE]/;
1277 $_ *= 1024 if $unit =~ /[TPE]/;
1278 $_ *= 1024 if $unit =~ /[PE]/;
1279 $_ *= 1024 if $unit =~ /[E]/;
1284 # Convert a number of bytes to a human-readable number.
1298 sprintf "%s%dK", $sgn, $_;
1299 } elsif ($_ < 1024 * 1024) {
1300 sprintf "%s%.1fM", $sgn, ($_ / 1024);
1302 sprintf "%s%.1fG", $sgn, ($_ / 1024 / 1024);
1306 # Return the size in bytes of a HOST block device.
1307 sub host_blockdevsize
1312 open BD, "PATH=/usr/sbin:/sbin:\$PATH blockdev --getsize64 $dev |"
1313 or die "blockdev: $!";
1319 # The reverse of device name translation, see
1320 # BLOCK DEVICE NAMING in guestfs(3).
1325 if (m{^/dev/[hv]d([a-z]\d)$}) {
1331 # Not as sophisticated as the guestfish progress bar, because
1332 # I intend to use an external library for this at some point (XXX).
1333 sub progress_callback
1335 my $proc_nr = shift;
1337 my $position = shift;
1340 my $ratio = $position / $total;
1341 if ($ratio < 0) { $ratio = 0 }
1342 elsif ($ratio > 1) { $ratio = 1 }
1344 my $dots = int ($ratio * 76);
1346 print "[", "#"x$dots, "-"x(76-$dots), "]\r";
1347 print "\n" if $ratio == 1;
1352 =head2 "Partition 1 does not end on cylinder boundary."
1354 Virt-resize aligns partitions to multiples of 64 sectors. Usually
1355 this means the partitions will not be aligned to the ancient CHS
1356 geometry. However CHS geometry is meaningless for disks manufactured
1357 since the early 1990s, and doubly so for virtual hard drives.
1358 Alignment of partitions to cylinders is not required by any modern
1361 =head2 RESIZING WINDOWS VIRTUAL MACHINES
1363 In Windows Vista and later versions, Microsoft switched to using a
1364 separate boot partition. In these VMs, typically C</dev/sda1> is the
1365 boot partition and C</dev/sda2> is the main (C:) drive. We have not
1366 had any luck resizing the boot partition. Doing so seems to break the
1367 guest completely. However expanding the second partition (ie. C:
1370 Windows may initiate a lengthy "chkdsk" on first boot after a resize,
1371 if NTFS partitions have been expanded. This is just a safety check
1372 and (unless it find errors) is nothing to worry about.
1374 =head1 ALTERNATIVE TOOLS
1376 There are several proprietary tools for resizing partitions. We
1377 won't mention any here.
1379 L<parted(8)> and its graphical shell gparted can do some types of
1380 resizing operations on disk images. They can resize and move
1381 partitions, but I don't think they can do anything with the contents,
1382 and they certainly don't understand LVM.
1384 L<guestfish(1)> can do everything that virt-resize can do and a lot
1385 more, but at a much lower level. You will probably end up
1386 hand-calculating sector offsets, which is something that virt-resize
1387 was designed to avoid. If you want to see the guestfish-equivalent
1388 commands that virt-resize runs, use the C<--debug> flag.
1392 L<virt-list-partitions(1)>,
1393 L<virt-list-filesystems(1)>,
1405 L<http://libguestfs.org/>.
1409 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
1413 Copyright (C) 2010 Red Hat Inc.
1415 This program is free software; you can redistribute it and/or modify
1416 it under the terms of the GNU General Public License as published by
1417 the Free Software Foundation; either version 2 of the License, or
1418 (at your option) any later version.
1420 This program is distributed in the hope that it will be useful,
1421 but WITHOUT ANY WARRANTY; without even the implied warranty of
1422 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1423 GNU General Public License for more details.
1425 You should have received a copy of the GNU General Public License
1426 along with this program; if not, write to the Free Software
1427 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.