Now this is userspace networking I can get behind!
Rather than re-implement a new network stack and solve all the same problems again, this builds on the years of good work already done and leverages the existing time investment within the existing stack.
"Librarising" existing stacks to userspace, great idea, this is the way of the future.
The NetBSD rump kernel (rumpkernel.org) does this for every driver in the kernel, and is part of the OS, so they are maintained (there are lots of stacks pulled out but not maintained).
Thats why it is important that this project becomes part of upstream so it can be maintained as the stack changes.
There are environments that do not have a strong distinction between OS and language. While adored by their users, for some reason they are never very popular. Oberon, Smalltalk and the old Lisp Machines come to mind. (Maybe Forth too, though most "Forth OSes" never tried to do multitasking or even file systems.) I suspect there are anti-network effects holding them back. They support one language and one language only. You can't easily bolt them into whatever OS you already use. None of your familiar tools run on them either. Adoption rates are poor with no way to dip your toe into the environment.
What would a "no OS" system that equally supports multiple languages look like?
edit: Multiple languages that have nothing in common. Think about the insane variety of languages you have available on *nix.
We are getting there with the rump kernel (rumpkernel.org). It now runs PHP, Lua, LuaJIT, C, C++. This is very much work in progress and it is not particularly user friendly, but it is improving rapidly. I plant to look at Go soon, which has built in syscall traps, which need replacing with library calls. There are a whole bunch of environment assumptions, like existence of dynamic linkers, build systems and so on that need to be worked around.
OSv is another option, it makes life easier by supporting Linux binaries modified to be dynamic libraries, and runs several languages too, although it was initially mainly targeted at JVM languages.
Using a standalone Forth is more or less a rejection of the utility of an operating system. My years of using a stand alone Forth for day to day computing instilled in me a deep cynicism when it comes to the complexity of operating systems.
I've been reading kragen mailing lists where they bootstrap a lot of 'utilities' on metal with asm (using alt keycodes as 'editor', funky). It's very inspiring and relaxing to see how few things you need to start using a computer. It flatten the whole abstraction stack into a thin core.
> IIRC the Lisp Machines supported C in addition to the system's dialect of Lisp.
IIRC the Lisp Machines (well, CADR at least) compiled code down to some pretty high-level machine code implemented in microcode. How many standard C idioms could actually be expressed in that kind of code?
I'm also not seeing how it would give a speed-up, which is the usual reason to code in C.
No reason you can't compile C down to that. It's just that there will be less of a clear performance advantage for C as some of the semantics will be slightly awkward to map to that instruction set.
You might still get a speedup by writing C in some areas, but I think the real reason for supporting it is that you have a bunch of legacy software and drivers written in C, and it's easier to get a C compiler working on that platform than to port all that software.
I know all these names, unfortunately only by reading and not by experience. Some lispers are also keen on bypassing OS interface and emit binary code on the go.
Why isn't that "just" either using lwIP, or using your host's TCP running against a TUN/TAP device and then encapsulating the data you read from /dev/net/tun into your custom datagram protocol?
(This is not meant to be dismissive, just inquisitive. I'm sure it can't be anywhere near as easy as what I said, I'd just like to learn why.)
As someone who's currently facing that daunting task myself, may I ask what you ended up doing? Did you have to roll your own reliable stream-oriented protocol?
- It used to be impossible to implement securely. Until very recently, there was no hardware support for virtualizing the network buffers, which would mean emulating the network hardware in userspace. This would be very slow.
- Because even today, many devices don't have the required hardware virtualization support. For example, many (most?) ARM devices. If you give direct DMA access, you might be allowing anyone to splatter whatever code they want across whatever memory they want.
- Without kernel arbitration of some sort, there's no way to do load balancing across services, throttle, or firewall effectively.
- The kernel is designed to provide a uniform interface for all programs to the hardware. Putting networking in userspace gets rid of this abstraction, and means that every program has to be aware of the network hardware; software that works with file descriptors directly can't use the same abstraction for files and network.
- Because there are no hardware limitations on the amount of multiplexing. I don't remember how much muxing various hardware supports, but hardware has limits for this sort of thing. If you want more than N processes using the virtual network, you might be SOL with a virtualized userspace network stack.
These are valid objections to in-process access to the networking hardware. Not to running the networking stack in user space, in a privileged process.
For the latter, performance concerns would be a bigger issue.
Not a stupid question at all. It's kind of like the question why did we have to program computers in Assembler (which was great fun, BTW) and not in high level languages. It wasn't feasible. Assembly coding did continue for quite some time in the interest of performance but once the proverbial turn is taken, there is no looking back. That's where networking is now.
What we still call (rigid) "protocols" should and indeed can become freestanding application code
See my paper "Tearing Down the Protocol Wall" at https://www.linkedin.com/in/yitzhakbg#background-publication...
To multiplex multiple users and applications. Which is less necessary in these days of virtual network devices etc, eg SR-IOV can make a PCI device appear as say 64 network devices so every application can have its own.
It will be interesting to see how this evolves; hopefully it will make it easier to build a userland TCP/IP stack, and maybe even to make it easier to ship a new transport protocol (this might make it easier to push for HTTP over SCTP instead of TCP, which makes far more sense, really). Also this will be nice if it allows userland applications to utilize ICMP (traceroute/nmap would no longer be nerfed without root access). NUSE alone should be incredibly handy.
My first thought was that this sounds like an idea taken from microkernels. Is this a correct analogy? Would it be sufficient to use libos and fuse to call the Linux kernel a microkernel? What would be missing?
More seriously though, you're absolutely right in that it's a step in the direction of an "optional" microkernel architecture. That's actually how rump kernels on NetBSD started: running the kernel file system driver as a library in userspace on top of a FUSE-like subsystem. It's pretty useful functionality, since it allows you to handle untrusted file system images safely in userspace, while not imposing performance penalty on the trusted images which can be handled by the same driver running in the kernel. Unlike with FUSE-specific drivers, you don't run into issues with unsymmetric driver support in userspace vs. kernel.
My first thouvht on hearing the name "libOS" was that someone had gotten Linux running on an exokernel, which is in some ways a variation on the microkernel theme.
Linux on a microkernel has been done before. The MkLinux projext is one example, though it also doubled as a port to PowerPC. I haven't heard of any exokernel attempts, though.
The design is quite heavily influenced by the rump kernel design, although Linux has its own issues that make it a bit different. Obviously its only the network stack.
The other closest thing is probably an exokernel, which is essentially a rump kernel with all the of the stuff that's optionally in userspace removed from the kernel. MIT did a lot of experimentation there.
It was submitted as a patch series to the Linux kernel mailing list, with proper "Signed-off-by" headers in the commit messages. So presumably it's usable under GPLv2.
EDIT: I was referring to the kernel support, but it looks like you might have been talking about the code on Github which uses the LibOS API. That does indeed seem to be missing a license.
Rather than re-implement a new network stack and solve all the same problems again, this builds on the years of good work already done and leverages the existing time investment within the existing stack.
"Librarising" existing stacks to userspace, great idea, this is the way of the future.