Many times there are multiple solutions to a problem. This statement is driven to an extreme by the number of tools provided in a standard Linux distribution.
Most of the time, I'd like to find the fastest solution.
In Linux, the fastest solution usually includes installing a tool that does the job.
But sometimes I prefer an elegant solution - one that uses the tools at hand, one that will teach me more about the versatility of the environment I'm already using.
The task at hand was to install an upstream kernel on a fedora VM.
The catch - the VM has no network connectivity.
Why? no reason really. I just wanted a simple test VM that didn't need any network adapters in the first place.
How do I copy the kernel sources and all related build tools to the VM?
Possible solutions could have been - adding a network adapter, sharing the host FS using some modern solution like virtio-fs, or using a specific tool for the job - something like libguestfs.
But if I want a more elegant solution?
Assuming I'm already using Qemu/KVM as the hypervisor, it's likely I already have a tool for the job. It's called qemu-nbd.
NBD stands for "Network Block Device" - it's a protocol for accessing block devices over the network.
qemu-nbd provides a way to access the VM disk image as if it was a block device on a remote host.
The Linux kernel has a built-in driver for NBD, so accessing a disk image is fairly simple.
Load the nbd driver module:
sudo modprobe nbd
nbd provides some module parameters: nbds_max and max_part, see
modinfo nbd for their description.
Then use qemu-nbd to map the disk image to an nbd device:
sudo qemu-nbd -c /dev/nbd0 image.qcow2
The disk image most likely contained a partitioned disk, so the result will be multiple partitions - /dev/nbd0p1, /dev/nbd0p2, etc.
Now we can mount and access the filesystem on the image by mounting the nbd partion:
sudo mount /dev/nbd0p1 /mnt
Don't forget to clean up after you're done:
sudo umount /mnt sudo qemu-nbd -d /dev/nbd0 sudo rmmod nbd
In future posts, I'll discuss how to install an upstream kernel on a mounted image and also how to create an image from scratch.