Wednesday, September 29, 2010

Removing entries from the known_hosts

One often encounters the following error message, particularly in situations where the machine owning the target IP address has changed:

user@host-machine:~$ ssh user@target_IP
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
XX:XX:XX.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending key in /home/user/.ssh/known_hosts:4
RSA host key for target_IP has changed and you have requested strict checking.
Host key verification failed.


The issue can be resolved by using the ssh-keygen command with the -R option to remove and update the known_hosts file. Simply do:

user@host-machine:~$ ssh-keygen -R target_IP -f /home/user/.ssh/known_hosts
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old
user@host-machine:~$ ssh user@target_IP
The authenticity of host 'target_IP (target_IP)' can't be established.
RSA key fingerprint is XX:XX:XX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'target_IP' (RSA) to the list of known hosts.
user@target_IP's password:
Linux XenOpen 2.6.32.21-xen #2 SMP Mon Sep 27 10:23:06 EDT 2010 x86_64 GNU/Linux
Ubuntu 10.04.1 LTS



Starting new domains on Xen 4.0.1 from command line

So, I have issues with my installation of Xen4.0.1 as the graphics driver keeps crashes during boot up, resulting in a hung machine. For now, I am using a work around suggested by my colleagues David Wolinsky and Pierre St. Juste, namely to disable the graphics display module (using "mv /etc/init/gdm.conf /etc/init/gdm.disabled") and hence I only have command line access to my domain-0 at this point.

At this point, Domain-0 boots up just fine, and xm and xend seem to be working. I now need to start Virtual domains using only the command line. (Later I will explore ways to do the same thing using APIs like Virt-Manager, or its console variant Virt-install)

Creating an Image
The first step is to create an image that will hold the user-domain (domU) virtual disk. This can be just a raw zero-filled file and so we can use the dd command here:
dd if=/dev/zero of=/var/lib/xen/images/domain1.img oflag=direct bs=1M seek=2047 count=1
The above command will create /var/lib/xen/images/domain1.img file of 2048MB although the actual data blocks are allocated in a lazy fashion. To reserve all the data blocks right away, get rid of the seek option from above. So do:
dd if=/dev/zero of=/var/lib/xen/images/domain1.img oflag=direct bs=1M count=2048
This will avoid data block allocation problems if the volume that holds the image is full. It is important to check that the image has the correct security context (permissions), otherwise access to the virtual disk will be denied to the user domain system. You can check this as follows:
ls -l /var/lib/xen/images/domain1.img
-rw-r--r-- 1 root root 2147483648 2010-10-13 10:23 /var/lib/xen/images/domain1.img
Preparing a Xen configuration file for the installation
Xen uses a configuration file per domain. The configuration for the domains is different because we have to provide installation kernels, initial ram-disk and possibly some boot parameters. The domainU installation initrd image and kernel for my machine architecture (64-bit x86) can be downloaded from this page. You can put them in some sensible directory and name them appropriately.
root@Xen-Open:~# mkdir /home/user/x86_64_domU_images
root@Xen-Open:~# cd /home/user/x86_64_domU_images
root@Xen-Open:~/x86_64_domU_images# wget http://archive.ubuntu.com/ubuntu/dists/lucid/main/installer-amd64/current/images/netboot/xen/initrd.gz
root@Xen-Open:~/x86_64_domU_images# wget http://archive.ubuntu.com/ubuntu/dists/lucid/main/installer-amd64/current/images/netboot/xen/vmlinuz
root@Xen-Open:~/x86_64_domU_images# ls
initrd.gz vmlinuz
root@Xen-Open:~/x86_64_domU_images# gunzip -c initrd.gz > initrd.img
root@Xen-Open:~/x86_64_domU_images# ls
initrd.gz initrd.img vmlinuz
In this example, the kernel and the initrd image were named /home/user/x86_64_domU_images/vmlinuz and /home/user/x86_64_domU_images/initrd.img respectively. With the images in place, we can now create the installation configuration file named /etc/xen/domain1.cfg

kernel = "/home/user/x86_64_domU_images/vmlinuz"
ramdisk = "/home/user/x86_64_domU_images/initrd.img"
name = "domain1"
memory = "256"
disk = [ 'file://var/lib/xen/images/disk.img,xvda,w', ]
vif = [ '' ]
dhcp="dhcp"
netmask="255.255.240.0"
gateway="10.5.144.1"
root="/dev/xvda ro"
vcpus=1
extra="4"
on_reboot = 'destroy'
on_crash = 'destroy'


Couple of points to note:
  1. The netmask and gateway values to be used can be determined by using the route command on your control domain. If you encounter problems in getting the network to start, you could try using methods suggested here.


  2. The [ 'file://var/lib/xen/images/disk.img,xvda,w', ] line here does not work if you use "tap:aio" instead of "file". Also for some reason, if you replace "xvda" with "xvda1" or something else, it does not work either. If you do any of those things you will get the following error:

    Error message:

    Error informing the kernel about modifications to partition
    /dev/xvda1p1
    -- Invalid argument. This means Linux won't know about
    any changes you made to /dev/xvda1p1 until you reboot -- so you
    shouldn't mount it or use it in any way before rebooting.
Once your config file is ready, you can start creating a domain with:
sudo xm create -c /etc/xen/domain1.cfg
And now, to access your domain, do:
sudo xm domain1
This will open an interactive installation window. Everything is self explanatory in general. If you get an error to the effect that the Ubuntu repository cannot be reached, check your control domain network and here is the fix.

Once your domain is properly created it will ask permission to reboot and will automatically get destroyed in the process because of the last two lines in the configuration command line, namely:
on_reboot = 'destroy'
on_crash = 'destroy'
So now you need to change your configuration file to the following:
name ="domain1"
memory ="256"
disk =[ 'file://var/lib/xen/images/disk.img,xvda,w', ]
vif=[ '' ]
dhcp="dhcp"
netmask="255.255.240.0"
gateway="10.5.144.1"
vcpus=1
on_reboot="restart"
on_crash="restart"
bootloader="/usr/bin/pygrub"

And now just use the xm create command to create your new domain. Finally in order to automatically start and stop your domains when domain-0 starts, move the location of the configuration file to /etc/xen/auto.

At this point, it is a good idea to create a copy of your virtual machine image. To create new virtual machines using the same image all you have to do is to change the configuration file (name, location of the disk image etc) to point to the copy and start the new machines... waaa la !

Monday, September 13, 2010

How to install Xen4.0 on Ubuntu 10.04 LTS

This post provides documentation about how to get Xen4.0 (the opensouce version) up and running on an Ubuntu 10.04 LTS (Long Term Support) 64-bit machine.

Start of with a fresh new installation of Ubuntu 10.04 LTS. Install the required packages first:
apt-get install bcc bin86 gawk bridge-utils iproute libcurl3 libcurl4-openssl-dev bzip2 module-init-tools transfig tgif texinfo texlive-latex-base texlive-latex-recommended texlive-fonts-extra texlive-fonts-recommended pciutils-dev mercurial build-essential make gcc libc6-dev zlib1g-dev python python-dev python-twisted libncurses5-dev patch libvncserver-dev libsdl-dev libjpeg62-dev iasl libbz2-dev e2fslibs-dev git-core uuid-dev ocaml libx11-dev
On a 64-bit machine, you will also need this additional package:
apt-get install gcc-multilib
The next step is to get Xen4.0.1
cd /usr/src/
wget http://bits.xensource.com/oss-xen/release/4.0.1/xen-4.0.1.tar.gz
Un-tar and make:
tar xf xen-4.0.1.tar.gz
cd xen-4.0.1
make xen
make tools
make stubdom
At this point you should have the Xen hypervisor/tools binaries in "dist/" directory ready for installation. Now run:
make install-xen
make install-tools
make install-stubdom
The next step is to download and compile a dom0 kernel, and to update the grub file. We can do this using the following commands:
make prep-kernels
This will create a build-linux-2.6-pvops_x86_64 directory in /usr/src/ which has by a .config file in it. You need to modify the .config file to suit your requirements. You can have a look at mine here. (Source Boris Derzhavets).
You could use make menuconfig from inside the build-linux-2.6-pvops_x86_64 to make alterations to your .config file.
cd build-linux-2.6-pvops_x86_64
make menuconfig
make
chmod g-s /usr/src/ -R
make deb-pkg
dpkg -i ../linux-image-2.6.32.21-xen_*.deb
depmod 2.6.32.21-xen
update-initramfs -c -k 2.6.32.21-xen
At this point enable Xend at boot:
update-rc.d xend defaults 20 21
update-rc.d xendomains defaults 21 20
When I typed in the last two lines, I got warning messages saying:
update-rc.d: warning: xend start runlevel arguments (2 3 4 5) do not match LSB
Default-Start values (3 4 5)
update-rc.d: warning: xend stop runlevel arguments (0 1 6) do not match LSB
Default-Stop values (0 1 2 6)

