Skip to content
Permalink
Browse files

Fix kpartx parsing to return devices in right order

Previously we were assuming that the first number in
the kpartx output is index for the device, but found out that it's
probably static zero, reserved for something.
Updated the parsing to sort based on starting point of partition.
  • Loading branch information...
ernoaapa committed Mar 14, 2018
1 parent cd804ab commit b343965b040a56b46ca90a91b568912ea4939c8c
Showing with 25 additions and 8 deletions.
  1. +23 −6 pkg/image/kpartx.go
  2. +2 −2 pkg/image/kpartx_test.go
@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"os/exec"
"sort"
"strconv"
"strings"

@@ -37,25 +38,41 @@ func removeDevMappings(path string) error {
func mustParseDevMappings(raw string) []string {
scanner := bufio.NewScanner(strings.NewReader(raw))

partitions := []string{}
lines := []string{}
for scanner.Scan() {
line := scanner.Text()
if line != "" && !strings.Contains(line, "deleted") {
partitions = append(partitions, line)
lines = append(lines, line)
}
}

result := make([]string, len(partitions))
for _, line := range partitions {
partitions := make([]struct {
start int
path string
}, len(lines))

for i, line := range lines {
parts := strings.SplitN(line, ":", 2)
if parts[0] != "" {
info := strings.SplitN(strings.TrimSpace(parts[1]), " ", 4)
index, err := strconv.Atoi(info[0])
size, err := strconv.Atoi(info[3])
if err != nil {
log.Fatalf("Failed to parse kpartx output line: %s", line)
}
result[index] = fmt.Sprintf("/dev/mapper/%s", strings.TrimSpace(parts[0]))
partitions[i] = struct {
start int
path string
}{
start: size,
path: fmt.Sprintf("/dev/mapper/%s", strings.TrimSpace(parts[0])),
}
}
}
sort.Slice(partitions, func(i, j int) bool { return partitions[i].start < partitions[j].start })

result := make([]string, len(partitions))
for i, device := range partitions {
result[i] = device.path
}
return result
}
@@ -14,12 +14,12 @@ loop deleted : /dev/loop0

assert.Equal(t, []string{"/dev/mapper/loop1p1", "/dev/mapper/loop1p2"}, mustParseDevMappings(`
loop1p1 : 0 202752 /dev/loop1 2048
loop1p2 : 1 202752 /dev/loop1 102400
loop1p2 : 0 202752 /dev/loop1 102400
loop deleted : /dev/loop1
`))

assert.Equal(t, []string{"/dev/mapper/loop1p1", "/dev/mapper/loop1p2"}, mustParseDevMappings(`
loop1p2 : 1 202752 /dev/loop1 102400
loop1p2 : 0 202752 /dev/loop1 102400
loop1p1 : 0 202752 /dev/loop1 2048
loop deleted : /dev/loop1
`))

0 comments on commit b343965

Please sign in to comment.
You can’t perform that action at this time.