fix drive name normalization (#74)

This commit is contained in:
Gustavo de Andrade Rosa
2026-07-21 13:43:59 -04:00
committed by GitHub
parent 9d1bce45af
commit 27eb24bd4b
6 changed files with 29 additions and 16 deletions
+13 -3
View File
@@ -118,6 +118,11 @@ local function smartDeviceFor(path)
return controller ~= nil and "/dev/" .. controller or tostring(path)
end
local function deviceBasename(value)
local normalized = tostring(value or ""):gsub("/+$", "")
return normalized:match("([^/]+)$") or ""
end
local function listDirectory(path)
local entries = noctalia.listDir(path)
return type(entries) == "table" and entries or {}
@@ -765,8 +770,13 @@ local function normalizeRaw(raw, source)
local disks = {}
for _, block in ipairs(lsblk.blockdevices or {}) do
local device = tostring(block.path or ("/dev/" .. tostring(block.name or "")))
local name = tostring(block.name or "")
local device = tostring(block.path or "")
local name = deviceBasename(block.name)
if name == "" then name = deviceBasename(block.kname) end
if name == "" then name = deviceBasename(device) end
if not device:match("^/dev/") and name ~= "" then device = "/dev/" .. name end
local kernelName = deviceBasename(block.kname)
if kernelName == "" then kernelName = name end
local virtual = name:match("^zram") or name:match("^loop") or name:match("^ram") or name:match("^sr")
if block.type == "disk" and device:match("^/dev/") and not virtual then
local smartDevice = smartDeviceFor(device)
@@ -789,7 +799,7 @@ local function normalizeRaw(raw, source)
local model = noctalia.string.trim(tostring(block.model or ""))
local namespace = name:match("^nvme%d+(n%d+)$")
local id = serial ~= "" and serial .. (namespace ~= nil and ":" .. namespace or "")
or tostring(block.kname or device)
or (kernelName ~= "" and kernelName or device)
local preferences = preferenceFor(id)
local removable = block.rm == true or tonumber(block.rm) == 1 or block.hotplug == true or tonumber(block.hotplug) == 1
local transport = tostring(block.tran or "unknown")
+1 -1
View File
@@ -1,6 +1,6 @@
id = "gustav0ar/drive-health"
name = "Drive Health"
version = "1.2.0"
version = "1.2.1"
plugin_api = 3
author = "Drive Health contributors"
license = "MIT"
+1 -1
View File
@@ -59,7 +59,7 @@ lsblk --nodeps --noheadings --paths --output PATH,TYPE,ROTA >"$devices_tmp"
{
printf '{"schema":2,"collector_version":"%s","collection_id":"%s","generated_at_epoch":%s,"lsblk":' \
"$collector_version" "$collection_id" "$generated_at_epoch"
lsblk --json --bytes --output \
lsblk --json --bytes --paths --output \
NAME,KNAME,PATH,PKNAME,TYPE,TRAN,ROTA,RM,HOTPLUG,SIZE,LOG-SEC,PHY-SEC,MODEL,SERIAL,FSTYPE,FSSIZE,FSUSED,FSAVAIL,MOUNTPOINTS
printf ',"smart":['
+9 -7
View File
@@ -392,10 +392,10 @@ local normalized, normalizeError = normalizeRaw({
generated_at_epoch = 1700000000,
lsblk = { blockdevices = {
{
name = "nvme9n1", kname = "nvme9n1", path = "/dev/nvme9n1", type = "disk",
name = "/dev/nvme9n1", kname = "/dev/nvme9n1", path = "/dev/nvme9n1", type = "disk",
tran = "nvme", rota = false, size = 2000000000, model = "Fixture NVMe", serial = "FIXTURE1",
mountpoints = {}, children = {
{ name = "nvme9n1p1", kname = "nvme9n1p1", path = "/dev/nvme9n1p1", type = "part",
{ name = "/dev/nvme9n1p1", kname = "/dev/nvme9n1p1", path = "/dev/nvme9n1p1", type = "part",
mountpoints = { "/mnt/work" }, fsused = 250, fsavail = 750 },
},
},
@@ -485,15 +485,17 @@ assert(sleeping.summary.sleeping_count == 1 and sleeping.summary.smart_unavailab
local namespaces = assert(normalizeRaw({
schema = 2, generated_at_epoch = 1700000000,
lsblk = { blockdevices = {
{ name = "nvme0n1", kname = "nvme0n1", path = "/dev/nvme0n1", type = "disk",
{ name = "/dev/nvme0n1", kname = "/dev/nvme0n1", path = "/dev/nvme0n1", type = "disk",
tran = "nvme", rota = false, serial = "SHARED", children = {} },
{ name = "nvme0n2", kname = "nvme0n2", path = "/dev/nvme0n2", type = "disk",
{ name = "/dev/nvme0n2", kname = "/dev/nvme0n2", path = "/dev/nvme0n2", type = "disk",
tran = "nvme", rota = false, serial = "SHARED", children = {} },
{ name = "/dev/zram0", kname = "/dev/zram0", path = "/dev/zram0", type = "disk",
rota = false, serial = "VIRTUAL", children = {} },
} }, smart = {},
}, "test"))
assert(namespaces.disks[1].id ~= namespaces.disks[2].id
and namespaces.disks[1].id:match(":n%d+$") and namespaces.disks[2].id:match(":n%d+$"),
"NVMe namespaces sharing a controller serial did not receive unique IDs")
assert(#namespaces.disks == 2, "absolute zram name was not excluded from physical drive inventory")
assert(namespaces.disks[1].id == "SHARED:n1" and namespaces.disks[2].id == "SHARED:n2",
"absolute NVMe names did not receive stable namespace-qualified IDs")
local empty = assert(normalizeRaw({
schema = 2, collection_id = " ", generated_at_epoch = 1700000000,
+4 -3
View File
@@ -3,12 +3,13 @@ set -eu
case " $* " in
*" --nodeps "*)
printf '%s\n' "/dev/sda disk 1" "/dev/nvme0n1 disk 0"
printf '%s\n' "/dev/sda disk 1" "/dev/nvme0n1 disk 0" "/dev/zram0 disk 0"
;;
*" --json "*)
printf '%s\n' '{"blockdevices":[' \
'{"name":"sda","kname":"sda","path":"/dev/sda","type":"disk","tran":"sata","rota":true,"size":1000000000,"model":"Fixture SATA","serial":"SATA1","mountpoints":[]},' \
'{"name":"nvme0n1","kname":"nvme0n1","path":"/dev/nvme0n1","type":"disk","tran":"nvme","rota":false,"size":2000000000,"model":"Fixture NVMe","serial":"NVME1","mountpoints":[]}' \
'{"name":"/dev/sda","kname":"/dev/sda","path":"/dev/sda","type":"disk","tran":"sata","rota":true,"size":1000000000,"model":"Fixture SATA","serial":"SATA1","mountpoints":[]},' \
'{"name":"/dev/nvme0n1","kname":"/dev/nvme0n1","path":"/dev/nvme0n1","type":"disk","tran":"nvme","rota":false,"size":2000000000,"model":"Fixture NVMe","serial":"NVME1","mountpoints":[]},' \
'{"name":"/dev/zram0","kname":"/dev/zram0","path":"/dev/zram0","type":"disk","rota":false,"size":4294967296,"mountpoints":[]}' \
']}'
;;
*)
+1 -1
View File
@@ -9,7 +9,7 @@ printf '%s\n' "$payload" | jq -e '
.schema == 2
and .collector_version == "2.0.0"
and (.collection_id | type == "string" and length > 0)
and (.lsblk.blockdevices | length) == 2
and ([.lsblk.blockdevices[].name] | sort) == ["/dev/nvme0n1", "/dev/sda", "/dev/zram0"]
and (.smart | length) == 2
and ([.smart[].requested_device] | sort) == ["/dev/nvme0", "/dev/sda"]
and (.smart[] | select(.requested_device == "/dev/sda") | .payload.test_standby) == true