Lulo – Disk View

The DISK page is the one heavy page with no daemon behind it: it gathers everything synchronously in-process from /proc, /sys/block, and the mount tables, then lays it out as a responsive multi-panel dashboard covering filesystems, block devices, live I/O, and queue tunables.

Table of Contents

  1. What the page shows
  2. Where the data comes from
  3. The responsive panel layout
  4. Filesystems panel
  5. Devices, I/O, and queue panels
  6. Why DISK has no daemon
  7. See also

1. What the page shows

DISK is a read-only storage dashboard. Unlike the cgroups, systemd, udev, and tune pages – which each talk to lulod over a socket – the disk page calls one synchronous gather (lulo_dizk_snapshot_gather) directly on the frontend thread and renders the result into a set of stacked panels.

Panel Source What it shows
Filesystems getmntent + statvfs Mounted filesystem usage with an aggregate total row
Devices /sys/block Block devices: size, rotational, model, transport
I/O /proc/diskstats + /proc/uptime Per-device utilization and read/write bytes
Queue & Swap /sys/block/*/queue/*, /proc/swaps Scheduler, read-ahead, request depth, swap usage

2. Where the data comes from

Every field is parsed from a kernel-provided file or pseudo-file; there is no df, lsblk, or iostat subprocess. The whole snapshot is a flat struct of fixed-size arrays, so the gather does no heap allocation.

DISK snapshot: kernel sources into one synchronous gather /etc/mtab -> /proc/mounts + statvfs /sys/block (size, rotational) /proc/diskstats + /proc/uptime /sys/block/*/queue/* /proc/swaps /etc/fstab + /dev/disk/by-* lulo_dizk_snapshot_gather in-process, synchronous, fixed arrays, no heap Filesystems (+ total row) Devices I/O (util% + rd/wr) Queue & Swap

The gather is selective about what it shows so the dashboard stays meaningful:

3. The responsive panel layout

The renderer (build_disk_widget_layout) is a responsive splitter rather than a fixed grid. The Filesystems panel is always on top; the Devices, I/O, and Queue & Swap panels arrange side by side when the terminal is at least 96 columns wide and stack vertically below that, with per-breakpoint reserved heights and clamped sizing.

Lulo DISK page with filesystems, devices, I/O, and queue panels
The DISK dashboard: aggregate total row atop per-filesystem bars, with device, I/O, and queue panels alongside.

4. Filesystems panel

The Filesystems panel leads with a synthetic total / “all mounts” row that sums used and total bytes across every mount and draws an aggregate usage meter. That row uses its own dedicated purple/lavender color so it reads as a summary, not as one of the component mounts.

Each per-filesystem row gets a stable color keyed to its index, not its usage: the row index is cycled through a fixed palette permutation into the theme’s fill slots, so adjacent filesystems always get distinct hues and a given mount keeps the same color across frames regardless of how full it is. This is a deliberate choice – the color encodes identity (which mount), while the bar length and percentage encode capacity.

5. Devices, I/O, and queue panels

Panel Columns / content
Devices Device name, size, rotational/SSD, transport, model
I/O Utilization% bar, read bytes, write bytes (from diskstats deltas)
Queue & Swap I/O scheduler, read-ahead, nr_requests, plus swap usage meters

I/O utilization and swap meters are threshold-colored (graded at 25 / 50 / 75 / 90%), so a saturated device or near-full swap is visible at a glance.

6. Why DISK has no daemon

Every other heavy page caches its data in lulod and serves it to the TUI over a socket, because gathering it (a full systemd unit inventory, a deep cgroup walk) is expensive and must stay off the UI thread. Disk data is cheap – a handful of small /proc and /sys reads plus statvfs per mount – so it is gathered inline whenever the page renders or a refresh is requested. There is no TTL cache and no IPC: the snapshot is simply rebuilt each time. This keeps the disk page self-contained and is the reason it is structurally the simplest page in the app.

7. See also