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
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;
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