Some Linux virtual machines

and how to interface the host and guest filesystems

I run Linux. Sometimes it's helpful to use a different Linux distro installation than my main one. For example:

Some methods I've used:

For installation:

For running:

QEMU

QEMU of a system installed on a disk image does not require root. (Unless you use `sudo mount -o loop` to help create your disk image.) Regular disk images are fixed-size and can thus waste space and/or run out of space if you install things on the guest system. (QEMU's qcow2 disk image can allocate storage as-needed for the guest, but, since it's emulating a block device, I don't believe it can shrink unless it listens to guest TRIM requests. `qemu-img` can create these.)

One way:

# Setup (if you have already created a debootstrap as above)
# Make sure a kernel is installed in the debootstrap
# e.g.: (superchroot as mentioned above)
sudo superchroot ./debootstrap-amd64-wheezy \
    /usr/bin/aptitude install linux-image-3.2.0-4-amd64
sudo dd if=/dev/zero of=./deb-amd64-wheezy.img bs=1M count=5000
sudo mkfs.ext4 ./deb-amd64-wheezy.img
# If necessary, sudo mkdir /media/x or any dir name you like in /media/
sudo mount -o loop ./deb-amd64-wheezy.img /media/x
# If you've chrooted to the copy source before, make sure to
# unmount its dev, dev/pts, proc, sys before copying: we want to copy
# the physical files that are present before special filesystems are
# mounted, not the special filesystems' contents! :
sudo umount ./debootstrap-amd64-wheezy/{dev/pts,dev,proc,sys}
# Warning: this glob would miss top-level dot files if there were any.
sudo cp -a ./debootstrap-amd64-wheezy/* /media/x
# Warning: make sure to unmount before using the image!
# Otherwise host and/or guest kernels might panic by both thinking
# they have exclusive modification rights to this ext4 filesystem
# (if you're unlucky).
sudo umount /media/x

# Running
# This method uses the kernel/initrd from the original debootstrap
# rather than the disk image.
# Optional flags: -enable-kvm makes it run much faster. -m 1500 gives
# it up to 1.5 GB of RAM.  -cpu core2duo is a workaround to prevent
# guest `gcc -march=native` mis-detecting the emulated CPU as 32-bit
# even though QEMU is emulating a 64-bit CPU.
sudo qemu-system-x86_64 -enable-kvm -m 1500 -cpu core2duo \
    -kernel ./debootstrap-amd64-wheezy/boot/vmlinuz-3.2.0-4-amd64 \
    -initrd ./debootstrap-amd64-wheezy/boot/initrd.img-3.2.0-4-amd64 \
    -hda ./deb-amd64-wheezy-openmo.img \
    -append 'root=/dev/sda'

To access the disk contents from the host system, either transfer files over the virtual network (e.g. run an ssh server in the VM), or shut down the VM and mount the disk image with host Linux. If the disk image is qcow2, you can mount it using qemu-nbd (and modprobe nbd) along the lines of this post. qemu-img convert can also convert between image types.

QEMU of a host filesystem tree that's not encapsulated in a disk image:

Apparently 9p, the filesystem protocol originally created for Plan 9, is the way to run QEMU on a guest stored in a host-mounted filesystem. The guest's kernel must support 9p (e.g. 9p kernel modules must be loaded before any 9p filesystems need to be mounted). For my Debian guest, I had to edit its etc/initramfs-tools/modules to include

9p
9pnet
9pnet_virtio

and then run update-initramfs -u in the chroot. 9p is the filesystem and 9pnet_virtio is the "transport" that lets it connect to QEMU-provided 9p filesystems. The host kernel does not need to understand 9p: QEMU uses the regular filesystem interface on the host, and creates a virtual 9p interface for the guest.

Then, to run,

sudo qemu-system-x86_64 -enable-kvm -m 1500 -cpu core2duo \
    -kernel ./debootstrap-amd64-wheezy/boot/vmlinuz-3.2.0-4-amd64 \Some 
    -initrd ./debootstrap-amd64-wheezy/boot/initrd.img-3.2.0-4-amd64 \
    -fsdev local,id=test_dev,path=./debootstrap-amd64-wheezy,security_model=none \
    -device virtio-9p-pci,fsdev=test_dev,mount_tag=test_mount \
    -append 'rootfstype=9p rootflags=trans=virtio root=test_mount console=ttyS0'</pre>

Without 'sudo', it will run but then fail to access files such as etc/shadow that non-root can't access. You won't be able to log in and you'll have no idea why. The flags `-enable-kvm -m 1500 -cpu core2duo` are optional as described above. -virtfs can be used as a shorthand for -fsdev + -device. The names 'test_dev' and 'test_mount' are arbitrary but used as names: if you rename one instance of either, rename all instances of it. console=ttyS0 changes which guest debug messages and interactive prompts you can get: add/remove it freely while debugging this setup.

Warning: Don't start a VM while the VM's disk image is loop-mounted or while you're chrooted to it with dev/proc/sys mounted on the host system. Weird things can happen, including kernel panics. However, the host editing the files within a guest 9p filesystem should work (provided 9p caching isn't turned on in the guest kernel mount options).


  1. Perhaps because of a GCC or toolchain version incompatibility. Error message "Simulation execution failed for model" when trying to run the "Hello World" model in OMNotebook or OMShell. The only relevant search result was a Gentoo user trying to install OpenModelica. I use Arch Linux, which can be similarly cutting-edge. OpenModelica provides Debian binaries and I chose to see if those worked on Debian rather than try to debug further on Arch Linux. They worked fine.