|
Abstracting away the parts that are Plan-9-implementation-specific, this article seems to be advocating replacing shared libraries with remote procedure calls / a network API, or more fundamentally, calls that can cross address spaces. It's worth nothing that this was an approach that, as I understand it, predated the advent of shared libraries on UNIX. Terminal handling (termios) and the X Window System protocol both come to mind, and we've been slowly moving away from that at least for X (libGL, Wayland/Mir, etc.). It's also strongly reminiscent of Mach's approach of message-passing between daemons, which was a decent idea, but ultimately failed because of performance. There are definitely advantages to address-space isolation: an unintentional mistake in one component is much less likely to affect the other, the two components can pull in conflicting versions of dependencies, etc. But versioning and ABI compatibility remain issues. I think this post briefly touches on the versioning problem and assumes that providing both the old and new version of the library-daemon would solve it: that's probably technically true, but you'd need to keep every version of the library around to avoid the problem of libc introducing bugs in the process of fixing other bugs (the only concrete problem mentioned here). So yes, there's definitely more flexibility to solve problems than in the current implementations of dynamic linkers, but the problems themselves remain hard. Meanwhile, you've also introduced the difficult constraint that libraries have to operate on copies of all your data. The hypothetical crypto library here is copying every block of ciphertext over an inter-process call, decrypting it, and copying it back to the original program. Apart from making security folks generically twitchy at all the copies of secret data running around, this is going to be awful for performance. And each side either has to trust the other side not to be trying to exploit it (which reduces the benefits of address-space isolation), or verify the data structures' integrity (which makes things even slower). It's possible that with good implementations of cross-process shared memory and low-overhead, secure message encodings (like Cap'n Proto), you could make this better, but it'll be a bit of a project. I'm happy to admit that the implementations of dynamic linking are all less than awesome. Fundamentally, there's no reason that you can't design a shared-library system with all of the properties in this design, including the ability to load two copies of the same library that differ only by minor version, to satisfy dependencies of two different components. Even the current GNU linker (which is not my favorite dynamic linker) supports symbol versioning, so it could offer both the GLIBC_2.18 and GLIBC_2.19 versions of a function in the same library, although this facility isn't used very much. |