Sunday, May 10, 2015

Preparing a test VM - Filesystem

Hello,

This will be the first of a five part how-to on using virtualization to create a testing environment. We need a separate test machine because we will be crashing the kernel most of the time and rebooting your computer each time will be hazardous for your computer and frustrating for you.

We will be using QEMU for virtualization and Gentoo for the guest operating system where our kernel code will run. I assume development will be done in the same machine which is the virtualization host. I will not cover the virt host/development environment, you can use any distro capable of running QEMU (and preferably kvm).


For the guest machine which is going to be our testing environment, we need a minimal and fast OS setup. It needs to be minimal to get rid of unnecessary complications and it needs to be fast, or at least boot fast, since we need to reboot the machine each time we develop a new kernel. For example, installing Ubuntu as a kernel testing environment is overkill.

We will be using Gentoo as the guest machine in our tutorials. There are three reasons for that:
  • Gentoo doesn't really touch the kernel if you don't want it to and it does not assume the kernel to be capable of most things (for example DRM for X)
  • You can do a minimal install and it will boot pretty quick.
  • portage is a decent package control system I think. Not overly complicated for small setups but powerful enough to keep your setup small.
Arch Linux and Buildroot (if you want to use qemu for embedded system emulation) are also okay. I am covering basic Gentoo installation here but you can use any OS setup which you think you are comfortable.

Adjust the root filesystem disk


You can use sparse disks and qcows for root filesystem but we won't need much space so I will create the disk solidly using dd.
Create a directory for the VM in your working directory and create the disk for our root filesystem inside:

mkdir test-vm
cd test-vm
dd if=/dev/zero of=root.disk bs=1G count=4
sudo losetup /dev/loop0 root.disk
sudo mkfs.ext4 -i 8192 /dev/loop0
mkdir mnt-root.disk
sudo mount /dev/loop0 mnt-root.disk/

Then download and copy the OS files to this disk. Download the stage3 tarball from the Gentoo repos. (http://distfiles.gentoo.org/releases/amd64/autobuilds/current-iso/ http://distfiles.gentoo.org/releases/amd64/autobuilds/current-iso/stage3-amd64-DATE.tar.bz2 for amd64 systems). Then extract it to the root disk we just created.

sudo tar -xjf stage3-amd64-DATE.tar.bz2  -C mnt-root.disk/
Next we need to chroot into our root filesystem and assign a password for the root user.
sudo chroot mnt-root.disk
. /etc/profile
passwd #and then type your password

You'd want to use a short and easy password as you will type it a lot. Something like '1234' or even one character like 'a' is fine. You can also try a setup with no root password but usually that causes unexpected problems elsewhere, so I don't advise doing that.

Next we need to setup portage (emerge command). It is the package utility of Gentoo, just like aptitude and apt-get command in Ubuntu.

# still chrooted
mkdir /usr/portage
emerge-webrsync

Note that this takes some time.

I ran into a problem in this step. This command downloads lots of package data from the net and creates a lot of files each time. So if you need to run it for a second time for some reason, make sure previous setup files are cleaned under /var/tmp/portage/webrsync-qwerty. I ran out of inodes in my little filesystem. Just use smaller inodes or a larger file system if somehow you cannot install portage (4GB should be fine with the inode size I used above). You can investigate how many inodes you have left with df -i comamnd.

Now a few configurations under /etc.

Using nano inside chroot (or with your favourite editor from outside) edit the /etc/fstab file. We will tell kernel which disk to use as root at boot time but it is good practice to be consistent with fstab.

Just remove every entry and put this:
/dev/vda                /               ext3            noatime         1 2

Secondly edit /etc/inittab. Remove the # in the first line of serial consoles because we want to use our VM over a serial console all the time.

s0:12345:respawn:/sbin/agetty -L 115200 ttyS0 vt100

You can also use an emulated VGA monitor but that is uncomfortable since it can show only a handful of lines at a time and cannot be logged. You can control the VM over network using telnet or ssh but you won't be able to see stack dumps when kernel crashes (which is our whole point).

Another good change about kernel logging would be adding the following line to /etc/sysctl.conf file. Now kernel prints all output to the console in user-space too.

kernel.printk = 8

You can edit various other stuff like hostname, timezones or keymaps but they are not mandatory. It would be good to adjust networking but I will cover that once we see our virtual machine is working.

Don't forget to unmount the loopback device when you are done.

sudo umount /dev/loop0
sudo losetup -d /dev/loop0

Now we have what people call a root filesystem. In next post we will compile a kernel and then we will talk about virtual machine configuration.

No comments:

Post a Comment