Skip to content

Commit a7497c3

Browse files
committed
Fixing issue of docker top command failure when dealing with -m option
Changed per requested review to refactor to make it more logic clear. Current output for "docker top <contianer-id> m" option,eg: root@b2c7ec58399d:/go/src/github.com/docker/docker# docker top 755d5871ec45 am PID TTY STAT TIME COMMAND 148 pts/0 - 0:00 bash - - Ss+ 0:00 - fixing issue:moby#30580 Signed-off-by: catinthesky <[email protected]>
1 parent 3c32e17 commit a7497c3

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

daemon/top_unix.go

+38-9
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@ func fieldsASCII(s string) []string {
4141
return strings.FieldsFunc(s, fn)
4242
}
4343

44+
func appendProcess2ProcList(procList *container.ContainerTopOKBody, fields []string) {
45+
// Make sure number of fields equals number of header titles
46+
// merging "overhanging" fields
47+
process := fields[:len(procList.Titles)-1]
48+
process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
49+
procList.Processes = append(procList.Processes, process)
50+
}
51+
52+
func hasPid(pids []int, pid int) bool {
53+
for _, i := range pids {
54+
if i == pid {
55+
return true
56+
}
57+
}
58+
return false
59+
}
60+
4461
func parsePSOutput(output []byte, pids []int) (*container.ContainerTopOKBody, error) {
4562
procList := &container.ContainerTopOKBody{}
4663

@@ -58,25 +75,37 @@ func parsePSOutput(output []byte, pids []int) (*container.ContainerTopOKBody, er
5875
}
5976

6077
// loop through the output and extract the PID from each line
78+
// fixing #30580, be able to display thread line also when "m" option used
79+
// in "docker top" client command
80+
preContainedPidFlag := false
6181
for _, line := range lines[1:] {
6282
if len(line) == 0 {
6383
continue
6484
}
6585
fields := fieldsASCII(line)
66-
p, err := strconv.Atoi(fields[pidIndex])
86+
87+
var (
88+
p int
89+
err error
90+
)
91+
92+
if fields[pidIndex] == "-" {
93+
if preContainedPidFlag {
94+
appendProcess2ProcList(procList, fields)
95+
}
96+
continue
97+
}
98+
p, err = strconv.Atoi(fields[pidIndex])
6799
if err != nil {
68100
return nil, fmt.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
69101
}
70102

71-
for _, pid := range pids {
72-
if pid == p {
73-
// Make sure number of fields equals number of header titles
74-
// merging "overhanging" fields
75-
process := fields[:len(procList.Titles)-1]
76-
process = append(process, strings.Join(fields[len(procList.Titles)-1:], " "))
77-
procList.Processes = append(procList.Processes, process)
78-
}
103+
if hasPid(pids, p) {
104+
preContainedPidFlag = true
105+
appendProcess2ProcList(procList, fields)
106+
continue
79107
}
108+
preContainedPidFlag = false
80109
}
81110
return procList, nil
82111
}

daemon/top_unix_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,20 @@ func TestContainerTopParsePSOutput(t *testing.T) {
4242
{[]byte(` PID COMMAND
4343
42 foo
4444
43 bar
45+
- -
4546
100 baz
4647
`), []int{42, 43}, false},
4748
{[]byte(` UID COMMAND
4849
42 foo
4950
43 bar
51+
- -
5052
100 baz
5153
`), []int{42, 43}, true},
5254
// unicode space (U+2003, 0xe2 0x80 0x83)
5355
{[]byte(` PID COMMAND
5456
42 foo
5557
43 bar
58+
- -
5659
100 baz
5760
`), []int{42, 43}, true},
5861
// the first space is U+2003, the second one is ascii.

0 commit comments

Comments
 (0)