Hacker News new | ask | show | jobs
by ori_b 1616 days ago
The number of special cases.

For example: consider how you'd write some generic code to forward all ioctls transparently across the network. Keep in mind that the data attached to the ioctls is machine dependent, driver dependent, and has no information about how it's formatted. Every ioctl for every driver is its own special case.

Meanwhile, faithfully forwarding all devices in a plan 9 system is trivial. Control messages aren't strictly formatted -- but they're done via reads and writes on file descriptors, so sending them to the devices that understand them, and relaying back the result, is trivial. It's just 9p: https://man.9front.org/5/0intro

Doing this fully, for all devices (except /srv, which is a bit magical) is implemented here, in a short shell script. This is the remote login program used by 9front, which gives you something resembling ssh or vnc, but with full access to the data and devices on your local machine, graphics, audio, mouse, keyboard, USB, network, and anything else, even if it hasn't been implemented yet. It does both client and server side:

https://git.9front.org/plan9front/plan9front/HEAD/rc/bin/rcp...

The client side sets itself as a file server, using exportfs. It exports everything in its namespace, including /dev, over to the server.

The server takes the client's namespace, and mounts it over /mnt/term. Then, it takes /mnt/term/dev/cons and binds that over /dev/cons and starts a shell. That means that every time a program is run, it opens /dev/cons to interact with the user, using the client's mouse, keyboard, and so on, forwarding all the operations transparently over the network.

The idea can go further; Instead of using network translation layers, for example, a plan 9 machine would import a different machine's network stack and mount it over itself:

    # whats my ip?
    % cat /net/ipselftab
    192.168.1.11                                 01   4u
    % hget https://api.ipify.org
    74.{home.address}

    # ok, let's import another machine's network stack and use it.
    % rimport orib.dev /net/ /net

    # what's my ip now? look ma, I'm proxying!
    % cat /net/ipselftab
    144.202.1.203                                01   4u
    % hget https://api.ipify.org
    144.202.1.203
There are no special hooks in the network stack for this. It doesn't know. This happens for free because the network stack being accessible through the filesystem API.

This kind of thing happens everywhere, because everything goes through 9p, and everything can be namespaced. There isn't any other special case to consider: If you forward 9p, you forward all operations you can do with a device. Or any other file server.

If everything is in a namespace, you don't pull the devices other programs are using out from under them, so you can put one login in one sandbox with a remote mouse and keyboard, and a different one in a different sandbox with a different network stack.

This falls apart when you have the 53,719 special cases bundled with posix. If you need a special case for each operation you through the network, or interpose in userspace, you're in for a rough time.

Plan 9 works because it's relatively simple and uniform.