A drive is a drive: NVMe namespaces fold into their controller
An Apple SSD presents three namespaces and the kernel lists each as a whole disk, so the dashboard was showing one drive as three. The Disks page has always folded them; now the dashboard, the Top tab and the disk.* sensors do too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
5761ee09db
commit
4b255fe63f
@@ -97,3 +97,47 @@ func TestKeepSpacing(t *testing.T) {
|
||||
t.Errorf("at the default window every sample is kept, got %d of 50", len(c.ring))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFoldNVMe(t *testing.T) {
|
||||
// an Apple SSD as the kernel lists it: one controller, three namespaces
|
||||
got := foldNVMe([]Disk{
|
||||
{Name: "nvme0n1", Model: "APPLE SSD AP0512Z", Size: 500 << 30, ReadBps: 100, WriteBps: 200, UtilPct: 12, Temp: 37},
|
||||
{Name: "nvme0n2", Model: "APPLE SSD AP0512Z", Size: 3 << 20, ReadBps: 10, WriteBps: 20, UtilPct: 40},
|
||||
{Name: "nvme0n3", Model: "APPLE SSD AP0512Z", Size: 128 << 20, ReadBps: 1, WriteBps: 2, UtilPct: 5},
|
||||
{Name: "sda", Size: 100 << 30, ReadBps: 7, UtilPct: 3},
|
||||
{Name: "nvme1n1", Size: 200 << 30, ReadBps: 5},
|
||||
})
|
||||
if len(got) != 3 {
|
||||
t.Fatalf("three namespaces of one controller are one drive: %v", names(got))
|
||||
}
|
||||
d := got[0]
|
||||
if d.Name != "nvme0" {
|
||||
t.Errorf("the drive is the controller, got %q", d.Name)
|
||||
}
|
||||
if d.Size != 500<<30+3<<20+128<<20 {
|
||||
t.Errorf("its size is all of its namespaces, got %d", d.Size)
|
||||
}
|
||||
if d.ReadBps != 111 || d.WriteBps != 222 {
|
||||
t.Errorf("rates add up, got %v/%v", d.ReadBps, d.WriteBps)
|
||||
}
|
||||
if d.UtilPct != 40 {
|
||||
t.Errorf("busy is the longest of them, not the sum: got %v", d.UtilPct)
|
||||
}
|
||||
if d.Temp != 37 {
|
||||
t.Errorf("a temperature from any namespace is the drive's, got %v", d.Temp)
|
||||
}
|
||||
if got[1].Name != "sda" || got[1].UtilPct != 3 || got[2].Name != "nvme1" {
|
||||
t.Errorf("everything else is left alone: %v", names(got))
|
||||
}
|
||||
if n := len(foldNVMe(nil)); n != 0 {
|
||||
t.Errorf("no disks, no drives, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func names(d []Disk) []string {
|
||||
out := make([]string, len(d))
|
||||
for i, x := range d {
|
||||
out[i] = x.Name
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user