Tag Archives: virt-resize

Cool new bash-completions of libguestfs tools

Starting in libguestfs ≥ 1.21.23-2, bash tab completions of guestfish, guestmount and virt-* tools have been rewritten and greatly improved.

Note you will need to install the libguestfs-bash-completion package to enable this feature.

You can now tab complete all long options on most tools:

$ virt-df --[tab]
--add             --domain          --human-readable  --uuid
--connect         --format          --inodes          --verbose
--csv             --help            --one-per-guest   --version
$ virt-resize --[tab]
--align-first          --help                 --no-extra-partition
--alignment            --ignore               --ntfsresize-force
--debug                --lvexpand             --output-format
--debug-gc             --lv-expand            --quiet
--delete               --LVexpand             --resize
--dryrun               --LV-expand            --resize-force
--dry-run              --machine-readable     --shrink
--expand               --no-copy-boot-loader  --version
--format               --no-expand-content    

Where appropriate, the -d option will now expand to the list of libvirt domains:

# virt-df -d [tab]
archlinux20121201x64  f19rawhidex32
f18x64                f19rawhidex64

Finally, guestfish commands are expanded on the command line:

$ guestfish add /tmp/disk : run : list-[tab]
list-9p              list-events          list-md-devices
list-devices         list-filesystems     list-partitions
list-disk-labels     list-ldm-partitions  
list-dm-devices      list-ldm-volumes     

To make this less intrusive, so you can really use it daily, I left the default readline expansions enabled. This means that filenames and so on can continue to be used in every position on the command line, and should mean that bash completions won’t try to be cleverer than the user.

Libguestfs bash completions are also demand-loaded now, so that if you’re not using them, they don’t consume any resources in the shell.

Leave a Comment

Filed under Uncategorized

Build a guest library

I have this exported over NFS to all my local machines:

$ ls -lh /mnt/media/guest-library/
total 12G
-rw-r--r--. 1 rjones rjones 971M Apr 16 23:38 debian5x64.img.xz
-rw-r--r--. 1 rjones rjones 250M Jul 26 23:09 f16x32.img.xz
-rw-r--r--. 1 rjones rjones 809M Jul 26 20:29 f17x64.img.xz
-rw-r--r--. 1 rjones rjones  59M Jul  6 22:19 freedos11.img.xz
-rw-r--r--. 1 rjones rjones 379M Jul  7 20:11 opensuse1113x64.img.xz
-rw-r--r--. 1 rjones rjones 349M Jul  6 22:31 plan9.img.xz
-rw-rw-r--. 1 rjones rjones  126 Apr 16 17:22 README
-rw-r--r--. 1 rjones rjones 384M Apr 18 00:19 rhel3x64.img.xz
-rw-r--r--. 1 rjones rjones 471M Apr 18 00:15 rhel4x64.img.xz
-rw-r--r--. 1 rjones rjones 848M Apr 16 17:02 rhel5epelx64.img.xz
-rw-r--r--. 1 rjones rjones 768M Jul  7 07:21 sl60x64.img.xz
-rw-r--r--. 1 rjones rjones 148M May 23 16:08 ubuntu1204ppc.img.xz
-rw-r--r--. 1 rjones rjones 1.1G Apr 16 17:09 win2003.img.xz
-rw-r--r--. 1 rjones rjones 3.4G Jun  1 10:46 win8-preview.img.xz
-rw-r--r--. 1 rjones rjones 2.1G Apr 16 20:28 winxp.img.xz

Having a library of images which are (relatively) small like this is great for testing. If someone gives me a bug and it happens to affect one of the guests I have saved, then I can just unpack that guest, virt-resize it to the right size and off I go, and that’s usually a lot quicker than installing a new guest, particularly when you’ve got only slow ADSL.

Adding a new guest is easy using virt-sparsify and xz. Note I’ve set the temporary directory (TMPDIR) to somewhere with plenty of space.

