Browse Source

fix: macOS virtual filesystem handling #1213

Jacky 4 hours ago
parent
commit
8f8cb6d054

+ 1 - 1
app/src/components/NgxConfigEditor/NgxUpstream.vue

@@ -75,7 +75,7 @@ function availabilityTest() {
   }
 
   if (sockets.length > 0) {
-    websocket.value = upstream.availability_test()
+    websocket.value = upstream.availabilityWebSocket()
     websocket.value.onopen = () => {
       websocket.value!.send(JSON.stringify(sockets))
     }

+ 24 - 1
internal/analytic/disk.go

@@ -35,6 +35,11 @@ func GetDiskStat() (DiskStat, error) {
 			continue
 		}
 
+		// Skip OS-specific paths that shouldn't be counted
+		if shouldSkipPath(partition.Mountpoint, partition.Device) {
+			continue
+		}
+
 		// Create partition stat for display purposes
 		partitionStat := PartitionStat{
 			Mountpoint: partition.Mountpoint,
@@ -75,6 +80,7 @@ func GetDiskStat() (DiskStat, error) {
 // isVirtualFilesystem checks if the filesystem type is virtual
 func isVirtualFilesystem(fstype string) bool {
 	virtualFSTypes := map[string]bool{
+		// Common virtual filesystems
 		"proc":        true,
 		"sysfs":       true,
 		"devfs":       true,
@@ -98,7 +104,24 @@ func isVirtualFilesystem(fstype string) bool {
 		"selinuxfs":   true,
 		"systemd-1":   true,
 		"none":        true,
+
+		// Network filesystems (should be excluded from total disk calculation)
+		"nfs":    true,
+		"nfs4":   true,
+		"cifs":   true,
+		"smb":    true,
+		"smbfs":  true,
+		"afpfs":  true,
+		"webdav": true,
+		"ftpfs":  true,
+	}
+
+	// Check common virtual filesystems first
+	if virtualFSTypes[fstype] {
+		return true
 	}
 
-	return virtualFSTypes[fstype]
+	// Check OS-specific additional virtual filesystems
+	additionalFS := getAdditionalVirtualFilesystems()
+	return additionalFS[fstype]
 }

+ 81 - 0
internal/analytic/disk_darwin.go

@@ -0,0 +1,81 @@
+//go:build darwin
+
+package analytic
+
+import "strings"
+
+// macOSVirtualFilesystems contains macOS-specific virtual filesystem types
+var macOSVirtualFilesystems = map[string]bool{
+	"devtmpfs":      true,
+	"kernfs":        true,
+	"fdesc":         true,
+	"map":           true,
+	"synthfs":       true,
+	"volfs":         true,
+	"ctlfs":         true,
+	"objfs":         true,
+	"procfs":        true,
+	"lifs":          true,
+	"mtab":          true,
+	"nullfs":        true,
+	"unionfs":       true,
+	"osxfuse":       true,
+	"macfuse":       true,
+	"fuse":          true,
+	"bindfs":        true,
+	"autofs_nowait": true,
+}
+
+// shouldSkipPath checks if a macOS path should be skipped from disk calculation
+func shouldSkipPath(mountpoint, device string) bool {
+	// Skip Time Machine snapshots and system snapshots
+	if strings.Contains(mountpoint, ".timemachine") ||
+		strings.Contains(mountpoint, ".Snapshot") ||
+		strings.Contains(mountpoint, "/.vol/") ||
+		strings.Contains(device, "@") { // APFS snapshots contain @
+		return true
+	}
+
+	// Skip read-only system volumes (including root partition on macOS Catalina+)
+	// The root "/" partition is read-only and shares space with "/System/Volumes/Data"
+	if strings.HasPrefix(mountpoint, "/System/Volumes/") &&
+		!strings.HasPrefix(mountpoint, "/System/Volumes/Data") {
+		return true
+	}
+
+	// Skip root partition "/" on macOS Catalina+ to avoid double counting with Data volume
+	// In modern macOS, "/" and "/System/Volumes/Data" are the same APFS container
+	if mountpoint == "/" {
+		return true
+	}
+
+	// Skip preboot and recovery volumes
+	if strings.Contains(mountpoint, "Preboot") ||
+		strings.Contains(mountpoint, "Recovery") ||
+		strings.Contains(mountpoint, "Update") ||
+		strings.Contains(mountpoint, "VM") {
+		return true
+	}
+
+	// Skip network mounts
+	if strings.HasPrefix(device, "//") ||
+		strings.HasPrefix(device, "afp://") ||
+		strings.HasPrefix(device, "smb://") ||
+		strings.HasPrefix(device, "nfs://") {
+		return true
+	}
+
+	// Skip virtual disk images
+	if strings.Contains(device, ".dmg") ||
+		strings.Contains(device, ".sparsebundle") ||
+		strings.Contains(device, ".sparseimage") {
+		return true
+	}
+
+	return false
+}
+
+// getAdditionalVirtualFilesystems returns macOS-specific virtual filesystem types
+func getAdditionalVirtualFilesystems() map[string]bool {
+	return macOSVirtualFilesystems
+}

+ 28 - 0
internal/analytic/disk_other.go

@@ -0,0 +1,28 @@
+//go:build !darwin
+
+package analytic
+
+// otherOSVirtualFilesystems contains additional virtual filesystem types for non-macOS systems
+var otherOSVirtualFilesystems = map[string]bool{
+	// Empty map for other systems - all virtual filesystems are already in the common list
+	// Could add Linux-specific virtual filesystems here if needed:
+	// "snap":      true,  // Snap package mounts
+	// "squashfs":  true,  // SquashFS (used by snap)
+	// "overlay":   true,  // Docker overlay filesystems (already in common list)
+}
+
+// shouldSkipPath checks if a path should be skipped from disk calculation on non-macOS systems
+func shouldSkipPath(mountpoint, device string) bool {
+	// For non-macOS systems, we only do basic filtering
+	// Most filtering is handled by the virtual filesystem check
+
+	// Could add Linux-specific logic here if needed
+	// For example: skip snap mounts, docker overlay filesystems, etc.
+
+	return false
+}
+
+// getAdditionalVirtualFilesystems returns additional virtual filesystem types for non-macOS systems
+func getAdditionalVirtualFilesystems() map[string]bool {
+	return otherOSVirtualFilesystems
+}