Skip to content

Make desktop process state and lifecycle truthful#886

Open
brandonpayton wants to merge 4 commits into
mainfrom
fix/procfs-resource-accounting
Open

Make desktop process state and lifecycle truthful#886
brandonpayton wants to merge 4 commits into
mainfrom
fix/procfs-resource-accounting

Conversation

@brandonpayton

@brandonpayton brandonpayton commented Jul 11, 2026

Copy link
Copy Markdown
Member

Standalone lifecycle extraction: #893 isolates the host-owned ppid=0 reaping fix for independent review. This combined branch still carries that change for LXDE integration until the extraction lands.

Why

Linux desktop consumers need a truthful process view, not demo-authored rows or invented resource measurements. lxtask could enumerate numeric PIDs but discarded every row because Kandelo lacked the procfs files it reads. Separately, the LXDE browser workload exposed two lifecycle mismatches: an omitted non-PTY stdin remained open and stalled Leafpad before its GTK loop, and top-level host-owned exits remained as unreaped ppid=0 zombies after the host had consumed their statuses.

The fixes belong in shared kernel/host behavior. Node and browser remain peers, guest-owned zombies remain governed by wait()/waitpid(), and unsupported CPU/RSS/system-memory accounting stays explicitly unavailable.

What changed

  • Add Linux-shaped /proc/stat, /proc/meminfo, /proc/<pid>/statm, and /proc/<pid>/task/<tid> views.
  • Correct /proc/<pid>/stat field positions and report authoritative nice, thread-count, state, credentials, and kernel-tracked logical virtual size.
  • Own PID-scoped procfs nodes with the target effective uid/gid, validate PID/TID paths, and exclude internal Limbo placeholders while retaining real unreaped zombies.
  • Keep PR_SET_NAME state per thread so a worker rename cannot replace the process leader identity.
  • Default omitted non-PTY browser VFS launches to a finite empty stdin (immediate EOF), while preserving explicit finite input and open PTY/incremental-input streams.
  • Make host-delegated pipe readiness reflect buffered data, open-empty state, finite EOF, peer closure, and write capacity; preserve PIPE_BUF atomicity and EPIPE/SIGPIPE.
  • Reap only exited ppid=0 processes after Node/browser worker teardown and channel deactivation. Rust validates ownership, so guest-child zombies remain wait-owned.
  • Preserve one absolute deadline across host retries for finite poll/ppoll and select/pselect6 calls.
  • Finalize expired waits through a zero-timeout kernel pass so fd outputs are cleared and temporary ppoll/pselect6 masks are restored before copyback.
  • Add kernel, shared-host, Node integration, and browser-protocol regressions for these contracts.

Accounting and lifecycle boundaries

Logical virtual size is the kernel-tracked address-space prefix through brk plus active guest mmap ranges, without overlap double-counting. It is not RSS.

CPU counters, resident pages/RSS, and system physical/free/cache totals are zero in procfs by documented contract to mean unavailable. The LXDE port renders those values as unavailable/N/A; this PR does not synthesize measurements.

Host-owned reaping is deliberately limited to exited ppid=0 processes whose host status has been consumed. This does not implement general orphan reparenting and does not bypass guest waitpid() ownership.

Validation

Every build/test/validation command below ran through bash scripts/dev-shell.sh -- ....

  • Kernel unit suite: 974 passed, 0 failed.
  • Full host Vitest suite: 105 files passed, 25 skipped; 802 passed, 2 expected failures, 111 skipped.
  • Host declaration/type build: passed.
  • ABI snapshot/version check: passed; snapshot, C header, and TypeScript bindings are in sync.
  • Focused final-timeout coverage verifies retained poll deadlines, final zero-timeout kernel dispatch, cleared revents, unchanged guest timespec input, and restored ppoll mask.
  • LXDE integration branch, client-control Playwright smoke:
    • selected lxappearance's Color page and closed it with status 0;
    • verified its /proc entry disappeared while lxtask remained live;
    • waited through lxtask's refresh and visually confirmed the lxappearance row was gone;
    • toggled More details, quit lxtask with status 0, and verified its /proc entry disappeared;
    • focused the boot Leafpad, typed a sentinel, observed framebuffer change, and recorded all keyboard edges.
  • LXDE integration branch, real-system-menu Playwright smoke:
    • retained the mapped boot Leafpad;
    • launched a second mapped Leafpad through the menu-cache-backed Accessories entry;
    • observed the double-fork intermediate exit and final exec before any post-click kernel control request.
  • Both browser validators completed without their forbidden diagnostic patterns.

The Open POSIX and Sortix suites were considered; this repository has no direct external case for the host-managed procfs/accounting or timeout-finalization paths changed here. No broad POSIX-conformance or performance claim is made.

Make host-delegated pipe readiness reflect buffered data, open-empty state, EOF, and write capacity, while preserving finite select/pselect deadlines through retries and finalizing timeouts through the kernel.

Default omitted non-PTY browser VFS launches to finite EOF and reap only exited ppid=0 processes after Node/browser worker teardown. Guest-child zombies remain owned by waitpid.

Add Rust and host regressions for readiness, deadline copyback and mask restoration, process reaping, and browser spawn protocol behavior. The host/kernel ABI surface is unchanged.
@brandonpayton brandonpayton changed the title Expose process lists without inventing resource metrics Make desktop process state and lifecycle truthful Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant