t3x.org / bits / plan9_on_u9fs.html

Most of the files referred to on this page have been lost. Sorry.

Running Plan9 off a U9FS Server

Copyright (C) 2004 Nils M Holm <nmh@t3x.org>

When installing Plan9 from Bell labs, you basically have two choices:

  1. install the entire system on a local computer
  2. install a file server and a diskless terminal

While the first solution is certainly simpler, the second option provides the advantage of a diskless workplace with most noisy components moved to a machine room. On the other hand, an additional file server needs additional power and requires additional maintenance.

If you happen to have access to a Unix server that is running 24x7h anyway, wouldn't it be great, if there was a way to make the Unix machine serve the Plan9 file system?

Indeed such a possibility exists. The Plan9 distribution comes with a program called u9fs(4). U9fs is a Unix program rather than a Plan9 program. Once compiled and installed on a Unix computer, it exports the entire directory tree seen by Unix (or parts thereof) using 9P, the Plan9 communications protocol. Plan9 computers can mount a file system exported in such a way using the 9fs(4) command. What is even even more interesting, though: Other Plan9 terminals can use a Unix filesystem exported by u9fs as their root file system.

So a Unix machine can be used to serve the root file system for diskless Plan9 terminals, thereby eliminating the need for an additinal machine. The remainder of this document deals with the details of setting up both:

Disclaimer

This approach certainly has some implications that make it impossible to use some of the advanced parts of Plan9. For example, u9fs cannot be combined with services such as fossil(4) and venti(8). Backup of user data must be done by the Unix host.

In addition, the u9fs(4) man page states:

  Semantics like remove-on-close or the atomicity of wstat are hard to provide exactly.  

Finally, u9fs can only authenticate one single user, whose name and password have to be placed in plaintext format in a (root-readable) file on the Unix server. So, if you plan to have multiple users share the file server, you should better install a real Plan9 server.

I am actually running Plan9 using the configuration described here, but this does not mean that it works for you, too. This setup should be considered an experiment and it is certainly not recommended for production use. If it blows up on you, don't blame me.

Prerequisits

In order to follow the procedure outlined in this document, you will need the following things:

[1] If your Unix host does not provide the mtools (mformat, mcopy, and friends), installing them is strongly recommended. Otherwise, you will need to find a different way to format DOS floppies and copy files to them.

For FreeBSD and Linux it is easy to get pre-compiled mtools packages from the usual places. For a last resort, try the sources at mtools.linux.lu.

Getting the Plan9 Distribution

To get a copy of the Plan9 installation CDROM, visit

http://plan9.bell-labs.com/plan9dist/

Once there, select the Download the Distribution link and follow the instructions.

Copying the Distribution Files

In order to install Plan9, you will first have to burn the distribution ISO image to a CDROM. The details of this process are beyond the scope of this document.

The Plan9 CDROM is in ISO9660 format, so you can probably mount it directly on your Unix file system. The exact command to do so is specific to your flavour of Unix. However, sample commands will be given in the remainder of this document. The sample commands should work without significant modification on most FreeBSD releases. To mount the Plan9 CDROM, type

mount -t cd9660 /dev/cd0a /mnt

This command will attach the content of the Plan9 CDROM to the /mnt directory. First you will have to get all the files on the CDROM to your local disk. The tar(1) command is probably most suitable for this task. All the files require about 260M bytes of disk space, but since your user data will require some space, too, a partition with at least 300M bytes of free space is recommended. Let us assume that the partition mounted on /scratch contains such an amount of free space. In this partition, create a directory to hold your Plan9 file system. Let us call this directory p9root. Here are the commands to copy the contents of the Plan9 CDROM:

mkdir /scratch/p9root
cd /mnt
tar cf - * | tar xvfC - /scratch/p9root

This step will take some time. When it finishes, go to the p9root directory and unmount the CDROM:

cd /scratch/p9root
umount /dev/cd0a

Fixing the Permissions

There is one problem with the files you just copied. The Plan9 permission data like file owner, group, and access bits have not been copied. Fixing this normally requires a working Plan9 system, but you are lucky: here is a shell script that fixes all the permissions of your Plan9 file tree:

fix-perms.sh.gz (broken link!)

