Follow-Up

A quick follow-up to "Parallels" for Linux. I’ve managed to run the Windows XP Partition on my Laptop inside KVM-88 like this:

#!/bin/sh

export SDL_VIDEO_X11_DGAMOUSE=0
sudo qemu-system-x86_64 -hda /dev/sda -net nic -net user -m 1024 -cdrom fixntldr.iso -boot d -usb -usbdevice tablet -monitor stdio

To send Ctrl+Alt+Del, I needed to enter this at the QEMU shell:

sendkey ctrl-alt-delete

Edit (Jul 30th, 2009): Here is a link to the QEMU console commands.

SSH Tricks

My shell scripting skills suck. So it comes naturally that I learn a lot every time I need to write a script. The trick I’m about to describe is so neat that I want to share it.

Assume for a second that you need to execute a series of commands on a remote machine, but you can’t pass them to SSH at once. Or consider that you might need to transfer a file over to a remote host and then extract it there. Normally, you’d need to create several SSH connections for this. In the “transfer, then extract” scenario, you need one connection for scp(1) and another one to extract the file on the remote host. Unless you have your public key in the remote host’s ~/.ssh/authorized_keys file, you need to enter your password for the remote host twice. It’s probably not a big deal for most, but it’s annoying at times.

It might be obvious for some, but I recently found out that ssh(1) offers a solution for the problem described above. It allows you to open one connection in "master" mode to which other SSH processes can connect through a socket. The options for the "master" connection are:

$ ssh -M -S /path/to/socket user@rhost

Alternatively, the ControlPath and ControlMaster options can be set in the appropriate SSH configuration files. Other SSH processes that want to connect to the "master" connection only need to use the -S option. The authentication of the "master" connection will be re-used for all other connections that go through the socket. I’m not sure if SSH even opens a separate TCP connection.

Going further, this can be used in scripts to save the user a lot of password typing, especially if the execution flow switches between local and remote commands a lot. At the beginning of the script, simply create a &qout;master" connection like this:

$ ssh -M -S /path/to/socket -f user@rhost 
    "while true ; do sleep 3600 ; done"

It should be noted that the path to the socket can be made unique by using a combination of the placeholders %l, %h, %p, %r for the local host, remote host, port and remote username, respectively. The -f parameter makes SSH go into the background just before command execution. However, it requires that a command is specified, hence an endless loop of sleep(1) calls is added to the command line. Other SSH connections can be opened like this, not requiring any further user input (for authentication):

$ ssh -S /path/to/socket user@rhost

This leaves the problem of how the "master" process can be terminated when the script has finished. Some versions of SSH offer the -O parameter which can be used to check if the "master" is still running and, more importantly, to tell the "master" to exit. Note that in addition to the socket, the remote user and host need to be specified.

$ ssh -S /path/to/socket -O check user@rhost
$ ssh -S /path/to/socket -O exit user@rhost

However, there are still two problems to be solved. First, when the "master" quits, the dummy sleep loop continues to run. And second, how can the "master" be terminated if the given SSH version doesn’t offer the -O parameter (short of killing the process by its PID)?

“Parallels” for Linux

Ben has an interesting post on how to boot Windows XP using KVM on Fedora Core 9. The interesting part is that Windows XP is installed on the host’s hard disk. His instructions almost work verbatim, but there’s one exception. Since I’m using KVM-73, the QEMU command is:

$ qemu-system-x86_64 -hda /dev/sda -net nic -net user -m 1024 
    -cdrom fixntldr.iso -boot d -std-vga 

This will also give the guest system access to the network.

Encrypted Devices/Filesystems on Linux

Yesterday I tried to encrypt a complete USB Stick under Linux. I followed this tutorial and it worked quite well.

Mounting the encrypted device isn’t as obvious as could be, so here it goes:

$ cryptsetup create <symbolic name> <device name>
$ mount /dev/mapper/<symbolic name> <mountpoint>

Linux KVM (kvm-70) on IBM Open Client 2.2

