- Rust 99.7%
- Linker Script 0.3%
| .github | ||
| src | ||
| .editorconfig | ||
| .gitignore | ||
| .markdownlint-cli2.yaml | ||
| ARCHITECTURE.md | ||
| Cargo.toml | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| linker.ld | ||
| README.md | ||
| ROADMAP.md | ||
| rustfmt.toml | ||
| SECURITY.md | ||
logd
logd is the centralized in-memory logging service for EriX.
EriX is a clean-room, capability-based microkernel operating system written entirely in Rust.
Technical requirements are tracked in the EriX requirements, conventions, and project documentation.
See:
- docs for design documents, specifications, and development plans.
- Related architecture repositories for kernel, services, libraries, drivers, and integration tooling.
Purpose of This Repository
This repository implements the EriX log service daemon. Its purpose in EriX is to provide the log service role through explicit IPC and startup authority.
Functionally, it implements the daemon runtime, state model, IPC handling, and validation tests. The repository keeps the implementation, interface contracts, tests, and documentation for that behavior in one reviewable ownership boundary.
The maintained responsibilities are:
- implement the log service runtime and state model
- validate startup authority before accepting IPC requests
- handle bounded service operations through the assigned endpoint set
- keep service behavior, tests, and authority invariants documented
Clean-Room Policy
EriX follows a strict clean-room philosophy:
- No external source code may be copied.
- No external Rust crates are allowed.
- No code generation tools that embed third-party code.
- All code must be authored within the project.
Violations will result in rejection of the contribution.
License
All EriX repositories are licensed under the ISC License.
Development Model
EriX development is modular, deterministic, reproducible, authority-explicit, security-first, and self-hosting oriented.
This repository follows the project roadmap and the validation rules documented in its own roadmap.
Runtime feature model
logd-runtime: core daemon behaviorlogd-runtime-phase1-logging: base logging contract enablementlogd-runtime-phase1-time: timestamp source fromtimedlogd-runtime-phase3-serial: mirror appends toserialdlogd-runtime-phase3-framebuffer: mirror appends to bothserialdandfbcond
Integration aliases (logd-integration-*) map to the same runtime behavior,
with optional force-fail test injection in dedicated test modes. Feature-matrix
builds are expected to stay warning-free across the phase1-only and
framebuffer/serial variants of this append path. The readiness priority set
follows the current VFS marker names, including ERIX_ROOTD:READY:RAMFSD,
ERIX_ROOTD:READY:KEYD, ERIX_ROOTD:READY:E2FSD, and ERIX_ROOTD:READY:FATD,
and also treats the configured ERIX_DEVICED:READY:* driver startup restamps as
framebuffer priority records. Log replay no longer depends on the old
provider-specific ready label and keeps filesystem backend plus driver readiness
visible on fbcond.
Startup accepts a zero primary control slot in v1. In that peer-only mode,
logd still serves append/read IPC and peer-service mirrors, but direct
kernel-backed legacy sinks stay disabled until explicit authority exists. The
normal startup path now validates actual local endpoint/transfer slots through
caller-local capability introspection before readiness. Direct-output sink
routing is now explicit-only: logd uses deterministic local sink slots only,
preferring any startup-wired peer cap already present in those slots and
otherwise relying on explicit named lookup materialization instead of guessing
foreign slot numbers. Peer-only late sink resolution still performs the real
named materialization request when the local slot is empty; an empty sink slot
is no longer treated as something to poll until another actor fills it
out-of-band. Timed direct-sink calls now preserve one in-flight ipc_call and
poll its reply buffer on RETRY/BUSY instead of stampeding seriald,
fbcond, or timed with fresh calls before the first reply arrives. The
critical rootd framebuffer markers (ERIX_ROOTD:READY:FBCOND and the later
rootd-fb-mirror verification append) now resolve fbcond immediately, refresh
a live fbcond materialization even if logd cached an older one earlier in
boot, and bypass any older deferred framebuffer backlog for those appends. When
named only reports the seeded registry identity instead of the requested local
slot materialization, logd now treats that as an incomplete handoff and
retries on later service-loop turns instead of burning the full retry budget
inline. Occupied requested local materialization slots are explicitly dropped
before retry so stale sink caps cannot leave named replies stuck on
transfer-destination BUSY, but empty slots now skip that rootd cleanup RPC so
idle fbcond replay can still reach named under boot load. The
rootd-fb-mirror probe also bypasses the broader ready-stamp direct-output gate
and now runs through APPEND_NO_KERNEL|INTERNAL_ONLY, so rootd can validate
framebuffer continuity without waiting on a redundant serial fan-out after the
serial console has already been verified. Those internal-only framebuffer-only
appends now use a bounded hybrid path: ERIX_ROOTD:READY:FBCOND still gets the
inline refresh/write attempt against a freshly resolved fbcond endpoint, while
the later rootd-fb-mirror verification probe first runs a bounded inline retry
loop that re-resolves fbcond with the reply-aware transport and retries the
direct write before it falls back to the priority-deferred framebuffer queue, so
the verification append no longer depends on a later idle turn just to populate
the sink slot. That transition path still skips synchronous seriald
materialization for those framebuffer-only internal appends, so rootd's
framebuffer verification cannot wedge behind an unrelated late serial sink
lookup. That includes the earlier ready-transition resolver and the deferred
ERIX_DEVICED:READY:* handoff path, so the rootd-fb-mirror append reply
itself stays off the serial materialization path. The fbcond-side
ERIX_DEVICED:READY:* restamps from rootd stay on that framebuffer-only path
as prioritized records as well, so bootstrap does not spin on non-critical
driver-ready mirrors through seriald while fbcond finishes switching from
startup reply handling to its runtime receive loop. Idle framebuffer replay now
retries fbcond materialization once per service loop turn before pumping
deferred mirrors, so a transient miss during the original append path does not
strand the queued rootd-fb-mirror probe until some unrelated later request
happens to re-enter the direct-sink resolver. After a caller-facing append reply
has been sent, logd now performs one bounded post-reply framebuffer
maintenance turn immediately only when a priority framebuffer record is queued.
Ordinary deferred framebuffer backlog still drains on later receive-idle turns,
so priority verification mirrors can resolve and drain before rootd scans
fbcond's retained stream without making later append replies inherit unrelated
framebuffer replay work. Those late sink transitions now keep consuming
readiness markers even after the kernel route has already been locked, so
ERIX_ROOTD:READY:FBCOND can still arm deferred framebuffer replay on peer-only
boots that have already switched away from the kernel mirror. Late
seriald/fbcond sink resolution is now single-attempt per service-loop turn
so the outer sink policy still owns retry scheduling, but transfer-bearing
named materialization now keeps one bounded in-flight reply alive for direct
seriald resolution and for the early ERIX_ROOTD:READY:FBCOND refresh. That
lets late lookup replies deliver the transferred sink cap before rootd reaches
the later framebuffer continuity append, instead of turning named resolution
into an unbounded inline retry loop. Only the direct seriald/fbcond/timed
sink transports and those bounded transfer-bearing named materializations poll
in-flight replies; other named lookups still return immediately. The
rootd-fb-mirror verification append now performs bounded inline retry against
the reply-aware fbcond resolution/write path before it falls back to the
priority-deferred framebuffer queue. When fbcond is already materialized,
logd still makes the reply-boundary drain attempt before returning to the
caller. When the slot is still empty, or the bounded retry still misses, the
append reply is released and the queued verification probe is left for the next
idle sink-maintenance turn to materialize and flush. Late named sink
materialization is only cached after the requested local slot actually contains
a cap, so reply metadata alone cannot wedge logd on an empty fbcond slot.
Previously materialized sink slots are now retained only while runtime state
already points at that slot and a fresh local-cap query still reports an
endpoint with SEND. Raw slot occupancy alone is no longer enough to revive
seriald or fbcond sink authority, so stale or mis-materialized caps cannot
linger as residual runtime authority. seriald materialization is now held
behind both ERIX_ROOTD:READY:SERIALD and ERIX_DEVICED:READY:DRV_SERIAL, so
peer-only logd startup cannot spin on an empty local seriald slot before the
runtime path is actually live. Idle serial endpoint prewarming is now further
restricted to turns that actually have queued serial replay work, so
framebuffer-only verification traffic cannot get stranded behind best-effort
seriald lookups when there is no pending serial mirror backlog to flush.
Framebuffer direct-sink calls now use the normal sink-call timeout budget and
perform one final in-flight reply decode before returning RETRY, so a single
RETRY from fbcond on loaded single-vCPU boots does not drop the mirror.
logd also sizes its local named transport buffer for transfer-bearing lookup
replies, and leaves any retry/busy handling to the outer per-turn sink
resolution policy instead of spinning inside the transport helper. That keeps
lazy sink activation from monopolizing the service loop when named
registration is still settling. Idle sink maintenance now runs only on
receive-idle turns, not immediately after every replied request, and each idle
pass performs only one bounded sink action before returning to recv, so late
sink materialization cannot starve unrelated append traffic during busy boot
bursts. That action surface is stable across feature subsets: Phase1-only builds
keep the same idle-maintenance enum and route unavailable Phase3 sink actions
through the existing no-op helpers instead of compiling a narrower runtime match
surface. Immediate retry appends of ERIX_ROOTD:READY* and
ERIX_DEVICED:READY* markers are deduplicated, and the terminal
ERIX_ROOTD:READY append is kept eligible for deferred serial replay if serial
provider activation lands after the final rootd append.
ERIX_DEVICED:READY:DRV_SERIAL is emitted only after the provider-registration
RPC has unwound, so the first canonical marker can follow the normal
direct/deferred seriald sink path. When rootd later restamps the runtime
driver-ready tail for framebuffer continuity, logd accepts those
ERIX_DEVICED:READY:* lines on the internal fbcond-only append route instead of
re-fanning them synchronously through seriald. Later ERIX_DEVICED:READY:*
markers are likewise queued for post-reply serial replay when needed so deviced -> logd -> seriald cannot recurse back into a still-blocked deviced provider
lookup.
Build and test
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test
Governance Principles
logd governance is scoped to bounded system log collection and retrieval.
The scoped governance rules are:
- It accepts log records only through authorized logging IPC.
- It keeps storage bounded and deterministic so log traffic cannot exhaust service memory.
- It preserves ordering and readback behavior expected by diagnostics and tests.
- It does not receive authority to control reporting services or callers.
Authority Boundaries
logdoperates only through startup-assigned service capabilities.- New authority must be represented in bootstrap/capability validation and integration tests before use.
Contact
Development occurs in EriX organization and discussions happen in issues and design documents.
No decisions are considered valid without documented rationale.
Maintainers can be reached via email: admin@erikinkinen.fi.