todo: Suggest removing repo name from appliance name.
[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 $| = 1;
37
38 =encoding utf8
39
40 =head1 NAME
41
42 virt-resize - Resize a virtual machine disk
43
44 =head1 SYNOPSIS
45
46  virt-resize [--resize /dev/sdaN=[+/-]<size>[%]]
47    [--expand /dev/sdaN] [--shrink /dev/sdaN]
48    [--ignore /dev/sdaN] [--delete /dev/sdaN] [...] indisk outdisk
49
50 =head1 DESCRIPTION
51
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
54 contained within.
55
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.
59
60 If you are not familiar with the associated tools:
61 L<virt-list-partitions(1)>,
62 L<virt-list-filesystems(1)> and
63 L<virt-df(1)>,
64 we recommend you go and read those manual pages first.
65
66 =head1 EXAMPLES
67
68 Copy C<olddisk> to C<newdisk>, extending one of the guest's partitions
69 to fill the extra 5GB of space.
70
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
75
76 As above, but make the /boot partition 200MB bigger, while giving the
77 remaining space to /dev/sda2:
78
79  virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 olddisk newdisk
80
81 =head1 DETAILED USAGE
82
83 =head2 EXPANDING A VIRTUAL MACHINE DISK
84
85 =over 4
86
87 =item 1. Shut down the virtual machine
88
89 =item 2. Locate input disk image
90
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:
94
95  # virsh dumpxml guestname | xpath /domain/devices/disk/source
96  Found 1 nodes:
97  -- NODE --
98  <source dev="/dev/vg/lv_guest" />
99
100 =item 3. Look at current sizing
101
102 Use L<virt-list-partitions(1)> to display the current partitions and
103 sizes:
104
105  # virt-list-partitions -lht /dev/vg/lv_guest
106  /dev/sda1 ext3 101.9M
107  /dev/sda2 pv 7.9G
108  /dev/sda device 8.0G
109
110 (This example is a virtual machine with an 8 GB disk which we would
111 like to expand up to 10 GB).
112
113 =item 4. Create output disk
114
115 Virt-resize cannot do in-place disk modifications.  You have to have
116 space to store the resized output disk.
117
118 To store the resized disk image in a file, create a file of a suitable
119 size:
120
121  # rm -f outdisk
122  # truncate -s 10G outdisk
123
124 Or use L<lvcreate(1)> to create a logical volume:
125
126  # lvcreate -L 10G -n lv_name vg_name
127
128 Or use L<virsh(1)> vol-create-as to create a libvirt storage volume:
129
130  # virsh pool-list
131  # virsh vol-create-as poolname newvol 10G
132
133 =item 5. Resize
134
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
137 the previous step.
138
139  # virt-resize indisk outdisk
140
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.
146
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).
150
151 L</--expand> is the most useful option.  It expands the named
152 partition within the disk to fill any extra space:
153
154  # virt-resize --expand /dev/sda2 indisk outdisk
155
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).
158
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:
162
163  # virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 \
164      indisk outdisk
165
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.
174
175 Other options are covered below.
176
177 =item 6. Test
178
179 Thoroughly test the new disk image I<before> discarding the old one.
180
181 If you are using libvirt, edit the XML to point at the new disk:
182
183  # virsh edit guestname
184
185 Change E<lt>source ...E<gt>, see
186 L<http://libvirt.org/formatdomain.html#elementsDisks>
187
188 Then start up the domain with the new, resized disk:
189
190  # virsh start guestname
191
192 and check that it still works.  See also the L</NOTES> section below
193 for additional information.
194
195 =item 7. Resize LVs etc inside the guest
196
197 (This can also be done offline using L<guestfish(1)>)
198
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.
203
204 =back
205
206 =head2 SHRINKING A VIRTUAL MACHINE DISK
207
208 Shrinking is somewhat more complex than expanding, and only an
209 overview is given here.
210
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.
215
216 (Shrinking can also be done offline using L<guestfish(1)>)
217
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.
220
221 Then run virt-resize with any of the C<--shrink> and/or C<--resize>
222 options.
223
224 =head2 IGNORING OR DELETING PARTITIONS
225
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.
232
233 =head1 OPTIONS
234
235 =over 4
236
237 =cut
238
239 my $help;
240
241 =item B<--help>
242
243 Display help.
244
245 =cut
246
247 my $version;
248
249 =item B<--version>
250
251 Display version number and exit.
252
253 =cut
254
255 my @resize;
256
257 =item B<--resize part=size>
258
259 Resize the named partition (expanding or shrinking it) so that it has
260 the given size.
261
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:
266
267  --resize /dev/sda2=10G
268
269  --resize /dev/sda4=90%
270
271  --resize /dev/sda2=+1G
272
273  --resize /dev/sda2=-200M
274
275  --resize /dev/sda1=+128K
276
277  --resize /dev/sda1=+10%
278
279  --resize /dev/sda1=-10%
280
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>
283 below).
284
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>).
289
290 You can give this option multiple times.
291
292 =cut
293
294 my @resize_force;
295
296 =item B<--resize-force part=size>
297
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).
303
304 See also the C<--ignore> option.
305
306 =cut
307
308 my $expand;
309
310 =item B<--expand part>
311
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).
314
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.
319
320 Currently virt-resize can resize:
321
322 =over 4
323
324 =item *
325
326 ext2, ext3 and ext4 filesystems when they are contained
327 directly inside a partition.
328
329 =item *
330
331 NTFS filesystems contained directly in a partition, if libguestfs was
332 compiled with support for NTFS.
333
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.
338
339 =item *
340
341 LVM PVs (physical volumes).  However virt-resize does I<not>
342 resize anything inside the PV.  The user will have to resize
343 LVs as desired.
344
345 =back
346
347 Note that you cannot use C<--expand> and C<--shrink> together.
348
349 =cut
350
351 my $shrink;
352
353 =item B<--shrink part>
354
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.
360
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.
368
369 Note that you cannot use C<--expand> and C<--shrink> together.
370
371 =cut
372
373 my @ignore;
374
375 =item B<--ignore part>
376
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).
381
382 You can give this option multiple times.
383
384 =cut
385
386 my @delete;
387
388 =item B<--delete part>
389
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.
393
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
397 unbootable.
398
399 You can give this option multiple times.
400
401 =cut
402
403 my @lv_expand;
404
405 =item B<--LV-expand logvol>
406
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:
411
412  virt-resize indisk outdisk \
413    --expand /dev/sda2 --LV-expand /dev/vg_guest/lv_root
414
415 This would first expand the partition (and PV), and then expand the
416 root device to fill the extra space in the PV.
417
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>.
421
422 Use L<virt-list-filesystems(1)> to list the filesystems in
423 the guest.
424
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.
428
429 =cut
430
431 my $copy_boot_loader = 1;
432
433 =item B<--no-copy-boot-loader>
434
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.
439
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.
442
443 =cut
444
445 my $extra_partition = 1;
446 my $min_extra_partition = 10 * 1024 * 1024; # see below
447
448 =item B<--no-extra-partition>
449
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.
455
456 Note that if the surplus space is smaller than 10 MB, no extra
457 partition will be created.
458
459 =cut
460
461 my $expand_content = 1;
462
463 =item B<--no-expand-content>
464
465 By default, virt-resize will try to expand the direct contents
466 of partitions, if it knows how (see C<--expand> option above).
467
468 If you give the C<--no-expand-content> option then virt-resize
469 will not attempt this.
470
471 =cut
472
473 my $debug;
474
475 =item B<-d> | B<--debug>
476
477 Enable debugging messages.
478
479 =cut
480
481 my $dryrun;
482
483 =item B<-n> | B<--dryrun>
484
485 Print a summary of what would be done, but don't do anything.
486
487 =cut
488
489 my $quiet;
490
491 =item B<-q> | B<--quiet>
492
493 Don't print the summary.
494
495 =back
496
497 =cut
498
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,
514     ) or pod2usage (2);
515 pod2usage (1) if $help;
516 if ($version) {
517     my $g = Sys::Guestfs->new ();
518     my %h = $g->version ();
519     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
520     exit
521 }
522
523 die "virt-resize [--options] indisk outdisk\n" unless @ARGV == 2;
524
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)
529     unless -r $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)
531     unless -w $outfile;
532
533 my @s;
534 @s = stat $infile;
535 my $insize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($infile);
536 @s = stat $outfile;
537 my $outsize = S_ISREG ($s[2]) ? $s[7] : host_blockdevsize ($outfile);
538
539 if ($debug) {
540     print "$infile size $insize bytes\n";
541     print "$outfile size $outsize bytes\n";
542 }
543
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).
547 #
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.
551 #
552 # It doesn't matter if we copy too much.
553 my $boot_sectors = 4096;
554
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;
561
562 # Copy the boot loader across.
563 do_copy_boot_loader () if $copy_boot_loader;
564
565 sub do_copy_boot_loader
566 {
567     print "copying boot loader ...\n" if $debug;
568     open IFILE, $infile or die "$infile: $!";
569     my $s;
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;
576 }
577
578 # Add them to the handle and launch the appliance.
579 my $g;
580 launch_guestfs ();
581
582 sub launch_guestfs
583 {
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;
589     $g->launch ();
590 }
591
592 my $sectsize = $g->blockdev_getss ("/dev/sdb");
593
594 my $to_be_expanded = 0;
595
596 # Get the partitions on the source disk.
597 my @partitions;
598 my %partitions;
599 check_source_disk ();
600
601 sub check_source_disk
602 {
603     local $_;
604
605     # Partitions and PVs.
606     my @p = $g->part_list ("/dev/sda");
607     foreach (@p) {
608         my $name = "/dev/sda" . $_->{part_num};
609         push @partitions, $name;
610
611         my %h = %$_;
612         $h{name} = $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;
616     }
617 }
618
619 # Examine each partition.
620 my @pvs_full = $g->pvs_full ();
621 examine_partition ($_) foreach @partitions;
622
623 sub examine_partition
624 {
625     local $_;
626     my $part = shift;
627
628     # What is it?
629     my $type = "unknown";
630     eval {
631         $type = $g->vfs_type ($part);
632     };
633     $partitions{$part}->{type} = $type;
634
635     # Can we get the actual size of this object (ie. to find out if it
636     # is smaller than the container for shrinking)?
637     my $fssize;
638     if ($type eq "LVM2_member") { # LVM PV
639         foreach (@pvs_full) {
640             $fssize = $_->{pv_size}
641               if canonicalize ($_->{pv_name}) eq $part;
642         }
643     } else {                    # Something mountable?
644         eval {
645             $g->mount_ro ($part, "/");
646
647             my %stat = $g->statvfs ("/");
648             $fssize = $stat{bsize} * $stat{blocks};
649         };
650
651         eval {
652             $g->umount_all ();
653         };
654     }
655
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
658     # by forcing it.
659     $partitions{$part}->{fssize} = $fssize;
660
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";
673         }
674     }
675 }
676
677 if ($debug) {
678     print "partitions found: ", join (", ", @partitions), "\n";
679     foreach my $part (@partitions) {
680         print "$part:\n";
681         foreach (sort keys %{$partitions{$part}}) {
682             print("\t", $_, " = ",
683                   defined ($partitions{$part}->{$_})
684                   ? $partitions{$part}->{$_} : "undef",
685                   "\n");
686         }
687     }
688 }
689
690 # Examine the LVs (for --lv-expand option).
691 my @lvs = $g->lvs ();
692 my %lvs;
693 examine_lv ($_) foreach @lvs;
694 mark_lvs_to_expand ();
695
696 sub examine_lv
697 {
698     local $_ = shift;
699
700     $lvs{$_}->{name} = $_;
701
702     my $type = "unknown";
703     eval {
704         $type = $g->vfs_type ($_);
705     };
706     $lvs{$_}->{type} = $type;
707
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";
715         }
716     }
717 }
718
719 sub mark_lvs_to_expand {
720     local $_;
721
722     foreach (@lv_expand) {
723         die __x("virt-resize: no logical volume called {n}\n",
724                 n => $_)
725             unless exists $lvs{$_};
726
727         if ($lvs{$_}->{can_expand_content}) {
728             $lvs{$_}->{will_expand_content} = 1;
729             $to_be_expanded++;
730         }
731     }
732 }
733
734 sub find_partition
735 {
736     local $_ = shift;
737     my $option = shift;
738
739     $_ = "/dev/$_" unless $_ =~ m{^/dev};
740     $_ = canonicalize ($_);
741
742     unless (exists $partitions{$_}) {
743         die __x("{p}: partition not found in the source disk image, when using the '{opt}' command line option\n",
744                 p => $_,
745                 opt => $option)
746     }
747
748     if ($partitions{$_}->{ignore}) {
749         die __x("{p}: partition ignored, you cannot use it in another command line argument\n",
750                 p => $_)
751     }
752     if ($partitions{$_}->{delete}) {
753         die __x("{p}: partition deleted, you cannot use it in another command line argument\n",
754                 p => $_)
755     }
756
757     return $_;
758 }
759
760 # Handle --ignore.
761 do_ignore ($_) foreach @ignore;
762
763 sub do_ignore
764 {
765     local $_ = shift;
766     $_ = find_partition ($_, "--ignore");
767     $partitions{$_}->{ignore} = 1;
768 }
769
770 # Handle --delete.
771 do_delete ($_) foreach @delete;
772
773 sub do_delete
774 {
775     local $_ = shift;
776     $_ = find_partition ($_, "--delete");
777     $partitions{$_}->{delete} = 1;
778 }
779
780 # Handle --resize and --resize-force.
781 do_resize ($_, 0, "--resize") foreach @resize;
782 do_resize ($_, 1, "--resize-force") foreach @resize_force;
783
784 sub do_resize
785 {
786     local $_ = shift;
787     my $force = shift;
788     my $option = shift;
789
790     # Argument is "part=size" ...
791     my ($part, $sizefield) = split /=/, $_, 2;
792     $part = find_partition ($part, $option);
793
794     if (exists $partitions{$part}->{newsize}) {
795         die __x("{p}: this partition has already been marked for resizing\n",
796                 p => $part);
797     }
798
799     # Parse the size field.
800     my $oldsize = $partitions{$part}->{part_size};
801     my $newsize;
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;
819     } else {
820         die __x("{p}: {f}: cannot parse size field\n",
821                 p => $part, f => $sizefield)
822     }
823
824     $newsize > 0 or
825         die __x("{p}: new size is zero or negative\n", p => $part);
826
827     mark_partition_for_resize ($part, $oldsize, $newsize, $force, $option);
828 }
829
830 sub mark_partition_for_resize
831 {
832     local $_;
833     my $part = shift;
834     my $oldsize = shift;
835     my $newsize = shift;
836     my $force = shift;
837     my $option = shift;
838
839     # Do nothing if the size is the same.
840     return if $oldsize == $newsize;
841
842     my $bigger = $newsize > $oldsize;
843
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",
849                     p => $part);
850         }
851     }
852
853     $partitions{$part}->{newsize} = $newsize;
854
855     if ($partitions{$part}->{can_expand_content} && $bigger) {
856         $partitions{$part}->{will_expand_content} = 1;
857         $to_be_expanded++;
858     }
859 }
860
861 # Handle --expand and --shrink.
862 my $surplus;
863 if (defined $expand && defined $shrink) {
864     die __"virt-resize: you cannot use options --expand and --shrink together\n"
865 }
866 if (defined $expand || defined $shrink) {
867     calculate_surplus ();
868
869     if ($debug) {
870         print "surplus before --expand or --shrink: $surplus (",
871           human_size ($surplus), ")\n";
872     }
873
874     do_expand () if $expand;
875     do_shrink () if $shrink;
876 }
877
878 # (Re-)calculate surplus after doing expand or shrink.
879 calculate_surplus ();
880
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
884 {
885     local $_;
886
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
893         );
894
895     my $required = 0;
896     foreach (@partitions) {
897         if ($partitions{$_}->{newsize}) {
898             $required += $partitions{$_}->{newsize}
899         } else {
900             $required += $partitions{$_}->{part_size}
901         }
902     }
903
904     # Compare that to the actual target disk.
905     $surplus = $outsize - ($required + $overhead);
906 }
907
908 sub do_expand
909 {
910     local $_;
911
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));
915     }
916
917     my $part = find_partition ($expand, "--expand");
918     my $oldsize = $partitions{$part}->{part_size};
919     mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
920                                0, "--expand");
921 }
922
923 sub do_shrink
924 {
925     local $_;
926
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"
929     }
930
931     my $part = find_partition ($shrink, "--shrink");
932     my $oldsize = $partitions{$part}->{part_size};
933     mark_partition_for_resize ($part, $oldsize, $oldsize + $surplus,
934                                0, "--shrink");
935 }
936
937 # Print summary.
938 print_summary () unless $quiet;
939
940 sub print_summary
941 {
942     local $_;
943     print __"Summary of changes:\n";
944
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",
952                       p => $part,
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",
957                           p => $part,
958                           meth => $partitions{$part}->{expand_content_method});
959             }
960         } else {
961             print __x("{p}: partition will be left alone\n", p => $part);
962         }
963     }
964
965     foreach my $lv (@lv_expand) {
966         print __x("{n}: LV will be expanded to maximum size\n",
967                   n => $lv);
968     }
969
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",
973                       n => $lv,
974                       meth => $lvs{$lv}->{expand_content_method});
975         }
976     }
977
978     if ($surplus > 0) {
979         print __x("There is a surplus of {spl} bytes ({h}).\n",
980                   spl => $surplus,
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";
985             } else {
986                 print __"The surplus space is not large enough for an extra partition to be created\nand so it will just be ignored.\n";
987             }
988         } else {
989             print __"The surplus space will be ignored.  Run a partitioning program in the guest\nto partition this extra space if you want.\n";
990         }
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",
993                 def => -$surplus,
994                 h => human_size (-$surplus));
995     }
996 }
997
998 exit 0 if $dryrun;
999
1000 # Repartition the target disk.
1001 my $nextpart = 1;
1002 my $parttype;
1003 repartition ();
1004
1005 sub repartition
1006 {
1007     local $_;
1008
1009     if ($copy_boot_loader) {
1010         $parttype = $g->part_get_parttype ("/dev/sdb");
1011     } else {
1012         $parttype = "efi";
1013     }
1014     print "partition table type: $parttype\n" if $debug;
1015
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
1020         # partitions.
1021         foreach (sort { $b cmp $a } $g->list_partitions ()) {
1022             if (m{^/dev/.db(\d+)$}) {
1023                 $g->part_del ("/dev/sdb", $1);
1024             }
1025         }
1026     } else {
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);
1030     }
1031
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;
1036
1037     # Align to 64.
1038     $start = ($start + 63) & ~63;
1039
1040     print "starting to partition from $start\n" if $debug;
1041
1042     # Create the new partitions.
1043     foreach my $part (@partitions) {
1044         unless ($partitions{$part}->{delete}) {
1045             # Size in sectors.
1046             my $size;
1047             if ($partitions{$part}->{newsize}) {
1048                 $size = ($partitions{$part}->{newsize} + $sectsize - 1)
1049                     / $sectsize;
1050             } else {
1051                 $size = ($partitions{$part}->{part_size} + $sectsize - 1)
1052                     / $sectsize;
1053             }
1054
1055             # Create it.
1056             my ($target, $end, $part_num) = add_partition ($start, $size);
1057             $partitions{$part}->{target} = $target;
1058
1059             if ($partitions{$part}->{bootable}) {
1060                 $g->part_set_bootable ("/dev/sdb", $part_num, 1);
1061             }
1062
1063             if ($partitions{$part}->{mbr_id}) {
1064                 $g->part_set_mbr_id ("/dev/sdb", $part_num,
1065                                      $partitions{$part}->{mbr_id});
1066             }
1067
1068             # Start of next partition + alignment.
1069             $start = $end + 1;
1070             $start = ($start + 63) & ~63;
1071         }
1072     }
1073
1074     # Create surplus partition.
1075     if ($extra_partition && $surplus >= $min_extra_partition) {
1076         add_partition ($start, $outsize / $sectsize - 64 - $start);
1077     }
1078 }
1079
1080 # Add a partition.
1081 sub add_partition
1082 {
1083     local $_;
1084     my $start = shift;
1085     my $size = shift;
1086
1087     my ($target, $end, $part_num);
1088
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++;
1094     } else {
1095         if ($nextpart == 4) {
1096             $g->part_add ("/dev/sdb", "extended", $start, -1);
1097             $part_num = $nextpart++;
1098             $start += 64;
1099         }
1100         $target = "/dev/sdb$nextpart";
1101         $end = $start + $size - 1;
1102         $g->part_add ("/dev/sdb", "logical", $start, $end);
1103         $part_num = $nextpart++;
1104     }
1105
1106     return ($target, $end, $part_num);
1107 }
1108
1109 # Copy over the data.
1110 copy_data ();
1111
1112 sub copy_data
1113 {
1114     foreach my $part (@partitions)
1115     {
1116         unless ($partitions{$part}->{ignore}) {
1117             my $target = $partitions{$part}->{target};
1118             if ($target) {
1119                 my $oldsize = $partitions{$part}->{part_size};
1120                 my $newsize;
1121                 if ($partitions{$part}->{newsize}) {
1122                     $newsize = $partitions{$part}->{newsize};
1123                 } else {
1124                     $newsize = $partitions{$part}->{part_size};
1125                 }
1126
1127                 if (!$quiet && !$debug) {
1128                     print __x("Copying {p} ...\n", p => $part);
1129                 }
1130
1131                 $g->copy_size ($part, $target,
1132                                $newsize < $oldsize ? $newsize : $oldsize);
1133             }
1134         }
1135     }
1136 }
1137
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.
1142 #
1143 # The restart is only required if we're going to expand something.
1144
1145 if ($to_be_expanded > 0) {
1146     restart_appliance ();
1147     expand_partitions ();
1148     expand_lvs ();
1149     expand_lvs_content ();
1150 }
1151
1152 sub restart_appliance
1153 {
1154     # Sync disk and exit.
1155     $g->umount_all ();
1156     $g->sync ();
1157     undef $g;
1158
1159     $g = Sys::Guestfs->new ();
1160     $g->set_trace (1) if $debug;
1161     $g->add_drive ($outfile);
1162     $g->launch ();
1163
1164     # Target partitions have changed from /dev/sdb to /dev/sda,
1165     # so change them.
1166     foreach my $part (@partitions)
1167     {
1168         my $target = $partitions{$part}->{target};
1169         if ($target) {
1170             if ($target =~ m{/dev/(.)db(.*)}) {
1171                 $partitions{$part}->{target} = "/dev/$1da$2";
1172             } else {
1173                 die "internal error: unexpected partition target: $target";
1174             }
1175         }
1176     }
1177 }
1178
1179 sub expand_partitions
1180 {
1181     foreach my $part (@partitions)
1182     {
1183         unless ($partitions{$part}->{ignore}) {
1184             my $target = $partitions{$part}->{target};
1185             if ($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",
1190                                   p => $part,
1191                                   meth => $partitions{$part}->{expand_content_method});
1192                     }
1193                     expand_target_partition ($part)
1194                 }
1195             }
1196         }
1197     }
1198 }
1199
1200 sub expand_target_partition
1201 {
1202     local $_;
1203     my $part = shift;
1204
1205     # Assertions.
1206     die unless $part;
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;
1212
1213     my $target = $partitions{$part}->{target};
1214     my $method = $partitions{$part}->{expand_content_method};
1215     if ($method eq "pvresize") {
1216         $g->pvresize ($target);
1217     }
1218     elsif ($method eq "resize2fs") {
1219         $g->e2fsck_f ($target);
1220         $g->resize2fs ($target);
1221     }
1222     elsif ($method eq "ntfsresize") {
1223         $g->ntfsresize ($target);
1224     }
1225     else {
1226         die "internal error: unknown method: $method";
1227     }
1228 }
1229
1230 sub expand_lvs
1231 {
1232     local $_;
1233
1234     foreach (@lv_expand) {
1235         $g->lvresize_free ($_, 100);
1236     }
1237 }
1238
1239 sub expand_lvs_content
1240 {
1241     local $_;
1242
1243     foreach (@lvs) {
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);
1249                     }
1250             if ($method eq "resize2fs") {
1251                 $g->e2fsck_f ($_);
1252                 $g->resize2fs ($_);
1253             } elsif ($method eq "ntfsresize") {
1254                 $g->ntfsresize ($_);
1255             } else {
1256                 die "internal error: unknown method: $method";
1257             }
1258         }
1259     }
1260 }
1261
1262 # Sync disk and exit.
1263 $g->umount_all ();
1264 $g->sync ();
1265 undef $g;
1266
1267 exit 0;
1268
1269 sub sizebytes
1270 {
1271     local $_ = shift;
1272     my $unit = shift;
1273
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]/;
1280
1281     return floor($_);
1282 }
1283
1284 # Convert a number of bytes to a human-readable number.
1285 sub human_size
1286 {
1287     local $_ = shift;
1288
1289     my $sgn = "";
1290     if ($_ < 0) {
1291         $sgn = "-";
1292         $_ = -$_;
1293     }
1294
1295     $_ /= 1024;
1296
1297     if ($_ < 1024) {
1298         sprintf "%s%dK", $sgn, $_;
1299     } elsif ($_ < 1024 * 1024) {
1300         sprintf "%s%.1fM", $sgn, ($_ / 1024);
1301     } else {
1302         sprintf "%s%.1fG", $sgn, ($_ / 1024 / 1024);
1303     }
1304 }
1305
1306 # Return the size in bytes of a HOST block device.
1307 sub host_blockdevsize
1308 {
1309     local $_;
1310     my $dev = shift;
1311
1312     open BD, "PATH=/usr/sbin:/sbin:\$PATH blockdev --getsize64 $dev |"
1313         or die "blockdev: $!";
1314     $_ = <BD>;
1315     chomp $_;
1316     $_;
1317 }
1318
1319 # The reverse of device name translation, see
1320 # BLOCK DEVICE NAMING in guestfs(3).
1321 sub canonicalize
1322 {
1323     local $_ = shift;
1324
1325     if (m{^/dev/[hv]d([a-z]\d)$}) {
1326         return "/dev/sd$1";
1327     }
1328     $_;
1329 }
1330
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
1334 {
1335     my $proc_nr = shift;
1336     my $serial = shift;
1337     my $position = shift;
1338     my $total = shift;
1339
1340     my $ratio = $position / $total;
1341     if ($ratio < 0) { $ratio = 0 }
1342     elsif ($ratio > 1) { $ratio = 1 }
1343
1344     my $dots = int ($ratio * 76);
1345
1346     print "[", "#"x$dots, "-"x(76-$dots), "]\r";
1347     print "\n" if $ratio == 1;
1348 }
1349
1350 =head1 NOTES
1351
1352 =head2 "Partition 1 does not end on cylinder boundary."
1353
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
1359 operating system.
1360
1361 =head2 RESIZING WINDOWS VIRTUAL MACHINES
1362
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:
1368 drive) should work.
1369
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.
1373
1374 =head1 ALTERNATIVE TOOLS
1375
1376 There are several proprietary tools for resizing partitions.  We
1377 won't mention any here.
1378
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.
1383
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.
1389
1390 =head1 SEE ALSO
1391
1392 L<virt-list-partitions(1)>,
1393 L<virt-list-filesystems(1)>,
1394 L<virt-df(1)>,
1395 L<guestfs(3)>,
1396 L<guestfish(1)>,
1397 L<lvm(8)>,
1398 L<pvresize(8)>,
1399 L<lvresize(8)>,
1400 L<resize2fs(8)>,
1401 L<ntfsresize(8)>,
1402 L<virsh(1)>,
1403 L<parted(8)>,
1404 L<Sys::Guestfs(3)>,
1405 L<http://libguestfs.org/>.
1406
1407 =head1 AUTHOR
1408
1409 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
1410
1411 =head1 COPYRIGHT
1412
1413 Copyright (C) 2010 Red Hat Inc.
1414
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.
1419
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.
1424
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.