From f11564a7ac43998dca9524bec8746c9109f7decb Mon Sep 17 00:00:00 2001 From: Sven van Ginkel Date: Mon, 27 Oct 2025 16:44:21 +0100 Subject: [PATCH] Skip virtual disks (#1332) --- agent/smart.go | 30 ++++++++++++++++++++++++++++++ internal/entities/smart/smart.go | 2 ++ 2 files changed, 32 insertions(+) diff --git a/agent/smart.go b/agent/smart.go index dea386e9..108ff260 100644 --- a/agent/smart.go +++ b/agent/smart.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os/exec" + "strings" "sync" "time" @@ -250,6 +251,29 @@ func (sm *SmartManager) parseScan(output []byte) bool { return true } +// isVirtualDevice checks if a device is a virtual disk that should be filtered out +func (sm *SmartManager) isVirtualDevice(data *smart.SmartInfoForSata) bool { + vendorUpper := strings.ToUpper(data.ScsiVendor) + productUpper := strings.ToUpper(data.ScsiProduct) + modelUpper := strings.ToUpper(data.ModelName) + + switch { + case strings.Contains(vendorUpper, "IET"), // iSCSI Enterprise Target + strings.Contains(productUpper, "VIRTUAL"), + strings.Contains(productUpper, "QEMU"), + strings.Contains(productUpper, "VBOX"), + strings.Contains(productUpper, "VMWARE"), + strings.Contains(vendorUpper, "MSFT"), // Microsoft Hyper-V + strings.Contains(modelUpper, "VIRTUAL"), + strings.Contains(modelUpper, "QEMU"), + strings.Contains(modelUpper, "VBOX"), + strings.Contains(modelUpper, "VMWARE"): + return true + default: + return false + } +} + // parseSmartForSata parses the output of smartctl --all -j for SATA/ATA devices and updates the SmartDataMap // Returns hasValidData and exitStatus func (sm *SmartManager) parseSmartForSata(output []byte) (bool, int) { @@ -264,6 +288,12 @@ func (sm *SmartManager) parseSmartForSata(output []byte) (bool, int) { return false, data.Smartctl.ExitStatus } + // Skip virtual devices (e.g., Kubernetes PVCs, QEMU, VirtualBox, etc.) + if sm.isVirtualDevice(&data) { + slog.Debug("skipping virtual device", "device", data.Device.Name, "model", data.ModelName) + return false, data.Smartctl.ExitStatus + } + sm.Lock() defer sm.Unlock() diff --git a/internal/entities/smart/smart.go b/internal/entities/smart/smart.go index c1fd6aa1..e25c8291 100644 --- a/internal/entities/smart/smart.go +++ b/internal/entities/smart/smart.go @@ -211,6 +211,8 @@ type SmartInfoForSata struct { // Wwn WwnInfo `json:"wwn"` FirmwareVersion string `json:"firmware_version"` UserCapacity UserCapacity `json:"user_capacity"` + ScsiVendor string `json:"scsi_vendor"` + ScsiProduct string `json:"scsi_product"` // LogicalBlockSize int `json:"logical_block_size"` // PhysicalBlockSize int `json:"physical_block_size"` // RotationRate int `json:"rotation_rate"`