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"
40 virt-resize - Resize a virtual machine disk
44 virt-resize [--resize /dev/sdaN=[+/-]<size>[%]]
45 [--expand /dev/sdaN] [--shrink /dev/sdaN]
46 [--ignore /dev/sdaN] [--delete /dev/sdaN] [...] indisk outdisk
50 Virt-resize is a tool which can resize a virtual machine disk, making
51 it larger or smaller overall, and resizing or deleting any partitions
54 Virt-resize B<cannot> resize disk images in-place. Virt-resize
55 B<should not> be used on live virtual machines - for consistent
56 results, shut the virtual machine down before resizing it.
58 If you are not familiar with the associated tools:
59 L<virt-list-partitions(1)>,
60 L<virt-list-filesystems(1)> and
62 we recommend you go and read those manual pages first.
66 =head2 EXPANDING A VIRTUAL MACHINE DISK
70 =item 1. Shut down the virtual machine
72 =item 2. Locate input disk image
74 Locate the input disk image (ie. the file or device on the host
75 containing the guest's disk). If the guest is managed by libvirt, you
76 can use C<virsh dumpxml> like this to find the disk image name:
78 # virsh dumpxml guestname | xpath /domain/devices/disk/source
81 <source dev="/dev/vg/lv_guest" />
83 =item 3. Look at current sizing
85 Use L<virt-list-partitions(1)> to display the current partitions and
88 # virt-list-partitions -lht /dev/vg/lv_guest
93 (This example is a virtual machine with an 8 GB disk which we would
94 like to expand up to 10 GB).
96 =item 4. Create output disk
98 Virt-resize cannot do in-place disk modifications. You have to have
99 space to store the resized output disk.
101 To store the resized disk image in a file, create a file of a suitable
105 # truncate -s 10G outdisk
107 Or use L<lvcreate(1)> to create a logical volume:
109 # lvcreate -L 10G -n lv_name vg_name
111 Or use L<virsh(1)> vol-create-as to create a libvirt storage volume:
114 # virsh vol-create-as poolname newvol 10G
118 virt-resize takes two mandatory parameters, the input disk (eg. device
119 or file) and the output disk. The output disk is the one created in
122 # virt-resize indisk outdisk
124 This command just copies disk image C<indisk> to disk image C<outdisk>
125 I<without> resizing or changing any existing partitions. If
126 C<outdisk> is larger, then an extra, empty partition is created at the
127 end of the disk covering the extra space. If C<outdisk> is smaller,
128 then it will give an error.
130 More realistically you'd want to expand existing partitions in the
131 disk image by passing extra options (for the full list see the
132 L</OPTIONS> section below).
134 L</--expand> is the most useful option. It expands the named
135 partition within the disk to fill any extra space:
137 # virt-resize --expand /dev/sda2 indisk outdisk
139 (In this case, an extra partition is I<not> created at the end of the
140 disk, because there will be no unused space).
142 L</--resize> is the other commonly used option. The following would
143 increase the size of /dev/sda1 by 200M, and expand /dev/sda2
144 to fill the rest of the available space:
146 # virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 \
149 If the expanded partition in the image contains a filesystem or LVM
150 PV, then if virt-resize knows how, it will resize the contents, the
151 equivalent of calling a command such as L<pvresize(8)>,
152 L<resize2fs(8)> or L<ntfsresize(8)>. However virt-resize does not
153 know how to resize some filesystems, so you would have to online
154 resize them after booting the guest. And virt-resize also does not
155 resize anything inside an LVM PV, it just resizes the PV itself and
156 leaves the user to resize any LVs inside that PV as desired.
158 Other options are covered below.
162 Thoroughly test the new disk image I<before> discarding the old one.
164 If you are using libvirt, edit the XML to point at the new disk:
166 # virsh edit guestname
168 Change E<lt>source ...E<gt>, see
169 L<http://libvirt.org/formatdomain.html#elementsDisks>
171 Then start up the domain with the new, resized disk:
173 # virsh start guestname
175 and check that it still works. See also the L</NOTES> section below
176 for additional information.
178 =item 7. Resize LVs etc inside the guest
180 (This can also be done offline using L<guestfish(1)>)
182 Once the guest has booted you should see the new space available, at
183 least for filesystems that virt-resize knows how to resize, and for
184 PVs. The user may need to resize LVs inside PVs, and also resize
185 filesystem types that virt-resize does not know how to expand.
189 =head2 SHRINKING A VIRTUAL MACHINE DISK
191 Shrinking is somewhat more complex than expanding, and only an
192 overview is given here.
194 Firstly virt-resize will not attempt to shrink any partition content
195 (PVs, filesystems). The user has to shrink content before passing the
196 disk image to virt-resize, and virt-resize will check that the content
197 has been shrunk properly.
199 (Shrinking can also be done offline using L<guestfish(1)>)
201 After shrinking PVs and filesystems, shut down the guest, and proceed
202 with steps 3 and 4 above to allocate a new disk image.
204 Then run virt-resize with any of the C<--shrink> and/or C<--resize>
207 =head2 IGNORING OR DELETING PARTITIONS
209 virt-resize also gives a convenient way to ignore or delete partitions
210 when copying from the input disk to the output disk. Ignoring a
211 partition speeds up the copy where you don't care about the existing
212 contents of a partition. Deleting a partition removes it completely,
213 but note that it also renumbers any partitions after the one which is
214 deleted, which can leave some guests unbootable.
234 Display version number and exit.
240 =item B<--resize part=size>
242 Resize the named partition (expanding or shrinking it) so that it has
245 C<size> can be expressed as an absolute number followed by
246 b/K/M/G/T/P/E to mean bytes, Kilobytes, Megabytes, Gigabytes,
247 Terabytes, Petabytes or Exabytes; or as a percentage of the current
248 size; or as a relative number or percentage. For example:
250 --resize /dev/sda2=10G
252 --resize /dev/sda4=90%
254 --resize /dev/sda2=+1G
256 --resize /dev/sda2=-200M
258 --resize /dev/sda1=+128K
260 --resize /dev/sda1=+10%
262 --resize /dev/sda1=-10%
264 You can increase the size of any partition. Virt-resize will expand
265 the direct content of the partition if it knows how (see C<--expand>
268 You can only I<decrease> the size of partitions that contain
269 filesystems or PVs which have already been shrunk. Virt-resize will
270 check this has been done before proceeding, or else will print an
271 error (see also C<--resize-force>).
273 You can give this option multiple times.
279 =item B<--resize-force part=size>
281 This is the same as C<--resize> except that it will let you decrease
282 the size of any partition. Generally this means you will lose any
283 data which was at the end of the partition you shrink, but you may not
284 care about that (eg. if shrinking an unused partition, or if you can
285 easily recreate it such as a swap partition).
287 See also the C<--ignore> option.
293 =item B<--expand part>
295 Expand the named partition so it uses up all extra space (space left
296 over after any other resize changes that you request have been done).
298 If virt-resize knows how, it will expand the direct content of the
299 partition. For example, if the partition is an LVM PV, it will expand
300 the PV to fit (like calling L<pvresize(8)>). Virt-resize leaves any
301 other content it doesn't know about alone.
303 Currently virt-resize can resize:
309 ext2, ext3 and ext4 filesystems when they are contained
310 directly inside a partition.
314 NTFS filesystems contained directly in a partition, if libguestfs was
315 compiled with support for NTFS.
317 The filesystem must have been shut down consistently last time it was
318 used. Additionally, L<ntfsresize(8)> marks the resized filesystem as
319 requiring a consistency check, so at the first boot after resizing
320 Windows will check the disk.
324 LVM PVs (physical volumes). However virt-resize does I<not>
325 resize anything inside the PV. The user will have to resize
330 Note that you cannot use C<--expand> and C<--shrink> together.
336 =item B<--shrink part>
338 Shrink the named partition until the overall disk image fits in the
339 destination. The named partition B<must> contain a filesystem or PV
340 which has already been shrunk using another tool (eg. L<guestfish(1)>
341 or other online tools). Virt-resize will check this and give an error
342 if it has not been done.
344 The amount by which the overall disk must be shrunk (after carrying
345 out all other operations requested by the user) is called the
346 "deficit". For example, a straight copy (assume no other operations)
347 from a 5GB disk image to a 4GB disk image results in a 1GB deficit.
348 In this case, virt-resize would give an error unless the user
349 specified a partition to shrink and that partition had more than a
350 gigabyte of free space.
352 Note that you cannot use C<--expand> and C<--shrink> together.
358 =item B<--ignore part>
360 Ignore the named partition. Effectively this means the partition is
361 allocated on the destination disk, but the content is not copied
362 across from the source disk. The content of the partition will be
363 blank (all zero bytes).
365 You can give this option multiple times.
371 =item B<--delete part>
373 Delete the named partition. It would be more accurate to describe
374 this as "don't copy it over", since virt-resize doesn't do in-place
375 changes and the original disk image is left intact.
377 Note that when you delete a partition, then anything contained in the
378 partition is also deleted. Furthermore, this causes any partitions
379 that come after to be I<renumbered>, which can easily make your guest
382 You can give this option multiple times.
388 =item B<--LV-expand logvol>
390 This takes the logical volume and, as a final step, expands it to fill
391 all the space available in its volume group. A typical usage,
392 assuming a Linux guest with a single PV C</dev/sda2> and a root device
393 called C</dev/vg_guest/lv_root> would be:
395 virt-resize indisk outdisk \
396 --expand /dev/sda2 --LV-expand /dev/vg_guest/lv_root
398 This would first expand the partition (and PV), and then expand the
399 root device to fill the extra space in the PV.
401 The contents of the LV are also resized if virt-resize knows how to do
402 that. You can stop virt-resize from trying to expand the content by
403 using the option C<--no-expand-content>.
405 Use L<virt-list-filesystems(1)> to list the filesystems in
408 You can give this option multiple times, I<but> it doesn't
409 make sense to do this unless the logical volumes you specify
410 are all in different volume groups.
414 my $copy_boot_loader = 1;
416 =item B<--no-copy-boot-loader>
418 By default, virt-resize copies over some sectors at the start of the
419 disk (up to the beginning of the first partition). Commonly these
420 sectors contain the Master Boot Record (MBR) and the boot loader, and
421 are required in order for the guest to boot correctly.
423 If you specify this flag, then this initial copy is not done. You may
424 need to reinstall the boot loader in this case.
428 my $extra_partition = 1;
429 my $min_extra_partition = 10 * 1024 * 1024; # see below
431 =item B<--no-extra-partition>
433 By default, virt-resize creates an extra partition if there is any
434 extra, unused space after all resizing has happened. Use this option
435 to prevent the extra partition from being created. If you do this
436 then the extra space will be inaccessible until you run fdisk, parted,
437 or some other partitioning tool in the guest.
439 Note that if the surplus space is smaller than 10 MB, no extra
440 partition will be created.
444 my $expand_content = 1;
446 =item B<--no-expand-content>
448 By default, virt-resize will try to expand the direct contents
449 of partitions, if it knows how (see C<--expand> option above).
451 If you give the C<--no-expand-content> option then virt-resize
452 will not attempt this.
458 =item B<-d> | B<--debug>
460 Enable debugging messages.
466 =item B<-n> | B<--dryrun>
468 Print a summary of what would be done, but don't do anything.
474 =item B<-q> | B<--quiet>
476 Don't print the summary.
482 GetOptions ("help|?" => \$help,
483 "version" => \$version,
484 "resize=s" => \@resize,
485 "resize-force=s" => \@resize_force,
486 "expand=s" => \$expand,
487 "shrink=s" => \$shrink,
488 "ignore=s" => \@ignore,
489 "delete=s" => \@delete,
490 "lv-expand=s" => \@lv_expand,
491 "copy-boot-loader!" => \$copy_boot_loader,
492 "extra-partition!" => \$extra_partition,
493 "expand-content!" => \$expand_content,
494 "d|debug" => \$debug,
495 "n|dryrun|dry-run" => \$dryrun,
496 "q|quiet" => \$quiet,
498 pod2usage (1) if $help;
500 my $g = Sys::Guestfs->new ();
501 my %h = $g->version ();
502 print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
506 die "virt-resize [--options] indisk outdisk\n" unless @ARGV == 2;
508 # Check in and out images exist.
509 my $infile = $ARGV[0];
510 my $outfile = $ARGV[1];
511 die __x("virt-resize: {file}: does not exist or is not readable\n", file => $infile)
513 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)
518 my $insize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($infile);
520 my $outsize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($outfile);
523 print "$infile size $insize bytes\n";
524 print "$outfile size $outsize bytes\n";
527 # In reality the number of sectors containing boot loader data will be
528 # less than this (although Windows 7 defaults to putting the first
529 # partition on sector 2048, and has quite a large boot loader).
531 # However make this large enough to be sure that we have copied over
532 # the boot loader. We could also do this by looking for the sector
533 # offset of the first partition.
535 # It doesn't matter if we copy too much.
536 my $boot_sectors = 4096;
538 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
539 file => $infile, sz => $insize)
540 if $insize < $boot_sectors * 512;
541 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
542 file => $outfile, sz => $outsize)
543 if $outsize < $boot_sectors * 512;
545 # Copy the boot loader across.
546 do_copy_boot_loader () if $copy_boot_loader;
548 sub do_copy_boot_loader
550 print "copying boot loader ...\n" if $debug;
551 open IFILE, $infile or die "$infile: $!";
553 my $r = sysread (IFILE, $s, $boot_sectors * 512) or die "$infile: $!";
554 die "$infile: short read" if $r < $boot_sectors * 512;
555 open OFILE, "+<$outfile" or die "$outfile: $!";
556 sysseek OFILE, 0, SEEK_SET or die "$outfile: seek: $!";
557 $r = syswrite (OFILE, $s, $boot_sectors * 512) or die "$outfile: $!";
558 die "$outfile: short write" if $r < $boot_sectors * 512;
561 # Add them to the handle and launch the appliance.
567 $g = Sys::Guestfs->new ();
568 $g->set_trace (1) if $debug;
569 $g->add_drive_ro ($infile);
570 $g->add_drive ($outfile);
574 my $sectsize = $g->blockdev_getss ("/dev/sdb");
576 my $to_be_expanded = 0;
578 # Get the partitions on the source disk.
581 check_source_disk ();
583 sub check_source_disk
587 # Partitions and PVs.
588 my @p = $g->part_list ("/dev/sda");
590 my $name = "/dev/sda" . $_->{part_num};
591 push @partitions, $name;
595 $h{bootable} = $g->part_get_bootable ("/dev/sda", $h{part_num});
596 eval { $h{mbr_id} = $g->part_get_mbr_id ("/dev/sda", $h{part_num}); };
597 $partitions{$name} = \%h;
601 # Examine each partition.
602 my @pvs_full = $g->pvs_full ();
603 examine_partition ($_) foreach @partitions;
605 sub examine_partition
611 my $type = "unknown";
613 $type = $g->vfs_type ($part);
615 $partitions{$part}->{type} = $type;
617 # Can we get the actual size of this object (ie. to find out if it
618 # is smaller than the container for shrinking)?
620 if ($type eq "LVM2_member") { # LVM PV
621 foreach (@pvs_full) {
622 $fssize = $_->{pv_size}
623 if canonicalize ($_->{pv_name}) eq $part;
625 } else { # Something mountable?
627 $g->mount_ro ($part, "/");
629 my %stat = $g->statvfs ("/");
630 $fssize = $stat{bsize} * $stat{blocks};
638 # This might be undef if we didn't successfully find the size. In
639 # that case user won't be allowed to shrink this partition except
641 $partitions{$part}->{fssize} = $fssize;
643 # Is it partition content that we know how to expand?
644 $partitions{$part}->{can_expand_content} = 0;
645 if ($expand_content) {
646 if ($type eq "LVM2_member") {
647 $partitions{$part}->{can_expand_content} = 1;
648 $partitions{$part}->{expand_content_method} = "pvresize";
649 } elsif ($type =~ /^ext[234]$/) {
650 $partitions{$part}->{can_expand_content} = 1;
651 $partitions{$part}->{expand_content_method} = "resize2fs";
652 } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
653 $partitions{$part}->{can_expand_content} = 1;
654 $partitions{$part}->{expand_content_method} = "ntfsresize";
660 print "partitions found: ", join (", ", @partitions), "\n";
661 foreach my $part (@partitions) {
663 foreach (sort keys %{$partitions{$part}}) {
664 print("\t", $_, " = ",
665 defined ($partitions{$part}->{$_})
666 ? $partitions{$part}->{$_} : "undef",
672 # Examine the LVs (for --lv-expand option).
673 my @lvs = $g->lvs ();
675 examine_lv ($_) foreach @lvs;
676 mark_lvs_to_expand ();
682 $lvs{$_}->{name} = $_;
684 my $type = "unknown";
686 $type = $g->vfs_type ($_);
688 $lvs{$_}->{type} = $type;
690 if ($expand_content) {
691 if ($type =~ /^ext[234]$/) {
692 $lvs{$_}->{can_expand_content} = 1;
693 $lvs{$_}->{expand_content_method} = "resize2fs";
694 } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
695 $lvs{$_}->{can_expand_content} = 1;
696 $lvs{$_}->{expand_content_method} = "ntfsresize";
701 sub mark_lvs_to_expand {
704 foreach (@lv_expand) {
705 die __x("virt-resize: no logical volume called {n}\n",
707 unless exists $lvs{$_};
709 if ($lvs{$_}->{can_expand_content}) {
710 $lvs{$_}->{will_expand_content} = 1;
721 $_ = "/dev/$_" unless $_ =~ m{^/dev};
722 $_ = canonicalize ($_);
724 unless (exists $partitions{$_}) {
725 die __x("{p}: partition not found in the source disk image, when using the '{opt}' command line option\n",
730 if ($partitions{$_}->{ignore}) {
731 die __x("{p}: partition ignored, you cannot use it in another command line argument\n",
734 if ($partitions{$_}->{delete}) {
735 die __x("{p}: partition deleted, you cannot use it in another command line argument\n",
743 do_ignore ($_) foreach @ignore;
748 $_ = find_partition ($_, "--ignore");
749 $partitions{$_}->{ignore} = 1;
753 do_delete ($_) foreach @delete;
758 $_ = find_partition ($_, "--delete");
759 $partitions{$_}->{delete} = 1;
762 # Handle --resize and --resize-force.
763 do_resize ($_, 0, "--resize") foreach @resize;
764 do_resize ($_, 1, "--resize-force") foreach @resize_force;
772 # Argument is "part=size" ...
773 my ($part, $sizefield) = split /=/, $_, 2;
774 $part = find_partition ($part, $option);
776 if (exists $partitions{$part}->{newsize}) {
777 die __x("{p}: this partition has already been marked for resizing\n",
781 # Parse the size field.
782 my $oldsize = $partitions{$part}->{part_size};
784 if (!defined ($sizefield) || $sizefield eq "") {
785 die __x("{p}: missing size field in {o} option\n",
786 p => $part, o => $option);
787 } elsif ($sizefield =~ /^([.\d]+)([bKMGTPE])$/) {
788 $newsize = sizebytes ($1, $2);
789 } elsif ($sizefield =~ /^\+([.\d]+)([bKMGTPE])$/) {
790 my $incr = sizebytes ($1, $2);
791 $newsize = $oldsize + $incr;
792 } elsif ($sizefield =~ /^-([.\d]+)([bKMGTPE])$/) {
793 my $decr = sizebytes ($1, $2);
794 $newsize = $oldsize - $decr;
795 } elsif ($sizefield =~ /^([.\d]+)%$/) {
796 $newsize = $oldsize * $1 / 100;
797 } elsif ($sizefield =~ /^\+([.\d]+)%$/) {
798 $newsize = $oldsize + $oldsize * $1 / 100;
799 } elsif ($sizefield =~ /^-([.\d]+)%$/) {
800 $newsize = $oldsize - $oldsize * $1 / 100;
802 die __x("{p}: {f}: cannot parse size field\n",
803 p => $part, f => $sizefield)
807 die __x("{p}: new size is zero or negative\n", p => $part);
809 mark_partition_for_resize ($part, $oldsize, $newsize, $force, $option);
812 sub mark_partition_for_resize
821 # Do nothing if the size is the same.
822 return if $oldsize == $newsize;
824 my $bigger = $newsize > $oldsize;
826 # Check there is space to shrink this.
827 unless ($bigger || $force) {
828 if (! $partitions{$part}->{fssize} ||
829 $partitions{$part}->{fssize} > $newsize) {
830 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",
835 $partitions{$part}->{newsize} = $newsize;
837 if ($partitions{$part}->{can_expand_content} && $bigger) {
838 $partitions{$part}->{will_expand_content} = 1;
843 # Handle --expand and --shrink.
845 if (defined $expand && defined $shrink) {
846 die __"virt-resize: you cannot use options --expand and --shrink together\n"
848 if (defined $expand || defined $shrink) {
849 calculate_surplus ();
852 print "surplus before --expand or --shrink: $surplus (",
853 human_size ($surplus), ")\n";
856 do_expand () if $expand;
857 do_shrink () if $shrink;
860 # (Re-)calculate surplus after doing expand or shrink.
861 calculate_surplus ();
863 # Add up the total space required on the target so far, compared
864 # to the size of the target. We end up with a surplus or deficit.
865 sub calculate_surplus
869 # We need some overhead for partitioning. Worst case would be for
870 # EFI partitioning + massive per-partition alignment.
871 my $overhead = $sectsize * (
872 2 * 64 + # GPT start and end
873 (64 * (@partitions + 1)) + # Maximum alignment
874 ($boot_sectors - 64) # Boot loader
878 foreach (@partitions) {
879 if ($partitions{$_}->{newsize}) {
880 $required += $partitions{$_}->{newsize}
882 $required += $partitions{$_}->{part_size}
886 # Compare that to the actual target disk.
887 $surplus = $outsize - ($required + $overhead);
894 unless ($surplus > 0) {
895 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",
896 h => human_size (-$surplus));
899 my $part = find_partition ($expand, "--expand");
900 my $oldsize = $partitions{$part}->{part_size};
901 mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
909 unless ($surplus < 0) {
910 die __"virt-resize: error: cannot use --shrink because there is no deficit\n(see 'deficit' in the virt-resize(1) man page)\n"
913 my $part = find_partition ($shrink, "--shrink");
914 my $oldsize = $partitions{$part}->{part_size};
915 mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
920 print_summary () unless $quiet;
925 print __"Summary of changes:\n";
927 foreach my $part (@partitions) {
928 if ($partitions{$part}->{ignore}) {
929 print __x("{p}: partition will be ignored\n", p => $part);
930 } elsif ($partitions{$part}->{delete}) {
931 print __x("{p}: partition will be deleted\n", p => $part);
932 } elsif ($partitions{$part}->{newsize}) {
933 print __x("{p}: partition will be resized from {oldsize} to {newsize}\n",
935 oldsize => human_size ($partitions{$part}->{part_size}),
936 newsize => human_size ($partitions{$part}->{newsize}));
937 if ($partitions{$part}->{will_expand_content}) {
938 print __x("{p}: content will be expanded using the '{meth}' method\n",
940 meth => $partitions{$part}->{expand_content_method});
943 print __x("{p}: partition will be left alone\n", p => $part);
947 foreach my $lv (@lv_expand) {
948 print __x("{n}: LV will be expanded to maximum size\n",
952 foreach my $lv (@lvs) {
953 if ($lvs{$lv}->{will_expand_content}) {
954 print __x("{n}: content will be expanded using the '{meth}' method\n",
956 meth => $lvs{$lv}->{expand_content_method});
961 print __x("There is a surplus of {spl} bytes ({h}).\n",
963 h => human_size ($surplus));
964 if ($extra_partition) {
965 if ($surplus >= $min_extra_partition) {
966 print __"An extra partition will be created for the surplus.\n";
968 print __"The surplus space is not large enough for an extra partition to be created\nand so it will just be ignored.\n";
971 print __"The surplus space will be ignored. Run a partitioning program in the guest\nto partition this extra space if you want.\n";
973 } elsif ($surplus < 0) {
974 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",
976 h => human_size (-$surplus));
982 # Repartition the target disk.
991 if ($copy_boot_loader) {
992 $parttype = $g->part_get_parttype ("/dev/sdb");
996 print "partition table type: $parttype\n" if $debug;
998 # Delete any existing partitions on the destination disk,
999 # but leave the bootloader that we copied over intact.
1000 if ($copy_boot_loader) {
1001 # Delete in reverse as an easy way to deal with extended
1003 foreach (sort { $b cmp $a } $g->list_partitions ()) {
1004 if (m{^/dev/.db(\d+)$}) {
1005 $g->part_del ("/dev/sdb", $1);
1009 # Didn't copy over the initial boot loader, so we need
1010 # to make a new partition table here.
1011 $g->part_init ("/dev/sdb", $parttype);
1014 # Work out where to start the first partition.
1015 die __"virt-resize: source disk does not have a first partition\n"
1016 unless exists ($partitions{"/dev/sda1"});
1017 my $start = $partitions{"/dev/sda1"}->{part_start} / $sectsize;
1020 $start = ($start + 63) & ~63;
1022 print "starting to partition from $start\n" if $debug;
1024 # Create the new partitions.
1025 foreach my $part (@partitions) {
1026 unless ($partitions{$part}->{delete}) {
1029 if ($partitions{$part}->{newsize}) {
1030 $size = ($partitions{$part}->{newsize} + $sectsize - 1)
1033 $size = ($partitions{$part}->{part_size} + $sectsize - 1)
1038 my ($target, $end, $part_num) = add_partition ($start, $size);
1039 $partitions{$part}->{target} = $target;
1041 if ($partitions{$part}->{bootable}) {
1042 $g->part_set_bootable ("/dev/sdb", $part_num, 1);
1045 if ($partitions{$part}->{mbr_id}) {
1046 $g->part_set_mbr_id ("/dev/sdb", $part_num,
1047 $partitions{$part}->{mbr_id});
1050 # Start of next partition + alignment.
1052 $start = ($start + 63) & ~63;
1056 # Create surplus partition.
1057 if ($extra_partition && $surplus >= $min_extra_partition) {
1058 add_partition ($start, $outsize / $sectsize - 64 - $start);
1069 my ($target, $end, $part_num);
1071 if ($nextpart <= 3 || $parttype ne "msdos") {
1072 $target = "/dev/sdb$nextpart";
1073 $end = $start + $size - 1;
1074 $g->part_add ("/dev/sdb", "primary", $start, $end);
1075 $part_num = $nextpart++;
1077 if ($nextpart == 4) {
1078 $g->part_add ("/dev/sdb", "extended", $start, -1);
1079 $part_num = $nextpart++;
1082 $target = "/dev/sdb$nextpart";
1083 $end = $start + $size - 1;
1084 $g->part_add ("/dev/sdb", "logical", $start, $end);
1085 $part_num = $nextpart++;
1088 return ($target, $end, $part_num);
1091 # Copy over the data.
1096 foreach my $part (@partitions)
1098 unless ($partitions{$part}->{ignore}) {
1099 my $target = $partitions{$part}->{target};
1101 my $oldsize = $partitions{$part}->{part_size};
1103 if ($partitions{$part}->{newsize}) {
1104 $newsize = $partitions{$part}->{newsize};
1106 $newsize = $partitions{$part}->{part_size};
1109 if (!$quiet && !$debug) {
1111 print __x("Copying {p} ...", p => $part);
1114 $g->copy_size ($part, $target,
1115 $newsize < $oldsize ? $newsize : $oldsize);
1117 if (!$quiet && !$debug) {
1118 print " ", __"done", "\n";
1125 # After copying the data over we must shut down and restart the
1126 # appliance in order to expand the content. The reason for this may
1127 # not be obvious, but it's because otherwise we'll have duplicate VGs
1128 # (the old VG(s) and the new VG(s)) which breaks LVM.
1130 # The restart is only required if we're going to expand something.
1132 if ($to_be_expanded > 0) {
1133 restart_appliance ();
1134 expand_partitions ();
1136 expand_lvs_content ();
1139 sub restart_appliance
1141 # Sync disk and exit.
1146 $g = Sys::Guestfs->new ();
1147 $g->set_trace (1) if $debug;
1148 $g->add_drive ($outfile);
1151 # Target partitions have changed from /dev/sdb to /dev/sda,
1153 foreach my $part (@partitions)
1155 my $target = $partitions{$part}->{target};
1157 if ($target =~ m{/dev/(.)db(.*)}) {
1158 $partitions{$part}->{target} = "/dev/$1da$2";
1160 die "internal error: unexpected partition target: $target";
1166 sub expand_partitions
1168 foreach my $part (@partitions)
1170 unless ($partitions{$part}->{ignore}) {
1171 my $target = $partitions{$part}->{target};
1173 # Expand if requested.
1174 if ($partitions{$part}->{will_expand_content}) {
1175 if (!$quiet && !$debug) {
1176 print __x("Expanding {p} using the '{meth}' method\n",
1178 meth => $partitions{$part}->{expand_content_method});
1180 expand_target_partition ($part)
1187 sub expand_target_partition
1194 die unless $partitions{$part}->{can_expand_content};
1195 die unless $partitions{$part}->{will_expand_content};
1196 die unless $partitions{$part}->{expand_content_method};
1197 die unless $partitions{$part}->{target};
1198 die unless $expand_content;
1200 my $target = $partitions{$part}->{target};
1201 my $method = $partitions{$part}->{expand_content_method};
1202 if ($method eq "pvresize") {
1203 $g->pvresize ($target);
1205 elsif ($method eq "resize2fs") {
1206 $g->e2fsck_f ($target);
1207 $g->resize2fs ($target);
1209 elsif ($method eq "ntfsresize") {
1210 $g->ntfsresize ($target);
1213 die "internal error: unknown method: $method";
1221 foreach (@lv_expand) {
1222 $g->lvresize_free ($_, 100);
1226 sub expand_lvs_content
1231 if ($lvs{$_}->{will_expand_content}) {
1232 my $method = $lvs{$_}->{expand_content_method};
1233 if (!$quiet && !$debug) {
1234 print __x("Expanding {p} using the '{meth}' method\n",
1235 p => $_, meth => $method);
1237 if ($method eq "resize2fs") {
1240 } elsif ($method eq "ntfsresize") {
1241 $g->ntfsresize ($_);
1243 die "internal error: unknown method: $method";
1249 # Sync disk and exit.
1261 $_ *= 1024 if $unit =~ /[KMGTPE]/;
1262 $_ *= 1024 if $unit =~ /[MGTPE]/;
1263 $_ *= 1024 if $unit =~ /[GTPE]/;
1264 $_ *= 1024 if $unit =~ /[TPE]/;
1265 $_ *= 1024 if $unit =~ /[PE]/;
1266 $_ *= 1024 if $unit =~ /[E]/;
1271 # Convert a number of bytes to a human-readable number.
1285 sprintf "%s%dK", $sgn, $_;
1286 } elsif ($_ < 1024 * 1024) {
1287 sprintf "%s%.1fM", $sgn, ($_ / 1024);
1289 sprintf "%s%.1fG", $sgn, ($_ / 1024 / 1024);
1293 # Return the size in bytes of a HOST block device.
1294 sub host_blockdevsize
1299 open BD, "PATH=/usr/sbin:/sbin:\$PATH blockdev --getsize64 $dev |"
1300 or die "blockdev: $!";
1306 # The reverse of device name translation, see
1307 # BLOCK DEVICE NAMING in guestfs(3).
1312 if (m{^/dev/[hv]d([a-z]\d)$}) {
1320 =head2 "Partition 1 does not end on cylinder boundary."
1322 Virt-resize aligns partitions to multiples of 64 sectors. Usually
1323 this means the partitions will not be aligned to the ancient CHS
1324 geometry. However CHS geometry is meaningless for disks manufactured
1325 since the early 1990s, and doubly so for virtual hard drives.
1326 Alignment of partitions to cylinders is not required by any modern
1329 =head2 RESIZING WINDOWS VIRTUAL MACHINES
1331 In Windows Vista and later versions, Microsoft switched to using a
1332 separate boot partition. In these VMs, typically C</dev/sda1> is the
1333 boot partition and C</dev/sda2> is the main (C:) drive. We have not
1334 had any luck resizing the boot partition. Doing so seems to break the
1335 guest completely. However expanding the second partition (ie. C:
1338 Windows may initiate a lengthy "chkdsk" on first boot after a resize,
1339 if NTFS partitions have been expanded. This is just a safety check
1340 and (unless it find errors) is nothing to worry about.
1342 =head1 ALTERNATIVE TOOLS
1344 There are several proprietary tools for resizing partitions. We
1345 won't mention any here.
1347 L<parted(8)> and its graphical shell gparted can do some types of
1348 resizing operations on disk images. They can resize and move
1349 partitions, but I don't think they can do anything with the contents,
1350 and they certainly don't understand LVM.
1352 L<guestfish(1)> can do everything that virt-resize can do and a lot
1353 more, but at a much lower level. You will probably end up
1354 hand-calculating sector offsets, which is something that virt-resize
1355 was designed to avoid. If you want to see the guestfish-equivalent
1356 commands that virt-resize runs, use the C<--debug> flag.
1360 L<virt-list-partitions(1)>,
1361 L<virt-list-filesystems(1)>,
1373 L<http://libguestfs.org/>.
1377 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
1381 Copyright (C) 2010 Red Hat Inc.
1383 This program is free software; you can redistribute it and/or modify
1384 it under the terms of the GNU General Public License as published by
1385 the Free Software Foundation; either version 2 of the License, or
1386 (at your option) any later version.
1388 This program is distributed in the hope that it will be useful,
1389 but WITHOUT ANY WARRANTY; without even the implied warranty of
1390 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1391 GNU General Public License for more details.
1393 You should have received a copy of the GNU General Public License
1394 along with this program; if not, write to the Free Software
1395 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.