Re: Formulating a newbies overview of how applications are packaged for use in rump kerrnels

  • From: Antti Kantee <pooka@xxxxxx>
  • To: rumpkernel-users@xxxxxxxxxxxxx
  • Date: Fri, 19 Jun 2015 15:49:18 +0000

On 19/06/15 01:40, Andrew Stuart wrote:

There is no support for shared libraries.

OK so I’m going to need to better understand some basics here. Does this mean
the only sorts of applications suitable for running on a rump kernel are those
that can be statically compiled? Or am I just misunderstanding what libraries
are? I had thought all libraries were “shared libraries”. Is iot correct that
most *nix applications use a bunch of libraries to get their job done?

I don't know how to answer that in a short way, so I'll answer it in a long way.

First, let's not confuse "rump kernel" with "rumprun".

So, in the beginning of Unix, libraries were statically linked into applications. That meant if you ran n applications which used the same library, the same code was loaded into memory n times. Then someone probably discovered a mainframe technology from the 1880's which enabled libraries to work by loading them into memory -1 times. Since they were Unix folk, they couldn't quite get it right, and ended up with shared libraries which had to be loaded into memory once. After a shared library is mapped into memory system-wide once, all applications in different address spaces using that library share the same physical memory for the library.

You probably already spotted that sharing memory between address spaces doesn't make too much of a difference when you have only one address space. Memory mapping files is not supported either, because rump kernels don't do virtual memory -- yes, rump kernels, not rumprun, since file system operations go through the rump kernel. (rumprun "theoretically" does support virtual memory, though especially on i386 it's more theory than anything else)

Besides being able shared code pages between applications, shared libraries are also associated with the dynamic linker's dl*() interfaces, which allow to dynamically load and unload libraries at runtime, as well as perform some queries about the symbols the libraries provide. Unlike the property of sharing code pages, which is invisible to the application, this interface is used by a number of applications. One could argue that it should always be possible to compile code statically. Unfortunately, some systems which like running after the latest trends campaigned about 10 years ago that nobody could ever need static linking anymore and removed support for it entirely.

So, a bunch of applications were written for the 2000's Solaris/Linux/etc. everything-is-dynamic fad and unconditionally require dl*(). What to do about them? We could build some tables at compile-time, statically link everything, and then pretend that we have a dynamic linker (which wouldn't link anything). It probably wouldn't be too many days of work, though there are some intricacies, as supporting dlsym(RTLD_NEXT). However, I'd rather see upstream applications supporting static link mode than try to pretend that we're doing something we're actually not.

The one advantage that actually supporting dlopen() could bring is being able to respond to various inputs without having to keep unnecessary code wired in memory. That said, it seems like something that would add too much complexity for the benefit. Just run another unikernel to handle that different work.

A few weeks ago I did say that rump kernels support loading and linking kernel modules at runtime (which, I stress, are not loaded and linked via the dlopen() interface). How come? Isn't that against the simplicity principle? Yes. Let's call it a mistake from my crazy days of youth.

Is the python34m runtime a shared library? For example are there any sort of
libraries in the case of what you have just done here:

libpython3.4m.a, as the name indicates, is a static library. python is also explicitly configured with --disable-shared.

That said, I have no idea about the rest of the stuff that python builds. I didn't feel particularly interested in trawling through 100MB of the python/lib installation given that everything just worked.

Other related posts: