I’m writing a new nbdkit plugin called linuxdisk. nbdkit is our flexible, plugin-based NBD server, and this new plugin lets you create a complete Linux-compatible virtual disk from a host directory on the fly.
One of the many uses for this is booting minimal VMs very quickly. Here’s an example you can set up in a few seconds. It boots to an interactive busybox shell:
$ mkdir /tmp/root /tmp/root/sbin /tmp/root/bin /tmp/root/dev
$ sudo mknod /tmp/root/dev/console c 5 1
$ cp /sbin/busybox /tmp/root/sbin/
$ ln /tmp/root/sbin/busybox /tmp/root/bin/sh
$ ln /tmp/root/sbin/busybox /tmp/root/bin/ls
$ ln /tmp/root/sbin/busybox /tmp/root/sbin/init
$ nbdkit -U - linuxdisk /tmp/root \
--run 'qemu-kvm -display none -kernel /boot/vmlinuz-4.20.8-200.fc29.x86_64 -drive file=nbd:unix:$unixsocket,snapshot=on -append "console=ttyS0 root=/dev/sda1 rw" -serial stdio'
If you need any extra files in the VM just drop them straight into
/tmp/root before booting it.
Edit: How the heck does
/dev get populated in this VM?
We’ve had to change the way libguestfs boots its appliance, so now the appliance will be an ext2 filesystem from an ordinary drive, instead of an initrd.
The problem is that we need to create the ext2 filesystem on the fly, and we can’t use libguestfs to do this (which would be way easier than the method I’m about to describe).
However e2fsprogs comes with a low-level library for manipulating ext2 filesystem images, and it is just about possible to use this to make an ext2 filesystem and put files and directories on to it.
The documentation on libext2fs is very light on detail, but I have written some example code:
Compile and run this with:
$ gcc -Wall test.c -o test -lext2fs -lcom_err
$ guestfish -a /tmp/test.img -m /dev/sda
><fs> ll /
drwxr-xr-x 4 500 500 1024 Aug 19 12:08 .
dr-xr-xr-x 20 root root 0 Aug 19 12:09 ..
-rw-r--r-- 1 root root 100000 Aug 19 12:08 hello
drwx------ 2 root root 12288 Aug 19 12:08 lost+found
drwxr-xr-x 2 root root 1024 Aug 19 12:08 mydir
><fs> ll /mydir/
drwxr-xr-x 2 root root 1024 Aug 19 12:08 .
drwxr-xr-x 4 500 500 1024 Aug 19 12:08 ..
-rw-r--r-- 1 root root 99 Aug 19 12:08 file_in_mydir
><fs> cat /mydir/file_in_mydir
It’s also advisable to read about how ext2 works internally.