Apparently these messages are benign and should not cause any issues in the working of Xen Daemon. Now create the Grub2 entry for your new kernel:
vim /etc/grub.d/40_custom
Following is what I entered to in the 40_custom file. My installation still has issues because the graphics driver keeps crashing, and I think that the grub file has something to do with it.
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.

menuentry 'Xen 4.0.1, Ubuntu 10.4 kernel 2.6.32.21' {
recordfail
insmod ext2
set root='(hd0,1)'
multiboot (hd0,1)/boot/xen-4.0.1.gz dummy=dummy dom0_mem=832M
module (hd0,1)/boot/vmlinuz-2.6.32.21-xen dummy=dummy root=/dev/sda1 nopat ro nomodeset console=tty0 earlyprintk=xen
module (hd0,1)/boot/initrd.img-2.6.32.21-xen
}
Update grub and reboot... And choose the correct grub option from the boot-up menu.
update-grub
reboot

Friday, September 10, 2010

Compile glxgears from source on Ubuntu 9.10

I decided to modify the source code of glxgears to overcome a peculiar problem. This application would not write the FPS information to file (if redirected) unless it is shutdown.

I checked the source code, glxgears.c and found the problem was simply that there was no fflush statement after the output printf:
static void
event_loop(Display *dpy, Window win)
{
....
if (t - t0 >= 5.0) {

GLfloat seconds = t - t0;
GLfloat fps = frames / seconds;
printf("%d frames in %3.1f seconds = %6.3f FPS\n",frames, seconds,
fps); //no flushing!

t0 = t;
frames = 0;
}}}
}
And so, the solution seemed simple: add the line of code that would force the output buffer to flush (fflush(stdout);) after printf and re-compile the source code.

To be able to compile glxgears.c, however one needs to install many other libraries and packages. Here are the steps that I followed to get the whole thing working.
  1. glxgears is part of the Mesa Library. I downloaded th latest source code (MesaLib-7.8.2.tar.gz)

  2. Start by untarring this file:
    tar -xvf MesaLib-7.8.2.tar.gz
  3. Enter the directory Mesa-7.8.2 and type: ./configure --with-driver=xlib. The configuration code will now start spitting out the libraries that it needs (and which your machine does not have). Following are the libraries that I needed on my machine:

    1. libdrm:
      sudo wget http://dri.freedesktop.org/libdrm/libdrm-2.4.21.tar.gz
      tar -xvf libdrm-2.4.21.tar.gz
      cd libdrm-2.4.21/
      ./configure
      make
      make install
    2. xorg-macros:
      wget http://mirrors.kernel.org/ubuntu/pool/main/x/xutils-dev/xutils-dev_7.5+4_i386.deb
      sudo dpkg -r xutils-dev
      sudo dpkg -i xutils-dev_7.5+4_i386.deb
      ls /usr/share/pkgconfig/
    3. dri2proto:
      wget http://xorg.freedesktop.org/releases/individual/proto/dri2proto-2.3.tar.gz
      tar -xvf dri2proto-2.3.tar.gz
      cd dri2proto-2.3/
      ./configure
      make
      make install
    4. glproto:
      wget http://xorg.freedesktop.org/releases/individual/proto/glproto-1.4.12.tar.gz
      tar -xvf glproto-1.4.12.tar.gz
      cd glproto-1.4.12/
      ./configure
      make
    5. xxf86vm:
      sudo apt-get install libxxf86vm-dev
    6. xdamage:
      sudo apt-get install libxdamage-dev
  4. After all the dependencies are satisfied, ./configure --with-driver=xlib will complete and create the make file.

  5. Follow it up with: make. Once you modify the Mesa-7.8.2/progs/xdemos/glxgears.c file, call ./configure --with-driver=xlib and make. The new glxgears executable will be created in the same directory as the souce code.

