97 lines
1.9 KiB
Go
97 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"syscall"
|
|
|
|
"go.wit.com/log"
|
|
)
|
|
|
|
/*
|
|
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" {
|
|
log.Printf("New block device added: %s\n", msg["DEVNAME"])
|
|
devname := "/dev/" + msg["DEVNAME"]
|
|
me.dd.AddText(devname + " new")
|
|
me.pb.InsertByName(devname)
|
|
}
|
|
log.Printf("New syscall.NETLINK_KOBJECT_UEVENT: %v\n", msg)
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|