From ab35fb1bc68625c891a19a66473a9c40ca12e69d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 8 Jul 2010 06:08:32 +0200 Subject: [PATCH] systemctl: filter and sort member pid of cgroup --- Makefile.am | 6 ++- src/cgroup-show.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++ src/cgroup-show.h | 27 ++++++++++ src/systemctl.c | 59 ++++---------------- 4 files changed, 175 insertions(+), 51 deletions(-) create mode 100644 src/cgroup-show.c create mode 100644 src/cgroup-show.h diff --git a/Makefile.am b/Makefile.am index e76eee43e..eb911fc89 100644 --- a/Makefile.am +++ b/Makefile.am @@ -312,7 +312,8 @@ EXTRA_DIST += \ src/sd-daemon.h \ src/special.h \ src/dbus-common.h \ - src/bus-errors.h + src/bus-errors.h \ + src/cgroup-show.h MANPAGES = \ man/systemd.1 \ @@ -479,7 +480,8 @@ systemd_cgroups_agent_LDADD = \ systemctl_SOURCES = \ src/systemctl.c \ src/utmp-wtmp.c \ - src/dbus-common.c + src/dbus-common.c \ + src/cgroup-show.c systemctl_CFLAGS = \ $(AM_CFLAGS) \ diff --git a/src/cgroup-show.c b/src/cgroup-show.c new file mode 100644 index 000000000..b637c1c16 --- /dev/null +++ b/src/cgroup-show.c @@ -0,0 +1,134 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "util.h" +#include "macro.h" +#include "cgroup-show.h" + +static int compare(const void *a, const void *b) { + const pid_t *p = a, *q = b; + + if (*p < *q) + return -1; + if (*p > *q) + return 1; + return 0; +} + +void show_cgroup(const char *name, const char *prefix, unsigned columns) { + char *fn; + FILE *f; + size_t n = 0, n_allocated = 0; + pid_t *pids = NULL; + + if (!startswith(name, "name=systemd:")) + return; + + if (asprintf(&fn, "/cgroup/systemd/%s/cgroup.procs", name + 13) < 0) { + log_error("Out of memory"); + return; + } + + f = fopen(fn, "r"); + free(fn); + + if (!f) + return; + + while (!feof(f)) { + unsigned long ul; + + if (fscanf(f, "%lu", &ul) != 1) + break; + + if (ul <= 0) + continue; + + if (n >= n_allocated) { + pid_t *npids; + + n_allocated = MAX(16U, n*2U); + + if (!(npids = realloc(pids, sizeof(pid_t) * n_allocated))) { + log_error("Out of memory"); + goto finish; + } + + pids = npids; + } + + assert(n < n_allocated); + pids[n++] = (pid_t) ul; + } + + if (n > 0) { + unsigned i, m; + + /* Filter duplicates */ + m = 0; + for (i = 0; i < n; i++) { + unsigned j; + + for (j = i+1; j < n; j++) + if (pids[i] == pids[j]) + break; + + if (j >= n) + pids[m++] = pids[i]; + } + n = m; + + /* And sort */ + qsort(pids, n, sizeof(pid_t), compare); + + if (!prefix) + prefix = ""; + + if (columns > 8) + columns -= 8; + else + columns = 20; + + printf("%s\342\224\202\n", prefix); + + for (i = 0; i < n; i++) { + char *t = NULL; + + get_process_cmdline(pids[i], columns, &t); + + printf("%s%s %5lu %s\n", + prefix, + i < n-1 ? "\342\224\234" : "\342\224\224", + (unsigned long) pids[i], strna(t)); + + free(t); + } + } + +finish: + free(pids); + + if (f) + fclose(f); +} diff --git a/src/cgroup-show.h b/src/cgroup-show.h new file mode 100644 index 000000000..3def2f309 --- /dev/null +++ b/src/cgroup-show.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8 -*-*/ + +#ifndef foocgroupshowhfoo +#define foocgroupshowhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +void show_cgroup(const char *name, const char *prefix, unsigned columns); + +#endif diff --git a/src/systemctl.c b/src/systemctl.c index 75d98c67c..bb831adb5 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -42,6 +42,7 @@ #include "initreq.h" #include "strv.h" #include "dbus-common.h" +#include "cgroup-show.h" static const char *arg_type = NULL; static const char *arg_property = NULL; @@ -131,7 +132,6 @@ static int columns(void) { parsed_columns = 80; return parsed_columns; - } static void warn_wall(enum action action) { @@ -946,53 +946,6 @@ finish: return r; } -static void show_cgroup(const char *name) { - char *fn; - FILE *f; - pid_t last = 0; - - if (!startswith(name, "name=systemd:")) - return; - - if (asprintf(&fn, "/cgroup/systemd/%s/tasks", name + 13) < 0) - return; - - f = fopen(fn, "r"); - free(fn); - - if (!f) - return; - - while (!feof(f)) { - unsigned long ul; - - if (fscanf(f, "%lu", &ul) != 1) - break; - - if (ul <= 0) - continue; - - if (last > 0) { - char *t = NULL; - get_process_cmdline(last, 60, &t); - printf("\t\t \342\224\234 %lu %s\n", (unsigned long) last, strna(t)); - free(t); - } else - printf("\t\t \342\224\202\n"); - - last = (pid_t) ul; - } - - if (last > 0) { - char *t = NULL; - get_process_cmdline(last, 60, &t); - printf("\t\t \342\224\224 %lu %s\n", (unsigned long) last, strna(t)); - free(t); - } - - fclose(f); -} - typedef struct UnitStatusInfo { const char *id; const char *load_state; @@ -1114,8 +1067,16 @@ static void print_status_info(UnitStatusInfo *i) { } if (i->default_control_group) { + unsigned c; + printf("\t CGroup: %s\n", i->default_control_group); - show_cgroup(i->default_control_group); + + if ((c = columns()) > 18) + c -= 18; + else + c = 0; + + show_cgroup(i->default_control_group, "\t\t ", c); } } -- 2.30.2