Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

They did not have the original unix vision. and it is a lot easier to to design an interface as a programming interface than shoehorn it into a filesystem interface.

I think having a filesystem interface is pretty great, and plan9 showed it could be done. but having to describe all your io in the [database_key, open(), close(), read(), write(), seek()] interface. can be tricky and limiting for the developer. It is pretty great for the end user however. Having a single api for all io is a super power for adaptive access patterns.

I think the thing that bothers me the most about the bsd socket interface is how close it is to a fs interface. connect()/bind() instead of open(), recv()/send() instead ot read()/write() but it still uses file discripters so that stuff tends to work the same. We almost had it.

As much as I like BSD and as great an achievement that the socket interface was, I still think this was their big failure.



I just think this sounds very elegant

https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs#/net

> Plan 9 does not have specialised system calls or ioctls for accessing the networking stack or networking hardware. Instead, the /net file system is used. Network connections are controlled by reading and writing control messages to control files. Sub-directories such as /net/tcp and /net/udp are used as an interface to their respective protocols.

> Combining the design concepts

> Though interesting on their own, the design concepts of Plan 9 were supposed to be most useful when combined. For example, to implement a network address translation (NAT) server, a union directory can be created, overlaying the router's /net directory tree with its own /net. Similarly, a virtual private network (VPN) can be implemented by overlaying in a union directory a /net hierarchy from a remote gateway, using secured 9P over the public Internet. A union directory with the /net hierarchy and filters can be used to sandbox an untrusted application or to implement a firewall.[43] In the same manner, a distributed computing network can be composed with a union directory of /proc hierarchies from remote hosts, which allows interacting with them as if they are local.

> When used together, these features allow for assembling a complex distributed computing environment by reusing the existing hierarchical name system

I remember first setting up NAT or IP masquerading around 1998. It seemed like an ugly hack and some custom protocols did not work.

I use a bunch of VPNs now and it still seems like a hack.

The Plan 9 way just seems very clean although you now have to secure the server more strongly because you are exporting filesystems from it and others are mounting it.


> The Plan 9 way just seems very clean although you now have to secure the server more strongly because you are exporting filesystems from it and others are mounting it.

With that I mind I wish (the standard Unix gripe!) 9P had a more complex permissions model... 9P's flexibility and per-process namespaces get you a long way, but it's not a natural way to express them.


> The Plan 9 way just seems very clean although you now have to secure the server more strongly because you are exporting filesystems from it and others are mounting it.

aye. this was my first thought too. I seem to recall older Windows doing something like the same thing -- e.g. internet controls tied to the same system as the files -- and that's how we got the 90s-2000s malware 'asplosion.


Clean doesn't mean easy to use. I've worked with a system before that had a very clean, elegant design (message-passing/mailboxes), easy to implement, easy to apply security measures to, small, efficient, everything you could ask for, and pretty much the first thing anyone who used it did was write a set of wrappers for it to make it look and feel more natural.


Plan 9 does that, e.g. dial(2) to do the /net dance. ("2" here actually means something like "3plan9".)


> I just think this sounds very elegant

Where the elegance starts to fade for me is when you see all the ad hoc syntaxes for specifying what ta connect to and what to mount. I have no love for tcp!10.0.0.1!80 or #c or #I. I want to move away from parsing strings in trusted code, especially when that code is C.

I also have no love for "read a magic file to have a new connection added to your process".

9P is neat but utterly unprepared for modern day use where caching is crucial for performance.


> can be tricky and limiting for the developer. It is pretty great for the end user however.

This seems to be a great general principle of api design! The best apis are those that are hated by the developer and loved by the end users.


> The best apis are those that are hated by the developer and loved by the end users.

No, just those loved by the API consumer. Negative emotions on one end doens't do anything positive.

In the case of plan9, not everything can be described elegantly in the filesystem paradigm and a lot of things end up having really awkward "ctl" files which you write command strings to that the fileserver needs to parse. It also handicaps performance due to the number of filesystem operation roundtrips you usually end up making.

