Using nolibc is fine when you compile it together with the kernel.
The parent article is about a C header that you can use to compile your program independently of the source files of the Linux kernel.
Even the presence of the Linux kernel sources on your computer is not enough to enable the compilation of a program that uses directly the syscalls, as the raw sources do not contain any suitable header. You must first compile the kernel with the desired configuration, because header files are selected or auto-generated accordingly. That is enough for nolibc, which lives in the kernel source tree, but it would still be difficult to identify which are the header files that could be used to compile an external program.
Moreover, including Linux header files in your program is an extremely bad idea, because they are not stable. It is frequent that a minor version increase of the Linux kernel breaks the "#include" directives of external programs (such as out-of-tree device drivers), because items are moved between headers or some headers disappear and other headers appear.
That makes sense, I guess this was not a problem for the times I needed nolibc.
I do agree that trying to extract data/logic from linux is a pain -- I've tried a few times to extract some of the eBPF verifier handling, but end up pulling most of the kernel along.
Unikraft aims to offer a Linux-compatible environment (so it feels familiar) with the ability to strip out unnecessary internal components in order to improve both boot-time/runtime performance and operational security.
Why would you need a memory allocator and garbage collector if you serve static content? Why would you need a scheduler if your app is run-to-completion?
Linux gives you the safety-net of generality and if you want to do anything remotely performant, you by-pass/hack it altogether.
In the article, Unikraft cold-boots in 150ms in an emulated environment (TCG). If it was running natively with virtualization hardware extensions, it can be even shorter, and without the need for snapshots which means you don't need to store this separately either.
Unikraft is cool, I still have it in my 'todo' list to play around with sometime.
Linking the app with the 'kernel' seems pretty nice, would be cool to see what that looks like for a virtio-only environment.
Just wanted to point out that the 150ms is not snapshot based, you can get <10ms for small vms (128MB ram, 2GB ram moves you to ~15ms range), for 'cold' boots.
I think "in a VM" was elided. It's easy to tune qemu + Linux to boot up a VM in 150ms (or much less in fact).
Real hardware is unfortunately limited by the time it takes to initialize firmware, some of which could be solvable with open source firmware and some (eg. RAM training) is not easily fixable.
And most importantly and TFA mentions it several times: stripping unused drivers (and even the ability to load drivers/modules) and bloat brings very real security benefits.
I know you were responding about the boot times but that's just the icing on the cake.
yeah, I've tried their 24" 4k monitor, was okay, but not great, so returned.
24" is the max size I can tolerate with short-sightedness, but avoid using glasses for the monitor.
It's an interesting idea. I'm butchering TCC (tiny c compiler) for a side project/experiment, and using arenas sped it up 2x. This of course requires the memory limit to be specified in advance, but for my situation that's fine.
IMO eBPF is best viewed as a mechanism that allows you to load "arbitrary" code in specific kernel paths, while guaranteeing that the kernel won't hang or crash.
That's it. Though I said "arbitrary" because the program has to pass the verifier, which limits valid programs to ones where it can make the stability guarantees.
Do you mind elaborating more about the use case? Postgres itself is heavily engineered around OS process boundaries for both correctness and resiliency.
I'm not sure it'll be a serious project, but the main goal is to use it in CI or dev, where setting up postgres is kind of a pain.
I got it to work already by setting up the global context in single-user mode (like postgres --single) and exposing bindings for SPI operations.
Yesterday night I got extensions working, but as this project builds as a static archive, the extensions also have to be part of the build. Both plpgsql and pgvector worked fine.
The bigger challenge is dealing with global state -- comparing the pre-start and post-shutdown state of the process memory, about 200 globals change state. Been slowly making progress to get restarts working
I've had this project idea in my list for a while, I even implemented thr software side (an option rom for the pci card) but the hardware side is quite difficult to get started. My plan was to get an FPGA with a hard pci core to do this, but I don't even know what to buy.
I got a cheap Tang Mega 238k but I never managed to even get the PCI examples working (and couldn't even adjust BAR settings)