Linux Format

Virtual Arch build

Want to test software without crashing your computer? Neil Bothwick creates a disposable system that you can crash without consequenc­e.

- Neil Bothwick is a big fan of virtualisa­tion. You name it and he has virtually done it. Occasional­ly, he really does something.

Want to test software without crashing your computer? (BORING!–JONNI) Neil Bothwick shows how to create a disposable system.

When developing and testing software, it helps to have a stable base platform on which to test it. This is particular­ly true when doing anything low level that would otherwise involve rebooting to test. For this type of testing environmen­t a virtual machine is often the best option. It boots quickly, it doesn’t interfere with your normal system and if it goes wrong, you can easily delete it and start over.

In this article we’ll see how you can create a virtual machine image based on Arch Linux, a distro popular among those who like to get involved with the nuts and bolts of Linux (but may not have the patience to install Gentoo). One of the useful side effects of the way in which Arch Linux (and Gentoo) are installed is that it’s a largely manual process, which can be time-consuming when setting up a full distro, but can be very efficient for setting up a virtual machine.

Because the Arch Linux installer disc is just a live version of Arch, you can just as easily install from an existing Arch system, and that’s what we’ll cover here. Although this requires Arch Linux on the host computer, it’s also possible to follow this when booted from an Arch live disc, or you could boot the emulator from the live disc.

Avoiding confusion

Because we’re working with virtual machines, there are often two systems running at the same time. The host is the OS running on your computer as normal, while the guest is the environmen­t running on the virtual machine. We’ve tried to make it clear which commands should be run on the host and which on the guest by prefixing them with /host/ or /guest/ , respective­ly. Obviously, you don’t type this in the command, just the part after the $ as normal.

The normal approach is to boot a virtual machine from an installati­on disc (or USB stick) and then install the OS. However, using Arch as the host system makes it easy to create a disk image without going through the full installati­on process. We’ll be using the disk image with Qemu, a fully open source emulator, so make sure you’ve that installed, as well as the scripts used by the install discs:

/host/ $ pacman -S qemu arch-install-scripts

Set your limits

Now let’s create the disk image. If you’re creating a fairly minimal system, such as for testing kernel changes, then 5GB should be more than enough. We’ll use a sparse file that sets a maximum size, but will only use the amount of disk space it needs:

/host/ $ truncate -s 5G minimal.img

You’ll see that ls reports the size of this file as 5GB but du shows it as empty. Normally you’d create an image file and then partition it in the emulator, but we only want a single filesystem so we’ll create it on the whole “disk”:

/host/ $ mkfs.ext4 minimal.img

Because this is an unpartitio­ned device containing a single filesystem, we can mount it directly:

/host/ $ mkdir -p mnt

/host/ $ sudo mount minimal.img mnt

Now we can install the base system into it:

/host/ $ sudo pacstrap mnt base base-devel

This is the same command used to install from an install disk, but we can run it directly in our host system

here. The first argument is the destinatio­n directory, where you mounted your image file, and the rest are packages to install. If there are other packages that you want in your virtual system, you can add them to the pacstrap command here.

You’ve created an almost full Arch base system in mnt, and you can see this by listing the directory. You need to chroot into the system with /host/ $ sudo arch-chroot mnt

You’ll see the command prompt because you’re now in the root directory of the chrooted system as the root user. Now you need to set a root password. This is for the virtualise­d system and so it doesn’t need to be the same as for your host system. In fact, it shouldn’t be the same. Because this will only be used for testing and has no access to the host system, you can safely ignore the rules and set a short password, but don’t tell anyone we said that. Press Ctrl+d to exit the chroot.

You can unmount the filesystem now. The next time we access it will be through the virtual machine and we don’t want two systems with write access to the same filesystem.

We need a kernel

Now it’s time to install the kernel source so that you can begin experiment­ing. First ensure you have the tools:

/host/ $ pacman -S base-devel git bc

Then download, configure and build a kernel with

/host/ $ git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

/host/ $ cd linux

/host/ $ make x86_64_defconfig

/host/ $ make kvm_guest.config

/host/ $ make -jn

The git command downloads the latest Linux sources. After changing to the kernel source directory we configure it with the two make commands. The first creates a default config while the second adds settings that set it up to be used in a virtualise­d environmen­t. You can also run make menuconfig or make xconfig here to bring up one of the config editors and make any other changes you may want or need.

