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