Files
RedBear-OS/local/docs/dbus-interfaces/redbear-sessiond.md
T
vasilito 9f2de2a0b1 docs+build: correct version drift, mangled prose, and toolchain-version gaps
Docs:
- Baseline was stated as 0.3.1 across the canonical set while the branch,
  Cat 0/1 crates and every Cat 2 fork are 0.3.2. AGENTS.md also cited a
  sources/redbear-0.3.1/ archive that does not exist; the only archive
  present is sources/redbear-0.1.0/. Versioning examples now match the
  forks as they actually stand (redoxfs/syscall 0.9.1, libredox 0.1.19).
- Repaired 18 instances of 'immutable archived' across 8 documents, where
  a global find/replace had turned sync/synced/archived into that phrase
  and produced ungrammatical text ('never auto-immutable archived',
  '### Source immutable archived').
- Settled the apply-patches.sh contradiction empirically. Both sides were
  wrong: the GROSS WARNING blocks (x5) described it as routine
  patch-linking, and SCRIPT-BEHAVIOR-MATRIX.md said build-redbear.sh
  'never invokes' it. It is invoked at build-redbear.sh:487, but only to
  auto-repair a failed verify-overlay-integrity.sh check.
- Dropped the dangling reference to a local/AGENTS.md section
  'NO OVERLAY-STYLE PATCHES — SCOPED POLICY' that does not exist.

Build system:
- mk/prefix.mk hardcoded 13.2.0 in the limits.h removal, which silently
  no-ops after a toolchain upgrade and leaves the conflicting header.
  Version-globbed.
- Parameterized GCC_RECIPE so the from-source toolchain path is not
  pinned to gcc13.
- The three cstdlib strtold seds were not idempotent -- the shipped GCC
  13 toolchain carried that comment block 17 times from repeated
  'make prefix' runs. Each is now guarded.
2026-08-03 13:07:25 +03:00

153 lines
8.2 KiB
Markdown

