2.2 Startup Sequence

Startup runs to completion before loregd accepts a single request. Any failure in it is fatal: loregd logs the error and exits non-zero rather than serving a hive it could not fully prepare.

2.2.1 1. Parse and validate arguments #

Extract the hive name to database path mapping and apply the validation in §2.1.

2.2.2 2. Open each hive database #

For each declared hive, create the database file's parent directory if it is absent (mode 0700), then open — or create — the SQLite database at that path. Registry hives can contain credentials and security policy, so the fallback directory is private to the service. A packaged system normally receives the same protected directory from the dev.peios.loregd package, but a first boot onto an empty /var/state still works without anything having prepared it.

Four pieces of connection state are established immediately:

  • PRAGMA journal_mode=wal. The result is read back and checked; if the database does not report wal, the open fails. WAL mode is what allows concurrent readers alongside a writer (§4.1), so silently running without it is not acceptable.
  • PRAGMA foreign_keys=ON. Neither schema declares a foreign key, so this constrains nothing.
  • PRAGMA busy_timeout=0 — SQL lock conflicts return busy immediately (§4.4).
  • The volatile database is attached (§3.3).

Each database/sql handle is limited to a single underlying connection.

2.2.3 3. Attach the volatile store #

Each hive gets a fresh tmpfs-backed SQLite database, attached as volatile and put in WAL mode with private caches. Before opening hives, loregd protects and locks /run/loregd, verifies tmpfs, and removes old volatile stores left by a crash (§3.3). It never reuses a prior process's volatile data.

2.2.4 4. Establish the schema #

If the database has no schema_version table, it is new: loregd creates the persistent tables, creates the volatile tables, and stamps the schema version, in one transaction.

If the version is present, it is compared against the version loregd supports. A newer version aborts startup, and so does an older one (§3.1).

2.2.5 5. First-boot root key #

For each hive, look for a key with no parent. If none exists, this is the hive's first boot: loregd generates a random 16-byte GUID for the root key, builds the default hive-root security descriptor, and inserts the root key record.

The default root descriptor grants SYSTEM and Administrators full access to the key, grants Authenticated Users read access, marks all three as container-inheritable, and sets both owner and group to SYSTEM.

2.2.6 6. Crash recovery #

SQLite's own WAL recovery handles any transaction that was uncommitted when the process died; it happens when the database is opened and needs nothing from loregd.

What loregd does on top of that is clean up orphaned keys — key records that no path entry in any layer points at. These can survive a crash between a key's creation and the creation of the path entry naming it. In one transaction, loregd deletes the values belonging to orphaned keys, then their blanket tombstones, then the key records themselves.

The hive root is exempt: it legitimately has no parent and no path entry pointing at it, so orphan detection skips keys whose parent_guid is null.

2.2.7 7. Compute the maximum sequence number #

For each hive, take the maximum sequence across the path entries, values, and blanket tombstones — in both the persistent and the volatile tables — then take the maximum across all hives. That single global figure is what loregd reports at registration, so the kernel can resume allocating sequence numbers above everything already stored.

In practice the volatile tables are empty at this point in startup and contribute nothing.

2.2.8 8. Open the registry device #

Open /dev/pkm_registry. The kernel requires SeTcbPrivilege in the calling thread's token to permit this; loregd performs no check of its own and relies on the kernel to refuse.

Before registration, negotiate RSI lifetime extension version 1 with REG_SRC_NEGOTIATE. Retain the returned source-session identifier for request contexts and lease renewal. A kernel without this extension is incompatible; startup fails before registering hives instead of silently changing lifetime semantics.

2.2.9 9. Register the hives #

Issue REG_SRC_REGISTER with every hive name, its root key GUID, and the global maximum sequence number from step 7. The registration flags are zero: loregd registers global hives only and never private ones.

2.2.10 10. Signal readiness and serve #

Send readiness to NOTIFY_SOCKET if it is set (§2.1), install the termination signal handler (§2.3), and enter the request loop (§4.2).

2.2.11 Backup and repair limits #

The source-checked implementation at 3cb9768 (1 October 2026) does not create an automatic backup at startup. The startup caller opens each hive; hive initialization prepares its database, schema, root, orphan cleanup and reader pool. The orphan cleanup is a transaction deleting unreferenced persistent records, not backup restoration or a database-corruption repair facility.

WAL recovery and RSI_FLUSH checkpointing do not create a backup copy. Separately, loregd supports read-only RSI snapshot transactions used by higher-level backup operations. A transaction snapshot is not an automatically saved startup backup. See the LCS backup contract for that separate operation; this startup behavior does not establish an end-to-end offline repair or restore procedure.

Verify the existence and coverage of a recovery copy rather than assuming startup made one. The command-line limits also rule out the previously described loregd repair switches for this implementation.

Edit this page