Traditional Unix systems have a rather static view on the filesystem. The root directory is always there and regular users never really modifies anything outside their home directory and other permitted places. The root user is able to modify this base view on the filesystem through chrooting and mounting or just modifying the files, but he can’t make any big changes or the whole system breaks.
Modern Unix-like systems offer an interesting feature called filesystem namespaces. In short, they are a set of mountpoints. Each process then belongs to a namespace that governs what it sees, usually a process shares the same namespace with its parent. For instance, if the system administrator mounts a directory, other users would see the mountpoint as well. A new namespace is created by cloning an existing one. The process can then change what is mounted at /usr as it pleases without affecting the original namespace. Linux have supported for this for a while, although sadly it requires root permissions. The Plan 9 operating system introduced this feature a long time ago but embraced it into its design allowing regular users to fully control their namespace.
You can do a few things with namespaces. For instance, you could bind a directory or file at another location, thus giving it a new name (and possibly overwriting what was there in the first place, but on disk, it is not overwritten) much like a hardlink. You could even remove a file/directory from the namespace. This could be useful for webservers that if attacked, they won’t be able to even see the existence of the /home directory. And you could even bind multiple directories at the same location, thus providing the union of their contents.
Filesystem namespaces fits well into the design of Sortix. I intend to try follow the Plan 9 model for namespaces with my own changes. After all, this area is hardly standardized and I’m free to experiment with the implementation. I have to be careful, though, as namespaces can easily cause mass confusion for users if they are used in non-obvious ways. It’s better to let the users do the non-obvious usage once they learn of the feature.
What is filesystem namespaces good for? A simple usage is providing each user with their own private /tmp directory. This avoids conflicts and if documented would surprise no one. Another interesting usage is to obsolete the PATH enviromental variable. The shell could then hardcode PATH as /bin and only load programs from there. The user could then make /bin the union directory of /x86_64-pc-sortix/bin, /share/bin, /data/x86_64-pc-sortix/bin, /data/share/bin, /home/$USER/Software/x86_64-pc-sortix/bin, and /home/ $USER/Software/share/bin. This has the amazing consequence that all programs reside in /bin at runtime, just like the good old days of early Unix. The same is possible with /lib, /etc and /include. Users can then install software into their own directory and it will integrate perfectly with the rest of the system. Indeed, this also gets rid of shared library search paths as they are all in /lib at runtime.
Even more insane constructs are possible. For instance, we can create filesystem server that provides TCP connections through /net/tcp, UDP through /net/udp, and so on. Programs can then be routed to communicate through /net either by modifying them or using a patched libc. A user could then mount the /net directory of another computer on the local /net directory. Programs accessing /net would then be forwarded transparently to the /net directory of another computer, thus using its Internet connection. If we use an encrypted tunnel, we just invented a simple VPN solution.
The chroot system call could be implemented through this method: Simply create a new namespace and mount /home/$USER/my-chroot as / and we’re done.
I’m sure there are plenty of more exciting and creative uses of namespaces. I look forward to implementing this and toying around with it. In my new build system, I’ve used unionfs-fuse to simulate namespaces when cross-compiling software.