Booting a diskless Sun SLC as an XTerminal

A colleague recently came across a cache of Sun SLC diskless workstations; these are Sun4c architecture with 17" black-and-white (no gray) screens. While these could have a disk added and run SunOS stand-alone or boot SunOS over the net, it seemed like it would increase my sysadm requirement. I wanted something I could sit in the kitchen or basement and use -- without having to baby-sit it, back it up, worry about crackers getting in, etc.

The SLC now runs as an XTerminal, booting from another host; the boot server also happens to be a SunOS system but that's not necessary. While this document may refer to SunOS-specific configuration files and syntax, examples here should apply to any other UNIX-like system; binaries necessary for the Sun SLC are available on the net.

This document stole ideas from http://www.stat.uga.edu/~huckaby/sysadmin/xterminal/. An excellent resource for booting diskless Sun workstations is O'Reilly's _Managing NFS and NIS_, by Hal Stern, chapter 8.

The basic mechanism is as follows. Install the Xkernel software and core filesystem. Use rarpd to assign the box an IP addresses. Supply it a boot loader image via tftpd. Tell it where to get its operating system with bootparamd. Export its filesystem with NFS. Configure the client boot process and X-Window initialization, then tell the server to offer it xdm login access.

Install Xkernel software and filesystem

The Xkernel software is available from ftp://ftp.ctr.columbia.edu/pub/Xkernel/. For Sun4c architecture SLC systems you'll need files client-binaries-sun4.tar.z, kernel-sun4.tar.z, and proto-root.tar.gz. Files for Sun3 systems and supporing documents/code is also available. You can get the three mentioned files from my site if you must, but I'm on the end of an lowly 28.8 link so you'll be waiting quite a while and annoying me at the same time; but if you really want them, get binaries, kernel, proto.

The software needs to be installed into directories used by daemons which will be configured later; sorry about the forward reference. It may be helpful when following particular software install directions to skip ahead to the appropriate daemon configuration sections later on.

NFS filesystem

Create a directory which will be NFS-exported to the Xterminal and contain the Unix kernel, Xsun server, and critical system and device files; /export/root is customary but I put these under my /home partition due to partition constraints. Unpack the kernel-sun4c.tar.z file; it contains the boot loader and Unix kernel:

1124884 Oct 17 05:10 1993 kernel-sun4c/vmunix.sun4c
   1177 Oct 17 05:26 1993 kernel-sun4c/vmunix.sun4c.conf
 110336 Oct 17 05:28 1993 kernel-sun4c/boot.sun4c.sunos.4.1.3
   3410 Mar 14 15:15 1994 kernel-sun4c/.install
     60 Jan 27 19:58 1994 kernel-sun4c/vmunix.sun4c.desc
then the client-binaries-sunn4.tar.z there, creating:
      0 Mar 14 15:15 1994 client-binaries-sun4/Xsuns/
1687552 Oct 17 05:17 1993 client-binaries-sun4/Xsuns/Xsun
    250 Mar 14 15:15 1994 client-binaries-sun4/Xsuns/Xsun.desc
      0 Oct 17 05:16 1993 client-binaries-sun4/sbin/
 163840 Oct 17 05:14 1993 client-binaries-sun4/sbin/clearsockets
 172032 Oct 17 05:16 1993 client-binaries-sun4/sbin/syslogd
  20848 Oct 17 05:13 1993 client-binaries-sun4/sbin/hostname
 180224 Oct 17 05:13 1993 client-binaries-sun4/sbin/ifconfig
  65536 Oct 17 05:13 1993 client-binaries-sun4/sbin/init.old
  32768 Oct 17 05:13 1993 client-binaries-sun4/sbin/intr
 163840 Oct 17 05:13 1993 client-binaries-sun4/sbin/mount
 172032 Oct 17 05:13 1993 client-binaries-sun4/sbin/route
 106496 Oct 17 05:13 1993 client-binaries-sun4/sbin/sh
   3932 Mar 14 15:15 1994 client-binaries-sun4/.install