The Linux kernel-based virtual machine (KVM) is a great way for virtualization on computers running Linux. It requires virtualization support by the host processor (most modern x86 CPUs have this) and a kernel module. The kernel module can be built from the KVM sources.

Unfortunately, compiling the module on the IBM Open Client 2.2 distribution doesn’t work out of the box. Instead, a patch is required. The patch is an extended version of this commit to the KVM repository and applies against the KVM-70 release tar ball.

Networking

The KVM networking documentation lists brctl(8) and tunctl(8) as requirements for a bridge between the host and the guest. On the Open Client distribution, the brctl utility is part of the bridge-utils package whereas the tunctl tool is part of uml-utils – on other distributions, that is. However, there is a Fedora Core 9 package available which seems to work.

Before starting the KVM guest, make sure that the tun kernel module is loaded. These are the steps I use to start the guest:

$ sudo modprobe tun
$ MACADDR=`genmac`
$ sudo qemu-system-x86_64 -hda freebsd-7.0.img 
   -net nic,macaddr=$MACADDR -net tap,script=qemu-ifup

Note that the genmac and qemu-ifup scripts are the examples from the KVM documentation.

NAT on the bridge

Because I cannot put the KVM guest on the host network, I need to do NAT on the host. I’ve found this quick tutorial on NAT with iptables. The four steps are:

# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# iptables -A FORWARD -i eth0 -o tap0 -m state 
     --state RELATED,ESTABLISHED -j ACCEPT
# iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT

Also, make sure the tap0 interface has an IP address:

$ sudo ifconfig tap0 192.168.0.1/24

Cross-compiling the Linux kernel

I need to cross-compile a PowerPC Linux kernel on an x86 laptop. I’ve found instructions on how to compile (not cross-compile) the Linux kernel at this website. Further, there is a post to a mailing list here which shows how to cros-compile the kernel. The mailing list post mentions a ccontrol file, but I have no clue what that is. Luckily I’ve found this blog post, which seems to be more accurate.

Dual Monitor on T60 (Internal + DVI)

I think I’ve found a way to make my T60p use the internal display and also drive an external monitor via the DVI port (on Linux). For some reason, this does not work automatically upon reboot, but has to be done from the command line.

aticonfig --dtop=horizontal --screen-layout=left --enable-monitor=lvds,tmds1

Now restart the X server and you should see video output on both monitors. I have the external monitor left of the laptop, so I need to run this command as well:

aticonfig --swap-monitor

Then, both monitors work. Unfortunately, I seem to have broken suspend/resume somewhere along the way. It seems that a combination of the things listed below make suspend/resume work again. I don’t know if both are required or if either helps.

  • Update the fglrx driver. I’m using the kernel-module-ATI-upstream-fglrx (carries version numbers 8.452.1 and 2.6.18_53.1) as well as the ATI-upstream-fglrx package (version number 8.452.1-3.oc2) from the repository the IBM Open Client uses by default.
  • Disable the AIGLX extension

The beauty of security extensions

I just spent a good day debugging a problem that eventually turned out to be (most likely) caused by some Linux security extensions deployed on the machine I test my code on.

The code loads an ELF image at runtime and then transfers control to it. Previously, I have worked with 32-Bit PowerPC executables that I ran on a 64-Bit PowerPC host. I recently changed this so that my code (as well as the ELF images it loads) would be a 64-Bit PowerPC executables.

In order to obtain memory where the ELF image could be loaded into, I previously used the malloc(3) call. I didn’t want to use mmap(2) since I was going to port the code to an environment where mmap(2) would not be available. That worked fine in the 32-Bit case.

Anyways, it turns out that, in the 64-Bit case, trying to execute code in a malloc(3)-ed buffer instantly results in a segmentation fault. Using a mmap(2)-ed buffer (with the PROT_EXEC flag) fixes the issue.

I would still like to know why there is a difference between the 32-Bit and the 64-Bit case.