| 149 | } |
| 150 | |
| 151 | func GetLoopDeviceMap() (map[string][]*Device, error) { |
| 152 | deviceMap := make(map[string][]*Device, 0) |
| 153 | cmd := exec.Command("losetup", "-a") |
| 154 | cmd.Env = []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"} |
| 155 | o, err := cmd.CombinedOutput() |
| 156 | if err != nil { |
| 157 | return nil, err |
| 158 | } |
| 159 | s := strings.Split(string(o), "\n") |
| 160 | for _, v := range s { |
| 161 | v = strings.TrimSpace(v) |
| 162 | if len(v) == 0 { |
| 163 | continue |
| 164 | } |
| 165 | if !strings.HasPrefix(v, "/dev/loop") { |
| 166 | continue |
| 167 | } |
| 168 | loopInfoSlice := strings.Split(strings.TrimSpace(v), " ") |
| 169 | if len(loopInfoSlice) < 3 { |
| 170 | continue |
| 171 | } |
| 172 | numStr := strings.Trim(strings.TrimLeft(loopInfoSlice[0], "/dev/loop"), ":") |
| 173 | if numStr == "" { |
| 174 | continue |
| 175 | } |
| 176 | loopNum, err := strconv.ParseUint(numStr, 10, 64) |
| 177 | if err != nil { |
| 178 | continue |
| 179 | } |
| 180 | device := NewDevice(loopNum, os.O_RDWR) |
| 181 | deviceID, err := utils.GetDevice(device.String()) |
| 182 | if err != nil { |
| 183 | continue |
| 184 | } |
| 185 | device.Rdev = deviceID |
| 186 | fPath := strings.TrimRight(strings.TrimLeft(loopInfoSlice[2], "("), ")") |
| 187 | |
| 188 | if len(loopInfoSlice) == 4 && strings.ContainsAny(loopInfoSlice[3], "(deleted)") { |
| 189 | device.IsDeleted = true |
| 190 | } |
| 191 | |
| 192 | if deviceList, ok := deviceMap[loopInfoSlice[2]]; !ok { |
| 193 | deviceMap[fPath] = []*Device{&device} |
| 194 | } else { |
| 195 | deviceMap[fPath] = append(deviceList, &device) |
| 196 | } |
| 197 | } |
| 198 | return deviceMap, nil |
| 199 | } |