Commit f6314734 by Michel Normand Committed by Daniel Lezcano

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/<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: 's avatarMichel Normand <michel.mno@free.fr> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 65cb447f
...@@ -35,12 +35,54 @@ our @PS_LINES; # Output lines of the ps command ...@@ -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_DISPLAY = 0; # By default do not display container information
our %LXC_NAMES; # Specified container names (if any) 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. sub get_pids_in_containers {
# The $PS_HEADERS must be set to the first line of ps output and must my $ref_names = shift;
# contains the columns headers. my $ref_cgroup = shift;
# This function will set the $PS_PID_INDEX global or exit with an error my $ref_pids = shift;
# message if the PID index can't be retrieved. 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 { sub reclaim_pid_index {
my @headers = split " ", $PS_HEADERS; my @headers = split " ", $PS_HEADERS;
...@@ -54,28 +96,18 @@ sub reclaim_pid_index { ...@@ -54,28 +96,18 @@ sub reclaim_pid_index {
exit 1; exit 1;
} }
# Execute the ps command
sub execute_ps { sub execute_ps {
open(ps, "ps @_ |") or die "Cannot execute ps command: $!\n"; open(ps, "ps @_ |") or die "Cannot execute ps command: $!\n";
# Reclaim the PID index in ps output
$PS_HEADERS = <ps>; $PS_HEADERS = <ps>;
reclaim_pid_index; reclaim_pid_index;
# Reclaim lines of ps output
while (<ps>) { while (<ps>) {
push @PS_LINES, $_; push @PS_LINES, $_;
} }
close ps; 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 { sub get_container {
my $pid = shift; my $pid = shift;
my $filename = "/proc/$pid/cgroup"; my $filename = "/proc/$pid/cgroup";
...@@ -91,26 +123,16 @@ sub get_container { ...@@ -91,26 +123,16 @@ sub get_container {
return $container; return $container;
} }
# Display headers line.
# The $PS_HEADERS global must be set.
sub display_headers { sub display_headers {
printf "%-10s %s", "CONTAINER", $PS_HEADERS; printf "%-10s %s", "CONTAINER", $PS_HEADERS;
} }
# Display command usage
sub display_usage { sub display_usage {
print <<EOF; print <<EOF;
Usage: lxc-ps [--help] [--usage] [--name NAME...] [--lxc] [ps options] Usage: lxc-ps [--help] [--usage] [--name NAME...] [--lxc] [ps options]
EOF EOF
} }
# Display command help
sub display_help { sub display_help {
display_usage; display_usage;
print <<EOF; print <<EOF;
...@@ -130,9 +152,6 @@ or try a 'ps --help' for further details. ...@@ -130,9 +152,6 @@ or try a 'ps --help' for further details.
EOF EOF
} }
# Process lxc-ps arguments and build
use Getopt::Long qw(:config no_auto_abbrev pass_through); use Getopt::Long qw(:config no_auto_abbrev pass_through);
my $arg_help = ''; my $arg_help = '';
...@@ -153,36 +172,30 @@ if ($arg_usage) {display_usage; exit 0;} ...@@ -153,36 +172,30 @@ if ($arg_usage) {display_usage; exit 0;}
# Should we filter processes related to containers # Should we filter processes related to containers
if ($arg_lxc) { if ($arg_lxc) {
# Display processes related to all containers $LXC_DISPLAY = 1;
$LXC_DISPLAY = 1; get_container_names \@arg_name;
@ARGV = ('-e', @ARGV); }
} elsif (@arg_name > 0) { if (@arg_name > 0) {
# Display processes related to specified containers my $cgroup;
$LXC_DISPLAY = 2; my $pid_list;
foreach (@arg_name) { $LXC_DISPLAY = 2;
$LXC_NAMES{$_} = 1;
} get_cgroup \$cgroup;
@ARGV = ('-e', @ARGV); get_pids_in_containers(\@arg_name, \$cgroup, \$pid_list);
if ($pid_list) {
@ARGV = ("-p $pid_list",@ARGV);
}
} }
# Execute the ps command
execute_ps @ARGV; execute_ps @ARGV;
# Display result with addition of container name
display_headers; display_headers;
for (@PS_LINES) { for (@PS_LINES) {
my @a = split; my @a = split;
my $container = get_container $a[$PS_PID_INDEX]; 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 == 2 and not $LXC_NAMES{$container}) {next;}
if ($LXC_DISPLAY == 1 and $container eq '') {next;}
printf "%-10s %s", $container, $_; printf "%-10s %s", $container, $_;
} }
# Done
exit 0; exit 0;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment