I’ve long since been a die-hard BeOS fan and have been running the open-source recreation Haiku for many years. I think it’s interesting to explore the “alternative OS” world and consider some great ideas that for whatever reason never caught on elsewhere.
The way Haiku handles package management and its alternative approach to an “immutable system” is one of those ideas I find really cool. Here’s what it looks like from a desktop user’s perspective – there’s all the usual stuff like an “app store”, package updater, repositories of packages and so on:
It’s all there and works well – it’s easily as smooth as any desktop Linux experience. However, it’s the implementation details behind the scenes that make it so interesting to me. Haiku takes a refreshingly new approach to package management: Despite the user experience “feeling” like a traditional package manager – say, something like apt
or dnf
– it has seamless support for:
- Immutable system directories
- Rollback to previous states
- User-managed packages separated from system packages
And a whole bunch of infrastructure and tooling to support multiple package repositories, building packages from source and more. As a geek, I find it beautifully elegant and an idea that I’d love to see other platforms exploring.
Let’s take a closer look, starting with how Haiku handles the split between “system” and “user” directories.
Running a df
command from the Haiku shell (BASH is the default, but others like ZSH can be easily installed) shows the following:
~> df -h
Mount Type Total Free Flags Device
----------------- --------- --------- --------- ------- ------------------------
/boot bfs 232.9 GiB 219.6 GiB QAM-P-W /dev/disk/scsi/0/0/0/0
/boot/system packagefs 4.0 KiB 4.0 KiB QAM-P--
/boot/home/config packagefs 4.0 KiB 4.0 KiB QAM-P--
In Haiku, the root /
is a ram-based virtual filesystem set up by the kernel when it’s booted. All other filesystems and devices are mounted under /
, so /boot
refers to the entire boot volume – and not a boot partition as is the case with e.g. most Linux installs.
The /boot/system
mountpoint is essentially the system directory which makes up the Haiku OS and installed applications. In the root directory, there are a bunch of symlinks that point there for convenience:
~> ls -l /
total 6
lrwxrwxrwx 1 user root 16 Feb 13 14:18 bin -> /boot/system/bin
drwxr-xr-x 1 user root 2048 Mar 31 2021 boot
drwxr-xr-x 1 user root 0 Feb 13 14:18 dev
lrwxrwxrwx 1 user root 25 Feb 13 14:18 etc -> /boot/system/settings/etc
lrwxrwxrwx 1 user root 5 Feb 13 14:18 Haiku -> /boot
lrwxrwxrwx 1 user root 26 Feb 13 14:18 packages -> /boot/system/package-links
lrwxrwxrwx 1 user root 12 Feb 13 14:18 system -> /boot/system
lrwxrwxrwx 1 user root 22 Feb 13 14:18 tmp -> /boot/system/cache/tmp
lrwxrwxrwx 1 user root 16 Feb 13 14:18 var -> /boot/system/var
So we can access e.g. /boot/system
as /system
and so on. Note that this mount point is backed by packagefs
– this is provided by a virtual filesystem that presents a merged view of all the packages installed. It’s sort of like an overlay filesystem (commonly used by container runtimes) in the Linux world.
This mount-point is read only:
~> touch /system/test
touch: cannot touch '/system/test': Read-only file system
But we can however write to anything in our home directory, which ensures a clean separation of system and user data/configuration.
NOTE : Due to its BeOS ancestry, Haiku is not currently a multi-user system so there is only one /boot/home
directory and the user is effectively the sole administrator account. As I understand it, the scaffolding is present to support multiple users, but it won’t be a priority until after R1 is released. However, this opens up the later possibility for packages to be installed and configured on a per-user basis.
There’s a great overview of how all these components fit together in the developer documentation, but here’s my lay-persons understanding of it…
Haiku has many packages available, ranging from system components, development libraries and end-user applications. There’s even recent ports of Wine, LibreOffice and KDE Applications. These are available as .hpkg
files which are placed in a special packages
directory, and the packagefs
service mounts the contents into e.g. the /boot/system
mountpoint.
Unlike traditional package management tools, the contents of the package are not unarchived and copied into the filesystem; When you’re looking at /boot/system
, you’re essentially looking at a collection of multiple packages and their contents, all dynamically mounted and made available on-the-fly as a read-only, virtual filesystem.
This is why /boot/system
is read-only: It’s not a “real” filesystem and only exists as a virtual union of all the different packages that are activated at that point in time.
NOTE : There are some exceptions to this, as some directories such as packages
, cache
, var
etc. are writeable. There are called “shine-through directories” which reside on the underlying BFS volume. You can read more about these in the developer documentation. And while we’re geeking out, BeFS itself is definitely also worth investigat