The final command compiles the kernel. The N setting for -j is the maximum number of parallel jobs to run. Set this to the number of cores on your CPU for a fast build, or set it lower for a slower build while still using the computer for other tasks.

We’re installing the kernel sources on the host system and building the kernel there. This is the fastest way to do this because it means you have the full resources of your computer at your disposal, compared with compiling in a virtual machine that only has access to a limited ration of your memory and CPU cores.

Gentlemen, start your engines

So now that we have a disk image containing a base distributi­on and a separate Linux kernel, let’s put them together in a virtual machine using Qemu:

/host/ $ qemu-system-x86_64 -hda minimal.img -m 4G -nographic -kernel linux/arch/x86_64/boot/bzimage -append “root=/dev/sda rw console=ttys0 loglevel=5” --enable-kvm

Run this from your starting directory, the one containing your disk image file and the linux directory created with git . Alter the paths if you want to arrange things differentl­y. You should see the usual Systemd boot messages displayed on your console, followed by a login prompt. Login as root using the password you set earlier. When you want to exit the guest, the magic key combinatio­n is Ctrl+a followed by X.

Before we continue, let’s have a closer look at the

Qemu command line. There were several options and you may want or need to change some of them. The first option, -hda , is the path to the main disk image (you can use hdb , hdc and so on to have more than one virtual disk). You set the amount of memory allocated to the virtual machine with -m (in this example it’s 4GB). Here we see the text of the guest in the existing terminal window, thanks to the -nographic option. You can drop this to display a separate window for the emulator, which is necessary if you want to load a desktop.

Now we’re just making sure things work, so we keep it simple. The next option obviously gives the path to your kernel image, while the -append parameter give the options to be passed to the kernel – those that would normally be set in the bootloader menu of a physical system. Finally, we want the emulation to run at a decent speed. --enable-kvm tells it to use your CPU’S hardware accelerati­on for virtualisa­tion.

One significan­t option that we’ve not used here is -smp . If you look at /proc/cpuinfo on the guest system

you’ll see there’s only one processor core. If you want to use more, the -smp parameter sets the number used.

Talk to the world

There’s no networking in your new virtual environmen­t. We could set it up manually, but the easiest way is to install a DHCP client that will talk to the host computer and from there to the rest of the world. So how do we install network software when we’ve no network? The solution is to exit the emulator, mount the image file as before, re-enter the chroot from the host and install the software from there.

/host/ $ sudo mount minimal.img mnt

/host/ $ sudo arch-chroot mnt

/host/ $ pacman -S dhcpcd

/host/ $ Ctrl-d

/host/ $ sudo umount mnt

Now start the guest, login as root and run

/guest/ $ systemctl enable dhcpcd

/guest/ $ systemctl start dhcpcd

This starts up networking within the guest, routing everything through Qemu and the host computer’s network connection. It should also route DNS queries through Qemu, but we found this didn’t always work. In that case, the solution is to set the DNS entries in

/etc/resolv.conf, in the following form:

nameserver aaa.bbb.ccc.ddd

using the IP address of your favourite DNS server. Then add this line to /etc/dhcpcd.conf to tell it to not overwrite your settings on startup: nohook resolv.conf

We now have a minimal image that boots to a console and has networking, enabling us to install further software. This is a good time to make a copy of the image file, not while the guest is running. A copy of this copy can then be used as a consistent starting point for further experiment­s.

Graphics time

Now we can look at setting up the guest to run graphical applicatio­ns. The obvious way is to run X on the guest system, for which the first step is to go into the linux source directory and run:

/host/ $ make menuconfig

Press / to open the search function and type in bochs . The first item shown should be DRM_BOCHS. Press 1 to go to it and then y to enable it. Exit menuconfig, saving the configurat­ion as you do so, and run:

/host/ $ make -jn again to rebuild the kernel. This option creates a graphic driver suitable for use with Qemu. If you remove the

-nographic option from the command to start the emulator, it will boot in its own window instead of the current terminal. But it still boots to a text console, because we haven’t installed a graphical environmen­t, so let’s do that now:

/guest/ $ pacman -S xorg-server xorg-xinit xf86-videovesa xorg-xterm

Create the file ~/.xinitrc containing

exec xterm

and then run

/guest/ $ startx

This gives a very basic X-window desktop running

xterm, but no window manager. It’s a proof of concept, so if you want a useful desktop install a basic window manager or at the very least, a desktop environmen­t if that’s what you want.

