Disk layout and updates
GurtOS keeps two complete systems on disk, slots A and B, and runs from one. An update is written to the other slot, started once on trial, and kept only if the box comes up healthy. Everything that must outlive an update lives on a separate data partition. For the reasoning, read System updates. To run an update, see Update and roll back.
Partitions
Section titled “Partitions”The installer erases the disk and makes these partitions, in this order:
| Partition | Size | Partition name | Mounted at | Holds |
|---|---|---|---|---|
| BIOS boot | 1 MB | box-bios |
GRUB for machines that start with BIOS. x86 only. | |
| EFI system partition | 512 MB | box-esp (FAT label BOX-ESP) |
/boot/efi |
GRUB, its menu, and grubenv, which says which slot starts |
| System slot A | 6 GB, 12 GB on GurtOS Personal | box-a |
/ when running |
A whole system: kernel, Ubuntu base, the box service, and the desktop on Personal |
| System slot B | the same as slot A | box-b |
/ when running |
The other system. Empty until the first update. |
| Data | the rest | box-data |
/data |
Everything that must outlive an update |
| Edition | Both slots | Smallest disk | Use in practice |
|---|---|---|---|
| GurtOS Server | 12 GB | about 17 GB | 25 GB or more |
| GurtOS Personal | 24 GB | about 29 GB | 48 GB or more |
The installer refuses a disk too small for both slots, the EFI system partition and 4 GB of data.
The installer uses a blank disk straight away. It erases a disk that has anything on it only after someone types erase on the box's screen.
What lives on the data partition
Section titled “What lives on the data partition”The data partition is mounted at /data, and these paths are bind-mounted from it, so both slots see the same files:
| Path | What |
|---|---|
/var/lib/box |
The action log, workspaces and tasks (BOX_HOME) |
/etc/box |
The vault and the box's identity key |
/var/lib/spacetimedb |
SpacetimeDB's data |
/root/.config/spacetime |
The identity that owns the box's SpacetimeDB database |
/var/log/journal |
System logs, so a failed update's logs are still there after the rollback |
GurtOS Personal also keeps these on the data partition, and will not start its desktop without them:
| Path | What |
|---|---|
/home |
People's home folders |
| Network connections | Saved Wi-Fi and wired connections (NetworkManager) |
| AccountsService | Account pictures and account types |
| Bluetooth | Paired devices |
/data/update holds trial and last: the update in progress and the last result.
An update also copies into the new slot: /etc/machine-id, SSH host keys (debug builds), and the task users the core made (uids 30000 to 39999), so a resumed task keeps its uid. On GurtOS Personal it also carries people's accounts (uids 1000 to 29999), their groups, including sudo, the time zone, language, computer name and login settings.
On GurtOS Personal, software someone installs with apt, and any other change outside their home folder and the settings above, is gone after the next system update, because the update replaces the whole system.
Which slot starts
Section titled “Which slot starts”GRUB reads grubenv on the EFI system partition:
| Variable | Meaning |
|---|---|
saved_entry |
The default slot, a or b |
next_entry |
A slot to start once. GRUB clears it as it uses it. |
The running slot is on the kernel command line as box.slot=a or box.slot=b. The kernel starts with panic=10, so a kernel that panics restarts by itself after 10 seconds.
An update, step by step
Section titled “An update, step by step”box-update apply <file or URL>fetchesgurtos-<edition>-<arch>.sqfswith its.sha256and.sig.- It checks the signature on the hash against
/etc/box-os/update.pub, then checks the hash against the file. Either failing stops the update. - It formats the other slot, unpacks the image into it, and checks it holds a kernel and the box service, and that it is the same edition as the running system. A GurtOS Server image never replaces GurtOS Personal, which would lose its desktop.
- It copies the machine's identity and task users across, as above.
- It sets
next_entryto the new slot, writes/data/update/trial, and restarts. - At every start,
box-confirm.servicewaits up to 5 minutes forGET /healthon the box's API to answerok.- Healthy on trial: the new slot becomes
saved_entry, the default. The update is kept. - Not healthy: the box restarts.
saved_entrynever changed, so GRUB starts the old slot. - The new slot did not start at all: the box is already on the old slot, and the result is recorded.
- Healthy on trial: the new slot becomes
Each result is written to /data/update/last and printed on the serial console.
Update files
Section titled “Update files”image/build makes these, and the same .sqfs is both on the install disc and the update file:
| File | What |
|---|---|
gurtos-<edition>-<arch>.iso |
The install disc. Starts with BIOS and UEFI. Also runs as a live system. |
gurtos-<edition>-<arch>.sqfs |
The whole system as one compressed image |
gurtos-<edition>-<arch>.sqfs.sha256 |
Its SHA-256 hash |
gurtos-<edition>-<arch>.sqfs.sig |
The hash, signed with the build machine's ed25519 update key |
<edition> is server or personal, and <arch> is x86_64 or arm64: for example gurtos-server-x86_64.iso or gurtos-personal-x86_64.iso. Debug builds end in -debug, such as gurtos-server-x86_64-debug.iso.
box-update
Section titled “box-update”Run as root on the box. Release builds have no shell, so today this needs a debug build with SSH.
box-update status # the running slot, the other slot, the default, the last resultbox-update apply https://updates.example/gurtos-server-x86_64.sqfsbox-update apply /tmp/gurtos-server-x86_64.sqfs --no-reboot # write the slot now, restart laterbox-update rollback # make the other slot the default and restart into itbox-update confirm # what box-confirm.service runs at every startapply with a local file expects the .sha256 and .sig files beside it.
Trade-offs
Section titled “Trade-offs”- The slots are plain writable ext4. They are not read-only and not verified at boot (no dm-verity). Changes made by hand inside a running slot are lost at the next update, by design.
- A system that hangs, instead of panicking or failing its health check, stays hung until someone restarts it. A hardware watchdog would cover that; not every machine or VM has one.
- The GRUB menu on the EFI system partition is written once at install and never updated. A change to the boot menu itself needs a reinstall.
- Updates are signed with one ed25519 key held on one build machine. There is no key rotation and no rollback protection: an older signed image installs fine.
- The boot loader is not signed, so Secure Boot must be off.
Related
Section titled “Related”GurtOS is open source under the Apache License 2.0.Source code on GitHub.