A Programmer in King Arthur's Court

Occasional commentary about software, software construction, and the business of software.

Friday, October 12, 2007

Mount Namespaces in Linux

Some guys from IBM wrote an excellent article on Mount Namespaces in Linux. It does a great job illustrating what can be done with these particular legos. I happen to think that the legos are oddly shaped, and the one called "Kernel" is rather a lot larger and more complicated than the rest, but that's not the fault of the authors.

One day, I still think that the file system as we know it will go away. It has to. It's an outmoded idea. It was great in its time. People who used computers needed a way to organize their information, and people who programmed them did too, and many times those were the same people, so the system had to make lots of sense from both perspectives at the same time.

These days, most people's only concern for the filesystem is that they need access to their programs and data. Ok, it sounds circular; the filesystem provides that. The problem is that it provides so much more. I'll give you an example. Most people don't care about shared libraries. They are an implementation decision that doesn't show at the level of the keyboard and screen. Therefore, if the (end) user's view of the filesystem includes shared libraries, then the filesystem is wrong. On the other hand, if it doesn't include these things, then none of the programs work.

You could propose to rename /lib as /.lib, but that misses the point. People with a little too much knowledge would still be able to peer in the back window. This particular bucket of bits must be hidden entirely from the view of the casual user as well as the power user in casual mode. And it's not only this particular bucket. But just because they can't see it doesn't mean they should not be able to use it.

The typical Linux distribution puts a lot of stuff in /bin and /usr/bin. It's not categorized in any way. This inspires people to write and use package management software like RPM and APT. These tools are doing a necessary job which the filesystem itself is incompetent to perform. But because these tools are not the filesystem, it is possible for them to lose synchronicity with the filesystem. This happens if, for example, someone installs a tarball.

Desktop environments tend to offer menus for most major actions. As a result, a Linux user could go years without ever accessing the command prompt. But if a software developer wants to put his application on the menu, then he must learn the techniques for KDE and GNOME and whatever else he wishes to support, or else rely on vendors or users to perform the integration manually. This typically involves knowledge of the filesystem, which is unacceptable for end users and undesirable for vendors.

The development community needs a single standard way to make things show up in all the right places and none of the wrong ones. The administration community needs a way to explicitly control who can do what. The end user community must be insulated entirely from the mechanism. The tree-model hierarchical filesystem does not offer that. It cannot and it will not.

The namespace mounts in Linux begin to approach this goal. They provide a way for the administrator to control information sharing while allowing information sharing to take place. Hoping and praying and waiting won't bring an automagical desktop tool for these actions, though there may be one by the time this article reaches your eyes.

There are any number of partial solutions. Some advocate standardized directory layouts and such. This merely shifts the problem to picking a good standard, which is arguably the wrong problem. Others point out that two choices (KDE vs. Gnome, Linux vs. Windows, C# vs. Java, etc.) are enough to give people a feeling of freedom, so all is not lost. Developers merely have twice the work in any given domain. But many of them won't do it, and rely on volunteers to do the icky work involved in packaging a subsystem for distribution.

Perhaps the future holds only a conglomeration of partial solutions which will forever approach or orbit the ideal, but I'd like to share my vision of the ideal.

The first part is to eliminate the distinction between a user and a process. The user is a special process that happens to be mostly implemented in meat-ware. The "user interface" is really just a very special RPC mechanism for communicating with the human. One aspect of this is that information or transactions available on one login are automatically visible from every other, because the login is just a way to transmit information to and from the system's model of the user. If the user logs out of everywhere, his process merely goes to sleep.

The next part blurs the distinction between a program and a process. Typically, we think of the program as the bits on disk, and the process as the bits undergoing execution. But consider a mail client and an image viewer. The mail client needs access to the user's mailbox, but the image viewer doesn't. It might occasionally be called upon to display an image recieved in e-mail, but this should be done by passing (read access to the image data) and (write access to a display window) to the image viewer. The mail client provides the image data. Under normal use, a photo organizer or web browser might pass similar pairs of rights to instantiations of the image viewer. Rights to the mailbox would given to an instantiation of the mail client by the user upon invokation. Perhaps the shell might model this by letting the user drag a shadow of the mailbox to the client of his choice, thus invoking the reader on that mailbox. The file containing the code for the reader itself might have rights to speak with the mail server (for sending mail) but the user himself needs no such rights. These rights are moderated through, and accessable only to, the binary of the mail client.

The third part is very plan-9-ish. Treat lots of things, including inter-process communication, as individual file trees. Thus, there is a forest instead of one unified tree. Each process can import and export whatever files and trees it needs, but such interfacing is always at the discretion of the user and the administrative policy. Thus, to plug Java into your web browser, drag the Java shadow to your browser's "plug-ins" panel.

The final portion of this escapade into fantasy is the idea of an execution profile. It is a template of pre-existing access connections which becomes available to an instance of a program when it comes into existence. For instance, an administrator might add port 80 to (some part of) the execution profile of his web server, which enables the server to bind that port. This profile would be stored on disk as a separate object from the server binary itself, and the profile would be linked from the startup sequence. Now, suppose that a developer wants to test something on an alternate port. He may have access to invoke the server, but not using the main execution profile. To configure his own server profile, he would draw from his private palette of ports, all numbered higher than 1024.

Finally, a program menu is just one way of viewing a collection of execution profiles. With that in mind, adding a new program to your menu becomes trivial. You simply give an execution profile to the menu. If an administrator wants a certain submenu available to all users, he gives them all a read-only handle to the folder containing the execution profiles. This doesn't let them disect the binaries, though.

As an addendum, execution profiles might reasonably be stacked, such that holes left open in one profile might be filled by another profile higher in the stack. This creates a tree-like space of alternative configurations in which to start a process, only some of which are accessable to any given user.

This is the ultimate connection back around to the original topic of this article. Mount namespaces are a form of execution profile. They can be stacked and administered. There's not necessarily a graphical tool to do it with, but that's a separate issue. But the rest of Linux is not built around the idea of frobbing trees of namespaces. That's where the userspace seems to be behind.