Jon Rafkind Jon Rafkind's blog

26Aug/101

Interacting with unix

The most important feature any OS provides is quitting. Lets go over how to quit in unix:

ctrl-c - Sends SIGINT. Hi, can you please go away?
ctrl-\ - Sends SIGQUIT. Ok buddy, you're time is up.
ctrl-z && kill %1 - Puts the process in the background and sends it SIGTERM. There is some blood leaking from the holes in your chest.
ctrl-z && kill -9 %1 - Sends SIGKILL. Hadoken fireball!
sudo reboot - Reboots the machine. Where is your god now?

Filed under: Uncategorized 1 Comment
28May/100

UML and networking

(This post is from 2008 from my old blog)

I just finished setting up an instance of user mode linux with networking, but it was no easy task. The documentation I could find on the web provided contradictory explanations for how to do things and/or was simply out of date. But I managed to get it working, so let me start from the beginning.

First I had to compile a linux kernel. I downloaded 2.6.21.3 from kernel.org
and untarred it in some directory.

$ tar -jxvf linux-2.6.21.3.tar.bz2
$ cd linux-2.6.21.3

The 'j' option to tar is for bunzip instead of the usual 'z' for gunzip. Then I had to build the kernel in "user mode". This is mostly like a normal build but with ARCH=um on every command.

linux-2.6.21.3 $ make menuconfig ARCH=um
linux-2.6.21.3 $ make linux modules ARCH=um

What about 'make modules_install'? I'll get to that in a moment. The kernel isn't much good by itself, I also needed a root filesystem to run it on, so I downloaded a gentoo filesystem from uml.nagafix.co.uk and expanded it.

linux-2.6.21.3 $ wget http://uml.nagafix.co.uk/Gentoo-2006.1/Gentoo-2006.1-AMD64-root_fs.bz2
linux-2.6.21.3 $ bunzip2 Gentoo-2006.1-AMD64-root_fs.bz2

Note: I got the AMD64 rootfs because I have an amd64 computer.

Now I can test my linux build with the filesystem. The root filesystem is specified with the 'ubd0=...' argument to linux.

linux-2.6.21.3 $ ./linux ubd0=Gentoo-2006.1-AMD64-root_fs

And then linux booted up running gentoo. Now that I have a root filesystem, I have a place to put the modules I may have created. All I had to do was mount the filesystem and copy in the modules. I'm also going to rename the filesystem file to just 'gentoo' to make it easier to type.

linux-2.6.21.3 $ mv Gentoo-2006.1-AMD64-root_fs gentoo
linux-2.6.21.3 $ mkdir x
linux-2.6.21.3 $ sudo mount -o loop=/dev/loop0 gentoo x
linux-2.6.21.3 $ make modules_install ARCH=um INSTALL_MOD_PATH=x
linux-2.6.21.3 $ sudo umount x

And now any complaints gentoo might have had upon bootup about various modules not being found should go away.

I also wanted to give the uml instance some swap space which is easily done with dd.

linux-2.6.21.3 $ dd if=/dev/zero of=swap-space seek=1024 bs=640k count=0
linux-2.6.21.3 $ ls -lh swap-space
-rw-r--r-- 1 kazzmir wheel 640M Nov 17 21:11 swap-space

The seek=1024 option to dd is nice because you don't actually have to write any bytes to get a file of a certain size, you just have to set the file position within the file and write one byte there. This is *much* faster than writing 640 megs worth of 0's. Then I had to format the space for swap usage.

linux-2.6.21.3 $ mkswap swap-space

And finally use it within uml.

linux-2.6.21.3 $ ./linux ubd0=gentoo ubd1=swap-space
...linux is booting...
uml # swapon /dev/ubdb

Once I am inside uml ubd0 becomes ubda and ubd1 becomes ubdb, thus the swap space is /dev/ubdb.

Now all thats left to do is to set up networking. I'm not completely sure I did this right, but it works in my setup nonetheless. First I created a network bridge from br0 to eth0 by using some scripts I found on the net.

$ vi /etc/conf.d/net)(br)
..Add the following lines..
bridge_br0="eth0"
config_eth0=( "null" )
config_br0=( "dhcp" )
dhcpcd_br0="-t 10"
RC_NEED_br0="net.eth0"
brctl_br0=( "setfd 0" "sethello 0" "stp off" )
..And make sure the following line is commented out..
# config_eth0="dhcp"

Then I had to turn on br0.

$ cd /etc/init.d)(br)
$ sudo ln -s net.lo net.br0)(br)
$ sudo ./net.br0 start))

If you look in ifconfig you should see br0 take the ip of eth0 and your internet should still work.

$ ifconfig
br0 Link encap:Ethernet HWaddr 00:11:22:33:44:55
inet addr:192.168.1.104 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500 Metric:1
RX packets:552433 errors:0 dropped:0 overruns:0 frame:0
TX packets:396599 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:611072033 (582.7 Mb) TX bytes:31450891 (29.9 Mb)

