Bedrock Linux 1.0alpha3 "Bosco"
This page was intended to describe plans for the then-upcoming release of Bedrock Linux, 1.0alpha3 "Bosco". Bosco has since been released on 2012/12/25. The following is thus out-of-date, but is kept in case anyone is curious.
Momo's design
The current release of Bedrock Linux, 1.0alpha2 "Momo", allows
each chroot'd command to access the other clients via chroots.
Before it runs a command from a client - in a chroot - the
relevant mount points (/proc
, /sys
,
/home
, etc) in that chroot need to be set up. The
executables inside of the chroot cannot see outside of the
chroot, and so for it to run a command from another client the
chroot needs to see all of the files in the other client. To
go from one chrooted client into another client, the new
chroot/client needs to have its mount points set up as well.
This ends up creating a tree representing the client history of
every command, and every node on the tree must be set up.
Below you will find is a simple unicode art diagram to
demonstrate this concept. If the user were to log in to
Bedrock, run a shell from Debian, then run Arch's xorg, then
run Debian's xterm within Arch's xorg, the top most branch of
the tree below would be followed. Note that mounts such as
/proc
and /home
must each be set up
about fourty times in the example below.
Bedrock ↳ Arch | ↳ Arch | | ↳ Arch | | ↳ Debian | | ↳ Bedrock | ↳ Debian | | ↳ Arch | | ↳ Debian | | ↳ Bedrock | ↳ Bedrock | ↳ Arch | ↳ Debian | ↳ Bedrock ↳ Debian | ↳ Arch | | ↳ Arch | | ↳ Debian | | ↳ Bedrock | ↳ Debian | | ↳ Arch | | ↳ Debian | | ↳ Bedrock | ↳ Bedrock | ↳ Arch | ↳ Debian | ↳ Bedrock ↳ Bedrock ↳ Arch | ↳ Arch | ↳ Debian | ↳ Bedrock ↳ Debian | ↳ Arch | ↳ Debian | ↳ Bedrock ↳ Bedrock ↳ Arch ↳ Debian ↳ Bedrock
Real-world use of Momo can easily result in hundreds of thousands of mount points. Since it is not possible to predict how deep the tree will go, Momo cannot set up all of these mounts at boot. Rather, it attempts to create these mounts just before they are necessary on-the-fly. This has a number of down sides:
- There needs to be some way to detect whether or not a node on the tree has been set up or needs to be set up. In Momo, this check can easily take over a third of a second on relatively powerful hardware. An experimental branch of Momo has managed to significantly reduce this to hundredths of a second, although it did so with some potentially risky strategies.
- If a user runs commands differing clients in rapid succession (such as in the example describing a potential case for the top branch of the unicode art diagram above), the background mounting will fall behind and require a very noticeable delay. While this has been reduced in the aforementioned experimental branch of Momo, there can still be substantial amounts of Bedrock-specific delays in common situations.
-
The list of mounts (
/proc/mounts
) can become huge, with hundreds of thousands of lines in real-world situations. This not only causes some RAM overhead, but also makes managing non-Bedrock-specific mounts difficult. - It is difficult to cleanly remove any given client live as the client could be a node through which other clients' commands are running. It is quite possible to disentangle a client, but it is not as clean and easy as the Bedrock developer would like it to be.
Bosco's design
The current plan for Bosco is to completely abandon this tree structure in favor of a much flatter layout, which should fix all of the issues listed above. Rather that make the files from other clients accessible from within any given chrooted client, Bosco will allow clients to break out of the chroot (and then go back into another chroot) when trying to run a command from another client. The unicode art tree above will look like this with Bosco:
Bedrock ↳ Debian ↰ ↰ ↳ Arch ↲ ↰ | ↳ Bedrock ↲ ↲
The number of times each client's mounts have to be set up is constant irrelevant of the history of the commands. All of the mounts could be created at boot, and new mounts could easily be done if a new client is added to a system live. This completely resolves the first three issues with Momo described above and could potentially assist with the fourth.
Bosco's Implementation
brc
and capchroot
will be replaced by
a C program (which will likely take brc
's name).
This program will be called whenever a user wishes to run a
command from other client. This program will do the following:
- Determine (a) which command from (b) which client is desired to be run. This might be done in a similar style to how busybox works - it will detect what is desired based on how it is called.
- If it is currently in a chroot, break out of the chroot.
- Chroot into the client with the desired program
-
Execute the desired command, passing along all of the
arguments. Rather than running the command as a child
process, it might replace itself with the command, akin to
the Bourne shell's
exec
.
This command will require two things which typically requires root (using chroot and breaking out of a chroot). If possible, rather than being completely setuid'd, the command will use Linux capabilities (similar to capchroot). Moreover, it will make several checks to ensure it avoids security issues:
- It will refuse to run if it is not owned by root.
- It will only chroot into specific directories listed in a configuration file with a hard-coded path which must be owned by root.
- It will only run commands from specific directories listed in in the aforementioned configuration file.
Rather than having the BRPATH
contain many small
scripts which call brc
, it will be structured such
that a sub-directory for every client which contain symlinks
(with the name of the executable desired to be run) which point
the new brc
. brc
will detect how it
was called and run the desired command accordingly. For
example:
/usr/local/brbin/arch/startx → /opt/bedrock/bin/brc /usr/local/brbin/bedrock/busybox → /opt/bedrock/bin/brc /usr/local/brsbin/debian/gparted → /opt/bedrock/bin/brc
brp
will create this structure, just as it created
the equivalent structure in Momo.