Have you ever wanted to resize a disk in a VM and wondered how insanely painful that would be? After all, from the old days of platter-based spinning drives in computers (sorry to those of you still living in those days), before SANs with resizable LUNs, file-backed VMs, and other marvels of recent times, disks didn’t magically resize themselves unless it was to get smaller because they were breaking/broken. As a result, OS’s have learned to handle bad sectors by avoiding them, but growing the current, running disk just seems eerie to me every time I want to do it. Apparently I’m old.
Today I wanted to do just that (resize a disk, not get old), and I wanted to do it for a VM. Not just any VM, but a VM running within KVM on my openSUSE 12.2 x86_64 (yes, I’m out of date… waiting for 13.1) system. This VM also happens to run a proprietary OS for which I have little trust, but it’s new enough that should I accomplish my disk resizing properly I had hope that the OS could work with that new space correctly. To add a bit more interesting stuff to the mix, this VM has several snapshots. If you have not done snapshots with KVM you’re probably missing out as they are very simple and flexible and work as you’d expect with the possibility of branching over and over to your heart’s content. Anyway, what happens when, in the middle of a snapshot, you want to resize the disk? What if your base system from which the snapshot is generated is read-only (to prevent doing bad thing to the base)? How many convolutions of ‘dd’ will be needed and how terrible will the cleanup be from a need to do something that is just a bit too eerie to be plausible? In fact, it turns out that Linux Just Does That.
I set out to find out how to resize disks in KVM which was a trivial task as it turns out (thanks Google). Thanks to this little helpful article I found, the command is so basic I probably could have guessed it using tab completion: http://www.linux-kvm.com/content/how-resize-your-kvm-virtual-disk
And here is the daunting command in all of its complexity:
qemu-img resize disk-file-goes-here.qcow2 +20GB
Oooh…. ah….. so much power. The output is similarly anticlimactic in its declaration of ‘Image resized.’ In case it is not evident, this increases the size of the specified disk file by 20 GB. Because it is exceptionally clever it does so in a sparse way, just like the original disk was in my case, so I did not magically lose 20 GB of my host’s disk space, but instead I have the possibility of growing the guest with almost no space lost.
Still, the article mentioned above did not talk about KVM snapshots at all, so I was left wondering how to run this on my VM. In my case I have snapshots branching from a read-only base image that I took who-knows-how-long ago, and those snapshots are things I’d rather not try to recreate from scratch. Resizing the base image just seemed to be wrong…. adding that much space so late in the game to something up on which other snapshots depends just felt like asking for too much trouble. If something goes wrong there will it break all snapshots? If things go right there, will it still break all snapshots due to some odd block offsets that the snapshots use and assume are immutable? No idea…. don’t care to find out, so I went with the lower-risk (in my opinion) option and pointed at my latest snapshot with the qemu-img command, then pulled the death star’s trigger with the [Enter] key. As a note, all of this was done as my regular, non-root user because this was properly designed and so, of course, nothing here needs ‘root’ for playing in the filesystem.
The output from my resize attempt was as hoped: ‘Image resized.’ Of course, who knows if that means the file allows more space but the internals are not complete mush. Hoping that my trust in the intelligence of people creating Linux was justified, and realizing I had not taken a backup of my newly-modified snapshot file, I started the VM. As it started I fired up the ‘ping’ command to hope for some kind of response and after fifteen seconds I released my breath when the first replies came back. At least the system was able to boot.
Once inside the system it’s up to OS tools to resize filesystems, so using parted/gparted makes sense for most situations. At the end of the day this entire process has a few interesting implications.
- I can build VMs smaller than I have been. Why? Because I can resize them, and specifically their snapshots, whenever I want to. This isn’t a huge deal since I build the snapshots using sparse qcow2 files anyway, but it’s nice to know that my installs could be disk-conserving without limiting me in any real way in the long term.
- Changing disk sizes in snapshots is possible, which is just awesome! The awesomeness can come, if in no other way, in the form of a serene sense of calm knowing, as I did, that my resize attempt, if it were to fail, would not blow up my entire VM with all subsequent snapshots, but would only possible blow up my current snapshot. Looking back on it now I should have created a new snapshot called something creative like “bigger-disk” and then resized that specifically. The result is that I would have lost nothing had things gone awry.
- Since none of this required ‘root’ access on my host, and since it works on snapshots, this opens up the possibilities for interesting hardware-like tests I have wanted to perform, and let others perform on systems, without much risk to me. For example, I’ve read that ext3 allows you to resize (growing at least), but the number of allocated inodes does not change unless you recreate the entire filesystem. This is important when you run out of inodes in the filesystem before you run out of space to hold the files linked-to by those inodes. I’d like to test ext4 in order to see if things are different there, but before realizing I could safely resize a snapshot I was a bit worried about possibly needing to procure a physical box or use LVM or other things that might make my test a little less-pure. I do not have extra physical boxes and all of my systems are KVM VMs so this newly-found capability works perfectly.
Out of curiosity I poked at the qemu-imag manpage and found a few more gems in there that appear to be useful, in particular the ‘convert’ option. It appears to be possible to do a lot with disk files and the contained data, especially with the growable formats like qcow2, basically amounting to cloning, compressing, and creating new VMs from existing VMs with their snapshots (whichever, if any, you choose) applied. The possibilities for testing would seem to be endless since using snapshots strategically one could easily allow a tester to have dozens (no limit really) of systems created, all with the same origin since they are all basically the same system. This is nothing superbly new for VMs to pull off, but to do so with so little work, and in particularly no need for a GUI, means a lot of scripting possibilities.
At the end of the day the important lesson that I should have assumed from the start is that this is all built in. I am not a trailblazer in most Linux areas, and as a result I do not need to worry about how bleeding, or even cutting, edge my operations are. Because others have been here and solved these problems, Linux Just Does That.