improvements

- Consolidate status reads
- Pre-allocate descriptors
- Add read_only disk label
- Remove dead stdin field
- Guard nil pool maps
- Add error-path tests
- Add go vet to flake
This commit is contained in:
illustris
2026-03-12 12:47:50 +05:30
parent d8f4a77657
commit def7d3e086
16 changed files with 644 additions and 267 deletions

View File

@@ -48,7 +48,14 @@ func ParseBlockInfo(raw string) map[string]DiskInfo {
blockID := match[2]
diskPath := match[3]
diskTypeAndMode := match[4]
diskType := strings.Split(diskTypeAndMode, ", ")[0]
modeParts := strings.Split(diskTypeAndMode, ", ")
diskType := modeParts[0]
readOnly := false
for _, p := range modeParts[1:] {
if p == "read-only" {
readOnly = true
}
}
// Skip EFI disks
if strings.Contains(diskName, "efidisk") {
@@ -72,6 +79,10 @@ func ParseBlockInfo(raw string) map[string]DiskInfo {
Labels: make(map[string]string),
}
if readOnly {
info.Labels["read_only"] = "true"
}
// Detect disk type from path
classifyDisk(&info)

View File

@@ -130,6 +130,51 @@ func TestHandleJSONPath_NoHostDevice(t *testing.T) {
}
}
func TestParseBlockInfo_ReadOnly(t *testing.T) {
raw := `drive-scsi0 (#block100): /dev/zvol/rpool/data/vm-100-disk-0 (raw, read-only)
`
disks := ParseBlockInfo(raw)
d := disks["scsi0"]
if d.Labels["read_only"] != "true" {
t.Errorf("expected read_only=true, got %q", d.Labels["read_only"])
}
}
func TestParseBlockInfo_ReadWrite(t *testing.T) {
raw := `drive-scsi0 (#block100): /dev/zvol/rpool/data/vm-100-disk-0 (raw, read-write)
`
disks := ParseBlockInfo(raw)
d := disks["scsi0"]
if _, ok := d.Labels["read_only"]; ok {
t.Error("read_only label should not be set for read-write disks")
}
}
func TestParseBlockInfo_MalformedHeader(t *testing.T) {
raw := `drive-scsi0: this is not a valid header
`
disks := ParseBlockInfo(raw)
if len(disks) != 0 {
t.Fatalf("expected 0 disks for malformed header, got %d", len(disks))
}
}
func TestParseBlockInfo_Empty(t *testing.T) {
disks := ParseBlockInfo("")
if len(disks) != 0 {
t.Fatalf("expected 0 disks for empty input, got %d", len(disks))
}
}
func TestParseBlockInfo_JSONError(t *testing.T) {
raw := `drive-scsi0 (#block100): json:{invalid json} (raw, read-write)
`
disks := ParseBlockInfo(raw)
if len(disks) != 0 {
t.Fatalf("expected 0 disks for invalid JSON path, got %d", len(disks))
}
}
func TestParseBlockInfo_MultiDisk(t *testing.T) {
raw := `drive-scsi0 (#block100): /dev/zvol/rpool/data/vm-100-disk-0 (raw, read-write)
Attached to: /machine/peripheral/virtioscsi0/virtio-backend

View File

@@ -63,3 +63,27 @@ func TestParseNetworkInfo_Empty(t *testing.T) {
t.Fatalf("expected 0 NICs, got %d", len(nics))
}
}
func TestParseNetworkInfo_MalformedLine(t *testing.T) {
// Lines without colon-space or without "net" prefix should be skipped
raw := "this is garbage\nnotnet0: index=0,type=tap\nno-colon-here\n"
nics := ParseNetworkInfo(raw)
if len(nics) != 0 {
t.Fatalf("expected 0 NICs for malformed input, got %d", len(nics))
}
}
func TestParseNetworkInfo_MissingFields(t *testing.T) {
// NIC with minimal fields
raw := "net0: index=0"
nics := ParseNetworkInfo(raw)
if len(nics) != 1 {
t.Fatalf("expected 1 NIC, got %d", len(nics))
}
if nics[0].Queues != 1 {
t.Errorf("queues = %d, want 1", nics[0].Queues)
}
if nics[0].Model != "" {
t.Errorf("model = %q, want empty", nics[0].Model)
}
}

View File

@@ -31,7 +31,6 @@ type RealQMMonitor struct {
type deferredProc struct {
cmd *exec.Cmd
stdin io.WriteCloser
timestamp time.Time
}
@@ -113,7 +112,7 @@ func (m *RealQMMonitor) deferCloseProcess(cmd *exec.Cmd, stdin io.WriteCloser) {
stdin.Close()
if m.deferClose {
m.mu.Lock()
m.deferredProcs = append(m.deferredProcs, deferredProc{cmd: cmd, stdin: stdin, timestamp: time.Now()})
m.deferredProcs = append(m.deferredProcs, deferredProc{cmd: cmd, timestamp: time.Now()})
m.mu.Unlock()
slog.Warn("deferred closing qm monitor process", "pid", cmd.Process.Pid)
} else {