Before you run this script, though, you will have to create some users and user groups in order to make it work properly. The script will not restore all the owners of the files on the original CDROM, but all of the files will be onwed by glenda:sys (user glenda, group sys) and sys:sys. So you have to create the following users (if they do not already exist):

glenda
sys

On FreeBSD, you may use the adduser(8) command to add new users. In addition, you will have to add the group sys (if it does not already exist) and make the users sys and glenda members of this group. On most systems, this can be done by adding the following line to the /etc/group file:

sys:*:3:glenda,sys

If such a line already exists, just add the members glenda and sys.

Finally download the above shell script and unpack it to the /scratch/p9root directory. It will inflate to a rather large file (about 1000K bytes) containing a chown(1) and a chmod(1) command for each file in the entire tree. Run the script by typing

sh fix-perms.sh

If your shell does not want to run a script of that size, you may also try

sh < fix-perms.sh

Notice: Some of these items may cause trouble:

After fixing the permissions, the fix-perms.sh script is no longer needed and may be deleted.

Creating an Account

The next thing to do is to create a Plan9 user account for you. Since you cannot use kfscmd(8), you will have to set the account up manually. It is assumed that you already have an account on the Unix machine (which is trivially true, or you could not install Plan9 on it anyway). The sample commands in the following text also assume that your user name is nmh and your UID is 1001.

The first thing to do is to create a new Unix user group with the same name as your user name. Adding a group has been discussed earlier in this document. In short: add the line

nmh:*:1001:nmh

to the /etc/group file. I have chosen to use a GID that is equal to my UID, but I am not sure if this really is required. It certainly will not hurt.

The same account has to be added to the Plan9 file /adm/users (which is located at /scratch/p9root/adm/users on your Unix machine). Since Plan9 text files are in Unix format, you can use your favorite text editor to add the following line to that file:

1001:nmh:nmh:

Finally, you need a home directory. To get things started, a copy of Glenda's home directory will do. Use tar to duplicate that directory:

cd /scratch/p9root/usr
mkdir nmh
chown nmh:nmh nmh
cd glenda
tar cf - * | tar xvpfC - ../nmh

After copying the files, make nmh:nmh the owner of the files in your new home:

cd ../nmh
chown nmh:nmh * */* */*/*

That's it. You now have a Plan9 account.

Setting up U9FS

In order to access the Plan9 files on your Unix machine, you need the u9fs(4) daemon. The source code to that program is on the Plan9 CDROM and at this stage subsequently also on in /scratch/p9root. Further information about u9fs including detailed instructions regarding its installation can be found in its manual page. The following command will display the man page:

nroff -man /scratch/p9root/sys/man/4/u9fs | more

A brief summary follows.

First copy the u9fs sources to a directory owned by you. Let us use $HOME/u9fs. To get the sources to that directory use:

cd
mkdir u9fs
cd u9fs
cp /scratch/p9root/sys/src/cmd/unix/u9fs/* .

Once the files are there, typing make should be sufficient to compile the program. If it does not compile, have a look at the makefile and at plan9.h. After sucessful compilation, move the binary wherever the local daemons reside on your system, eg:

cp u9fs /usr/local/libexec

U9fs is normally started by inetd. If your inetd.conf(5) file (mostly located in /etc) does not already contain such a line, add it to it:

9fs     stream   tcp     nowait  root    /usr/local/libexec/u9fs   u9fs

However, this will start u9fs using its default parameters, which are not useful for the configuration described here. There are two issues:

  1. U9fs will export the entire Unix directory hierarchy and not just /scratch/p9root.
  2. U9fs uses rhosts authentication by default, which is insecure.

The -a p9any option enables the Plan9 authentication mechanisms. Specifying a directory as the last argument of the u9fs command line will do a chroot() to the given directory. So to export the /scratch/p9root directory using Plan9 authentication, change the trailing u9fs in /etc/inetd.conf to:

u9fs -a p9any /scratch/p9root

For the plan9 authentication to work, you have to create a file containing your user name, a password, and an authentication domain. This file is called /etc/u9fs.key. Since it contains secret information, it should be owned by root and have all permission bits (except for onwer-read) turned off (mode 0400). The file must contain three lines:

nmh
password
local

Nmh is your user name (mine in fact, replace it with yours), password is your secret password and local is the authentication domain. When in doubt about this, use the word 'local' literally.

Since u9fs will run chroot'ed, a local copy of some files of /etc is required in order to manage user names. Do duplicate these files in your Plan9 file tree, or u9fs will not work properly!

Again, the files required to identify users vary between systems. In any case, you will need the passwd, group, and u9fs.key files. Make sure that the files have the same owners and access bits as the original files, or secret information may be revealed. Here are the commands to duplicate the necessary files:

cd /scratch/p9root
mkdir etc
chown root etc
chmod 0644 etc
cd /etc
tar cf - u9fs.key passwd group | tar xvpfC - /scratch/p9root/etc

You may need some additional files like pwd.db, spwd.db, and master.passwd. If you are not sure which files to copy, refer to the getpwnam(3) manual page on your Unix system.

In case the 9fs protocol is not already in the /etc/services file, insert it by adding the following line:

9fs     564/tcp         9fs     # Plan9 FS

If your system does not accept the name 9fs, change it to u9fs in /etc/services and /etc/inetd.conf.

Finally, send a SIGHUP to your inetd or kill(1) it completely and re-start it. Make sure that inetd accepts the new protocol.

Setting up a Diskless Terminal

All you need to turn a PC with an ethernet card into a diskless Plan9 terminal is to

  1. remove all disks from it, if any. ;-)
  2. create a boot floppy for that PC.

(1) is optional, so we concentrate on (2). The first thing to do is to format a floppy and make sure it has no errors. Again, the details vary from Unix to Unix. On FreeBSD, you may use fdformat(1):

fdformat -y /dev/rfd0

The next thing to do is to create a DOS file system on the newly formatted floppy disk. Many Unix systems have a tool set called the mtools installed. This set contains a program named mformat, which creates DOS file systems. If you have this program, just type

mformat -f 1440 a:

If mformat is not installed on your machine, you may consider getting a copy of it. As a last resort, you may look for a real DOS machine and use that to format the floppy disk.

Next you will have to copy some files to the floppy. Most of the files you need are located at /scratch/p9root/386. Go there and copy the 9load file to the floppy. Using mtools, it can be done this way:

mcopy 9load a:

9load(8) is the Plan9 bootstrap loader. It will load the Plan9 kernel over the network. To get it into memory, though, a master boot program is required. The pbs program (also located in /scratch/p9root/386 is such a program. It must be copied to the first sector of the floppy.

Unfortunately, it is not sufficient to just copy it to the floppy using dd(1), since there are some fields in the boot sector that must be set up using the format(1) command of Plan9. Since the format command cannot yet be used, though, a different way must be chosen. Since I do not think that I may re-distribute a Plan9 boot program legally, I have extracted the necessary information from a working boot block:

p9boot.tar.gz (broken link!)

This archive contains two files called boot-head and boot-tail. They are used to patch pbs as follows (do this inside of a directory owned by you):

cp /scratch/p9root/386/pbs bootblock
cat boot-tail >> bootblock
dd if=boot-head of=bootblock conv=notrunc

The notrunc option is used to copy boot-head to the beginning of bootblock without truncating the destination file. After patching the boot block, copy it to the floppy disk:

dd if=bootblock of=/dev/rfd0

Finally, you need a plan9.ini file on your boot disk. Some parts of this file depend on your terminal hardware and network configuration, others are common. Here is a sample plan9.ini file:

*nomp=1

ether0=type=elnk3
bootfile=ether0!9pcdisk

fs=10.0.0.10
auth=10.0.0.10
bootargs=tcp -g 10.0.0.10 ether /net/ether0 10.0.0.90 255.255.255.0

mouseport=ps2
monitor=xga
vgasize=800x600x16

The strings in boldface denote settings that you will almost certainly have to adjust. The easy parts are the IP numbers. 10.0.0.10 is to be replaced with the IP number of the Unix host holding the Plan9 files. 10.0.0.90 is to be replaced with the IP number of the Plan9 terminal, and 255.255.255.0 is the netmask of the network connecting the terminal with the host.

The harder part is to find a network interface card that is supported by Plan9 and to enter its type instead of elnk3. Elnk3 denotes an Etherlink III card. If you have one in the PC you want to turn into a Plan9 terminal, just leave this line as it is. Other valid ether0 types include, for example:

ne2000 amd79c970 wd8003 3c589 ect2 i82557 2114x rtl8139 smc91cxx

If you think that one of these IDs matches your ethernet board, just replace elnk3 with it. Other types and further details on NICs can be found in the plan9.ini(8) manual page. You can render it using the following command:

nroff -man /scratch/p9root/sys/man/8/plan9.ini | more

You may have to tweak the values of the mouseport, monitor, and vgasize variables as well. Refer to the plan9.ini(8) manual page for details.

When finished, copy your custom plan9.ini file to the boot floppy:

mcopy plan9.ini a:

Preparing BOOTP and TFTP

The Plan9 boot disk requires BOOTP and TFTP support on the Unix host. See the Unix manual pages for bootpd(8) and tftpd(8) for details. Both of these services may have to be enabled in /etc/inetd.conf. To do so, add or uncomment the following lines:

bootps  dgram   udp     wait    root    /usr/libexec/bootpd     bootpd
tftp    dgram   udp     wait    root    /usr/libexec/tftpd      tftpd

Next copy a Plan9 kernel to the tftp boot directory. On many systems this directory will be named /tftpboot. When in doubt, refer to tftpd(8). When your Plan9 terminal has an ATA CDROM drive, use the 9pcdisk kernel:

cp /scratch/p9root/386/9pcdisk /tftpboot

If you want to save memory, you can use the 9pc kernel instead. This kernel lacks disk and CDROM support. If you decide to use it, you have to change the bootfile option in plan9.ini, too.

In order to make bootpd(8) support your terminal, it needs an entry in /etc/bootptab (see bootptab(5)). Here is a sample entry:

nine-term:\
        :ha=XXXXXXXXXXXX:\
        :ip=10.0.0.90:\
        :gw=10.0.0.10:\
        :sm=255.255.255.0:\
        :bf=9pcdisk:

Replace the boldface Xes with the media access code (MAC) of your ethernet board. If you do not know the MAC of your board, just boot the Plan9 boot floppy. The loader will display the code during boot. Look for the last item in the line starting with ether#0:. Also replace the terminal's IP number (ip) with its real IP number, the gateway IP number (gw) with the IP address of your Unix host, and adjust the subnet mask (sm). As you already may have guessed, bf specifies the boot file. It should be either 9pcdisk or 9pc, depending on the kernel you wish to load.

If you made any changes to /etc/inetd.conf, do not forget to re-start inetd.

That's it! You should now be able to boot your diskless Plan9 terminal.

Booting the Terminal

To boot your Plan9 terminal, insert the boot floppy into its A: drive and reset or power-cycle the machine. After doing its usual power-on self test, it will print some information while booting. In the following sample, user input is rendered in boldface characters. <ENTER> denotes pressing ENTER.

PBS... Plan 9 from Bells Labs
ELCR: 8000
apm ax=f000 cx=f000 dx=fdfa di=0 ebx=7ef0 esi=1000000
using fd0!dos!plan9.ini
.dev A0 port 1F0 config 85A0 capabilities 0F00 mwdma 0007 udma 0407
ether#0: elnk3: port 0x300 irq 10: 0123456789AB
Symmetry.UUCP (10.0.0.10!67): 9pcdisk
858185+812260+108588=1779033
entry: 0x80100020
cpu0: 134MHz CyrixInstead P6 (cpuid: AX 0x0601 DX 0x80A135)
ELCR: 8000
#l0: elnk3: 10Mbps port 0x300 irq 10: 0123456789AB
4587 free pages, 18348K bytes, 96748K swap
root is from (il, tcp, local) [tcp -g 10.0.0.10 ether /net/ether0 10.0.0.90 255
.255.255.0]: <ENTER>
user[none]: nmh<ENTER>
version...
!Adding key: dom=local proto=p9sk1
user[nmh]: <ENTER>
password: secret password<ENTER>
!
time...

init: starting /bin/rc

At this point, rio(1) should start up and you should see a welcome message. If so:

Congratulations! You are now running Plan9 from a Unix host.