virt-resize: Mention alternate tools like gparted in the documentation.
[libguestfs.git] / tools / virt-resize
1 #!/usr/bin/perl -w
2 # virt-resize
3 # Copyright (C) 2010 Red Hat Inc.
4 #
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.
9 #
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.
14 #
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.
18
19 use warnings;
20 use strict;
21
22 use Sys::Guestfs;
23 use Sys::Guestfs::Lib qw(feature_available);
24 use Fcntl qw(S_ISREG SEEK_SET);
25 use POSIX qw(floor);
26 use Pod::Usage;
27 use Getopt::Long;
28 use Data::Dumper;
29 use Locale::TextDomain 'libguestfs';
30
31 $Data::Dumper::Sortkeys = 1;
32
33 die __"virt-resize: sorry this program does not work on a 32 bit host\n"
34     if ~1 == 4294967294;
35
36 =encoding utf8
37
38 =head1 NAME
39
40 virt-resize - Resize a virtual machine disk
41
42 =head1 SYNOPSIS
43
44  virt-resize [--resize /dev/sdaN=[+/-]<size>[%]]
45    [--expand /dev/sdaN] [--shrink /dev/sdaN]
46    [--ignore /dev/sdaN] [--delete /dev/sdaN] [...] indisk outdisk
47
48 =head1 DESCRIPTION
49
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
52 contained within.
53
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.
57
58 If you are not familiar with the associated tools:
59 L<virt-list-partitions(1)>,
60 L<virt-list-filesystems(1)> and
61 L<virt-df(1)>,
62 we recommend you go and read those manual pages first.
63
64 =head1 BASIC USAGE
65
66 =head2 EXPANDING A VIRTUAL MACHINE DISK
67
68 =over 4
69
70 =item 1. Shut down the virtual machine
71
72 =item 2. Locate input disk image
73
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:
77
78  # virsh dumpxml guestname | xpath /domain/devices/disk/source
79  Found 1 nodes:
80  -- NODE --
81  <source dev="/dev/vg/lv_guest" />
82
83 =item 3. Look at current sizing
84
85 Use L<virt-list-partitions(1)> to display the current partitions and
86 sizes:
87
88  # virt-list-partitions -lht /dev/vg/lv_guest
89  /dev/sda1 ext3 101.9M
90  /dev/sda2 pv 7.9G
91  /dev/sda device 8.0G
92
93 (This example is a virtual machine with an 8 GB disk which we would
94 like to expand up to 10 GB).
95
96 =item 4. Create output disk
97
98 Virt-resize cannot do in-place disk modifications.  You have to have
99 space to store the resized output disk.
100
101 To store the resized disk image in a file, create a file of a suitable
102 size:
103
104  # rm -f outdisk
105  # truncate -s 10G outdisk
106
107 Or use L<lvcreate(1)> to create a logical volume:
108
109  # lvcreate -L 10G -n lv_name vg_name
110
111 Or use L<virsh(1)> vol-create-as to create a libvirt storage volume:
112
113  # virsh pool-list
114  # virsh vol-create-as poolname newvol 10G
115
116 =item 5. Resize
117
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
120 the previous step.
121
122  # virt-resize indisk outdisk
123
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.
129
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).
133
134 L</--expand> is the most useful option.  It expands the named
135 partition within the disk to fill any extra space:
136
137  # virt-resize --expand /dev/sda2 indisk outdisk
138
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).
141
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:
145
146  # virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 \
147      indisk outdisk
148
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.
157
158 Other options are covered below.
159
160 =item 6. Test
161
162 Thoroughly test the new disk image I<before> discarding the old one.
163
164 If you are using libvirt, edit the XML to point at the new disk:
165
166  # virsh edit guestname
167
168 Change E<lt>source ...E<gt>, see
169 L<http://libvirt.org/formatdomain.html#elementsDisks>
170
171 Then start up the domain with the new, resized disk:
172
173  # virsh start guestname
174
175 and check that it still works.  See also the L</NOTES> section below
176 for additional information.
177
178 =item 7. Resize LVs etc inside the guest
179
180 (This can also be done offline using L<guestfish(1)>)
181
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.
186
187 =back
188
189 =head2 SHRINKING A VIRTUAL MACHINE DISK
190
191 Shrinking is somewhat more complex than expanding, and only an
192 overview is given here.
193
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.
198
199 (Shrinking can also be done offline using L<guestfish(1)>)
200
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.
203
204 Then run virt-resize with any of the C<--shrink> and/or C<--resize>
205 options.
206
207 =head2 IGNORING OR DELETING PARTITIONS
208
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.
215
216 =head1 OPTIONS
217
218 =over 4
219
220 =cut
221
222 my $help;
223
224 =item B<--help>
225
226 Display help.
227
228 =cut
229
230 my $version;
231
232 =item B<--version>
233
234 Display version number and exit.
235
236 =cut
237
238 my @resize;
239
240 =item B<--resize part=size>
241
242 Resize the named partition (expanding or shrinking it) so that it has
243 the given size.
244
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:
249
250  --resize /dev/sda2=10G
251
252  --resize /dev/sda4=90%
253
254  --resize /dev/sda2=+1G
255
256  --resize /dev/sda2=-200M
257
258  --resize /dev/sda1=+128K
259
260  --resize /dev/sda1=+10%
261
262  --resize /dev/sda1=-10%
263
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>
266 below).
267
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>).
272
273 You can give this option multiple times.
274
275 =cut
276
277 my @resize_force;
278
279 =item B<--resize-force part=size>
280
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).
286
287 See also the C<--ignore> option.
288
289 =cut
290
291 my $expand;
292
293 =item B<--expand part>
294
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).
297
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.
302
303 Currently virt-resize can resize:
304
305 =over 4
306
307 =item *
308
309 ext2, ext3 and ext4 filesystems when they are contained
310 directly inside a partition.
311
312 =item *
313
314 NTFS filesystems contained directly in a partition, if libguestfs was
315 compiled with support for NTFS.
316
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.
321
322 =item *
323
324 LVM PVs (physical volumes).  However virt-resize does I<not>
325 resize anything inside the PV.  The user will have to resize
326 LVs as desired.
327
328 =back
329
330 Note that you cannot use C<--expand> and C<--shrink> together.
331
332 =cut
333
334 my $shrink;
335
336 =item B<--shrink part>
337
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.
343
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.
351
352 Note that you cannot use C<--expand> and C<--shrink> together.
353
354 =cut
355
356 my @ignore;
357
358 =item B<--ignore part>
359
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).
364
365 You can give this option multiple times.
366
367 =cut
368
369 my @delete;
370
371 =item B<--delete part>
372
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.
376
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
380 unbootable.
381
382 You can give this option multiple times.
383
384 =cut
385
386 my $copy_boot_loader = 1;
387
388 =item B<--no-copy-boot-loader>
389
390 By default, virt-resize copies over some sectors at the start of the
391 disk (up to the beginning of the first partition).  Commonly these
392 sectors contain the Master Boot Record (MBR) and the boot loader, and
393 are required in order for the guest to boot correctly.
394
395 If you specify this flag, then this initial copy is not done.  You may
396 need to reinstall the boot loader in this case.
397
398 =cut
399
400 my $extra_partition = 1;
401 my $min_extra_partition = 10 * 1024 * 1024; # see below
402
403 =item B<--no-extra-partition>
404
405 By default, virt-resize creates an extra partition if there is any
406 extra, unused space after all resizing has happened.  Use this option
407 to prevent the extra partition from being created.  If you do this
408 then the extra space will be inaccessible until you run fdisk, parted,
409 or some other partitioning tool in the guest.
410
411 Note that if the surplus space is smaller than 10 MB, no extra
412 partition will be created.
413
414 =cut
415
416 my $expand_content = 1;
417
418 =item B<--no-expand-content>
419
420 By default, virt-resize will try to expand the direct contents
421 of partitions, if it knows how (see C<--expand> option above).
422
423 If you give the C<--no-expand-content> option then virt-resize
424 will not attempt this.
425
426 =cut
427
428 my $debug;
429
430 =item B<-d> | B<--debug>
431
432 Enable debugging messages.
433
434 =cut
435
436 my $dryrun;
437
438 =item B<-n> | B<--dryrun>
439
440 Print a summary of what would be done, but don't do anything.
441
442 =cut
443
444 my $quiet;
445
446 =item B<-q> | B<--quiet>
447
448 Don't print the summary.
449
450 =back
451
452 =cut
453
454 GetOptions ("help|?" => \$help,
455             "version" => \$version,
456             "resize=s" => \@resize,
457             "resize-force=s" => \@resize_force,
458             "expand=s" => \$expand,
459             "shrink=s" => \$shrink,
460             "ignore=s" => \@ignore,
461             "delete=s" => \@delete,
462             "copy-boot-loader!" => \$copy_boot_loader,
463             "extra-partition!" => \$extra_partition,
464             "expand-content!" => \$expand_content,
465             "d|debug" => \$debug,
466             "n|dryrun|dry-run" => \$dryrun,
467             "q|quiet" => \$quiet,
468     ) or pod2usage (2);
469 pod2usage (1) if $help;
470 if ($version) {
471     my $g = Sys::Guestfs->new ();
472     my %h = $g->version ();
473     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
474     exit
475 }
476
477 die "virt-resize [--options] indisk outdisk\n" unless @ARGV == 2;
478
479 # Check in and out images exist.
480 my $infile = $ARGV[0];
481 my $outfile = $ARGV[1];
482 die __x("virt-resize: {file}: does not exist or is not readable\n", file => $infile)
483     unless -r $infile;
484 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)
485     unless -w $outfile;
486
487 my @s;
488 @s = stat $infile;
489 my $insize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($infile);
490 @s = stat $outfile;
491 my $outsize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($outfile);
492
493 if ($debug) {
494     print "$infile size $insize bytes\n";
495     print "$outfile size $outsize bytes\n";
496 }
497
498 # In reality the number of sectors containing boot loader data will be
499 # less than this (although Windows 7 defaults to putting the first
500 # partition on sector 2048, and has quite a large boot loader).
501 #
502 # However make this large enough to be sure that we have copied over
503 # the boot loader.  We could also do this by looking for the sector
504 # offset of the first partition.
505 #
506 # It doesn't matter if we copy too much.
507 my $boot_sectors = 4096;
508
509 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
510         file => $infile, sz => $insize)
511     if $insize < $boot_sectors * 512;
512 die __x("virt-resize: {file}: file is too small to be a disk image ({sz} bytes)\n",
513         file => $outfile, sz => $outsize)
514     if $outsize < $boot_sectors * 512;
515
516 # Copy the boot loader across.
517 do_copy_boot_loader () if $copy_boot_loader;
518
519 sub do_copy_boot_loader
520 {
521     print "copying boot loader ...\n" if $debug;
522     open IFILE, $infile or die "$infile: $!";
523     my $s;
524     my $r = sysread (IFILE, $s, $boot_sectors * 512) or die "$infile: $!";
525     die "$infile: short read" if $r < $boot_sectors * 512;
526     open OFILE, "+<$outfile" or die "$outfile: $!";
527     sysseek OFILE, 0, SEEK_SET or die "$outfile: seek: $!";
528     $r = syswrite (OFILE, $s, $boot_sectors * 512) or die "$outfile: $!";
529     die "$outfile: short write" if $r < $boot_sectors * 512;
530 }
531
532 # Add them to the handle and launch the appliance.
533 my $g;
534 launch_guestfs ();
535
536 sub launch_guestfs
537 {
538     $g = Sys::Guestfs->new ();
539     $g->set_trace (1) if $debug;
540     $g->add_drive_ro ($infile);
541     $g->add_drive ($outfile);
542     $g->launch ();
543 }
544
545 my $sectsize = $g->blockdev_getss ("/dev/sdb");
546
547 # Get the partitions on the source disk.
548 my @partitions;
549 my %partitions;
550 check_source_disk ();
551
552 sub check_source_disk
553 {
554     local $_;
555
556     # Partitions and PVs.
557     my @p = $g->part_list ("/dev/sda");
558     foreach (@p) {
559         my $name = "/dev/sda" . $_->{part_num};
560         push @partitions, $name;
561
562         my %h = %$_;
563         $h{name} = $name;
564         $h{bootable} = $g->part_get_bootable ("/dev/sda", $h{part_num});
565         eval { $h{mbr_id} = $g->part_get_mbr_id ("/dev/sda", $h{part_num}); };
566         $partitions{$name} = \%h;
567     }
568 }
569
570 # Examine each partition.
571 my @pvs_full = $g->pvs_full ();
572 examine_partition ($_) foreach @partitions;
573
574 sub examine_partition
575 {
576     local $_;
577     my $part = shift;
578
579     # What is it?
580     my $type = "unknown";
581     eval {
582         $type = $g->vfs_type ($part);
583     };
584     $partitions{$part}->{type} = $type;
585
586     # Can we get the actual size of this object (ie. to find out if it
587     # is smaller than the container for shrinking)?
588     my $fssize;
589     if ($type eq "LVM2_member") { # LVM PV
590         foreach (@pvs_full) {
591             $fssize = $_->{pv_size}
592               if canonicalize ($_->{pv_name}) eq $part;
593         }
594     } else {                    # Something mountable?
595         eval {
596             $g->mount_ro ($part, "/");
597
598             my %stat = $g->statvfs ("/");
599             $fssize = $stat{bsize} * $stat{blocks};
600         };
601
602         eval {
603             $g->umount_all ();
604         };
605     }
606
607     # This might be undef if we didn't successfully find the size.  In
608     # that case user won't be allowed to shrink this partition except
609     # by forcing it.
610     $partitions{$part}->{fssize} = $fssize;
611
612     # Is it partition content that we know how to expand?
613     $partitions{$part}->{can_expand_content} = 0;
614     if ($expand_content) {
615         if ($type eq "LVM2_member") {
616             $partitions{$part}->{can_expand_content} = 1;
617             $partitions{$part}->{expand_content_method} = "pvresize";
618         } elsif ($type =~ /^ext[234]/) {
619             $partitions{$part}->{can_expand_content} = 1;
620             $partitions{$part}->{expand_content_method} = "resize2fs";
621         } elsif ($type eq "ntfs" && feature_available ($g, "ntfsprogs")) {
622             $partitions{$part}->{can_expand_content} = 1;
623             $partitions{$part}->{expand_content_method} = "ntfsresize";
624         }
625     }
626 }
627
628 if ($debug) {
629     print "partitions found: ", join (", ", @partitions), "\n";
630     foreach my $part (@partitions) {
631         print "$part:\n";
632         foreach (sort keys %{$partitions{$part}}) {
633             print("\t", $_, " = ",
634                   defined ($partitions{$part}->{$_})
635                   ? $partitions{$part}->{$_} : "undef",
636                   "\n");
637         }
638     }
639 }
640
641 sub find_partition
642 {
643     local $_ = shift;
644     my $option = shift;
645
646     $_ = "/dev/$_" unless $_ =~ m{^/dev};
647     $_ = canonicalize ($_);
648
649     unless (exists $partitions{$_}) {
650         die __x("{p}: partition not found in the source disk image, when using the '{opt}' command line option\n",
651                 p => $_,
652                 opt => $option)
653     }
654
655     if ($partitions{$_}->{ignore}) {
656         die __x("{p}: partition ignored, you cannot use it in another command line argument\n",
657                 p => $_)
658     }
659     if ($partitions{$_}->{delete}) {
660         die __x("{p}: partition deleted, you cannot use it in another command line argument\n",
661                 p => $_)
662     }
663
664     return $_;
665 }
666
667 # Handle --ignore.
668 do_ignore ($_) foreach @ignore;
669
670 sub do_ignore
671 {
672     local $_ = shift;
673     $_ = find_partition ($_, "--ignore");
674     $partitions{$_}->{ignore} = 1;
675 }
676
677 # Handle --delete.
678 do_delete ($_) foreach @delete;
679
680 sub do_delete
681 {
682     local $_ = shift;
683     $_ = find_partition ($_, "--delete");
684     $partitions{$_}->{delete} = 1;
685 }
686
687 # Handle --resize and --resize-force.
688 my $to_be_expanded = 0;
689
690 do_resize ($_, 0, "--resize") foreach @resize;
691 do_resize ($_, 1, "--resize-force") foreach @resize_force;
692
693 sub do_resize
694 {
695     local $_ = shift;
696     my $force = shift;
697     my $option = shift;
698
699     # Argument is "part=size" ...
700     my ($part, $sizefield) = split /=/, $_, 2;
701     $part = find_partition ($part, $option);
702
703     if (exists $partitions{$part}->{newsize}) {
704         die __x("{p}: this partition has already been marked for resizing\n",
705                 p => $part);
706     }
707
708     # Parse the size field.
709     my $oldsize = $partitions{$part}->{part_size};
710     my $newsize;
711     if (!defined ($sizefield) || $sizefield eq "") {
712         die __x("{p}: missing size field in {o} option\n",
713                 p => $part, o => $option);
714     } elsif ($sizefield =~ /^([.\d]+)([bKMGTPE])$/) {
715         $newsize = sizebytes ($1, $2);
716     } elsif ($sizefield =~ /^\+([.\d]+)([bKMGTPE])$/) {
717         my $incr = sizebytes ($1, $2);
718         $newsize = $oldsize + $incr;
719     } elsif ($sizefield =~ /^-([.\d]+)([bKMGTPE])$/) {
720         my $decr = sizebytes ($1, $2);
721         $newsize = $oldsize - $decr;
722     } elsif ($sizefield =~ /^([.\d]+)%$/) {
723         $newsize = $oldsize * $1 / 100;
724     } elsif ($sizefield =~ /^\+([.\d]+)%$/) {
725         $newsize = $oldsize + $oldsize * $1 / 100;
726     } elsif ($sizefield =~ /^-([.\d]+)%$/) {
727         $newsize = $oldsize - $oldsize * $1 / 100;
728     } else {
729         die __x("{p}: {f}: cannot parse size field\n",
730                 p => $part, f => $sizefield)
731     }
732
733     $newsize > 0 or
734         die __x("{p}: new size is zero or negative\n", p => $part);
735
736     mark_partition_for_resize ($part, $oldsize, $newsize, $force, $option);
737 }
738
739 sub mark_partition_for_resize
740 {
741     local $_;
742     my $part = shift;
743     my $oldsize = shift;
744     my $newsize = shift;
745     my $force = shift;
746     my $option = shift;
747
748     # Do nothing if the size is the same.
749     return if $oldsize == $newsize;
750
751     my $bigger = $newsize > $oldsize;
752
753     # Check there is space to shrink this.
754     unless ($bigger || $force) {
755         if (! $partitions{$part}->{fssize} ||
756             $partitions{$part}->{fssize} > $newsize) {
757             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",
758                     p => $part);
759         }
760     }
761
762     $partitions{$part}->{newsize} = $newsize;
763
764     if ($partitions{$part}->{can_expand_content} && $bigger) {
765         $partitions{$part}->{will_expand_content} = 1;
766         $to_be_expanded++;
767     }
768 }
769
770 # Handle --expand and --shrink.
771 my $surplus;
772 if (defined $expand && defined $shrink) {
773     die __"virt-resize: you cannot use options --expand and --shrink together\n"
774 }
775 if (defined $expand || defined $shrink) {
776     calculate_surplus ();
777
778     if ($debug) {
779         print "surplus before --expand or --shrink: $surplus (",
780           human_size ($surplus), ")\n";
781     }
782
783     do_expand () if $expand;
784     do_shrink () if $shrink;
785 }
786
787 # (Re-)calculate surplus after doing expand or shrink.
788 calculate_surplus ();
789
790 # Add up the total space required on the target so far, compared
791 # to the size of the target.  We end up with a surplus or deficit.
792 sub calculate_surplus
793 {
794     local $_;
795
796     # We need some overhead for partitioning.  Worst case would be for
797     # EFI partitioning + massive per-partition alignment.
798     my $overhead = $sectsize * (
799         2 * 64 +                   # GPT start and end
800         (64 * (@partitions + 1)) + # Maximum alignment
801         ($boot_sectors - 64)       # Boot loader
802         );
803
804     my $required = 0;
805     foreach (@partitions) {
806         if ($partitions{$_}->{newsize}) {
807             $required += $partitions{$_}->{newsize}
808         } else {
809             $required += $partitions{$_}->{part_size}
810         }
811     }
812
813     # Compare that to the actual target disk.
814     $surplus = $outsize - ($required + $overhead);
815 }
816
817 sub do_expand
818 {
819     local $_;
820
821     unless ($surplus > 0) {
822         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",
823                 h => human_size (-$surplus));
824     }
825
826     my $part = find_partition ($expand, "--expand");
827     my $oldsize = $partitions{$part}->{part_size};
828     mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
829                                0, "--expand");
830 }
831
832 sub do_shrink
833 {
834     local $_;
835
836     unless ($surplus < 0) {
837         die __"virt-resize: error: cannot use --shrink because there is no deficit\n(see 'deficit' in the virt-resize(1) man page)\n"
838     }
839
840     my $part = find_partition ($shrink, "--shrink");
841     my $oldsize = $partitions{$part}->{part_size};
842     mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
843                                0, "--shrink");
844 }
845
846 # Print summary.
847 print_summary () unless $quiet;
848
849 sub print_summary
850 {
851     local $_;
852     print __"Summary of changes:\n";
853
854     foreach my $part (@partitions) {
855         if ($partitions{$part}->{ignore}) {
856             print __x("{p}: partition will be ignored\n", p => $part);
857         } elsif ($partitions{$part}->{delete}) {
858             print __x("{p}: partition will be deleted\n", p => $part);
859         } elsif ($partitions{$part}->{newsize}) {
860             print __x("{p}: partition will be resized from {oldsize} to {newsize}\n",
861                       p => $part,
862                       oldsize => human_size ($partitions{$part}->{part_size}),
863                       newsize => human_size ($partitions{$part}->{newsize}));
864             if ($partitions{$part}->{will_expand_content}) {
865                 print __x("{p}: content will be expanded using the '{meth}' method\n",
866                           p => $part,
867                           meth => $partitions{$part}->{expand_content_method});
868             }
869         } else {
870             print __x("{p}: partition will be left alone\n", p => $part);
871         }
872     }
873
874     if ($surplus > 0) {
875         print __x("There is a surplus of {spl} bytes ({h}).\n",
876                   spl => $surplus,
877                   h => human_size ($surplus));
878         if ($extra_partition) {
879             if ($surplus >= $min_extra_partition) {
880                 print __"An extra partition will be created for the surplus.\n";
881             } else {
882                 print __"The surplus space is not large enough for an extra partition to be created\nand so it will just be ignored.\n";
883             }
884         } else {
885             print __"The surplus space will be ignored.  Run a partitioning program in the guest\nto partition this extra space if you want.\n";
886         }
887     } elsif ($surplus < 0) {
888         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",
889                 def => -$surplus,
890                 h => human_size (-$surplus));
891     }
892 }
893
894 exit 0 if $dryrun;
895
896 # Repartition the target disk.
897 my $nextpart = 1;
898 my $parttype;
899 repartition ();
900
901 sub repartition
902 {
903     local $_;
904
905     if ($copy_boot_loader) {
906         $parttype = $g->part_get_parttype ("/dev/sdb");
907     } else {
908         $parttype = "efi";
909     }
910     print "partition table type: $parttype\n" if $debug;
911
912     # Delete any existing partitions on the destination disk,
913     # but leave the bootloader that we copied over intact.
914     if ($copy_boot_loader) {
915         # Delete in reverse as an easy way to deal with extended
916         # partitions.
917         foreach (sort { $b cmp $a } $g->list_partitions ()) {
918             if (m{^/dev/.db(\d+)$}) {
919                 $g->part_del ("/dev/sdb", $1);
920             }
921         }
922     } else {
923         # Didn't copy over the initial boot loader, so we need
924         # to make a new partition table here.
925         $g->part_init ("/dev/sdb", $parttype);
926     }
927
928     # Work out where to start the first partition.
929     die __"virt-resize: source disk does not have a first partition\n"
930         unless exists ($partitions{"/dev/sda1"});
931     my $start = $partitions{"/dev/sda1"}->{part_start} / $sectsize;
932
933     # Align to 64.
934     $start = ($start + 63) & ~63;
935
936     print "starting to partition from $start\n" if $debug;
937
938     # Create the new partitions.
939     foreach my $part (@partitions) {
940         unless ($partitions{$part}->{delete}) {
941             # Size in sectors.
942             my $size;
943             if ($partitions{$part}->{newsize}) {
944                 $size = ($partitions{$part}->{newsize} + $sectsize - 1)
945                     / $sectsize;
946             } else {
947                 $size = ($partitions{$part}->{part_size} + $sectsize - 1)
948                     / $sectsize;
949             }
950
951             # Create it.
952             my ($target, $end, $part_num) = add_partition ($start, $size);
953             $partitions{$part}->{target} = $target;
954
955             if ($partitions{$part}->{bootable}) {
956                 $g->part_set_bootable ("/dev/sdb", $part_num, 1);
957             }
958
959             if ($partitions{$part}->{mbr_id}) {
960                 $g->part_set_mbr_id ("/dev/sdb", $part_num,
961                                      $partitions{$part}->{mbr_id});
962             }
963
964             # Start of next partition + alignment.
965             $start = $end + 1;
966             $start = ($start + 63) & ~63;
967         }
968     }
969
970     # Create surplus partition.
971     if ($extra_partition && $surplus >= $min_extra_partition) {
972         add_partition ($start, $outsize / $sectsize - 64 - $start);
973     }
974 }
975
976 # Add a partition.
977 sub add_partition
978 {
979     local $_;
980     my $start = shift;
981     my $size = shift;
982
983     my ($target, $end, $part_num);
984
985     if ($nextpart <= 3 || $parttype ne "msdos") {
986         $target = "/dev/sdb$nextpart";
987         $end = $start + $size - 1;
988         $g->part_add ("/dev/sdb", "primary", $start, $end);
989         $part_num = $nextpart++;
990     } else {
991         if ($nextpart == 4) {
992             $g->part_add ("/dev/sdb", "extended", $start, -1);
993             $part_num = $nextpart++;
994             $start += 64;
995         }
996         $target = "/dev/sdb$nextpart";
997         $end = $start + $size - 1;
998         $g->part_add ("/dev/sdb", "logical", $start, $end);
999         $part_num = $nextpart++;
1000     }
1001
1002     return ($target, $end, $part_num);
1003 }
1004
1005 # Copy over the data.
1006 copy_data ();
1007
1008 sub copy_data
1009 {
1010     foreach my $part (@partitions)
1011     {
1012         unless ($partitions{$part}->{ignore}) {
1013             my $target = $partitions{$part}->{target};
1014             if ($target) {
1015                 my $oldsize = $partitions{$part}->{part_size};
1016                 my $newsize;
1017                 if ($partitions{$part}->{newsize}) {
1018                     $newsize = $partitions{$part}->{newsize};
1019                 } else {
1020                     $newsize = $partitions{$part}->{part_size};
1021                 }
1022
1023                 if (!$quiet && !$debug) {
1024                     local $| = 1;
1025                     print __x("Copying {p} ...", p => $part);
1026                 }
1027
1028                 $g->copy_size ($part, $target,
1029                                $newsize < $oldsize ? $newsize : $oldsize);
1030
1031                 if (!$quiet && !$debug) {
1032                     print " ", __"done", "\n";
1033                 }
1034             }
1035         }
1036     }
1037 }
1038
1039 # After copying the data over we must shut down and restart the
1040 # appliance in order to expand the content.  The reason for this may
1041 # not be obvious, but it's because otherwise we'll have duplicate VGs
1042 # (the old VG(s) and the new VG(s)) which breaks LVM.
1043 #
1044 # The restart is only required if we're going to expand something.
1045
1046 if ($to_be_expanded > 0) {
1047     restart_appliance ();
1048     expand_partitions ();
1049 }
1050
1051 sub restart_appliance
1052 {
1053     # Sync disk and exit.
1054     $g->umount_all ();
1055     $g->sync ();
1056     undef $g;
1057
1058     $g = Sys::Guestfs->new ();
1059     $g->set_trace (1) if $debug;
1060     $g->add_drive ($outfile);
1061     $g->launch ();
1062
1063     # Target partitions have changed from /dev/sdb to /dev/sda,
1064     # so change them.
1065     foreach my $part (@partitions)
1066     {
1067         my $target = $partitions{$part}->{target};
1068         if ($target) {
1069             if ($target =~ m{/dev/(.)db(.*)}) {
1070                 $partitions{$part}->{target} = "/dev/$1da$2";
1071             } else {
1072                 die "internal error: unexpected partition target: $target";
1073             }
1074         }
1075     }
1076 }
1077
1078 sub expand_partitions
1079 {
1080     foreach my $part (@partitions)
1081     {
1082         unless ($partitions{$part}->{ignore}) {
1083             my $target = $partitions{$part}->{target};
1084             if ($target) {
1085                 # Expand if requested.
1086                 if ($partitions{$part}->{will_expand_content}) {
1087                     if (!$quiet && !$debug) {
1088                         print __x("Expanding {p} using the '{meth}' method",
1089                                   p => $part,
1090                                   meth => $partitions{$part}->{expand_content_method});
1091                     }
1092                     expand_target_partition ($part)
1093                 }
1094             }
1095         }
1096     }
1097 }
1098
1099 sub expand_target_partition
1100 {
1101     local $_;
1102     my $part = shift;
1103
1104     # Assertions.
1105     die unless $part;
1106     die unless $partitions{$part}->{can_expand_content};
1107     die unless $partitions{$part}->{will_expand_content};
1108     die unless $partitions{$part}->{expand_content_method};
1109     die unless $partitions{$part}->{target};
1110     die unless $expand_content;
1111
1112     my $target = $partitions{$part}->{target};
1113     my $method = $partitions{$part}->{expand_content_method};
1114     if ($method eq "pvresize") {
1115         $g->pvresize ($target);
1116     }
1117     elsif ($method eq "resize2fs") {
1118         $g->e2fsck_f ($target);
1119         $g->resize2fs ($target);
1120     }
1121     elsif ($method eq "ntfsresize") {
1122         $g->ntfsresize ($target);
1123     }
1124     else {
1125         die "internal error: unknown method: $method";
1126     }
1127 }
1128
1129 # Sync disk and exit.
1130 $g->umount_all ();
1131 $g->sync ();
1132 undef $g;
1133
1134 exit 0;
1135
1136 sub sizebytes
1137 {
1138     local $_ = shift;
1139     my $unit = shift;
1140
1141     $_ *= 1024 if $unit =~ /[KMGTPE]/;
1142     $_ *= 1024 if $unit =~ /[MGTPE]/;
1143     $_ *= 1024 if $unit =~ /[GTPE]/;
1144     $_ *= 1024 if $unit =~ /[TPE]/;
1145     $_ *= 1024 if $unit =~ /[PE]/;
1146     $_ *= 1024 if $unit =~ /[E]/;
1147
1148     return floor($_);
1149 }
1150
1151 # Convert a number of bytes to a human-readable number.
1152 sub human_size
1153 {
1154     local $_ = shift;
1155
1156     my $sgn = "";
1157     if ($_ < 0) {
1158         $sgn = "-";
1159         $_ = -$_;
1160     }
1161
1162     $_ /= 1024;
1163
1164     if ($_ < 1024) {
1165         sprintf "%s%dK", $sgn, $_;
1166     } elsif ($_ < 1024 * 1024) {
1167         sprintf "%s%.1fM", $sgn, ($_ / 1024);
1168     } else {
1169         sprintf "%s%.1fG", $sgn, ($_ / 1024 / 1024);
1170     }
1171 }
1172
1173 # Return the size in bytes of a HOST block device.
1174 sub host_blockdevsize
1175 {
1176     local $_;
1177     my $dev = shift;
1178
1179     open BD, "PATH=/usr/sbin:/sbin:\$PATH blockdev --getsize64 $dev |"
1180         or die "blockdev: $!";
1181     $_ = <BD>;
1182     chomp $_;
1183     $_;
1184 }
1185
1186 # The reverse of device name translation, see
1187 # BLOCK DEVICE NAMING in guestfs(3).
1188 sub canonicalize
1189 {
1190     local $_ = shift;
1191
1192     if (m{^/dev/[hv]d([a-z]\d)$}) {
1193         return "/dev/sd$1";
1194     }
1195     $_;
1196 }
1197
1198 =head1 NOTES
1199
1200 =head2 "Partition 1 does not end on cylinder boundary."
1201
1202 Virt-resize aligns partitions to multiples of 64 sectors.  Usually
1203 this means the partitions will not be aligned to the ancient CHS
1204 geometry.  However CHS geometry is meaningless for disks manufactured
1205 since the early 1990s, and doubly so for virtual hard drives.
1206 Alignment of partitions to cylinders is not required by any modern
1207 operating system.
1208
1209 =head2 RESIZING WINDOWS VIRTUAL MACHINES
1210
1211 In Windows Vista and later versions, Microsoft switched to using a
1212 separate boot partition.  In these VMs, typically C</dev/sda1> is the
1213 boot partition and C</dev/sda2> is the main (C:) drive.  We have not
1214 had any luck resizing the boot partition.  Doing so seems to break the
1215 guest completely.  However expanding the second partition (ie. C:
1216 drive) should work.
1217
1218 Windows may initiate a lengthy "chkdsk" on first boot after a resize,
1219 if NTFS partitions have been expanded.  This is just a safety check
1220 and (unless it find errors) is nothing to worry about.
1221
1222 =head1 ALTERNATIVE TOOLS
1223
1224 There are several proprietary tools for resizing partitions.  We
1225 won't mention any here.
1226
1227 L<parted(8)> and its graphical shell gparted can do some types of
1228 resizing operations on disk images.  They can resize and move
1229 partitions, but I don't think they can do anything with the contents,
1230 and they certainly don't understand LVM.
1231
1232 L<guestfish(1)> can do everything that virt-resize can do and a lot
1233 more, but at a much lower level.  You will probably end up
1234 hand-calculating sector offsets, which is something that virt-resize
1235 was designed to avoid.  If you want to see the guestfish-equivalent
1236 commands that virt-resize runs, use the C<--debug> flag.
1237
1238 =head1 SEE ALSO
1239
1240 L<virt-list-partitions(1)>,
1241 L<virt-list-filesystems(1)>,
1242 L<virt-df(1)>,
1243 L<guestfs(3)>,
1244 L<guestfish(1)>,
1245 L<lvm(8)>,
1246 L<pvresize(8)>,
1247 L<lvresize(8)>,
1248 L<resize2fs(8)>,
1249 L<ntfsresize(8)>,
1250 L<virsh(1)>,
1251 L<parted(8)>,
1252 L<Sys::Guestfs(3)>,
1253 L<http://libguestfs.org/>.
1254
1255 =head1 AUTHOR
1256
1257 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
1258
1259 =head1 COPYRIGHT
1260
1261 Copyright (C) 2010 Red Hat Inc.
1262
1263 This program is free software; you can redistribute it and/or modify
1264 it under the terms of the GNU General Public License as published by
1265 the Free Software Foundation; either version 2 of the License, or
1266 (at your option) any later version.
1267
1268 This program is distributed in the hope that it will be useful,
1269 but WITHOUT ANY WARRANTY; without even the implied warranty of
1270 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1271 GNU General Public License for more details.
1272
1273 You should have received a copy of the GNU General Public License
1274 along with this program; if not, write to the Free Software
1275 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.