Wednesday, 10 September 2014

Relativistic User-Mode Linux

Relativization tutorial

Welcome to this "Relativization" tutorial. First of all you might be wondering what "relativization" is, and why it is useful.

The term is to be intended as a reference to the theory of relativity in physics. One of the implications of said theory is that we can take measurements only in relation to ourselves. In our case we want emulated processes to have a different perception of time.

This is useful because in this way we can create the illusion of extra fast or slow resources, like computing or network speed.

You will now be shown how to install and use this feature.
If you don't want to patch a Linux kernel (it is actually very easy) you can download and extract a patched version here; in that case skip the "Applying the patch" section of this tutorial.
 

Applying the patch


Create a new directory and cd into it: 
~$ mkdir relat
~$ cd relat

First you need to get the Linux source tree. You can download a tar.xz from http://www.kernel.org.
You can pick almost any version, but in our examples we will use version 3.2.62. Save the file in the previously created directory and extract the contents:

~/relat$ tar -xJf linux-3.2.62.tar.xz

Then cd into the extracted directory:

~/relat$ cd linux-3.2.62

Now you have to select the right patch for your version of User Mode Linux. Versions of Linux preceding 3.2 are not supported, because they are very old. On GitHub there is currently one patch available for versions of linux between 3.2 and 3.6.


In our example we will patch linux 3.2.62. The patch can be found here.
To apply the patch, issue the patch command:

~/relat/linux-3.2.62$ patch -p1 < ../linux-3.2.x-rel.patch

The output should look like this:

patching file arch/um/include/shared/common-offsets.h
patching file arch/um/include/shared/reltime.h
patching file arch/um/Kconfig.um
patching file arch/um/kernel/Makefile
patching file arch/um/kernel/reltime.c
patching file arch/um/kernel/um_arch.c
patching file arch/um/os-Linux/time.c


 Configure and compile your kernel

When the patching is done, you have to configure your virtual kernel. You can get a working configuration by typing “make defconfig ARCH=um”. Remember to always append “ARCH=um” when building User Mode Linux: by default, the make scripts will assume that you want to build a kernel for your architecture, but you want to build for the um architecture instead, that is the specific architecture for User Mode Linux. Alternatively you can export the ARCH variable, so you won't have to type it again. If you intend to use the virtual kernel with Marionnet's filesystems and you are on a 64 bit platform, also add SUBARCH=i386 to build a 32 bit UML.

~/relat/linux-3.2.62$ export ARCH=um SUBARCH=i386
~/relat/linux-3.2.62$ make defconfig

At this point you can further customize your kernel by typing “make menuconfig” and the like. When you are ready, start the build process by typing “make ARCH=um SUBARCH=i386”.

The compilation will take some time, depending on your machine.

When the process terminates, you will find an executable called “linux” in your working directory. This is the UML executable: you can move it wherever you want, and launch it like you would a normal process.

How to use it


The parameters for relativization are passed from the command line when you launch the process, along with other parameters for UML. The essetial parameters for UML are “mem” and “ubd0”. The first one defines how much memory the process can use, the second is used to specify the path to the virtual filesystem.

For example:

$ linux mem=48M ubd0=/path/to/rootfs

launches an UML process with 48 MB of memory and with the filesystem at path “/path/to/rootfs”. For more info about UML and its parameters check out the official UML website.

There are two relativization parameters, both optional: “timeconv” and “timefreq”.
Timeconv is used to specify the convergence point of virtual and real time, that is the point in time where the two have the same value. This is expressed as a unix timestamp, that is the number of seconds elapsed since the Unix Epoch. If you want to set the current time as the timeconv value, you can get it with “date +%s”. So to set the convergence point to the current time you can type this in a shell like bash:

$ linux mem=48M ubd0=rootfs timeconv=$(date +%s)

The default value of timeconv is 0.

Timefreq is used to specify the frequency of the virtual time, in Hz. If you set timefreq to 2, the virtual time will run twice as fast as real time. If you set timefreq to 0.5, the virtual time will run at half the speed of real time. The default value of timefreq is 1.

Note that for high frequency values you may find yourself unable to login in the virtual machine. This is because the login program only waits a set amount of time to let you type your password, and with a high frequency the timeout value will become just a fraction of second. To avoid this problem, change the value of LOGIN_TIMEOUT in /etc/login.defs in your virtual filesystem before starting the virtual machine with a high frequency. You should not worry too much about the security implications, especially if your virtual machine is not connected to the Internet.

You may want to check the values of timeconv and timefreq when you are inside a virtual machine. You can do that by accessing the contents of two virtual files in the /proc filesystem:

$ cat /proc/uml_reltime/convergence
1407955413
$ cat /proc/uml_reltime/frequency
0.50

The first line prints “1407955413”, which was the value passed as timeconv.

The second line prints “0.50”, which was the value passed as timefreq.

Conclusions

Relativization is a potentially useful feature to test many applications. One interesting usage involves creating networks of relativistic machines. Find out how to create such networks in the Marionnet tutorial.

No comments:

Post a Comment