Bug 1293063 - docker top treats ps args differently based on -d/-t
Summary: docker top treats ps args differently based on -d/-t
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: docker
Version: 23
Hardware: All
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Antonio Murdaca
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-12-19 19:18 UTC by Brent Baude
Modified: 2015-12-21 16:19 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-12-21 16:19:10 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Brent Baude 2015-12-19 19:18:50 UTC
docker top now takes ps_args as optional arguments.  There is a bug in docker where when ps args are provided, the return of docker top will differ.


To replicate, run two containers:

# docker run -d centos /usr/bin/vi
b753f4832fb11d260ab39c68ae6d6376d75cfbe20392b553b0d5a9679e7d483d

# docker run -it --rm centos /bin/bash
[root@01a2e3db9f7d /]#

Now, execute docker top for each without ps args.   The results are accurate:

$ docker top b753f4832fb
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                6103                3848                0                   13:12               ?                   00:00:00            /usr/bin/vi
$ docker top 01a2e3db9f7d
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                6025                3848                0                   13:12               pts/3               00:00:00            /bin/bash


Now execute the same commands but pass ps args with -o.

$ docker top b753f4832fb -o pid,cmd
PID                 CMD
6103                /usr/bin/vi
$ docker top 01a2e3db9f7d -o pid,cmd
PID                 CMD

Note how the second command issue returned no results.

Now execute the same commands but pass ps args with only 'o'
$ docker top b753f4832fb o pid,cmd
PID                 CMD
$ docker top 01a2e3db9f7d o pid,cmd
PID                 CMD
6025                /bin/bash


Note how the results are not inverse of before, where we didn't get results, we now do and visa versa.

Comment 1 Antonio Murdaca 2015-12-21 15:31:15 UTC
This is not a docker bug. Rather this is the way "ps" works wrt processes that have (or have not) a TTY. Let me explain. I'll work out a patch to the docker top man page after this.

You are running two containers, one with a TTY and one without.

When doing "docker top", docker shells out to the "ps" binary to find information about the pid the container is running with. It does so by first listing all processes and then selectively filtering out all pids except the container's one.

When "docker top" runs without ps arguments it will default to shell out to "ps -ef" (note the dash) which selects all processes (-e) and does full-format listing (-f).

But, "-ef" is UNIX style. If you run "ps ef" you'll get a totally different result because without the dash ps is interpreting the options as BSD style options.
If you want to list all process using the BSD style (the same way "ps -ef") you have to do, instead, "ps axu"

So this is why "docker top" without ps args works fine for both containers - because it's listing all processes (both with and w/o ttys)

Enough with this. Now let's get to TTYs.

---

If you provide ps arguments to "docker top", then Docker drops the default "-ef" argument in favor of just using the ones you provided.

Let's interpret your commands.

===

A. using "-o" which is UNIX style

1. you run a contianer WITH a TTY

1a. you run "docker top CONTAINERTTY -o pid,cmd"
1b. you are explicitly using the UNIX style ps options. The -o flag means use the UNIX style "-o" option which is a shorthand for "--format" to select fields.
1c. Docker will run "ps -o pid,cmd" to get a list of all processes
1d. from man ps: "ps selects all processes with the same effective user ID (euid=EUID) as the current user and associated with the same terminal as the invoker."
1e. so when docker runs "ps -o pid,cmd" it won't get anything because your container is running with another TTY (/dev/pts/3 for instance)

This is why you'll get no output when running with "-o" and a container WITH a TTY

2. you run a container WITHOUT a TTY

2a. on the other end, when you run "docker top CONTAINERNOTTY -o pid,cmd" the container do not get a TTY (that's why the TTY colum of just "docker top ID" shows "?")
2b. Docker will run "ps o pid,cmd"
2c. This time we'll get the correct process because the container runs with the same EUID + the calling process has not TTY (like the container)

This is why you'll get output when running with "-o" and a container WITHOUT a TTY

===

B. using "o" which is BSD style

1. you run a contianer WITH a TTY

1a. you run "docker top CONTAINERTTY o pid,cmd"
1b. you are explicitly using the BSD style ps options. The o flag means use the BSD style "o" option (same as UNIX -o and --format to select fields).
1c. Docker will run "ps o pid,cmd" to get a list of all processes
1d. when ps runs w/o BSD args it enforces processes to have a TTY!
1e. so when docker runs "ps o pid,cmd" it will get the correct pid because your container pid is listed because it has a TTY (/dev/pts/3 for instance)

This is why you'll get output when running with "o" and a container WITH a TTY

2. you run a container WITHOUT a TTY

2a. on the other end, when you run "docker top CONTAINERNOTTY o pid,cmd" the container do not get a TTY (that's why the TTY colum of just "docker top ID" shows "?")
2b. Docker will run "ps o pid,cmd"
2c. This time we won't get the correct process because the container runs w/o a TTY and ps with BSD style args do not list processes w/o a TTY

This is why you'll get no output when running with "o" and a container WITHOUT a TTY

===

All of that said, the correct args to give to "docker top" to achieve consistency with and w/o a TTY are either:

BSD-style: "docker top CONTAINER axo pid,cmd" 

or:

UNIX-style: "docker top CONTAINER -eo pid,cmd"

Both will firstly show all processes and then docker filters out to the pid the containers are running with.

Comment 2 Antonio Murdaca 2015-12-21 15:32:31 UTC
Sorry for the long explanation. I'll work out a patch for the "docker top" man page upstream.

Comment 3 Brent Baude 2015-12-21 16:11:15 UTC
Great explaination, thanks!  Want me to close this as not-a-bug ?


Note You need to log in before you can comment on or make changes to this bug.