> It really is amazing how much success Linux has achieved given its relatively haphazard nature.
That haphazard nature is probably part of the reason for its success, since it allowed for many alternative ways of doing things being experimented in parallel.
That was my impression from diving into The Design & Implementation of the FreeBSD Operating System. I really need to devote time to running it long term.
I’m very sure this is a myth. Like any good myth, it makes sense on the surface but holds zero water once you look close.
Code isn’t prose. Code doesn’t always go to the line length limit then wrap, and prose doesn’t need a new line after every sentence. (Don’t nitpick this; you know what I’m saying)
The rules about how code and prose are formatted are different, so how the human brain finds the readability of each is necessarily different.
No code readability studies specifically looking for optimal line length have been done, to my knowledge. It may turn out to be the same as prose, but I doubt it. I think it will be different depending on the language and the size of the keywords in the language and the size of the given codebase. Longer keywords and method/function names will naturally lead to longer comfortable line lengths.
Line length is more about concepts per line, or words per line, than it is characters per line.
The 80-column limit was originally a technical one only. It has remained because of backwards compatibility and tradition.
It’s not baffling at all. They strongly value maintaining backwards compatibility guarantees.
For example, Windows 11 has no backwards compatibility guarantees for DOS but operating systems that they do have backwards compatibility guarantees for do.
Enterprises need Microsoft to maintain these for as long as possible.
It is AMAZING how much inertia software has that hardware doesn’t, given how difficult each are to create.
I really wish Plan9 got more attention when it came out.
All processes in Plan9 are given their own namespace. By mounting things to or unmounting things from the namespace, you grant or disable access to specific parts of the filesystem. And because everything is a file in Plan9, the filesystem is the filesystem, the audio device is part of the filesystem, the video device is part of the filesystem, network interfaces are exposed via the filesystem, etc.
Isolation by default.
In 1995.
Docker would never have been needed if operating systems adopted this feature. The kraken known as Kubernetes might never have been needed if Plan9s features were adopted.
It’s too late to change how things are, but it’s never too late to set things right.
We need an operating system which isolates child processes from their parent and from siblings, and from everything else unless access to specific things is granted at launch time.
We’ve built so much crap on top of our old operating systems that we view it as normal. We should not need docker or virtualization to have isolation. There is no technical need for those things, and they are each another layer on a stack that is maybe already too tall. They are points of failure and if operating systems were capable, we would not need them.
The source code and design of Plan9 can fit entirely inside one mind. It isn’t a huge behemoth. It takes single digit seconds to compile.
It could be the basis of something supreme.
If I were rich, among my other altruistic endeavors, I would be hiring folks to develop this OS into something a little more current and a little more fit for the environment we see in 2025 and beyond.
My point: one should not need docker to do what you have done. Default per-process isolation should be a core feature of the operating system.
> The kraken known as Kubernetes might never have been needed if Plan9s features were adopted.
Which Plan9 features exactly give me a unified API layer to handle workload scheduling incl. fault tolerance, flat networking across a cluster or service discovery?
Containers are an implementation detail and not what Kubernetes is fundamentally about.
Let’s be clear about one thing: Kubernetes is an operating system on top of Linux which exists solely because operating systems don’t provide what it needs already. I’m saying that operating systems should provide scalable ways to launch applications securely across many physical machines natively. Plan9 offers that, and it has for 30 flippin years.
Plan9 has those things out of the box if you configure them. Fault tolerance, flat networking across a cluster, and service discovery. And if I’m wrong about that (my knowledge of both Plan9 and kubernetes is incomplete) then it would almost be trivial to implement given what plan9 has out of the box. In fact, I think the built-in network database can do all of these things if you put the relevant data in and use it. It was designed for these exact things.
Plan9 is designed to be deployed as lots of physical systems all working cooperatively. User systems and servers in a server room, both. A program that lives on computer A can run using the CPU of computer B and the networking of computer C. Natively. It can look up the address of any service via the network database (provided that info is put into the database when that service is started) and all of it. Note that I am not talking about DNS. That is separate from the network database.
Plan9 is different and it is superior in many ways.
Unix was built with the assumption that end users had terminals and that computing was centralized at the server. That assumption is no longer even remotely true. Yet we still cling to it as if it is ideal. It is not.
Plan9 was built with the assumption that everyone had capable computers at their desks and that people seated together often worked on things together. Closer to where we are today, but not quite. Today we have near-supercomputers at our desks in the form of development machines and servers of all descriptions in the server room, both more powerful and less powerful than our local machines.
If Plan9 were designed today it would be different, but the core features would remain.
And if you look at the source for Plan9 you’ll see that they got a hell of a lot done with very few lines of code. They were very, very “pro-simplicity”. Go read it and see how they did it. Then count the lines of code in Kubernetes and see which is bigger and more complex and then ponder that for a bit. It would have been easier to write an operating system to handle those workloads natively than it was to write Kubernetes.
I'm not sure, at the end of the day, it would have made that much difference. Those who are security and separation aware still are and plan9 would have been a much easier tool for those people.
Those people who are not, still would not be, and having that separation ability wouldn't help. You see this with apps and other things that have the ability to limit their access but you want the app and you just click through without reading what permissions it wants. So those who just want to use something without understanding the danger of it still fall prey to nefarious actors.
What? The MacOS Keychain is designed exactly for this. Every application that wants to access a given keychain entry triggers a prompt from the OS and you must enter your password to grant access.
I use it as my secret store provider but it has its quirks.
It would be better if you could have multiple providers attached (gnome-keyring and keepassxc) and then decide which app uses which provider.
Because only some secrets you want to share across devices, like wifi passwords, and the rest you don’t, like the key chromium uses to encrypt local cookies or the gh cli token.
One could easily allow or restrict visibility of almost anything to any program. There were/are some definite usability concerns with how it is done today (the OS was not designed to be friendly, but to try new things) and those could easily be solved. The core of this existed in the Plan9 kernel and the Plan9 kernel is small enough to be understood by one person.
I’m kinda angry that other operating systems don’t do this today. How much malware would be stopped in its tracks and made impotent if every program launched was inherently and natively walled off from everything else by default?
I think this normalises running untrustworthy, abusive proprietary software, because they can at least be somewhat contained. The only reason I have apps like Facebook on my android phone is that I have sufficient trust in GrapheneOSs permissions.
Then, apps like syncthing become crippled as filesystem virtualisation and restrictions prevent access and modification of files regardless of my consent.
Not disagreeing with the need for isolation though, I just think it should be designed carefully in a zero-sacrifice way (of use control/pragmatic software freedom)
Here I go again: Plan9 had per-process namespaces in 1995. The namespace for any process could be manipulated to see (or not see) any parts of the machine that you wanted or needed.
I really wish people had paid more attention to that operating system.
The tooling for that exists today in Linux, and it is fairly easy to use with podman etc.
K8s choices clouds that a little, but for vscode completions as an example, I have a pod, that systemd launches on request that starts it.
I have nginx receive the socket from systemd, and it communicates to llama.cpp through a socket on a shared volume. As nginx inherits the socket from systemd it does have internet access either.
If I need a new model I just download it to a shared volume.
Llama.cpp has now internet access at all, and is usable on an old 7700k + 1080ti.
People thinking that the k8s concept of a pod, with shared UTC, net, and IPC namespaces is all a pod can be confuses the issue.
The same unshare command that runc uses is very similar to how clone() drops the parent’s IPC etc…
I should probably spin up a blog on how to do this as I think it is the way forward even for long lived services.
The information is out there but scattered.
If it is something people would find useful please leave a comment.
Plan9 had this by default in 1995, no third party tools required. You launch a program, it gets its own namespace, by default it is a child namespace of whatever namespace launched the program.
I should not have to read anything to have this. Operating systems should provide it by default. That is my point. We have settled for shitty operating systems because it’s easier (at first glance) to add stuff on top than it is to have an OS provide these things. It turns out this isn’t easier, and we’re just piling shit on top of shit because it seems like the easiest path forward.
Look how many lines of code are in Plan9 then look at how many lines of code are in Docker or Kubernetes. It is probably easier to write operating systems with features you desire than it is to write an application-level operating system like Kubernetes which provide those features on top of the operating system. And that is likely due to application-scope operating systems like Kubernetes needing to comply with the existing reality of the operating system they are running on, while an actual operating system which runs on hardware gets to define the reality that it provides to applications which run atop it.
You seem to have a misunderstanding of what namespaces accomplished on plan9, or that it was extending Unix concepts and assembling them in another way.
As someone who actually ran plan9 over 30 years ago I ensure that if you go back and look at it, the namespaces were intended to abstract away the hardware limitations of the time, to build distributed execution contexts of a large assembly of limited resources.
And if you have an issue with Unix sockets you would have hated it as it didn’t even have stalls and everything was about files.
Today we have a different problem, where machines are so large that we have to abstract them into smaller chunks.
Plan9 was exactly the opposite, when your local system CPU is limited you would run the cpu command and use another host, and guess what, it handed your file descriptors to that other machine.
The goals of plan9 are dramatically different than isolation.
But the OSes you seem to hate so much implemented many of the plan9 ideas, like /proc, union file systems, message passing etc.
Also note I am not talking about k8s in the above, I am talking about containers and namespaces.
K8s is an orchestrater, the kernel functionality may be abstracted by it, but K8s is just a user of those plan9 inspired ideas.
Netns, pidns, etc… could be used directly, and you can call unshare(2)[0] directly, or use a cri like crun or use podman.
Heck you could call the ip() command and run your app in an isolated namespace with a single command if you wanted to.
Kubernetes is an operating system on top of an operating system. Its complexity is insane.
The base OS should be providing a lot/all of these features by default.
Plan9 is as you describe out of the box, but what I want is what plan9 might be if it were designed today and could be with a little work. Isolation would not be terribly difficult to add to it. The default namespace a process gets by default could limit it to its own configuration directory, its own data directory, and standard in and out by default. And imagine every instance of that application getting its own distinct copy of that namespace and none of them can talk to each other or scan any disk. They only do work sent to them via stdin, as dictated in the srv configuration for that software.
Everything doesn’t HAVE to be a file, but that is a very elegant abstraction when it all works.
> call the ip() command and run your app in an isolated namespace with a single command if you wanted to.
I should not have to opt in to that. Processes should be isolated by default. Their view of the computer should be heavily restricted; look at all these goofy NPM packages running malware, capturing credentials stored on disk. Why can an NPM package see any of that stuff by default? Why can it see anything else on disk at all? Why is everything wide fucking open all the time?
Because containers on Linux will never be able to provide this, they are fundamentally insecure from the kernel layer up, adding another OS stack on top (k8s) will never address the underlying mess that Linux containers are fundamentally.
The fact that tools like docker, podman and bubblewrap exist and work points out that the OS supports it, but using the OS APIs directly sucks. Otherwise the only "safe" implementations of such features would need a full software VM.
If using software securely was really a priority, everyone would be rustifing everything, and running everything in separated physical machines with restrictive AppArmor, SELinux, TOMOYO and Landlock profiles, with mTLS everywhere.
It turns out that in Security, "availability" is a very important requirement, and "can't run your insecure-by-design system" is a failing grade.
> The fact that tools like docker, podman and bubblewrap exist and work points out that the OS supports it
Only via virtualization in the case of MacOS. Somehow, even windows has native container support these days.
A much more secure system can be made I assure you. Availability is important, but an NPM package being able to scan every attached disk in its post-installation script and capture any clear text credentials it finds is crossing the line. This isn’t going to stop with NPM, either.
One can have availability and sensible isolation by default. Why we haven’t chosen to do this is beyond me. How many people need to get ransomwared because the OS lets some crappy piece of junk encrypt files it should not even be able to see without prompting the user?
This sounds very interesting to me. I'd read through that blog post, as I'm working on expanding my K8s skills - as you say knowledge is very scattered!
Plan9 “terminals” were like that. Create a window, and by default the text shell runs in it. If you have vdir installed, and you run that in the same window, you get a semi-graphical file browser. Exit that and then run games/doom and now doom is running in the same window. Exit that and “cpu” into another machine and run riostart and now that same window that did all the other things now is running a window manager on the remote machine, displayed on your machine. Graphical apps, textual apps, everything. All in Rio windows. Smoothly, too. (It is a very different paradigm so I am not going to profess that it is user friendly or anything, but it does work, and it works well once you get your head around it.)
See, that’s something I would never say to anyone.
A one-time event of a black person killing a white person is not enough for me to hate black people. For you it seems to be the topical reference you care to type out; just one of a library of events you pay attention to while ignoring everything else.
You are the problem here. Not anyone that’s black. People like you are who I’m afraid of. And I’m confident you’re the most violent demographic in the US.
You keep exclaiming I have some racial hatred but I really don't. You know who else hates these violent career criminals? Black people just trying to get on with their lives! They're the ones that suffer the most, statistically speaking.
It's white leftists who expose everyone to these threats through their crime-tolerant policies. You will never change until you experience the consequences of such policies first hand, like she did. In the meantime you're happy for everyone else's children to be sacrificed at the altar of progessivism so long as you can keep that Wojak smirk on your face and maintain an heir of (assumed) moral superiority.
Only one of us has blood on their hands. You would never say that (^) to anyone but you're content implementing it through the consequences of your political ideology.
FWIW I'm sorry I said that and I don't wish that for you.
FreeBSD always has been, and always will be, my favorite OS.
It is so much more coherent and considered, as the post author points out. It is cohesive; whole.
reply