$ sudo TMPDIR=$(pwd) virt-sparsify /dev/vg_pin/F18Rawhidex32 f18rawhidex32.img
Create overlay file to protect source disk ...
Examine source disk ...
 100% ⟦▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓⟧ 00:00
Fill free space in /dev/vda1 with zero ...
 100% ⟦▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓⟧ --:--
Fill free space in /dev/vg_f18rawhidex32/lv_root with zero ...
 100% ⟦▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓⟧ --:--
Clearing Linux swap on /dev/vg_f18rawhidex32/lv_swap ...
 100% ⟦▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓⟧ 00:00
Copy to destination and make sparse ...

Sparsify operation completed with no errors.  Before deleting the old 
disk, carefully check that the target disk boots and works correctly.

$ ll -h f18rawhidex32.img
-rw-r--r--. 1 root root 10G Jul 27 14:42 f18rawhidex32.img
$ du -sh f18rawhidex32.img
3.0G	f18rawhidex32.img
$ xz -T 0 --best f18rawhidex32.img
$ ll -h f18rawhidex32.img.xz
-rw-r--r--. 1 rjones rjones 667M Jul 27 14:42 f18rawhidex32.img.xz

2 Comments

Filed under Uncategorized

New tool: virt-sysprep

New in libguestfs 1.13.19 is a tool called virt-sysprep which makes it easier to clone virtual machines.

The new tool isn’t a complete clone tool, but you can easily combine it with other tools like dd, the old virt-clone, virt-resize and virt-sparsify to clone virtual machines.

6 Comments

Filed under Uncategorized

New tool for making VMs sparse (aka thin provisioning)

New in libguestfs 1.13.17 is a tool for making virtual machines or disk images sparse, also known as thin provisioning.

This tool restores sparseness lost after you’ve created and deleted files. It works for virtually any guest OS, and supports almost any filesystem.

It can also do some clever things like finding sparseness in the unused parts of LVM physical volumes, or converting between formats (eg. raw to thin-provisioned qcow2).

It’s also (like virt-resize) a temporary tool: hopefully one day KVM and guests will be able to resize and trim themselves. That day isn’t here yet.

virt-sparsify manual page

2 Comments

Filed under Uncategorized

Arrrgghh writing GUI programs is tedious

Last week I thought it would be a good idea to write a small GUI front end to virt-resize.

After two days, I nearly have the first tab (out of four) working.

Granted, maybe the first tab is the hardest one:

The job of the first tab is to ask the user for the source (disk image or libvirt guest). It then fires off a background job to open that guest and inspect it for operating systems. Based on the outcome of that (opened OK, found OSes, no OSes found, etc) it has to update and enable the other tabs.

Also the user can preselect a guest on the command line. We also have to deal with connecting to libvirt asynchronously to read the list of guests (and this might also fail in a number of ways).

So far, 1600 lines of code, and the first tab is by no means complete.

One part of the problem is there’s a certain “impedance mismatch” between functional programming in OCaml and writing Gtk. Gtk is heavily mutable and object based. OCaml prefers (but does not require) immutability, and objects in OCaml are obscure and not widely used, and the Gtk bindings are written in a very hard-core object OCaml style.

Another part is just that it’s tedious. It would be tedious if I was doing this in C or Python too. You’ve got asynchronous actions going off here and there which update bits of state. Every control or input could potentially affect every other control or output, resulting in a kind of O(n2) mess of wiring up signals and callbacks.

Is there an easier way? I don’t know …

13 Comments

Filed under Uncategorized

virt-resize machine readable output

As I planned earlier I have added machine readable output to virt-resize.

One huge frustration we have had with qemu for a long time is that you cannot query a qemu binary for its “capabilities” (eg. does this binary support virtio? does this binary support particular -drive options?).

virt-resize now supports this kind of querying, thus with any virt-resize ≥ 1.12.5 you can do:

$ virt-resize --machine-readable
virt-resize
ntfsresize-force
32bitok
ntfs
btrfs

The simple list of facts is designed to be easy to parse. Does this virt-resize work on 32-bit platforms (old versions written in Perl didn’t)? Answer: yes because of the 32bitok fact. Does this binary support btrfs guests? In this case yes.

Over time as we add more features to virt-resize we will add facts to this list, so that consumers of virt-resize can tell what the binary supports.

This is a simple plan. Qemu developers, take note!

The second thing that this option does is to make the output of virt-resize more regular and easier to consume. At the moment this means that progress bars in virt-resize will revert to a simple format:

$ virt-resize --machine-readable old.img new.img
...
0/100
1/100
2/100
...

so that programs can just match on ^\d+/\d+$ on stdout, and turn that into a progress bar. User messages go to stdout and errors to stderr. The output is designed to be both very lightweight to parse and easy to understand for humans (and in fact not that much different from the regular virt-resize output). We may make small enhancements in future.

Leave a Comment

Filed under Uncategorized

Half-baked idea: Standard machine readable output for command line programs

For more half-baked ideas, see the ideas tag.

It’s common, perhaps increasingly common, that one program needs to consume the output of another. This is the Unix philosophy — small, single purpose programs assembled together to carry out a more complex task.

However it’s not necessarily superior to alternative ways of composing programs, like COM or D-Bus.

There are two particular problems: 1. How do you find out if a particular feature is supported by the program? 2. How do you parse the output of the program (eg. to find progress bars or error messages)?

As a concrete example, let’s consider a program I wrote called virt-resize. 1. How do I find out if the version of virt-resize I have supports btrfs? 2. If I want to drive virt-resize from a graphical program, how can I parse the text progress bars that virt-resize prints?

For question 1, typical Unix programs take several approaches:

  1. Ignore the problem completely. Just blindly use the feature, and fail in unpredictable ways if it doesn’t work. This is probably the most popular “strategy”. People who write shell scripts tend to do this all the time. Shell scripts are often either unportable, or end up looking like “configure” because they try to use a very conservative subset of POSIX.
  2. Run the program, if it fails, run the program a bit differently (and if it fails, a bit differently again, …).
  3. Attempt to parse the output of program --help. This depends on help output being stable, when maybe it isn’t, so you end up chasing the upstream project.
  4. Parse program --version and work out if the feature was supported in that particular version. This is not very scalable, and doesn’t work with backports.

Question 2, how to get errors and progress bars, is usually too hard, unless the program offers a special “machine readable” flag (notable examples: rpm, parted).

Here’s my half-baked idea: We should standardize the way that program capabilities, help, progress bars, and error output is done.

An additional option is added to programs that support this:

$ program --machine-readable [...]

Programs that don’t support this, and programs that didn’t support it in earlier versions, ought to give an error if this option is not available.

Firstly, the caller just runs the program with this option on its own, and no other options:

$ program --machine-readable
resize-btrfs
resize-ext3
lv-expand
progress-bars

The program just prints out a list of capabilities, one per line, but with no defined format (that is a contract between the program and the caller). The program then exits with status 0. Using this option should not cause the program to perform any other action.

Secondly, if this was successful, the caller can use this option in combination with other options to produce machine-readable output. At least one other option or command line argument is required for this to work.

I would like to suggest the following standards for version numbers, progress bars and error messages.

Machine-readable version numbers are sent to stdout and have the form “program-name version”, where “program-name” should be one word. This is no different from how most GNU programs work:

$ program --version
program 0.1.2

Machine-readable progress bars are sent to stdout and have the form (example) “[10/100]“:

$ program --machine-readable foo
[0/100]
[1/100]
[2/100]
etc.

Error messages are anything sent to stderr when the status code of the program is non-zero. This is, of course, no change from standard Unix.

$ program --machine-readable foo
foo: File not found

24 Comments

Filed under Uncategorized

virt-resize now works with btrfs

virt-resize now works with guests that use btrfs:

$ virt-resize /dev/vg_pin/F15BTRFSx64 /dev/vg_pin/TmpBTRFS --expand sda3
Examining /dev/vg_pin/F15BTRFSx64 ...
[########################################################################]
**********

Summary of changes:

/dev/sda1: This partition will be left alone.

/dev/sda2: This partition will be left alone.

/dev/sda3: This partition will be resized from 9.0G to 14.0G.  The 
    filesystem btrfs on /dev/sda3 will be expanded using the 
    'btrfs-filesystem-resize' method.

**********
Setting up initial partition table on /dev/vg_pin/TmpBTRFS ...
Copying /dev/sda1 ...
[########################################################################]
Copying /dev/sda2 ...
[########################################################################]
Copying /dev/sda3 ...
[########################################################################]
[########################################################################]
Expanding /dev/sda3 using the 'btrfs-filesystem-resize' method ...

Resize operation completed with no errors.  Before deleting the old 
disk, carefully check that the resized disk boots and works correctly.

Leave a Comment

Filed under Uncategorized

Reminder: Summit talk on libguestfs, virt-v2v

Anyone who’s coming to the Red Hat Summit next week (Boston USA, May 3-6), please remember to drop in at our talk on libguestfs, the virt tools, virt-v2v and virt-p2v. It’s on Wednesday morning at 11.30am.

I will be live demonstrating guestfish, virt-resize and more. Matt will be showing us virt-v2v and the new version of virt-p2v that he has written.

To head off the expected question: Will the slides be available after the talk? Mine won’t because I don’t really “do” slides. However there will be a handout available (either on this blog or on the summit web pages or both) which covers all the background material and contains additional worked examples and exercises. We are hoping the talk will also be videoed like last year.

Leave a Comment

Filed under Uncategorized

Tip: Expand a Windows virtual machine

(You will need virt-resize ≥ 1.4 for this)

My Windows VM is stored in a logical volume on the host. It is 16GB currently, and for the purposes of this example I will expand that to 18GB. virt-resize doesn’t touch the old disk image, so I have to rename the old one and create a new one like this:

# lvrename /dev/vg_pin/Win7x32 /dev/vg_pin/Win7x32old
  Renamed "Win7x32" to "Win7x32old" in volume group "vg_pin"
# lvcreate -n Win7x32 -L 18G /dev/vg_pin
  Logical volume "Win7x32" created

Let’s have a look at how the Windows VM is organized at the moment. Some versions of Windows put the C: drive on the first partition, but recent versions use a small boot partition and have the C: drive on the second partition. virt-resize is only able to resize the C: drive (but for Linux VMs virt-resize can resize any partition including the boot partition):

# virt-list-filesystems -al /dev/vg_pin/Win7x32old
/dev/sda1 ntfs                <-- boot partition
/dev/sda2 ntfs                <-- C: drive

And now we simply do the resize. In this case I’m going to ask virt-resize to expand the C: drive (/dev/sda2). Other choices would be to ask virt-resize to create an extra partition at the end of the disk or to leave the extra space unpartitioned.

# virt-resize --expand /dev/sda2 /dev/vg_pin/Win7x32old /dev/vg_pin/Win7x32
Summary of changes:
/dev/sda1: partition will be left alone
/dev/sda2: partition will be resized from 15.9G to 17.9G
/dev/sda2: content will be expanded using the 'ntfsresize' method
Copying /dev/sda1 ...
[############################################################################]
Copying /dev/sda2 ...
[############################################################################]
Expanding /dev/sda2 using the 'ntfsresize' method

Finally, check that the new copy of Windows boots! (By the way, Windows will do a chkdsk the first time it boots. This is deliberate. We tell Windows to do this so we can be sure that we haven’t damaged any of the data during the copy or resize).

If it boots, you can delete the old copy of Windows:

# lvchange -an /dev/vg_pin/Win7x32old 
# lvremove /dev/vg_pin/Win7x32old 
  Logical volume "Win7x32old" successfully removed

If it doesn’t boot, please file a bug giving all the details, then revert back to the old copy.

Leave a Comment

Filed under Uncategorized