From 145244f63d2589203b1450af61987f16fb87aff3 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sun, 17 Aug 2025 17:43:34 -0500 Subject: more sanity checks --- isDriveInUse.go | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 isDriveInUse.go (limited to 'isDriveInUse.go') diff --git a/isDriveInUse.go b/isDriveInUse.go new file mode 100644 index 0000000..912ae07 --- /dev/null +++ b/isDriveInUse.go @@ -0,0 +1,95 @@ +package main + +import ( + "bufio" + "os" + "path/filepath" + "strings" + + "go.wit.com/log" +) + +func isBlockDeviceInUse(dev string) bool { + base := filepath.Base(dev) + + // 1. Check /proc/mounts + if isMounted(dev, base) { + log.Info(dev, "dev is mounted (/proc/mounts)") + return true + } + + // 2. Check /proc/swaps + if isSwap(dev) { + log.Info(dev, "dev is used by swap (/proc/swaps)") + return true + } + + // 3. Check /proc/mdstat for RAID + if isInRAID(base) { + log.Info(dev, "dev is in software raid (/proc/mdstat)") + return true + } + + // 4. Check sysfs for device-mapper or LVM use + if hasDMHolders(base) { + log.Info(dev, "dev has lvm partitions") + return true + } + + log.Info(dev, "dev appears to be unused") + return false +} + +func isMounted(dev, base string) bool { + f, err := os.Open("/proc/mounts") + if err != nil { + return false + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if strings.HasPrefix(scanner.Text(), dev) || strings.Contains(scanner.Text(), base) { + return true + } + } + return false +} + +func isSwap(dev string) bool { + f, err := os.Open("/proc/swaps") + if err != nil { + return false + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if strings.HasPrefix(scanner.Text(), dev) { + return true + } + } + return false +} + +func isInRAID(base string) bool { + f, err := os.Open("/proc/mdstat") + if err != nil { + return false + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if strings.Contains(scanner.Text(), base) { + return true + } + } + return false +} + +func hasDMHolders(base string) bool { + path := filepath.Join("/sys/block", base, "holders") + entries, err := os.ReadDir(path) + return err == nil && len(entries) > 0 +} -- cgit v1.2.3