cgtop: add -M/--machine

This commit is contained in:
Evgeny Vereshchagin 2015-09-21 12:04:45 +00:00
parent 8c710f3ce6
commit 96a6426f30
3 changed files with 80 additions and 3 deletions

View File

@ -246,6 +246,15 @@
3.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-M <replaceable>MACHINE</replaceable></option></term>
<term><option>--machine=<replaceable>MACHINE</replaceable></option></term>
<listitem><para>Limit control groups shown to the part
corresponding to the container
<replaceable>MACHINE</replaceable>.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>

View File

@ -24,17 +24,32 @@ __contains_word() {
done
}
__get_machines() {
local a b
machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
}
_systemd_cgtop() {
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
local comps
local -A OPTS=(
[STANDALONE]='-h --help --version -p -t -c -m -i -b --batch -n --iterations -d --delay'
[ARG]='--cpu --depth'
[ARG]='--cpu --depth -M --machine'
)
_init_completion || return
if __contains_word "$prev" ${OPTS[ARG]}; then
case $prev in
--machine|-M)
comps=$( __get_machines )
;;
esac
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
return 0
fi
COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
}

View File

@ -36,6 +36,10 @@
#include "cgroup-util.h"
#include "build.h"
#include "fileio.h"
#include "sd-bus.h"
#include "bus-util.h"
#include "bus-error.h"
#include "unit-name.h"
typedef struct Group {
char *path;
@ -65,6 +69,7 @@ static unsigned arg_iterations = (unsigned) -1;
static bool arg_batch = false;
static bool arg_raw = false;
static usec_t arg_delay = 1*USEC_PER_SEC;
static char* arg_machine = NULL;
enum {
COUNT_PIDS,
@ -645,6 +650,7 @@ static void help(void) {
" -n --iterations=N Run for N iterations before exiting\n"
" -b --batch Run in batch mode, accepting no input\n"
" --depth=DEPTH Maximum traversal depth (default: %u)\n"
" -M --machine= Show container\n"
, program_invocation_short_name, arg_depth);
}
@ -669,6 +675,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "cpu", optional_argument, NULL, ARG_CPU_TYPE },
{ "order", required_argument, NULL, ARG_ORDER },
{ "recursive", required_argument, NULL, ARG_RECURSIVE },
{ "machine", required_argument, NULL, 'M' },
{}
};
@ -678,7 +685,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 1);
assert(argv);
while ((c = getopt_long(argc, argv, "hptcmin:brd:kP", options, NULL)) >= 0)
while ((c = getopt_long(argc, argv, "hptcmin:brd:kPM:", options, NULL)) >= 0)
switch (c) {
@ -797,6 +804,10 @@ static int parse_argv(int argc, char *argv[]) {
recursive_unset = r == 0;
break;
case 'M':
arg_machine = optarg;
break;
case '?':
return -EINVAL;
@ -826,6 +837,48 @@ static const char* counting_what(void) {
return "userspace processes (excl. kernel)";
}
static int get_cgroup_root(char **ret) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
_cleanup_free_ char *unit = NULL, *path = NULL;
const char *m;
int r;
if (!arg_machine) {
r = cg_get_root_path(ret);
if (r < 0)
return log_error_errno(r, "Failed to get root control group path: %m");
return 0;
}
m = strjoina("/run/systemd/machines/", arg_machine);
r = parse_env_file(m, NEWLINE, "SCOPE", &unit, NULL);
if (r < 0)
return log_error_errno(r, "Failed to load machine data: %m");
path = unit_dbus_path_from_name(unit);
if (!path)
return log_oom();
r = bus_open_transport(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
if (r < 0)
return log_error_errno(r, "Failed to create bus connection: %m");
r = sd_bus_get_property_string(
bus,
"org.freedesktop.systemd1",
path,
unit_dbus_interface_from_name(unit),
"ControlGroup",
&error,
ret);
if (r < 0)
return log_error_errno(r, "Failed to query unit control group path: %s", bus_error_message(&error, r));
return 0;
}
int main(int argc, char *argv[]) {
int r;
Hashmap *a = NULL, *b = NULL;
@ -850,7 +903,7 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
r = cg_get_root_path(&root);
r = get_cgroup_root(&root);
if (r < 0) {
log_error_errno(r, "Failed to get root control group path: %m");
goto finish;