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