summaryrefslogtreecommitdiff
path: root/watchForNewDrives.go
diff options
context:
space:
mode:
Diffstat (limited to 'watchForNewDrives.go')
-rw-r--r--watchForNewDrives.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/watchForNewDrives.go b/watchForNewDrives.go
new file mode 100644
index 0000000..74b2efe
--- /dev/null
+++ b/watchForNewDrives.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+ "fmt"
+ "log"
+ "syscall"
+)
+
+/*
+func main() {
+ go listenForBlockEvents()
+
+ // Simulate other work
+ select {}
+}
+*/
+
+func listenForBlockEvents() {
+ // Open netlink socket
+ fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_KOBJECT_UEVENT)
+ if err != nil {
+ log.Fatalf("Failed to open netlink socket: %v", err)
+ }
+ defer syscall.Close(fd)
+
+ sa := &syscall.SockaddrNetlink{
+ Family: syscall.AF_NETLINK,
+ Groups: 1, // receive broadcast group 1 (KOBJ events)
+ }
+
+ if err := syscall.Bind(fd, sa); err != nil {
+ log.Fatalf("Failed to bind netlink socket: %v", err)
+ }
+
+ buf := make([]byte, syscall.Getpagesize())
+
+ for {
+ n, _, err := syscall.Recvfrom(fd, buf, 0)
+ if err != nil {
+ log.Printf("Recvfrom error: %v", err)
+ continue
+ }
+
+ msg := parseUevent(buf[:n])
+ if msg["SUBSYSTEM"] == "block" && msg["ACTION"] == "add" {
+ fmt.Printf("New block device added: %s\n", msg["DEVNAME"])
+ }
+ }
+}
+
+// parseUevent parses the raw uevent buffer into a map
+func parseUevent(buf []byte) map[string]string {
+ msg := make(map[string]string)
+ parts := bytesToStrings(buf)
+ for _, part := range parts {
+ kv := splitKV(part)
+ if len(kv) == 2 {
+ msg[kv[0]] = kv[1]
+ }
+ }
+ return msg
+}
+
+func bytesToStrings(buf []byte) []string {
+ var parts []string
+ start := 0
+ for i := 0; i < len(buf); i++ {
+ if buf[i] == 0 {
+ if i > start {
+ parts = append(parts, string(buf[start:i]))
+ }
+ start = i + 1
+ }
+ }
+ return parts
+}
+
+func splitKV(s string) []string {
+ if i := indexByte(s, '='); i >= 0 {
+ return []string{s[:i], s[i+1:]}
+ }
+ return []string{s}
+}
+
+func indexByte(s string, b byte) int {
+ for i := 0; i < len(s); i++ {
+ if s[i] == b {
+ return i
+ }
+ }
+ return -1
+}