Pay it forward

There’s another way of running X programs on the guest, if you don’t want to install a full X server and desktop setup: X forwarding over SSH. You already have X on the host, so use that to display programs from the guest. You can do this while having X installed, or you can do it starting with the minimal image we had at the back-up stage. First install one program on the host:

/host/ $ pacman -S xorg-xauth

On the guest there’s no need for an X server, but we do need SSH, an X program to test and a couple of other packages

/guest/ $ pacman -S xorg-xauth xorg-xclock openssh xorg-fonts-type1

SSH listens on port 22, but that’s already in use by SSH on the host, and we need a way of routing traffic to the guest. To do that, we add some extra options to the call to Qemu (this command is getting long enough to be put into an alias or a one-line script by now):

-net nic -net user,hostfwd=tcp::1337-:22

The first part enables a network card, the second routes traffic from port 1337 on the host to 22 on the guest. We also need to configure the SSH server on the guest, so fire it up and edit /etc/ssh/sshd_config and

ensure you have these settings:

Permitroot­login yes

X11forward­ing yes

They are normally commented out and set to no. Enabling root logins is a particular­ly bad idea in normal circumstan­ces, but this is a virtual machine only accessible locally. Now start the SSH server, and set it to start at boot, with

/guest/ $ systemctl start sshd

/guest/ $ systemctl enable sshd

Now you can login to the guest and run a program:

/host/ $ ssh -X root@localhost -p 1337

$ xclock

There’s an X program displayed on the host’s desktop but running on the guest. If you don’t believe this, try changing the clock or timezone on the guest and running xclock, you’ll see that it’s showing the guest’s time. Incidental­ly, if you just want to run program over SSH, you can do it all in one line:

/host/ $ ssh -X root@localhost -p 1337 xclock

Share and share alike

There may be times when you need to transfer files between host and guest. If you’ve set up SSH as above, you could do this with scp or rsync, but you can also share folders between host and guest in Qemu. To do this you add two more options to the Qemu command line (the argument for making this a script or alias becomes ever stronger):

-fsdev local,id=fs1,path=/home/user/shared,security_ model=none

-device virtio-9p-pci,fsdev=fs1,mount_tag=shared_ folder

The first sets up the folder to share, so make sure you give the correct path here. The security_ model=none doesn’t mean no security, it means let the OS handle file access permission­s. The second option sets up the device used to mount the folder in the guest. To do that, we need to edit /etc/fstab in the guest to add this line: shared_folder /root/host_folder 9p trans=virtio 0 0

That’s all there is to it. Now any changes to that folder on one side will immediatel­y be visible on the other. Note that if you run Qemu without the options to enable shared folders, the boot will fail when trying to mount the shared folder on the host. If you always run

Qemu with the above options, that’s not an issue, otherwise you may wish to add noauto to the fstab options and mount the shared folder manually when you need it. You may need to modprobe 9pnet_virtio before Qemu will load like this. A permanent solution would be to add it to /etc/modules-load.d to have it loaded on boot.

So there we’ve it: a virtual machine image that can be used as a testing platform. You could set up several different ones as templates for different types of testing. Then you only need to make a copy of the one you need, run your tests and then delete it. This is truly disposable computing in action!

 ??  ??
 ??  ?? First signs of life! Here’s the guest running in the terminal from which Qemu was run, which proves it works and may be all you need.
First signs of life! Here’s the guest running in the terminal from which Qemu was run, which proves it works and may be all you need.
 ??  ??
 ??  ?? It’s not the most exciting desktop environmen­t, but this proves that X is working on the virtual machine.
It’s not the most exciting desktop environmen­t, but this proves that X is working on the virtual machine.
 ??  ?? All those command line options! A shell script or alias makes life much simpler – you could supply the image file as an argument, say.
All those command line options! A shell script or alias makes life much simpler – you could supply the image file as an argument, say.
 ??  ?? Here we’re running an X program on the VM, but displaying its window on the host. Note the time difference­s.
Here we’re running an X program on the VM, but displaying its window on the host. Note the time difference­s.
 ??  ?? An alternativ­e method of creating the VM is to boot Qemu from the live ISO image, but you’ll need networking set up on the emulator.
An alternativ­e method of creating the VM is to boot Qemu from the live ISO image, but you’ll need networking set up on the emulator.

Newspapers in English

Newspapers from Australia