and the proto-root.tar.z creating:
      0 Mar 23 20:13 1993 proto-root/dev/
  12184 Mar 23 18:15 1993 proto-root/dev/MAKEDEV
      0 Aug 29 18:24 1992 proto-root/etc/
    428 Jul 23 03:22 1991 proto-root/etc/protocols
   1592 Jul 29 00:19 1991 proto-root/etc/services
    317 Aug 29 18:24 1992 proto-root/etc/syslog.conf
      0 Mar 14 15:15 1994 proto-root/sbin/
   7539 Mar 14 15:15 1994 proto-root/sbin/init
    678 Jun  3 12:51 1993 proto-root/sbin/message.Xterm
    346 Jun  3 12:53 1993 proto-root/sbin/message.busy_loop
    443 Jun  3 12:52 1993 proto-root/sbin/message.nofile
    540 Jun  3 12:52 1993 proto-root/sbin/message.norgb
    225 Mar 14 15:15 1994 proto-root/sbin/shcat
      0 Aug 29 18:27 1992 proto-root/usr/
      0 Aug 29 18:27 1992 proto-root/usr/lib/
      0 Aug 29 18:29 1992 proto-root/usr/lib/X11/
   4096 Aug 29 18:29 1992 proto-root/usr/lib/X11/rgb.dir
  29696 Aug 29 18:29 1992 proto-root/usr/lib/X11/rgb.pag
  16992 Aug 29 18:29 1992 proto-root/usr/lib/X11/rgb.txt
      0 Mar 21 00:09 1993 proto-root/Xsuns/
    279 Oct 16 22:10 1993 proto-root/version

I created a xterms.sun4c directory to consolidate these and make subsequent configuration easier. Merge these distributions and move the Unix kernel here too, then create expected link names and set permissions:

