How early SunOS did diskless workstations before NFS

July 12, 2026

Over on the Fediverse, I had a little exchange recently:

[other person in a conversation]: I still haven’t forgiven Sun for NFS. No I’m not bitter.

@cks: It could have been worse, Sun could have stuck with nd.

What I was referencing in my post is a now obscure piece of cursed knowledge that I'm happy to share with you today.

Sun's workstations could boot without a local disk from very early on (because that made them cheaper, not because it made them better), but famously NFS only appeared in SunOS 2.0 (which required Sun to also create the idea of a virtual filesystem switch (VFS), which has appeared in basically every Unix since). The pre-NFS versions of SunOS operated without a local disk by using Sun's 'nd', the 'net(work) disk', which is basically what it sounds like.

SunOS nd(4) was a kernel block device (well, pseudo-device) that did its block IO through the network to the server kernel. As covered in nd(4), the same driver was used on both the client and the server, and the server handles everything in the kernel; nd(8) is only there for server setup purposes. The client wasn't configured with the server's information; instead it found the server through the simple approach of "[it] finds the server by broadcasting the initial request". As you can see from the fact that the manual pages I've linked to are for SunOS 3.0, SunOS kept the nd driver and infrastructure quite a long time after NFS was available (I'm not sure, but it might have only been dropped in SunOS 4).

(You can also see the SunOS 1.0 nd(4).)

By itself, the idea of a network disk device isn't particularly cursed. We used to run iSCSI based fileservers quite happily, there's a general ATA over Ethernet protocol that was at least a lot simpler than iSCSI, and Linux has DRBD (and there's probably others out there). What makes SunOS nd into something special is how it works, which comes from a specific limitation of SunOS covered in nd(4):

One last type of unit is provided for use by the server. These are called local units and are named /dev/ndl∗. The Sun physical disk sector 0 label only provides a limited number of partitions per physical disk (eight). Since this number is small and these partitions have somewhat fixed meanings, the nd driver itself has a subpartitioning capability built-in. This allows the large server physical disk partition (e.g. /dev/xy0g ) to be broken up into any number of diskless client partitions.

What this meant in practice was that on your server, you set up one giant partition and then manually decided on the starting and ending sectors for every nd 'disk' within that partition. Keeping track of all of these and making sure that they didn't overlap was your problem; as the nd(8) manual page dryly notes in the BUGS section, 'no sanity checking of disk partitions is done'.

For extra bonus problems, you might run out of available partitions to use on your server disk because you needed all of the available ones for regular filesystems and your swap area. If you were in this situation you could take the dangerous but necessary step of specifying your network disks using the special 'c' partition (cf dkinfo(8)), which was conventionally used to provide access to the entire disk. This was extra dangerous because you had to make sure that the nd disks you specified weren't overlapping into any regular partitions that you were using, since as nd(8) says, nd itself did no sanity checking. If you said sectors X to Y were network disk X, that's what they were, and goodness help you if some of them were also something else.

(I think this meant you could expose the server's /usr disk partition as a read-only 'public' nd device, so all your diskless clients could mount it, rather than having to put a separate copy of /usr into your nd area. This seems to be explicit considered in nd(4).)

Another charming thing about nd was that it didn't use UDP (or TCP). Instead it uses its own IP datagram protocol because, as covered in nd(4), "IP datagrams were chosen instead of UDP datagrams because only the IP header is checksummed, not the entire packet as in UDP" (and the manual page straight up says it was also done because the kernel internal interfaces were simpler). What this means is that the data sent through nd had no checksum protections on the wire, not even UDP's basic one; you were very much counting on absolutely nothing going wrong on your early 1980s Ethernet network.

(With early 1980s CPUs and so on, it presumably made a real performance difference to not checksum 1024 bytes of data on each packet. Early Sun workstations were not exactly performance powerhouses.)

All of this made using nd extra exciting and somewhat cursed. I don't think anyone really liked it back in the days, and people were happy to move to NFS, which used regular server filesystems and had much less of a chance to blow up your server and your clients in exciting ways.