eth0 Link encap:Ethernet HWaddr 00:11:22:33:44:55
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:560126 errors:0 dropped:0 overruns:0 frame:0
TX packets:402749 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:626524627 (597.5 Mb) TX bytes:32121742 (30.6 Mb)
Interrupt:22

Now I also had to make sure that the 'tun' module was loaded.

$ modprobe tun

And now I can start linux and give it a network device to the outside world by using tun/tap.

linux-2.6.21.3 $ ./linux ubd0=gentoo ubd1=swap-space eth0=tuntap,,,192.168.0.254

There are other modes you can give besides 'tuntap' but I don't know what they are. The last parameter, 192.168.0.254, is the host ip. You can make this whatever you want and there is probably a way for dhcp to provide it. Anyway once uml boots up with eth0 bound to some tap device you have to manually configure the ip for it and start it up. The eth device in uml will change each time you boot it unless you specify a MAC address as one of the parameters to eth0=... so I had to use 'ifconfig -a' to find what the eth device's name was.)

uml # ifconfig -a
eth15 Link encap:Ethernet HWaddr 92:4B:CB:DB:0B:D5
...

So the eth device is eth15. You can give it any ip address you want, I think, to start it up.

uml # ifconfig eth15 192.168.0.1 up

And now you should be able to ping the host ip and ping the uml instance from the host.

uml # ping -c 2 192.168.0.254
...in a host xterm...
$ ping -c 2 192.168.0.1

But you will probably soon find out that you can't really get to the rest of the world from the uml instance.

uml # ping www.google.com
...no response...

To do that you a) need to set up iptables to forward the packets from the uml host and b) have to set up the nameservers for uml. b) is easy to handle, just copy /etc/resolv.conf from the host to uml.

$ scp /etc/resolv.conf root@192.168.0.1:/etc/resolv.conf

You should have set a password for root in uml the first time you logged in via passwd.

uml # passwd

Once /etc/resolv.conf was in uml I then set up iptables. This was not simple, however, as I didn't find any readily available documentation on how to configure iptables itself. Supposedly most distros set up iptables for you so you might not have to fuss with it but I had to. The main thing you need for iptables is the iptables_nat module and network packet filtering. In menuconfig on the host I found these things in networking -> networking options -> network packet filtering -> ip: netfilter configuration. Then I enabled IPv4 connection tracking support, IP tables support, and Full NAT.
linux menuconfig
Then it was just a matter of telling iptables to forward the packets sent to br0 and tell uml to use the host as a gateway.

$ iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
uml # route add default gw 192.168.0.254
uml # ping www.google.com
PING www.l.google.com (72.14.253.147) 56(84) bytes of data.
64 bytes from po-in-f147.google.com (72.14.253.147): icmp_seq=1 ttl=240 time=78.6 ms
64 bytes from po-in-f147.google.com (72.14.253.147): icmp_seq=2 ttl=240 time=54.1 ms

Hooray! Then I thought it would be fun to run some X11 programs from uml and connect to the host X11 server. To do this I used Xnest which emulates an X11 server.

$ Xnest :1

This should bring up an x11 window with a fuzzy grey background. You can connect to it with programs on the host os by specifying :1.0 as the display.

$ xclock -display :1.0
..or..
$ DISPLAY=:1.0 xclock

But the uml instance won't be able to connect to this Xnest as easily.

/ $ ssh root@192.168.0.1
uml # xclock -display 192.168.0.254:1.0
Xlib: connection to "192.168.0.254:1.0" refused by server
Xlib: No protocol specified

Error: Can't open display: 192.168.0.254:1.0

First I had to make sure the ssh server in uml would forward X11 connections.

uml # vi /etc/ssh/sshd_config
...
X11Forwarding yes
...

Make sure to restart the ssh server. Then I just had to use the -Y option to ssh, meaning authenticated connection, and set the display properly.

$ DISPLAY=:1.0 ssh -Y root@192.168.0.1
uml # xclock

And xclock should appear in the Xnest window. Of course you don't have to use Xnest, you can just let the uml programs talk to the regular X11 server you probably have going, but its nice to keep uml programs separate from the host os. If you want to use the existing X11 server, specify :0.0 for the display.

$ DISPLAY=:0.0 ssh -Y root@192.168.0.1

Filed under: Uncategorized No Comments
30Dec/091

News you can use

Here is a dumb little trick to make C++ a little more Java-esque.

typedef FooParent super;
class BarChild: public FooParent{
public:
  BarChild():
    super(){
  }
};

Just in case you can't remember what the parent name of the class is. It's probably not a good idea to use this if you have multiple inheritance.

I'm fishing for blog content, can you tell?

Filed under: Uncategorized 1 Comment
10Dec/092

test syntax

 
int main(int argc, char ** argv){
  return argc + 1;
}
def foo(x):
  return x * 9
def foo(x)
  return x.call{|y| y + 2}
end
Filed under: Uncategorized 2 Comments
10Dec/092

Hello

I am here.

Filed under: Uncategorized 2 Comments