#!/usr/bin/perl -w
# virt-resize
-# Copyright (C) 2010 Red Hat Inc.
+# Copyright (C) 2010-2011 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
results, shut the virtual machine down before resizing it.
If you are not familiar with the associated tools:
-L<virt-list-partitions(1)>,
-L<virt-list-filesystems(1)> and
-L<virt-df(1)>,
-we recommend you go and read those manual pages first.
+L<virt-filesystems(1)> and L<virt-df(1)>, we recommend you go and read
+those manual pages first.
=head1 EXAMPLES
to fill the extra 5GB of space.
truncate -r olddisk newdisk; truncate -s +5G newdisk
- virt-list-partitions -lht olddisk
+ virt-filesystems --long -h --all -a olddisk
# Note "/dev/sda2" is a partition inside the "olddisk" file.
virt-resize --expand /dev/sda2 olddisk newdisk
virt-resize --resize /dev/sda1=+200M --expand /dev/sda2 olddisk newdisk
+As above, but the output format will be uncompressed qcow2:
+
+ qemu-img create -f qcow2 newdisk.qcow2 15G
+ virt-resize --expand /dev/sda2 olddisk newdisk.qcow2
+
=head1 DETAILED USAGE
=head2 EXPANDING A VIRTUAL MACHINE DISK
=item 3. Look at current sizing
-Use L<virt-list-partitions(1)> to display the current partitions and
+Use L<virt-filesystems(1)> to display the current partitions and
sizes:
- # virt-list-partitions -lht /dev/vg/lv_guest
- /dev/sda1 ext3 101.9M
- /dev/sda2 pv 7.9G
- /dev/sda device 8.0G
+ # virt-filesystems --long --parts --blkdevs -h -a /dev/vg/lv_guest
+ Name Type Size Parent
+ /dev/sda1 partition 101M /dev/sda
+ /dev/sda2 partition 7.9G /dev/sda
+ /dev/sda device 8.0G -
(This example is a virtual machine with an 8 GB disk which we would
like to expand up to 10 GB).
equivalent of calling a command such as L<pvresize(8)>,
L<resize2fs(8)> or L<ntfsresize(8)>. However virt-resize does not
know how to resize some filesystems, so you would have to online
-resize them after booting the guest. And virt-resize also does not
-resize anything inside an LVM PV, it just resizes the PV itself and
-leaves the user to resize any LVs inside that PV as desired.
+resize them after booting the guest.
Other options are covered below.
but note that it also renumbers any partitions after the one which is
deleted, which can leave some guests unbootable.
+=head2 QCOW2 AND NON-SPARSE RAW FORMATS
+
+If the input disk is in qcow2 format, then you may prefer that the
+output is in qcow2 format as well. Alternately, virt-resize can
+convert the format on the fly. The output format is simply determined
+by the format of the empty output container that you provide. Thus to
+create qcow2 output, use:
+
+ qemu-img create [-c] -f qcow2 outdisk [size]
+
+instead of the truncate command (use C<-c> for a compressed disk).
+
+Similarly, to get non-sparse raw output use:
+
+ fallocate -l size outdisk
+
+(on older systems that don't have the L<fallocate(1)> command use
+C<dd if=/dev/zero of=outdisk bs=1M count=..>)
+
=head1 OPTIONS
=over 4
=item *
-LVM PVs (physical volumes). However virt-resize does I<not>
-resize anything inside the PV. The user will have to resize
-LVs as desired.
+LVM PVs (physical volumes). virt-resize does not usually resize
+anything inside the PV, but see the C<--LV-expand> option. The user
+could also resize LVs as desired after boot.
=back
that. You can stop virt-resize from trying to expand the content by
using the option C<--no-expand-content>.
-Use L<virt-list-filesystems(1)> to list the filesystems in
+Use L<virt-filesystems(1)> to list the filesystems in
the guest.
You can give this option multiple times, I<but> it doesn't
Don't print the summary.
+=cut
+
+my $format;
+
+=item B<--format> raw
+
+Specify the format of the input disk image. If this flag is not
+given then it is auto-detected from the image itself.
+
+If working with untrusted raw-format guest disk images, you should
+ensure the format is always specified.
+
+Note that this option I<does not> affect the output format.
+See L</QCOW2 AND NON-SPARSE RAW FORMATS>.
+
+=cut
+
+my $output_format;
+
+=item B<--output-format> raw
+
+Specify the format of the output disk image. If this flag is not
+given then it is auto-detected from the image itself.
+
+If working with untrusted raw-format guest disk images, you should
+ensure the format is always specified.
+
+Note that you still need to create the output disk with the right
+format. See L</QCOW2 AND NON-SPARSE RAW FORMATS>.
+
=back
=cut
"d|debug" => \$debug,
"n|dryrun|dry-run" => \$dryrun,
"q|quiet" => \$quiet,
+ "format=s" => \$format,
+ "output-format=s" => \$output_format,
) or pod2usage (2);
pod2usage (1) if $help;
if ($version) {
{
$g = Sys::Guestfs->new ();
$g->set_trace (1) if $debug;
- $g->add_drive_ro ($infile);
- $g->add_drive ($outfile);
- $g->set_progress_callback (\&progress_callback) unless $quiet;
+ my @args = ($infile);
+ push @args, readonly => 1;
+ push @args, format => $format if defined $format;
+ $g->add_drive_opts (@args);
+ @args = ($outfile);
+ push @args, format => $output_format if defined $output_format;
+ $g->add_drive_opts (@args);
+ $g->set_event_callback (\&progress_callback, $Sys::Guestfs::EVENT_PROGRESS)
+ unless $quiet;
$g->launch ();
}
$g = Sys::Guestfs->new ();
$g->set_trace (1) if $debug;
- $g->add_drive ($outfile);
+ my @args = ($outfile);
+ push @args, format => $output_format if defined $output_format;
+ $g->add_drive_opts (@args);
$g->launch ();
# Target partitions have changed from /dev/sdb to /dev/sda,
{
local $_ = shift;
- if (m{^/dev/[hv]d([a-z]\d)$}) {
+ if (m{^/dev/[hv]d([a-z]\d*)$}) {
return "/dev/sd$1";
}
$_;
# I intend to use an external library for this at some point (XXX).
sub progress_callback
{
- my $proc_nr = shift;
- my $serial = shift;
- my $position = shift;
- my $total = shift;
+ my $event = shift;
+ my $event_handle = shift;
+ my $buf = shift;
+ my $array = shift;
+
+ my $proc_nr = $array->[0];
+ my $serial = $array->[1];
+ my $position = $array->[2];
+ my $total = $array->[3];
my $ratio = $position / $total;
if ($ratio < 0) { $ratio = 0 }
if NTFS partitions have been expanded. This is just a safety check
and (unless it find errors) is nothing to worry about.
+=head2 GUEST BOOT STUCK AT "GRUB"
+
+If a Linux guest does not boot after resizing, and the boot is stuck
+after printing C<GRUB> on the console, try reinstalling grub. This
+sometimes happens on older (RHEL 5-era) guests, for reasons we don't
+fully understand, although we think is to do with partition alignment.
+
+ guestfish -i -a newdisk
+ ><fs> cat /boot/grub/device.map
+ # check the contents of this file are sensible or
+ # edit the file if necessary
+ ><fs> grub-install / /dev/vda
+ ><fs> exit
+
+For more flexible guest reconfiguration, including if you need to
+specify other parameters to grub-install, use L<virt-rescue(1)>.
+
=head1 ALTERNATIVE TOOLS
There are several proprietary tools for resizing partitions. We
=head1 SEE ALSO
-L<virt-list-partitions(1)>,
-L<virt-list-filesystems(1)>,
+L<virt-filesystems(1)>,
L<virt-df(1)>,
L<guestfs(3)>,
L<guestfish(1)>,
L<ntfsresize(8)>,
L<virsh(1)>,
L<parted(8)>,
+L<truncate(1)>,
+L<fallocate(1)>,
+L<grub(8)>,
+L<grub-install(8)>,
+L<virt-rescue(1)>,
L<Sys::Guestfs(3)>,
L<http://libguestfs.org/>.