MMotor OS
System

Filesystem

Motor FS is the default filesystem since June 2026. It is a journaling filesystem served by sys-io, with three-role permissions on every entry, advisory locks, and no notion of users, links, or numeric Unix modes.

Motor FS

The implementation is src/sys/lib/motor-fs (about 10,000 lines) on top of async-fs, an abstraction that also runs on a Linux host so that images can be built and tested there. Rust's std::fs works as expected on top of it, with the permission model below showing through Permissions.

Image layout

DirectoryPurpose
/system/binSystem commands: rush, sysbox and its command scripts, ripgrep, curl (developer image). Commands initially deny write access to every role.
/system/servicessys-init, sys-tty, strobe, russhd, dns-resolver.
/system/cfgConfiguration: sys-init.cfg, sys-net.toml, sshd.toml, rush.cfg, libc/ (hosts, resolv.conf), ssl/.
/system/logsService logs written by strobe. Interactive may read them; None cannot enter the directory.
/system/tmpScratch space for every role.
/user/binUser programs: red, rmux, kibim, httpd, httpd-axum. Interactive may install programs here.
/user/cfgInteractive configuration and credentials (red, rmux, kibim, gears, lorry). Hidden from None.
/user/tmpScratch for every role and the default TMPDIR.
/devtoolsDeveloper image only: bin, llvm, rust, lorry, tests, www, and the writable src and tmp trees.

Permissions

A Motor FS mode is three permission triplets in System, Interactive, None order; rw-r----- gives System read and write, Interactive read, and None nothing. Each triplet is one of rwx, rw-, r-x, r--, or ---, and permissions are monotonic across roles:

None ⊆ Interactive ⊆ System

sys-io learns the role of each client once, when the client connects, by asking the kernel for the peer's capabilities; it never trusts a role sent by the client.

Changes also need CAP_FS_WRITE. Without it a process can stat, read, and list what its role allows, and every other request fails with PermissionDenied, file locks included. The capability never overrides the permissions above: a change needs both. See Capabilities.

What an image ships with

Images are built with a declarative policy, src/imager/motor-os-permissions.yaml, that assigns a mode to every destination by the longest matching tree, with exact entries for two secrets. Smaller images omit trees; they never relax a mode. The main rules:

TreeDirectoriesFilesScriptsELF
defaultrwxr-xr-xrw-r--r--rwxr-xr-xr-xr-xr-x
/system/binrwxr-xr-xrw-r--r--r-xr-xr-xr-xr-xr-x
/system/logsrwxr-x---rw-r-----r-xr-----r-xr-----
/system/tmp, /user/tmp, /devtools/tmprwxrwxrwxrw-rw-rw-rwxrwxrwxr-xr-xr-x
/user, /user/bin, /devtools/srcrwxrwxr-xrw-rw-r--rwxrwxr-xr-xr-xr-x
/user/cfg, /devtools/lorryrwxrwx---rw-rw----rwxrwx---r-xr-x---
/devtools/binrwxr-xr-xrw-r--r--rwxrwxr-xr-xr-xr-x

/system/cfg/sshd.toml and /system/cfg/ssl/ssl-key.pem are rw-r-----: readable by the Interactive services that need them, invisible to None. With the initial modes, Interactive cannot create a new top-level directory or replace /system; it can edit a launcher script in /devtools/bin in place but not add or remove entries there; only System can create or rotate files in /system/logs.

The imager classifies each source file by its host execute bit (a host-executable file must be a #! script or an ELF executable, anything else is rejected), resolves every mode before it creates the image, and creates non-writable files through a staging step so that a shipped ELF is never writable and executable at the same time during image construction, even during image construction. An image description that does not name a policy does not parse.

Files created at run time

For offline changes, see imager chmod and imager resize. These host commands edit an image's permissions or copy it into an image with a different data-partition size.

Locks

Advisory file locks (std::fs::File::lock, lock_shared, try_lock, unlock) are served by a lock manager in sys-io, keyed by connection, with at most 64 queued waiters per connection. A lock is released when the file is closed or when its owner's connection to sys-io goes away. After wait() or try_wait() reports process completion, its locks no longer block other clients: acquisition checks disconnected owners even if the connection cleanup task has not run yet. Under memory pressure, releasing a lock is the one filesystem request that is still served, so that waiters queued before an episode are not stranded.