]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc-ps to limit its search to containers
authorMichel Normand <normand@fr.ibm.com>
Thu, 26 Nov 2009 15:46:22 +0000 (16:46 +0100)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Thu, 26 Nov 2009 15:46:22 +0000 (16:46 +0100)
The purpose of this patch is to limit the search
of pids to those in containers by looking at first
in the /cgroup/<name>/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 <michel.mno@free.fr>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/lxc-ps.in

index 567c4dc5a945ab5fa6f73dcc5bcf34713bfe8f9d..249b104399000e552bd83b0fcab9582eaaa3f77a 100755 (executable)
@@ -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(<active>) {
+               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 (<tasks>) {
+                       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 = <ps>;
     reclaim_pid_index;
 
-    # Reclaim lines of ps output
     while (<ps>) {
        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 <<EOF;
 Usage: lxc-ps [--help] [--usage] [--name NAME...] [--lxc] [ps options]
 EOF
 }
 
-
-# Display command help
-
 sub display_help {
     display_usage;
     print <<EOF;
@@ -130,9 +152,6 @@ or try a 'ps --help' for further details.
 EOF
 }
 
-
-# Process lxc-ps arguments and build
-
 use Getopt::Long qw(:config no_auto_abbrev pass_through);
 
 my $arg_help  = '';
@@ -153,36 +172,30 @@ if ($arg_usage) {display_usage; exit 0;}
 
 # Should we filter processes related to containers
 if ($arg_lxc) {
-    # Display processes related to all containers
-    $LXC_DISPLAY = 1;
-    @ARGV = ('-e', @ARGV);
-} elsif (@arg_name > 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;