# kmod-tui — Kernel Module Inspector (Rust TUI) A terminal UI for Linux sysadmins to browse and inspect loaded kernel modules. ## Goal Show all loaded kernel modules in a navigable, filterable list, with a detail view for each module's metadata, dependencies, parameters, and holders. ## Data Sources (verified on this host, kernel 6.8.0-137-generic, 130 modules) - `/proc/modules` — one line per loaded module: `name size refcnt used-by state addr` (e.g. `wireguard 114688 0 - Live 0xffffffffc125d000`) - `/sys/module//` — per-module sysfs dir with: `refcnt`, `initstate`, `coresize`, `initsize`, `version`, `srcversion`, `taint`, `holders/` (modules depending on this one), `parameters/` (tunable params) - `modinfo ` — richest metadata: filename, license, description, author, depends, retpoline, intree, vermagic, signature info ## Tech Stack - Rust (stable) - `ratatui` — TUI rendering (modern maintained fork of tui-rs) - `crossterm` — terminal backend (cross-platform, works everywhere) - `clap` — CLI args (optional: --sort, --filter, --no-modinfo for speed) - No shell-out to `modinfo`; parse `/proc/modules` + walk `/sys/module` directly. (Avoids a process spawn per module; modinfo data like license/description/author comes from the .ko file's modinfo section — we parse the relevant sysfs files and, where sysfs lacks it, read the module file's modinfo section directly. Decision: for v1, shell out to `modinfo` lazily only when a module is selected for detail — keeps the list fast and detail rich. Revisit later.) ## UI Layout ``` ┌─ kmod-tui — 130 modules loaded (kernel 6.8.0-137-generic) ──────────────┐ │ Filter: [_____________] Sort: name▼ Loaded only: on │ ├────┬──────────────────┬────────┬──────┬────────────────────┬────────────┤ │ # │ Module │ Size │ Refc │ Used by │ State │ ├────┼──────────────────┼────────┼──────┼────────────────────┼────────────┤ │ 1 │ cpuid │ 12288 │ 0 │ - │ Live │ │ 2 │ wireguard │ 114688 │ 0 │ - │ Live │ │ 3 │ curve25519_x86_64│ 36864 │ 1 │ wireguard │ Live │ │ .. │ .. │ .. │ .. │ .. │ .. │ ├────┴──────────────────┴────────┴──────┴────────────────────┴────────────┤ │ Detail: wireguard │ │ Filename: /lib/modules/.../wireguard.ko.zst │ │ License: GPL Description: ... Author: ... │ │ Depends: (none) Holders: (none) Parameters: (none) │ │ Coresize: 114688 Initsize: 0 Refcnt: 0 Srcversion: ... │ └────────────────────────────────────────────────────────────────────────┘ ↑/↓ move Enter expand / filter s sort q quit ``` Two-pane layout: scrollable module list (top ~70%), detail pane (bottom ~30%). Selecting a row populates the detail pane. Enter opens a full-screen detail view for the selected module with all sysfs fields, parameters, holders, and a dependency tree. ## Features ### v1 (MVP — the "nice looking, human-navigable" baseline) 1. Module list from /proc/modules with columns: #, name, size (human-readable), refcnt, used-by, state. 2. Detail pane for highlighted module: filename, license, description, author, depends, holders, parameters (name + current value), coresize, initsize, refcnt, srcversion, taint, vermagic. 3. Vim-style navigation: j/k or ↑/↓ to move, Enter for full detail, Esc/q back. 4. Live filter (`/` then type, fuzzy or substring match on name). 5. Sort cycle (`s`): name, size, refcnt, dependents-count. 6. Footer help bar. 7. Color: state (Live=green, Loading/Unloading=yellow), refcnt>0 (bold), module-with-dependents highlighted. 8. Header shows module count, kernel version (from `uname -r`). ### v1.1 (polish) - Dependency tree view (expand a module → see what it depends on and what depends on it, recursively). - Parameter inspection with current values read from /sys/module//parameters. - Export current view to file (CSV/TSV). - Config file (~/.config/kmod-tui/config.toml) for default sort, columns. ### v2 (nice-to-have, later) - Show ALL installable modules (from /lib/modules/$(uname -r)/), not just loaded — mark loaded vs available-not-loaded. - Toggle between "loaded only" and "all available". - modprobe/insmod/rmmod actions (guarded, with confirmation — but see note: this is read-only for v1; mutating is a separate, deliberate decision). - Module loading state watch (inotify on /proc/modules, auto-refresh). ## Architecture (v1) ``` src/ main.rs — CLI args, app bootstrap, event loop app.rs — App state: module list, cursor, filter, sort mode, focus model.rs — Module struct, data collection from /proc + /sys ui/ mod.rs — frame composition, layout list.rs — module list table rendering detail.rs — detail pane + full detail view help.rs — help bar / overlay event.rs — crossterm input polling config.rs — (v1.1) config file load ``` Data flow: collect_modules() → Vec (once on startup; refresh on 'r') App holds Vec + filter/sort/cursor state ratatui draws from App state each frame crossterm polls input; key handlers mutate App state; redraw on change (or redraw on a fixed tick — simpler: event-driven redraw) ## Open Decisions (for Isaac) 1. Shelling out to `modinfo` for detail metadata (filename/license/desc/author) vs parsing .ko files directly? Recommend: shell out lazily on selection — simple and correct. We only parse /proc + /sys for the list. 2. Read-only for v1 (no rmmod/modprobe)? Recommend: YES, read-only v1. 3. Project location: /root/kmod-tui ? Recommend: yes. 4. Install Rust via rustup (recommended) or apt rustc package? Recommend: rustup (stable toolchain, latest ratatui). 5. Naming: `kmod-tui` ok? ## Build & Run cargo run --release (or `cargo build --release` then ./target/release/kmod-tui) ## Non-goals (v1) - Editing module parameters (write to /sys) — risky, out of scope. - Loading/unloading modules — risky, out of scope. - Remote hosts — local only (could add SSH later). - Persistent state — none needed.