// Get information about block devices present on the system. // Uses the passed in system interface to retrieve the low level OS information. func GetBlockDeviceInfo(sysfs sysfs.SysFs) (map[string]info.DiskInfo, error) { disks, err := sysfs.GetBlockDevices() if err != nil { return nil, err } diskMap := make(map[string]info.DiskInfo) for _, disk := range disks { name := disk.Name() // Ignore non-disk devices. // TODO(rjnagal): Maybe just match hd, sd, and dm prefixes. if strings.HasPrefix(name, "loop") || strings.HasPrefix(name, "ram") || strings.HasPrefix(name, "sr") { continue } disk_info := info.DiskInfo{ Name: name, } dev, err := sysfs.GetBlockDeviceNumbers(name) if err != nil { return nil, err } n, err := fmt.Sscanf(dev, "%d:%d", &disk_info.Major, &disk_info.Minor) if err != nil || n != 2 { return nil, fmt.Errorf("could not parse device numbers from %s for device %s", dev, name) } out, err := sysfs.GetBlockDeviceSize(name) if err != nil { return nil, err } // Remove trailing newline before conversion. size, err := strconv.ParseUint(strings.TrimSpace(out), 10, 64) if err != nil { return nil, err } // size is in 512 bytes blocks. disk_info.Size = size * 512 sched, err := sysfs.GetBlockDeviceScheduler(name) if err != nil { sched = "none" } else { matches := schedulerRegExp.FindSubmatch([]byte(sched)) if len(matches) < 2 { sched = "none" } else { sched = string(matches[1]) } } disk_info.Scheduler = sched device := fmt.Sprintf("%d:%d", disk_info.Major, disk_info.Minor) diskMap[device] = disk_info } return diskMap, nil }