[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