[lxc-devel] [PATCH] lxc-ps: use posix shell and awk instead of bash

Stéphane Graber stgraber at ubuntu.com
Wed Jan 2 18:50:17 UTC 2013


On 01/02/2013 01:00 PM, Stéphane Graber wrote:
> On 12/26/2012 04:31 PM, Natanael Copa wrote:
>> Use awk to parse the output pf 'ps' and the tasks files for the
>> containers.
>>
>> Use awk fields to find PID column rather than assume that the PID field
>> is exactly 5 chars wide and has a leading space ' PID'. This works as
>> long as the PID field is before the command or other field that include
>> spaces. This also makes it work with busybox 'ps'.
>>
>> Signed-off-by: Natanael Copa <ncopa at alpinelinux.org>
> 
> Looks good. Pushed.
> 
> Acked-by: Stéphane Graber <stgraber at ubuntu.com>


Actually, the behaviour appears to have a changed quite a bit, at least
the output is quite clearly different.

I'm attaching some before/after output.

I don't think it's broken to the point where I should revert
immediately, but it'd be nice to have it fixed soon.

This was tested with:
 - lxc-ps
 - lxc-ps --lxc
 - lxc-ps --name raring-dev
 - lxc-ps --name raring-dev faux

On an Ubuntu 13.04 machine using a local build of staging.

