summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-09-21 14:55:48 +0200
committerLennart Poettering <lennart@poettering.net>2015-09-21 14:55:48 +0200
commit213634e47674a3e5eb64a61cdab22c71df7a8894 (patch)
tree8cc2f7268a299eebee0d5225824343c74aaa3e07
parent8c710f3ce64110a4cfe977116c55bd87777e641c (diff)
parent96a6426f30dc9bf3c4dd1f61548c334fa12034df (diff)
Merge pull request #1314 from evverx/cgtop-machine
cgtop: add -M/--machine
-rw-r--r--man/systemd-cgtop.xml9
-rw-r--r--shell-completion/bash/systemd-cgtop17
-rw-r--r--src/cgtop/cgtop.c57
3 files changed, 80 insertions, 3 deletions
diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml
index 859c1a2865..1c90c0a659 100644
--- a/man/systemd-cgtop.xml
+++ b/man/systemd-cgtop.xml
@@ -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>
diff --git a/shell-completion/bash/systemd-cgtop b/shell-completion/bash/systemd-cgtop
index 50464990ab..eefb8fc5c4 100644
--- a/shell-completion/bash/systemd-cgtop
+++ b/shell-completion/bash/systemd-cgtop
@@ -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") )
}
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 4786a155da..1307a34ab7 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -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;