summaryrefslogtreecommitdiff
path: root/doDrives.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-08-16 00:36:47 -0500
committerJeff Carr <[email protected]>2025-08-16 00:36:47 -0500
commitde6b45ced2fec64bdd4eb1c7d90c13251d394fe8 (patch)
treed5c4b08c74b4c3b3df544d0585a4cc0cea2878a1 /doDrives.go
day1v0.0.1
Diffstat (limited to 'doDrives.go')
-rw-r--r--doDrives.go138
1 files changed, 138 insertions, 0 deletions
diff --git a/doDrives.go b/doDrives.go
new file mode 100644
index 0000000..bc22dae
--- /dev/null
+++ b/doDrives.go
@@ -0,0 +1,138 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "go.wit.com/log"
+)
+
+func doDrives() {
+ parts, err := parseProcPartitions()
+ if err != nil {
+ panic(err)
+ }
+
+ for _, p := range parts {
+ fmt.Printf("Device: /dev/%s\tSize: %d KiB\n", p.Name, p.Blocks)
+ }
+
+ blockDir := "/sys/block"
+ mounts := getMountedDevices()
+
+ log.Info("doDrives()", mounts)
+
+ err = filepath.WalkDir(blockDir, func(path string, d fs.DirEntry, err error) error {
+ if path == blockDir {
+ return nil // skip root
+ }
+ if d.IsDir() && filepath.Dir(path) == blockDir {
+ dev := d.Name()
+ devPath := "/dev/" + dev
+ fmt.Printf("Drive: %s\n", devPath)
+
+ // Look for partitions
+ partitions, err := filepath.Glob(filepath.Join(blockDir, dev, dev+"*"))
+ if err != nil {
+ return err
+ }
+
+ hasPartition := false
+ used := false
+ for _, part := range partitions {
+ partName := filepath.Base(part)
+ if partName == dev {
+ continue // skip the main device
+ }
+ hasPartition = true
+ partDev := "/dev/" + partName
+ isMounted := mounts[partDev]
+ fmt.Printf(" Partition: %s [%v]\n", partDev, isMounted)
+ if isMounted {
+ used = true
+ }
+ }
+
+ if !hasPartition {
+ fmt.Println(" No partitions found.")
+ }
+
+ if !used {
+ fmt.Println(" → Drive appears to be unused.")
+ }
+ }
+ return nil
+ })
+
+ if err != nil {
+ panic(err)
+ }
+}
+
+// getMountedDevices reads /proc/self/mountinfo and returns a map of mounted device paths
+func getMountedDevices() map[string]bool {
+ f, err := os.Open("/proc/self/mountinfo")
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+
+ mounted := make(map[string]bool)
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ fields := strings.Fields(line)
+ if len(fields) < 10 {
+ continue
+ }
+ // Device path is after the last '-' token
+ for i, field := range fields {
+ if field == "-" && i+2 < len(fields) {
+ dev := fields[i+2]
+ if strings.HasPrefix(dev, "/dev/") {
+ mounted[dev] = true
+ }
+ break
+ }
+ }
+ }
+ return mounted
+}
+
+type Partition struct {
+ Major int
+ Minor int
+ Blocks int64
+ Name string
+}
+
+func parseProcPartitions() ([]Partition, error) {
+ f, err := os.Open("/proc/partitions")
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ var partitions []Partition
+ scanner := bufio.NewScanner(f)
+
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if strings.HasPrefix(line, "major") || line == "" {
+ continue // Skip header and empty lines
+ }
+
+ var p Partition
+ _, err := fmt.Sscanf(line, "%d %d %d %s", &p.Major, &p.Minor, &p.Blocks, &p.Name)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing line: %q: %w", line, err)
+ }
+ partitions = append(partitions, p)
+ }
+
+ return partitions, scanner.Err()
+}