summaryrefslogtreecommitdiff
path: root/isDriveInUse.go
diff options
context:
space:
mode:
Diffstat (limited to 'isDriveInUse.go')
-rw-r--r--isDriveInUse.go95
1 files changed, 95 insertions, 0 deletions
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
+}