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