Tuesday, September 7, 2010

Altering the behavior of CTRL-C

Short piece of code that might come in handy. One can use the "trap" procedure to alter the behavior of Ctrl-C which is often used to interrupt execution. One can use the altered behavior to delete back-ground processes or remove temporary files that might otherwise keep lying around.. So here is the src code which you can add anywhere in your script.



# trap ctrl-c and call ctrl_c()
trap 'ctrl_c' 2

function ctrl_c() {

pkill temp_processes
#run clean up code here ...

}

Friday, September 3, 2010

Writing the output of running glxgears to file

glxgears is a API that people frequently use to test if their graphical user interface works, and though it not a standardized benchmark of how good your GUI is, it does (at least, theoretically) give you some idea of the frames per second that are being rendered on your screen.

When you type the command glxgears in your terminal you should see an animation of rotating gears in the foreground and in the background, the terminal outputs every 5 or so seconds the frames per second that are being used in the rendering...

So now, my problem was simply to get the output of the terminal, that is the FPS values that are getting printed after roughly 5 seconds into a file.

The most obvious solution, that is:
glxgears >> out.txt
does not work. Apparently, glxgears does not flush the values if the output is redirected to file.

I was unable to "solve" the problem (that would require changing the source code of glxgears to make it not only print the output values but also flush it). For now I got something to work which is alright for me. I manually kill the glxgears every 5 seconds, store the output, and then restart another glxgears process.

This is not so trivial actually. If you kill the glxgears using something like
killall glxgears
no FPS values are returned or written to file. Instead you need to shutdown glxgears by telling x-server to withdraw its window resource!

Obtaining GUI access to Xen Domains Using TightVNC

This is a step by step tutorial on how to install a Xen Domain on Xen 3.2 (kernel version 2.6.24-24-xen) and how to get graphical user interface working on it.

I am using a rather ancient version of the Xen kernel because I am short of time at the moment and this is something I have worked with before. But hopefully, I should be able to get the same thing done on a more recent Xen kernel soon.

So to install a new domain from the command line, do:
sudo xen-create-image --hostname=xen_7 --size=1Gb --swap=256Mb --ide --ip=10.5.155.7 --netmask=255.255.240.0 --gateway=10.5.159.255 --force --dir=/home/xen --memory=256Mb --arch=i386 --kernel=/boot/vmlinuz-2.6.24-16-xen --initrd=/boot/initrd.img-2.6.24-16-xen --install-method=debootstrap --dist=hardy --mirror=http://archive.ubuntu.com/ubuntu/

Most of the parameters are self-explanatory. I am using static IP address (10.5.155.7) on my VM. The kernel (vmlinuz-2.6.24-16-xen) and the initial ram disk (initrd.img-2.6.24-16-xen) should be present in your boot directory. Ususally the gateway parameter and the netmask parameter would be the same for your Domain-0 and user domains. To see how much memory is available for the new domain that you are creating use the df or free commands before hand.

Once the new domain has been created you will see a new configuration file in the /etc/xen/ directory. This file needs to be edited a little bit as follows:
# Configuration file for the Xen instance xen_7, created
# by xen-tools 3.8 on Thu Sep 2 19:12:55 2010.
#

#
# Kernel + memory size
#
kernel = '/boot/vmlinuz-2.6.24-16-xen'
ramdisk = '/boot/initrd.img-2.6.24-16-xen'
memory = '256'
vcpu = '2'

