diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-17 19:10:59 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-17 19:10:59 +0200 |
| commit | 0048d3075adfd0336def9a25ce039765e43b4b3a (patch) | |
| tree | 42a27e5a6313884540c228453a1547f972b3b6c7 | |
| parent | 63d8dc8c4ec7a641efb614265478edfa7b7f0906 (diff) | |
| download | conky-theme-udt-0048d3075adfd0336def9a25ce039765e43b4b3a.tar.gz conky-theme-udt-0048d3075adfd0336def9a25ce039765e43b4b3a.zip | |
feat: read the available column from df
Free space is read rather than derived: size - used overstates it by the
root-reserved blocks, tens of gigabytes on a large filesystem, none of it
available to anyone but root.
Also asserts fs[3], the row whose device name ends in a digit. It sits next
to a numeric column and is the row most likely to break a parser counting
fields, and nothing covered it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| -rw-r--r-- | lib/data.lua | 7 | ||||
| -rw-r--r-- | test/test_data.lua | 21 |
2 files changed, 27 insertions, 1 deletions
diff --git a/lib/data.lua b/lib/data.lua index d5203a8..98c6898 100644 --- a/lib/data.lua +++ b/lib/data.lua @@ -219,7 +219,8 @@ function M.df_parse(text) for line in text:gmatch('[^\n]+') do -- A data row ends in 'NN% /some/path'. The header ends in 'Mounted on', -- which fails the percent match, so it is skipped without a special case. - local size, used, pct, mount = line:match('(%d+)%s+(%d+)%s+%d+%s+(%d+)%%%s+(%S+)%s*$') + local size, used, avail, pct, mount = + line:match('(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%%%s+(%S+)%s*$') if size then -- The device is kept so a caller can tell an NFS mount from a local one -- and recover its server, which is how the disks card labels the two @@ -231,6 +232,10 @@ function M.df_parse(text) host = dev and dev:match('^([^/:]+):') or nil, size = tonumber(size), used = tonumber(used), + -- Read, not derived: size - used overstates free space by the + -- root-reserved blocks, which is tens of gigabytes on a large + -- filesystem and is not available to anyone but root. + avail = tonumber(avail), pct = tonumber(pct), } end diff --git a/test/test_data.lua b/test/test_data.lua index 4def123..74167bf 100644 --- a/test/test_data.lua +++ b/test/test_data.lua @@ -110,6 +110,27 @@ assert(fs[1].pct == 84, 'root percent, got ' .. tostring(fs[1].pct)) assert(fs[1].size == 263174213632, 'root size in bytes, got ' .. tostring(fs[1].size)) assert(fs[1].used == 208111570944, 'root used, got ' .. tostring(fs[1].used)) +-- Available is READ, never derived as size - used: the two differ by the +-- root-reserved blocks, about 5%, which on this root is some 13GB that exists +-- but cannot be used. A card claiming that space is free would be lying. +assert(fs[1].avail == 41746907136, 'root available, got ' .. tostring(fs[1].avail)) +assert(fs[1].size - fs[1].used ~= fs[1].avail, + 'the fixture must exercise the reserved-block gap, or this assertion proves nothing') + +-- fs[3] is /dev/sda1: a device name ENDING IN A DIGIT, next to a numeric +-- column. A parser counting fields from the left, or matching digits without +-- anchoring, reads the partition number as a size. +assert(fs[3].mount == '/data', 'sda1 mount, got ' .. tostring(fs[3].mount)) +assert(fs[3].dev == '/dev/sda1', 'sda1 device, got ' .. tostring(fs[3].dev)) +assert(fs[3].size == 983350091776, 'sda1 size, got ' .. tostring(fs[3].size)) +assert(fs[3].used == 547869650944, 'sda1 used, got ' .. tostring(fs[3].used)) +assert(fs[3].avail == 385453473792, 'sda1 available, got ' .. tostring(fs[3].avail)) +assert(fs[3].pct == 59, 'sda1 percent, got ' .. tostring(fs[3].pct)) +assert(fs[3].host == nil, 'a local device has no host') + +-- A full filesystem reports zero available, which is a real reading. +assert(fs[6].avail == 0, 'a full mount has 0 available, got ' .. tostring(fs[6].avail)) + -- The NFS rows are the reason the last field matters: a colon in the device -- would break a parser splitting on punctuation. assert(fs[4].mount == '/mnt/nfs/Library', 'nfs mount, got ' .. tostring(fs[4].mount)) |