> 
>> ---
>>  src/lxc/lxc-ps.in | 92 ++++++++++++++++++++++++++++++++-----------------------
>>  1 file changed, 54 insertions(+), 38 deletions(-)
>>
>> diff --git a/src/lxc/lxc-ps.in b/src/lxc/lxc-ps.in
>> index 1f45044..25e843b 100644
>> --- a/src/lxc/lxc-ps.in
>> +++ b/src/lxc/lxc-ps.in
>> @@ -1,4 +1,4 @@
>> -#!/bin/bash
>> +#!/bin/sh
>>  
>>  #
>>  # lxc: linux Container library
>> @@ -56,16 +56,16 @@ get_parent_cgroup()
>>          init_cgroup=${fields#*:}
>>  
>>          # Get the filesystem mountpoint of the hierarchy
>> -        mountpoint=$(grep -E "^cgroup [^ ]+ [^ ]+ ([^ ]+,)?$subsystems(,[^ ]+)? " /proc/self/mounts | cut -d ' ' -f 2)
>> +        mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \
>> +            '$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts)
>>          if [ -z "$mountpoint" ]; then continue; fi
>>  
>>          # Return the absolute path to the containers' parent cgroup
>>          # (do not append '/lxc' if the hierarchy contains the 'ns' subsystem)
>> -        if [[ ",$subsystems," == *,ns,* ]]; then
>> -            parent_cgroup="${mountpoint}${init_cgroup%/}"
>> -        else
>> -            parent_cgroup="${mountpoint}${init_cgroup%/}/lxc"
>> -        fi
>> +        case ",$subsystems," in
>> +            *,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";;
>> +            *) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";;
>> +        esac
>>          break
>>      done
>>  }
>> @@ -97,46 +97,62 @@ if [ ! -d "$parent_cgroup" ]; then
>>      exit 1
>>  fi
>>  
>> -declare -a container_of_pid
>> -container_field_width=9
>> -IFS=","
>>  if [ -z "$containers" ]; then
>> -    containers=( $(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d -printf "%f," 2>/dev/null) )
>> -else
>> -    containers=( $containers )
>> +    containers="$(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')"
>>  fi
>>  
>> -declare -i pid
>> -IFS=$'\n'
>> -for container in ${containers[@]}; do
>> +container_field_width=9
>> +tasks_files=
>> +for container in ${containers}; do
>>      if [ "${#container}" -gt "$container_field_width" ]; then
>>          container_field_width=${#container}
>>      fi
>>  
>>      if [ -f "$parent_cgroup/$container/tasks" ]; then
>> -        while read pid; do
>> -            container_of_pid[$pid]=$container
>> -        done < "$parent_cgroup/$container/tasks"
>> +        tasks_files="$tasks_files $parent_cgroup/$container/tasks"
>>      fi
>>  done
>>  
>> -declare -i line_pid_end_position
>> -while read line; do
>> -    if [ -z "$line_pid_end_position" ]; then
>> -        if [[ "$line" != *" PID"* ]]; then
>> -            echo "$(basename $0): no PID column found in \`ps' output" >&2
>> -            exit 1
>> -        fi
>> -
>> -        buffer=${line%" PID"*}
>> -        let line_pid_end_position=${#buffer}+4
>> -        printf "%-${container_field_width}s %s\n" "CONTAINER" "$line"
>> -        continue
>> -    fi
>> +# first file is stdin, the rest are the container tasks
>> +ps "$@" | awk -v container_field_width="$container_field_width" '
>> +# first line is PS header
>> +NR == 1 {
>> +    # find pid field index
>> +    for (i = 1; i<=NF; i++)
>> +        if ($i == "PID") {
>> +            pididx = i
>> +            break
>> +        }
>> +    if (pididx == "") {
>> +        print("No PID field found") > "/dev/stderr"
>> +        exit 1
>> +    }
>> +    header = $0
>> +    next
>> +}
>>  
>> -    buffer=${line:0:$line_pid_end_position}
>> -    pid=${buffer##* }
>> -    if [ "$list_container_processes" -eq "0" -o ! -z "${container_of_pid[pid]}" ]; then
>> -        printf "%-${container_field_width}s %s\n" "${container_of_pid[pid]}" "$line"
>> -    fi
>> -done < <(ps "$@")
>> +# store lines from ps with pid as index
>> +NR == FNR {
>> +    ps[$pididx] = $0
>> +    next
>> +}
>> +
>> +# find container name from filename on first line
>> +FNR == 1 {
>> +    container = FILENAME
>> +    sub(/\/tasks/, "", container)
>> +    sub(/.*\//, "", container)
>> +}
>> +
>> +# container tasks
>> +{
>> +    container_of_pid[$0] = container
>> +}
>> +
>> +END {
>> +    printf("%-" container_field_width "s %s\n", "CONTAINER", header)
>> +    for (pid in container_of_pid)
>> +        printf("%-" container_field_width "s %s\n", container_of_pid[pid], ps[pid])
>> +}
>> +
>> +' - $tasks_files
>>
> 
> 

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: new-lxc-ps
Type: application/octet-stream
Size: 9295 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130102/ece22b3d/attachment.obj>
-------------- next part --------------
Script started on Wed 02 Jan 2013 01:40:58 PM EST
root at castiana:~/data/code/lxc/test# lxc-ps
CONTAINER     PID TTY          TIME CMD
              836 pts/29   00:00:00 bash
              837 pts/29   00:00:00 lxc-ps
              849 pts/29   00:00:00 lxc-ps
              850 pts/29   00:00:00 ps
root at castiana:~/data/code/lxc/test# lxc-ps --lxc
CONTAINER     PID TTY          TIME CMD
android-dev  1636 ?        00:00:00 init
precise-gui  1648 ?        00:00:00 init
qatracker01  1696 ?        00:00:00 init
raring-dev   1720 ?        00:00:00 init
qatracker01  2310 ?        00:00:00 upstart-udev-br
qatracker01  2343 ?        00:00:00 rsyslogd
qatracker01  2454 ?        00:00:00 udevd
qatracker01  2576 pts/20   00:00:00 getty
qatracker01  2588 pts/18   00:00:00 getty
qatracker01  2589 pts/19   00:00:00 getty
qatracker01  2657 ?        00:00:00 cron
android-dev  2824 ?        00:00:00 upstart-udev-br
precise-gui  2854 ?        00:00:00 upstart-udev-br
raring-dev   2867 ?        00:00:00 upstart-udev-br
android-dev  2896 ?        00:00:00 udevd
precise-gui  2956 ?        00:00:00 udevd
android-dev  2957 ?        00:00:03 rsyslogd
android-dev  2962 ?        00:00:00 upstart-socket-
precise-gui  2964 ?        00:00:00 dbus-daemon
raring-dev   2967 ?        00:00:00 udevd
raring-dev   2968 ?        00:00:00 dbus-daemon
precise-gui  2969 ?        00:00:05 rsyslogd
precise-gui  3018 ?        00:00:00 upstart-socket-
qatracker01  3069 ?        00:00:02 postgres
android-dev  3074 ?        00:00:00 dhclient
raring-dev   3087 ?        00:00:04 rsyslogd
raring-dev   3110 ?        00:00:00 upstart-socket-
precise-gui  3120 ?        00:00:25 sssd
android-dev  3149 ?        00:00:00 sshd
raring-dev   3255 ?        00:00:00 dhclient
precise-gui  3293 ?        00:00:00 dhclient3
android-dev  3324 pts/10   00:00:00 getty
raring-dev   3327 ?        00:00:00 sshd
android-dev  3328 pts/8    00:00:00 getty
precise-gui  3329 ?        00:00:03 sssd_nss
precise-gui  3331 ?        00:00:03 sssd_pam
precise-gui  3332 ?        00:00:03 sssd_sudo
android-dev  3336 pts/9    00:00:00 getty
android-dev  3341 ?        00:00:00 cron
android-dev  3413 pts/11   00:00:00 getty
android-dev  3424 pts/7    00:00:00 getty
precise-gui  3443 ?        00:00:00 sshd
raring-dev   3493 pts/26   00:00:00 getty
raring-dev   3503 pts/24   00:00:00 getty
raring-dev   3508 pts/25   00:00:00 getty
raring-dev   3522 ?        00:00:00 cron
raring-dev   3524 ?        00:00:00 atd
raring-dev   3537 pts/27   00:00:00 getty
raring-dev   3541 pts/23   00:00:00 getty
precise-gui  3569 pts/15   00:00:00 getty
precise-gui  3578 pts/13   00:00:00 getty
precise-gui  3580 pts/14   00:00:00 getty
precise-gui  3585 ?        00:00:00 cron
precise-gui  3624 pts/16   00:00:00 getty
precise-gui  3627 pts/12   00:00:00 getty
precise-gui  3638 ?        00:00:00 whoopsie
qatracker01  3744 ?        00:00:40 postgres
qatracker01  3745 ?        00:00:31 postgres
qatracker01  3746 ?        00:00:08 postgres
qatracker01  3747 ?        00:00:06 postgres
qatracker01  3766 ?        00:00:00 dhclient3
qatracker01  3783 ?        00:00:00 sshd
qatracker01  3805 ?        00:00:07 apache2
qatracker01  3821 pts/17   00:00:00 getty
qatracker01  3822 pts/21   00:00:00 getty
precise-gui  4849 ?        00:00:04 sssd_be
qatracker01  9504 ?        00:00:00 apache2
qatracker01  9505 ?        00:00:00 apache2
qatracker01  9506 ?        00:00:00 apache2
qatracker01  9507 ?        00:00:00 apache2
qatracker01  9508 ?        00:00:00 apache2
raring-dev  14271 ?        00:00:00 udevd
raring-dev  14272 ?        00:00:00 udevd
android-dev 14284 ?        00:00:00 udevd
android-dev 14285 ?        00:00:00 udevd
qatracker01 14297 ?        00:00:00 udevd
qatracker01 14298 ?        00:00:00 udevd
precise-gui 14313 ?        00:00:00 udevd
precise-gui 14314 ?        00:00:00 udevd
raring-dev  16471 ?        00:00:00 sshd
raring-dev  16483 ?        00:00:00 sshd
raring-dev  16484 pts/0    00:00:00 bash
raring-dev  32564 pts/0    00:00:00 git
raring-dev  32565 pts/0    00:00:00 more
root at castiana:~/data/code/lxc/test# lxc-ps --name raring-dev
CONTAINER    PID TTY          TIME CMD
raring-dev  1720 ?        00:00:00 init
raring-dev  2867 ?        00:00:00 upstart-udev-br
raring-dev  2967 ?        00:00:00 udevd
raring-dev  2968 ?        00:00:00 dbus-daemon
raring-dev  3087 ?        00:00:04 rsyslogd
raring-dev  3110 ?        00:00:00 upstart-socket-
raring-dev  3255 ?        00:00:00 dhclient
raring-dev  3327 ?        00:00:00 sshd
raring-dev  3493 pts/26   00:00:00 getty
raring-dev  3503 pts/24   00:00:00 getty
raring-dev  3508 pts/25   00:00:00 getty
raring-dev  3522 ?        00:00:00 cron
raring-dev  3524 ?        00:00:00 atd
raring-dev  3537 pts/27   00:00:00 getty
raring-dev  3541 pts/23   00:00:00 getty
raring-dev 14271 ?        00:00:00 udevd
raring-dev 14272 ?        00:00:00 udevd
raring-dev 16471 ?        00:00:00 sshd
raring-dev 16483 ?        00:00:00 sshd
raring-dev 16484 pts/0    00:00:00 bash
raring-dev 32564 pts/0    00:00:00 git
raring-dev 32565 pts/0    00:00:00 more
root at castiana:~/data/code/lxc/test# lxc-ps --name raring-dev faux
CONTAINER  USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
raring-dev root      1720  0.0  0.0  26496  2304 ?        Ss    2012   0:00  _ /sbin/init
raring-dev root      2867  0.0  0.0  17256   636 ?        S     2012   0:00      _ upstart-udev-bridge --daemon
raring-dev root      2967  0.0  0.0  21356  1088 ?        Ss    2012   0:00      _ /sbin/udevd --daemon
raring-dev root     14271  0.0  0.0  21352   660 ?        S    12:38   0:00      |   _ /sbin/udevd --daemon
raring-dev root     14272  0.0  0.0  21352   404 ?        S    12:38   0:00      |   _ /sbin/udevd --daemon
raring-dev 103       2968  0.0  0.0  23828   696 ?        Ss    2012   0:00      _ dbus-daemon --system --fork
raring-dev syslog    3087  0.0  0.0 249504  1624 ?        Sl    2012   0:04      _ rsyslogd -c5
raring-dev root      3110  0.0  0.0  15344   736 ?        S     2012   0:00      _ upstart-socket-bridge --daemon
raring-dev root      3255  0.0  0.0  10200  2936 ?        Ss    2012   0:00      _ dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
raring-dev root      3327  0.0  0.0  49976  2804 ?        Ss    2012   0:00      _ /usr/sbin/sshd -D
raring-dev root     16471  0.0  0.0  73404  3528 ?        Ss   13:17   0:00      |   _ sshd: ubuntu [priv] 
raring-dev stgraber 16483  0.0  0.0  73404  1696 ?        S    13:17   0:00      |       _ sshd: ubuntu at pts/0  
raring-dev stgraber 16484  0.0  0.0  22468  3844 pts/0    Ss   13:17   0:00      |           _ -bash
raring-dev stgraber 32564  0.0  0.0  15672  1672 pts/0    S+   13:39   0:00      |               _ git log
raring-dev stgraber 32565  0.0  0.0   9428   996 pts/0    S+   13:39   0:00      |               _ more
raring-dev root      3493  0.0  0.0  12768   872 pts/26   Ss+   2012   0:00      _ /sbin/getty -8 38400 tty4
raring-dev root      3503  0.0  0.0  12768   868 pts/24   Ss+   2012   0:00      _ /sbin/getty -8 38400 tty2
raring-dev root      3508  0.0  0.0  12768   884 pts/25   Ss+   2012   0:00      _ /sbin/getty -8 38400 tty3
raring-dev root      3522  0.0  0.0  19128   896 ?        Ss    2012   0:00      _ cron
raring-dev daemon    3524  0.0  0.0  16924   160 ?        Ss    2012   0:00      _ atd
raring-dev root      3537  0.0  0.0  12768   876 pts/27   Ss+   2012   0:00      _ /sbin/getty -8 38400 console
raring-dev root      3541  0.0  0.0  12768   864 pts/23   Ss+   2012   0:00      _ /sbin/getty -8 38400 tty1
root at castiana:~/data/code/lxc/test# exit

Script done on Wed 02 Jan 2013 01:41:15 PM EST
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20130102/ece22b3d/attachment.pgp>


More information about the lxc-devel mailing list