# redbear-sessiond — D-Bus Interface
**Bus:** system
**Well-known name:** `org.freedesktop.login1`
**Object paths:**
- `/org/freedesktop/login1` — Manager object (main entry point)
- `/org/freedesktop/login1/session/c1` — Session object
- `/org/freedesktop/login1/seat/seat0` — Seat object
- `/org/freedesktop/login1/user/current` — User object
## Interface: `org.freedesktop.login1.Manager`
### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `GetSession` | `(id: s) → (o)` | Returns object path for session by ID |
| `GetSessionByPID` | `(pid: u) → (o)` | Returns object path for session owning PID (stub: returns c1) |
| `ListSessions` | `() → (a(susso))` | List all sessions: `[(id, uid, user, seat, object_path)]` |
| `GetSeat` | `(id: s) → (o)` | Returns object path for seat by ID |
| `ListSeats` | `() → (a(so))` | List all seats: `[(id, object_path)]` |
| `GetUser` | `(uid: u) → (o)` | Returns object path for user by UID |
| `GetUserByPID` | `(pid: u) → (o)` | Returns object path for user owning PID (stub: returns current) |
| `ListUsers` | `() → (a(uso))` | List all users: `[(uid, name, object_path)]` |
| `ListInhibitors` | `() → (a(ssssuu))` | List all registered inhibitors |
| `Inhibit` | `(what: s, who: s, why: s, mode: s) → (h)` | Register a shutdown/sleep inhibitor; returns pipe FD. The inhibitor is tracked by sender bus name; removal occurs on FD close or sender vanishing |
| `PowerOff` | `(interactive: b) → ()` | Shut down the system. Writes `\n` to `/scheme/acpi/shutdown`. Emits `PrepareForShutdown(true)` before and `PrepareForShutdown(false)` after. |
| `Reboot` | `(interactive: b) → ()` | Reboot the system. Writes `\n` to `/scheme/acpi/reboot`. Emits `PrepareForShutdown(true)` before. |
| `Suspend` | `(interactive: b) → ()` | Suspend the system. Emits `PrepareForSleep(true)` before and `PrepareForSleep(false)` after. |
| `CanPowerOff` | `() → (s)` | Returns `"yes"`, `"no"`, or `"challenge"` (always `"yes"` when `/scheme/acpi/shutdown` is writable) |
| `CanReboot` | `() → (s)` | Returns `"yes"`, `"no"`, or `"challenge"` |
| `CanSuspend` | `() → (s)` | Returns `"yes"`, `"no"`, or `"challenge"` (stub: always `"no"`) |
| `CanHibernate` | `() → (s)` | Stub: always `"no"` |
| `CanHybridSleep` | `() → (s)` | Stub: always `"no"` |
| `CanSuspendThenHibernate` | `() → (s)` | Stub: always `"no"` |
| `CanSleep` | `() → (s)` | Aggregate: `"yes"` if any sleep state is available |
| `ActivateSession` | `(session_id: s) → ()` | Mark session as active |
| `ActivateSessionOnSeat` | `(session_id: s, seat_id: s) → ()` | Activate session on specific seat |
| `LockSession` | `(session_id: s) → ()` | Lock a specific session |
| `UnlockSession` | `(session_id: s) → ()` | Unlock a specific session |
| `LockSessions` | `() → ()` | Lock all sessions |
| `UnlockSessions` | `() → ()` | Unlock all sessions |
| `TerminateSession` | `(session_id: s) → ()` | Terminate a specific session |
| `TerminateUser` | `(uid: u) → ()` | Terminate all sessions for a user |
| `KillSession` | `(session_id: s, who: s, signal_number: i) → ()` | Send signal to session leader |
| `KillUser` | `(uid: u, signal_number: i) → ()` | Send signal to user session leader |
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `IdleHint` | `b` | Whether the seat has been idle for the configured timeout |
| `IdleSinceHint` | `t` | CLOCK_REALTIME timestamp of last activity |
| `IdleSinceHintMonotonic` | `t` | CLOCK_MONOTONIC timestamp of last activity |
| `BlockInhibited` | `s` | Colon-separated list of `who:why` for block-mode inhibitors |
| `DelayInhibited` | `s` | Colon-separated list of `who:why` for delay-mode inhibitors |
| `InhibitDelayMaxUSec` | `t` | Maximum delay before forced shutdown (5 s default) |
| `HandleLidSwitch` | `s` | Lid switch policy: `"ignore"` (default) |
| `HandlePowerKey` | `s` | Power key policy: `"poweroff"` (default) |
| `PreparingForShutdown` | `b` | Whether a shutdown operation is in progress |
| `PreparingForSleep` | `b` | Whether a sleep operation is in progress |
### Signals
| Signal | Signature | Description |
|--------|-----------|-------------|
| `SeatNew` | `(id: s, path: o)` | A new seat was added |
| `SeatRemoved` | `(id: s, path: o)` | A seat was removed |
| `PrepareForShutdown` | `(active: b)` | Shutdown is about to begin / has completed |
| `PrepareForSleep` | `(active: b)` | Sleep is about to begin / has completed |
## Interface: `org.freedesktop.login1.Session`
### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `Activate` | `() → ()` | Activate this session |
| `TakeControl` | `(force: b) → ()` | Take control of the session |
| `ReleaseControl` | `() → ()` | Release session control |
| `TakeDevice` | `(major: u, minor: u) → (h)` | Take a device (returns FD). Emits `PauseDevice` signal. |
| `ReleaseDevice` | `(major: u, minor: u) → ()` | Release a previously-taken device. Emits `ResumeDevice` signal. |
| `PauseDeviceComplete` | `(major: u, minor: u) → ()` | Signal that device pause is complete |
| `SetIdleHint` | `(idle: b) → ()` | Set the session idle state |
| `SetLockedHint` | `(locked: b) → ()` | Set the session lock state |
| `SetType` | `(type: s) → ()` | Set the session type (e.g. `"wayland"`) |
| `Terminate` | `() → ()` | Terminate this session |
| `Kill` | `(who: s, signal_number: i) → ()` | Send signal to session process |
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `Active` | `b` | Whether this session is currently active |
| `Remote` | `b` | Whether this is a remote session (always false) |
### Signals
| Signal | Signature | Description |
|--------|-----------|-------------|
| `PauseDevice` | `(major: u, minor: u, type: s)` | A device is being paused |
| `ResumeDevice` | `(major: u, minor: u, fd: h)` | A device is being resumed (FD re-opened) |
## Interface: `org.freedesktop.login1.Seat`
### Methods
| Method | Signature | Description |
|--------|-----------|-------------|
| `SwitchTo` | `(vt: u) → ()` | Switch to virtual terminal |
### Properties
| Property | Type | Description |
|----------|------|-------------|
| `Id` | `s` | Seat identifier (default: `"seat0"`) |
| `ActiveSession` | `(s, o)` | Active session ID and object path |
| `Sessions` | `a(so)` | List of sessions on this seat |
| `CanGraphical` | `b` | Whether this seat supports graphical sessions (always `true`) |
| `CanTTY` | `b` | Whether this seat supports TTY sessions (always `true`) |
| `IdleHint` | `b` | Whether this seat is idle |
## Runtime State
The daemon maintains a `SharedRuntime` (RwLock-protected) with:
- `seat_id`: current seat identifier
- `session_id`: current session identifier
- `uid`: current user UID
- `user_name`: current user name
- `display`: current display number
- `vt`: current virtual terminal
- `session_type`: session type string
- `inhibitors`: list of registered inhibitors with sender tracking
- `last_activity`: monotonic timestamp
## AC adapter / power events
The `acpi_watcher` background task:
- Reads `/sys/class/power_supply/ACAD/online` every 2 s (or `/sys/class/power_supply/AC*/online`)
- Emits `PropertyChanged` on `org.freedesktop.login1.Manager` when the AC state transitions
- Transitions are debounced: an event is only emitted when the state actually changes
## Connection
- Uses zbus `ConnectionBuilder` with the system bus address from `DBUS_STARTER_ADDRESS` or `DBUS_SYSTEM_BUS_ADDRESS` (default: `unix:path=/run/dbus/system_bus_socket`)
- Waits up to 30 s for the D-Bus socket, polling multiple candidate paths
- Retries connection 3 times with 1 s backoff (first attempt failure is silent — normal when D-Bus SASL auth is not yet ready)
- Exposes a UNIX control socket at `/run/redbear-sessiond/control` for out-of-band commands (e.g. `reload`)
## References
- [systemd-logind D-Bus API](https://www.freedesktop.org/wiki/Software/systemd/logind/)
- Conformance: Subset-compatible. Implements the login1 Manager, Session, and Seat interfaces. Inhibitor tracking with FD-polling reaper. Power/sleep operations via ACPI scheme. No user session tracking beyond a single "current" user. No multi-seat support. Device take/release with PauseDevice/ResumeDevice signal contract.