From: Michel Normand Date: Thu, 26 Nov 2009 15:46:22 +0000 (+0100) Subject: lxc-ps to limit its search to containers X-Git-Tag: lxc-0.6.5~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f63147349be9cac87f8f9abe08edacfe36f2c617;p=thirdparty%2Flxc.git lxc-ps to limit its search to containers The purpose of this patch is to limit the search of pids to those in containers by looking at first in the /cgroup//tasks when --lxc or --names options are specified by user. The idea is to speedup the output when only few container names are specified while the machine is running with many processes. Signed-off-by: Michel Normand Signed-off-by: Daniel Lezcano --- diff --git a/src/lxc/lxc-ps.in b/src/lxc/lxc-ps.in index 567c4dc5a..249b10439 100755 --- a/src/lxc/lxc-ps.in +++ b/src/lxc/lxc-ps.in @@ -35,12 +35,54 @@ our @PS_LINES; # Output lines of the ps command our $LXC_DISPLAY = 0; # By default do not display container information our %LXC_NAMES; # Specified container names (if any) +sub get_container_names { + my $ref_names = shift; + my $lxcpath='@LXCPATH@'; + + open(active, "netstat -xa | grep $lxcpath |") or return; + while() { + chomp; + s#.*$lxcpath/(.*)/command.*#$1#; + push @$ref_names, $_; + } + close active; +} + +sub get_cgroup { + my $ref_cgroup = shift; + my $mount_string; + + $mount_string=`mount -t cgroup |grep -E -e '^lxc '`; + unless ($mount_string) { + $mount_string=`mount |grep -m1 'type cgroup'`; + } + chomp($mount_string); + if ($mount_string) { + $$ref_cgroup=`echo "$mount_string" |cut -d' ' -f3`; + chomp($$ref_cgroup); + } + die "unable to find mounted cgroup" unless $$ref_cgroup; +} -# Reclaim the PID index in the ps output. -# The $PS_HEADERS must be set to the first line of ps output and must -# contains the columns headers. -# This function will set the $PS_PID_INDEX global or exit with an error -# message if the PID index can't be retrieved. +sub get_pids_in_containers { + my $ref_names = shift; + my $ref_cgroup = shift; + my $ref_pids = shift; + my @pidlist; + + for (@{$ref_names}) { + my $task_file = "$$ref_cgroup/$_/tasks"; + + $LXC_NAMES{$_} = 1; + open(tasks, "cat $task_file 2>/dev/null |") or next; + while () { + chomp $_; + push @pidlist, $_; + } + close tasks; + } + $$ref_pids = join(',', @pidlist); +} sub reclaim_pid_index { my @headers = split " ", $PS_HEADERS; @@ -54,28 +96,18 @@ sub reclaim_pid_index { exit 1; } - -# Execute the ps command - sub execute_ps { open(ps, "ps @_ |") or die "Cannot execute ps command: $!\n"; - # Reclaim the PID index in ps output $PS_HEADERS = ; reclaim_pid_index; - # Reclaim lines of ps output while () { push @PS_LINES, $_; } close ps; } - -# Get the container name (if any) associated to a given PID. -# @param $pid The PID to use. -# @return The container name as a string or an empty string. - sub get_container { my $pid = shift; my $filename = "/proc/$pid/cgroup"; @@ -91,26 +123,16 @@ sub get_container { return $container; } - -# Display headers line. -# The $PS_HEADERS global must be set. - sub display_headers { printf "%-10s %s", "CONTAINER", $PS_HEADERS; } - -# Display command usage - sub display_usage { print < 0) { - # Display processes related to specified containers - $LXC_DISPLAY = 2; - foreach (@arg_name) { - $LXC_NAMES{$_} = 1; - } - @ARGV = ('-e', @ARGV); + $LXC_DISPLAY = 1; + get_container_names \@arg_name; +} +if (@arg_name > 0) { + my $cgroup; + my $pid_list; + $LXC_DISPLAY = 2; + + get_cgroup \$cgroup; + get_pids_in_containers(\@arg_name, \$cgroup, \$pid_list); + if ($pid_list) { + @ARGV = ("-p $pid_list",@ARGV); + } } - - -# Execute the ps command execute_ps @ARGV; - -# Display result with addition of container name - display_headers; for (@PS_LINES) { my @a = split; my $container = get_container $a[$PS_PID_INDEX]; - if ($LXC_DISPLAY == 1 and $container eq '') {next;} if ($LXC_DISPLAY == 2 and not $LXC_NAMES{$container}) {next;} + if ($LXC_DISPLAY == 1 and $container eq '') {next;} printf "%-10s %s", $container, $_; } - -# Done - exit 0;