#
# Disk device(s).
#
root = '/dev/hda2 ro'
disk = [

'tap:aio:/home/xen/domains/xen_7/swap.img,hda1,w',
'tap:aio:/home/xen/domains/xen_7/disk.img,hda2,w',

The text in red shows the text that has been changed/added. The vcpu parameter can be used if your want your domain to have more than one virtual processor. Later when your machine has booted you can check that this is indeed the case from the /proc/cpuinfo file.

So now we are all set to boot up our machine. In the Domain-0 terminal, type:
sudo xm create /etc/xen/xen_7.cfg
You could monitor the booting up and working of your new domain from Domain-0 using xentop and
sudo xm list
To access your machine, use:
sudo xm console xen_7
Login as root and set your new password using passwd command. If the network on your new domain is not functioning for some reason, look at this post for possible ways to correct the problem.

So at this point you have a functioning domain that you can access via the terminal. But now we want to get GUI access using tightVNC. To do this, a truck load of software needs to be installed. I have used the dpkg --get-selections option to generate a list of all the software that I needed on my machine. Use the dpkg --set-selection command followed by dselect (Select the "install" option on the interface opened by dselect) to install all the packages in the list.

Now the client/remote machine from which you want to access the graphical user interface of your domains needs to have VNCviewer ( sudo apt-get install vncviewer) installed.

On the host (guest domain) terminal, do:
Xvfb :0 -screen 0 800x600x16 &
export DISPLAY=:0
x11vnc -display :0&
xterm&
You can check that the Xvfb and xterm processes have started from the list of running processes. (ps uax)

On the client machine, do vncviewer 10.5.155.6:0 . You should see the GUI interface at this point. To test that the graphics are working, try:
glxgears
Well, that's it! You should see an animation of a bunch of gears rotating on your screen.... Which means that you have a GUI access to your machine!



Wednesday, September 1, 2010

Issuing commands to VLC and collecting output to file

So, I wanted to play a video using VLC Media Player and collect statistics like lost frames and bit rate into a file every x seconds while the video is running. Seems pretty straight forward considering that the stats can be viewed from the VLC GUI. So it should be a straight forward matter to get them into a file, right? Wrong !!

I tried several approaches including using the rc interface. Pierre gave me a piece of code that solves the problem on his machine:
while true; do echo stats; sleep 2; done | vlc -I rc filename > out.txt

Here, the filename is the name of the file that needs to be played and the number following sleep is the time between two reads of the statistics. As you can see, all this piece of code does is to issue (using pipe |) stats command to the rc interface (denoted by the -I option) every 2 seconds and store the output into out.txt file. For some reason the same code did not work on my machine and I kept getting the error message:
user@machine:~$ while true; do echo stats; sleep 2; done | vlc -I rc 350animation2.mpg > out.txt
VLC media player 1.0.2 Goldeneye
[0x8731750] main interface error: no suitable interface module
[0x8685140] main libvlc error: interface "default" initialization failed
I am using VLC media player 1.0.2 and my OS is Ubuntu Karmic Koala.If anyone has a clue as to what could be causing the problem, please send me a comment. Between, I was able to redirect the output stats to a file using the rc interface. For that I started VLC using vlc --intf rc filename >output.txt and then in the interface that opens, I issued the stats command. What I could not do was to automate the process of issuing the stats command every x seconds.

While trying to resolve the issue, I stumbled upon this "Not a blog" where the author shows how to issue commands to VLC from the command line using netcat and UNIX sockets. I tried to extrapolate from the code and tweak it to channel the collection of stats but it did not work. My super naive attempts basically were along the lines of writing a bash script that starts the video and then runs in an infinite loop trying to collect stats and sleep, as shown below:
echo play 350animation2.mpg
while true
do
echo stats
sleep 2
done
Then I would redirect the input and output to the VLC interface. But the same error message persisted. David Wolinsky came to the rescue. Here is the script that he come up with:
#!/bin/bash

set +o nounset
LC_ALL=C ; LANG=C ; export LC_ALL LANG
version >/dev/null 2>&1 && version "=o" $(_eat $0 $1)
set -o nounset

set -m

run() {
pid=$1
sleep 4
while true; do
echo -n "stats" | nc -U vlc.sock
if [[ ! $(ps uax | grep -v grep | grep $pid) ]]; then
return
fi
sleep 2

done
}

vlc -I rc --rc-unix vlc.sock 350animation2.mpg &> out &
pid=$!
run $pid &
fg %1
As you can see, this code uses the UNIX socket approach as well. After the VLC process is started, the PID is stored and used to start the run script on the top. The output gets stored in the out file. The fg (fore ground) command in the end is apparently necessary.

Thanks to Pierre, David and Andrabr for help with this problem!