mv client-binaries-sun4c xterm.sun4c
cp -r root-proto/* xterm.sun4c		["mv" reportedly doesn't work]
mv kernel-sun4c/vmunix.sun4c xterm.sun4c
chown -R root.other xterm.sun4c
cd xterm.sun4c
ln -s vmunix.sun4c vmunix		[expected name of Unix kernel]
ln -s Xsuns/Xsun Xsun			[expected name of X server]
The links simply create names which the OS expects to find as it boots. You may have other Unix kernel images or versions of the X server; it's more flexible to use links rather than simply renaming the files to their expected names.

tftpboot boot loader

Create a /tftpboot directory consistent with where your tftpd expects it and move the boot loader to that directory; I used /home/tftpboot:

mv kernel-sun4c/boot.sun4c.sunos.4.1.3 /home/tftpboot

mostly finished

You can now remove the kernel-sun4c and proto-root directories if you want.

You'll have to return to this hierarchy and set-up various configuration files which the system will read as it boots. This will be described after all the daemons are configured since it's probably something you'll want to tweak until you get the behavior you want.

rarpd for IP address

When the client boots, it rarps to get it's IP address. The server must listen to the rarp, determine which host it is, and reply with the appropriate IP address; the rarpd daemon does this. The SLC tells you its hardware address when it is turned on; other devices might not be so helpful -- tcpdump can be very useful here. Specify the hardware to hostname mappying in /etc/ethers:

8:0:20:3:d:c7	lobotomy
then set the hostname to IP address mapping in /etc/hosts:
209.31.147.200	lobotomy.stonos.washington.dc.us lobotomy.i3inc.com lobotomy 
(I have a couple domains running so I have to ensure the name will resolve regardless of the domain the client and server think they're in today. Be careful with hostnames; when in doubt put the simple hostname as well as the FQDN, otherwise name matching like rarpd does may fail.) If it isn't already running, run rarpd; you should probably enable it at boot time from /etc/rc.local or something. I use:
/usr/etc/rarpd -a
to have it listen on all interfaces, even though I currently only have one network interface on the server.

tftpd for boot loader

After the client receives its IP address, it will try to retrieve a boot loader image via tftp. If it's not already running, enable tftpd in /etc/inetd.conf and point it to the directory you installed the boot.sun4c.sunos.4.1.3 image:
tftp	dgram	udp	wait	root	/usr/local/etc/tcpd	in.tftpd -s /home/tftpboot
I'm using tcp_wrappers, tcpd, here; you may not be. Signal the inetd to reread its config file with a "kill -HUP".

The name the file tries to retrieve is based on the client's IP address and (here anyway) the architecture of the machine. Convert each octet of the client IP address into hexidecimal and concatenate them, then add the suffix for the architecture. My client's address is 209.31.147.200, and the SLC is a Sun4c; put it together and upper case it and you get D11F93C8.SUN4C. Since the client will request this file by name, link it to the actuall boot file:

ln -s boot.sun4c.sunos-4.1.3 D11F93C8.SUN4C
This naming allows you to serve different boot files to different clients. The links make it easy to share binaries to change what boot image you give a client. I'm actually offering a SunOS-4.1.4 boot loader from my IPX system, so my /home/tftpboot directory looks like:
lrwxrwxrwx  1 root     22 Feb 28 01:02 D11F93C8.SUN4C -> boot.sun4c.sunos-4.1.4
-r--r--r--  1 root 110352 Jul  2  1996 boot.sun4c.sunos-4.1.4
-r--r--r--  1 510  110336 Oct 17  1993 boot.sun4c.sunos.4.1.3

At this point, if you try to boot the client from the net, it should get its IP address from rarpd and download its boot loader via tftpd. This should be a good test, but it will hang after getting the boot loader complaining it can't find its bootparam server.

bootparamd for finding filesystem

The client's boot loader queries the bootparamd daemon to find out where it should get its root filesystem, which includes the Unix kernel and the X server binaries. This is specified in /etc/bootparams:
lobotomy.stonos.washington.dc.us  root=absinthe:/home/export/root/xterm.sun4c

Again, be careful here with simple host names, FQDNs, client and server domains. It took me a long time to realize my server (absinthe) thought it was in a different domain (i3inc.com) from the client (lobotomy); this prevented the NFS mount from working.

Run the bootparamd so it will tell the client what to mount via NFS; this should also be done at server boot with /etc/rc.local or equivalent.

/usr/etc/rpc.bootparamd
You might want to run with the -d debugging option; tcpdump is also useful here. You should hopefully see -- from debug flags, tcpdump, etc -- the client getting its boot params when you next try to boot it from the net. Now export the filesystem it wants with NFS.

NFS exports the filesystem

You now need to export the filesystem you installed in /home/exports/root/xterm.sun4c so the client can find the Unix kernel, X server binary, and all it's boot and configuration files -- identical to those needed by disk-full workstations. Tell NFS your location and give it root access in /etc/exports like:

# Must export subdir before parent??

/home/export/root/xterm.sun4c	lobotomy.stonos.washington.dc.us	\
	-root=lobotomy.stonos.washington.dc.us

/home	thanatos	\
	sisyphus	\
	-root=thanatos:sisyphus

[I *should* be able to export a parent like /home which I share with others; the bootparams should tell it exactly which directory to use??]

You'll have to use exportfs -a or equivalent to get the sysetm to export this. Make sure you're running all the required NFS server daemons like nfsd and mountd. At this point, if you reboot the client, you should see it get the NFS location to mount from bootparamd then mount the filesystem, boot Unix and report the client's hardware configuration. It will probably fail to run the X server because you haven't configured the client's system configuration files yet.

Client boot configuration

Like any disk-full host, you've got to configure the system to boot properly. Diskless clients are no different except that their filesystem actually resides on the server's disk. All the files referenced here are under the "root" directory you indicated in bootparams, in this case /home/export/root/xterm.sun4c.

Go to the the .../dev directory and create the devices:

./MAKEDEV std

Create appropriate .../etc/hosts file indicating your server, fontserver, primary XDM host, loghost, etc:

209.31.147.194	absinthe.i3inc.com absinthe.stonos.washington.dc.us absinthe loghost fontserver primaryxdmhost
Again I'm playing games with multiple domains. The names "loghost", "fontserver", and "primaryxdmhost" are used later in the system initialization script.

You may need to tweak the client ethernet interface, even though it already got one from rarpd; I had to since I'm running with a /28 subnet, and SunOS was notorious for using 0-based broadcast instead of 1-based addresses. Enter the appropriate command in .../etc/ifconfig_cmd.le0 (where le0 should be replaced by a different network device name if needed):

ifconfig le0 broadcast 209.31.147.207 netmask 0xfffffff0
Make sure this file is executable otherwise the system's init will fail to run it.

System and X initialization and customization

Like other systems, the "init" program is run at boot to start system services. Since this one is designed to run only an X server, the process is simpler: almost everything happens in .../sbin/init.

When I first got the system to boot the X server, it failed, so I added a bunch of output to the init script like:

echo starting X server with $XSRVCMD  >/dev/console

There were some tweaks that were actual fixes, mostly having to do with paths, ports, or layout changes between X11R5 used by Xkernel and X11R6 which I'm running. The init expected to contact a fontserver at port 7000, but the /etc/services file shows the official port it 7100.

The X server command is started with the "-co" option pointing to an R5 path to the color database. You need to ensure this really points to the database on the NFS root, else it won't be able to get your colors unless you NFS-mount your R6 over top or something goofy. This will result in the inability to resolve even simple colors like "white" and your display being almost unusable; even xterm will act neurotic, refusing to use CRs in displayed newline breaks. It would be helpful if init made this and things like it variables, since it does go to the effort of validating them. You can take a look at what I've got so far in my init script where I've set such a variable.

One problem I have not resolved is when init tries to use a random numbered socket to connect to the font server with "clearsockets fontserver"; I get the error "connect: Connection refused; errno=61". Any leads would be appreciated.

There are some other customizations I have not monkeyed with yet because I don't seem to need them. You can set a .../etc/defaultrouter and an .../etc/fstab. There are others too so take a look at the file if you just can't leave well enough alone :-)

At this point, you should be able to boot up all the way into the X server and see the familiar stippled background. Now you need to get the client to find an XDM server so it can login.

XDM for login

In the .../sbin/init script it specifies XDMCMD=-indirect primaryxdmhost which tells it to ask the machine named "primaryxdmhost" for a reference to an XDM server. This hostname should have been defined in .../etc/hosts. On that host -- for me the same as the boot and NFS server -- I modified the xdm daemon configuration file /usr/X11R6/lib/X11/xdm/Xservers by adding the line according the the file's comments:
lobotomy:0 foreign
The file already specified a server configuration for the "local" screen on the server and I left this alone. I had to try and kill xdm a couple times ("kill him... kill him a lot") to get it to the point that the client would actually get an XDMCP chooser screen.

I also started the X font server, because the init script seemed to want it. In R6, you configure it with paths to your fonts in /usr/X11R6/lib/X11/fs/config like:

# Font server runs on std port 7100 by default
client-limit=10
clone-self=on
catalogue=/usr/X11R6/lib/X11/fonts/Speedo,
	/usr/X11R6/lib/X11/fonts/misc,
	/usr/X11R6/lib/X11/fonts/100dpi,
	/usr/X11R6/lib/X11/fonts/75dpi,
	/usr/X11R6/lib/X11/fonts/Type1
default-point-size=120
default-resolutions=100,100,75,75
use-syslog=on
and start it as /usr/X11R6/bin/xfs &. This should be done at boot. When it did, the chooser indicated that my server was willing to offer XDM login; if I had other machines running xdm for "foreign" systems I would see them there too. When I chose the server name, I got the familiar xdm login screen, logged in, and got my usual complement of clients started from .xsession and .fvwmrc.

Problems so far

I've noticed a couple problems in the few hours I've been using this and will itemize them here. As I find solutions, I'll try to update this doc.

My usual X startups presume I've got a color display. I need to determine how to test for color or monocrome display and invoke the right .Xdefaults, commands, or configuration for services like the fvwm window manager.

When .../sbin/init tries to randomize the font server connection it gets the error "connect: Connection refused; errno=61". Is this breaking anything?

Emacs doesn't highlight (inverse video) the horizontal separator and mode/status lines. This makes it difficult to notice a split window with multiple buffers. Is this just a color problem?


Chris Shenton
Last modified: Mon Mar 2 07:53:31 1998