GoboHide: surviving aside the legacy tree

Lucas Correia Villa Real , December 9th, 2003.

Last updated on October 14, 2006.

A little bit of history

As you might have already seen, GoboLinux adopts an alternative directory
tree. As you might also be wondering, without the legacy tree a lot of
common applications wouldn't work in GoboLinux. This document explains
how this problem is solved by the distribution and how it's solved by other
operating systems which must address the same problem. If you simply don't
want to read the entire story, click here
to get directly into the download section.

A long time ago, in a mailing list far, far away....
There was a discussion about how we could get rid of the legacy tree,
without actually removing it. We needed to keep it, but we just didn't
want to know it existed.

Inspired by MacOS, Hisham suggested that we started by modifying our "l" script
(which is a wrapper for the 'ls' command): if an entry belonging to the
legacy tree was going to be listed, then it should be skipped, and the final
listing would only show the GoboLinux hierarchy tree.

So, since all of the GoboLinux users at the time (that is, their developers)
used to use "l", this approach could be good enough.. for our shell needs.
MacOS uses an approach very similar to this: it keeps a file with the
directory names that should not be listed by the graphical interface. Their
toolkits then makes use of this file to avoid listing the legacy tree, and
everyone is happy.

Of course, since we are dealing with a great variety of window managers and
interpreters, we couldn't adopt the same solution, or we would need to have
a great job modifying every application which handled with filenames.

My suggestion was to hook these read operations directly in the root of the
problem: since every readdir() is performed by the kernel, then
we could have a list kept in kernel to check on every readdir() operation.
If the inode being read was present in this list, then it simply shouldn't be
copied onto the destination buffer, which should be returned to the user.

This first implementation was hardcoded with my own inode numbers (relative
to the legacy tree), and this was when Felipe Damasio came with his kernel
abilities and created a better interface based on ioctls in order to register
the entries that should be hidden from the userspace, and then we got our
first release of GoboHide.

From these old days until now, GoboHide has been kept up to date to the
newer kernel versions. The patch now is fully integrated with the VFS, which means
that it works with any filesystem that supports directories and/or symlinks. It has
been tested with EXT2, EXT3, ISOfs, JFFS2, JFS, NFS, ReiserFS, SquashFS and XFS, but
certainly works with others, too.

And how can I interact with this wonderful piece of ioctls?

As mentioned before, its interface with the userland is made through ioctls,
hence an application is needed to talk with the kernel. There's a tool called
GoboHide (very intuitive, isn't it?) that can do the job for you:

~] gobohide --help
gobohide: Hide/Unhide a directory
-h, --hide Hide the directory
-u, --unhide Unhide the directory
-l, --list List the hidden directories
--version Show the program version
--help Show this message

So, in order to hide a directory, one would need to run gobohide with '-h',
passing the target entry. A subsequent "ls" will not show the hidden entry,
then:

This allows one to hide an entry from the filesystem. But don't worry,
the superuser has power to ask the kernel for the entries being hidden, so
you can always be sure about what is being hidden in your system:

~] gobohide -l
Hidden directories:
/etc
/usr

And the best of it all: you can still access your files inside these hidden
entries, and even bash would tell you that files exist in these directories:

Getting and applying the kernel patches and the userspace application

The GoboHide patch is already applied by default on the GoboLinux kernel.
In case you are compiling a different kernel release, you can grab the
patches which are contained inside the Linux kernel recipe and apply the GoboHide
patch in the usual way, as follows: