package main import ( "bytes" "log" "os" "path/filepath" "strconv" "strings" "syscall" "golang.org/x/sys/unix" ) // Simulate a udev run for our needs func syncSysToDev() { // loop devices sysPaths, _ := filepath.Glob("/sys/devices/virtual/block/loop*/**/dev") for _, sysPath := range sysPaths { mknodBlk(sysPath) } } func mknodBlk(sysPath string) { devPath := "/dev/" + filepath.Base(filepath.Dir(sysPath)) if _, err := os.Stat(devPath); os.IsNotExist(err) { // ok } else if err != nil { log.Printf("stat %s failed: %v", devPath, err) return } else { return // exists } devBytes, err := os.ReadFile(sysPath) if err != nil { log.Printf("read %s failed: %v", sysPath, err) return } devBytes = bytes.TrimSpace(devBytes) // rust: let Some(dev) = devBytes.split_once(':').filter_map(|a,b| Some(mkdev(a.parse().ok()?, b.parse().ok()?))); majorStr, minorStr, ok := strings.Cut(string(devBytes), ":") if !ok { log.Printf("%s: invalid dev string: %s", sysPath, string(devBytes)) return } major, err := strconv.ParseUint(majorStr, 10, 32) if err != nil { log.Printf("%s: invalid major: %q", sysPath, majorStr) return } minor, err := strconv.ParseUint(minorStr, 10, 32) if err != nil { log.Printf("%s: invalid minor: %q", sysPath, minorStr) return } devMajMin := int(unix.Mkdev(uint32(major), uint32(minor))) log.Printf("mknod %s b %d %d", devPath, major, minor) unix.Mknod(devPath, syscall.S_IFBLK|0o0600, devMajMin) }