Maybe if combined with something io_uring-esque, but the complexity of that wouldn't be very plan9-esque.


> a lot of things end up having really awkward "ctl" files which you write command strings to that the fileserver needs to parse.

These are no different in principle than ioctl calls in *ix systems. The `ctl` approach is at least a proper generalization. Being able to use simple read/write primitives for everything else is nonetheless a significant gain.


They are very different. ioctl's on a file take an operation and arguments that are often userspace pointers as the kernel can freely access any process's memory space. ctl files on the other hand are merely human-readable strings that are parsed.

Say, imagine an API where you need to provide an 1KiB string. The plan9 version would have to process the input byte for byte to sort out what the command was, then read the string to a dynamic buffer while unescaping it until it finds, say, the newline character.

The ioctl would just have an integer for the operation, and if it wanted to it could set the source page up for CoW so it didn't even have to read or copy the data at all.

Then we have to add the consideration of context switches: The traditional ioctl approach is just calling process, kernel and back. Under plan9, you must switch from calling process, to kernel, to fileserver process, to kernel, to fileserver process (repeat multiple times for multiple read calls), to kernel, and finally to calling process to complete the write. Now if you need a result you need to read a file, and so you get to repeat the entire process for the read operation!

Under Linux we're upset with the cost of the ioctl approach, and for some APIs plan to let io_uring batch up ioctls - the plan9 approach would be considered unfathomably expensive.

> The `ctl` approach is at least a proper generalization.

ioctl is already a proper generalization of "call operation on file with arguments", but because it was frowned upon originally it never really got the beauty-treatment it needed to not just be a lot of header file defines.

However, ioctl'ing a magic define is no different than writing a magic string.


It's perfectly possible to provide binary interfaces that don't need byte-wise parsing or that work more like io_uring as part of a Plan9 approach, it's just not idiomatic. Providing zero-copy communication of any "source" range of pages across processes is also a facility that could be provided by any plan9-like kernel via segment(3) and segattach(2), though the details would of course be somewhat hardware-dependent and making this "sharing" available across the network might be a bit harder.


Indeed, you can disregard plan9 common practice and adopt the ioctl pattern, but then you just created ioctl under a different name, having gained nothing over it.

You will still have the significant context switching overhead, and you will still need distinct write-then-read phases for any return value. Manual buffer sharing is also notably more cumbersome than having a kernel just look directly at the value, and the neat part of being able to operate these fileservers by hand from a shell is lost.

So while I don't disagree with you on a technical level, taking that approach seems like it misses the point of the plan9 paradigm entirely and converts it to a worse form of the ioctl-based approach that it is seen as a cleaner alternative to.


Being able to do everything in user space looks like it might be a worthwhile gain in some scenarios. You're right that there can be some context switching overhead to deal with, though even that might possibly be mitigated; the rendezvous(2) mechanism (which works in combination with segattach(2) in plan9) is relevant, depending on how exactly it's implemented under the hood.


I must admit that the ability to randomly bind on top of your "drivers" to arbitrarily overwrite functionality, whether to VPN somewhere by binding a target machine's network files, or how rio's windows were merely /dev/draw proxies and you could forward windows by just binding your own /dev/draw on the target, holds a special place in my heart. 9front, if nothing else, is fun to play with. I just don't necessarily consider it the most optimal or most performant design.

(I also have an entirely irrational love for the idea the singular /bin folder with no concept of $PATH, simply having everything you need bound on top... I hate $PATH and the gross profile scripts that go with it with a passion.)


> I also have an entirely irrational love for the idea the singular /bin folder with no concept of $PATH, simply having everything you need bound on top

That's really an easy special case of what's called containerization or namespacing on Linux-like systems. It's just how the system works natively in plan9.


can you give a few examples of this "lot of things"? What operations do not map naturally to file access?


can you paper over the *ixian abstraction using transformer based metamodeling language oriented programming and the individual process namespace Lincos style message note passing hierarchy lets the Minsky society of mind idea fall out?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: