]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/cgtop/cgtop.c
cgtop: minimize aux variable scope
[thirdparty/systemd.git] / src / cgtop / cgtop.c
index 4894296554697baeb62385d7194b04675963b3bb..c67b328b3882176f1781d8301a453192b9aace54 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
@@ -74,13 +72,14 @@ static bool arg_batch = false;
 static bool arg_raw = false;
 static usec_t arg_delay = 1*USEC_PER_SEC;
 static char* arg_machine = NULL;
+static char* arg_root = NULL;
+static bool arg_recursive = true;
 
-enum {
+static enum {
         COUNT_PIDS,
         COUNT_USERSPACE_PROCESSES,
         COUNT_ALL_PROCESSES,
 } arg_count = COUNT_PIDS;
-static bool arg_recursive = true;
 
 static enum {
         ORDER_PATH,
@@ -271,13 +270,15 @@ static int process(
                 if (g->memory > 0)
                         g->memory_valid = true;
 
-        } else if (streq(controller, "blkio") && cg_unified() <= 0) {
+        } else if ((streq(controller, "io") && cg_unified() > 0) ||
+                   (streq(controller, "blkio") && cg_unified() <= 0)) {
                 _cleanup_fclose_ FILE *f = NULL;
                 _cleanup_free_ char *p = NULL;
+                bool unified = cg_unified() > 0;
                 uint64_t wr = 0, rd = 0;
                 nsec_t timestamp;
 
-                r = cg_get_path(controller, path, "blkio.io_service_bytes", &p);
+                r = cg_get_path(controller, path, unified ? "io.stat" : "blkio.io_service_bytes", &p);
                 if (r < 0)
                         return r;
 
@@ -295,25 +296,38 @@ static int process(
                         if (!fgets(line, sizeof(line), f))
                                 break;
 
+                        /* Trim and skip the device */
                         l = strstrip(line);
                         l += strcspn(l, WHITESPACE);
                         l += strspn(l, WHITESPACE);
 
-                        if (first_word(l, "Read")) {
-                                l += 4;
-                                q = &rd;
-                        } else if (first_word(l, "Write")) {
-                                l += 5;
-                                q = &wr;
-                        } else
-                                continue;
+                        if (unified) {
+                                while (!isempty(l)) {
+                                        if (sscanf(l, "rbytes=%" SCNu64, &k))
+                                                rd += k;
+                                        else if (sscanf(l, "wbytes=%" SCNu64, &k))
+                                                wr += k;
 
-                        l += strspn(l, WHITESPACE);
-                        r = safe_atou64(l, &k);
-                        if (r < 0)
-                                continue;
-
-                        *q += k;
+                                        l += strcspn(l, WHITESPACE);
+                                        l += strspn(l, WHITESPACE);
+                                }
+                        } else {
+                                if (first_word(l, "Read")) {
+                                        l += 4;
+                                        q = &rd;
+                                } else if (first_word(l, "Write")) {
+                                        l += 5;
+                                        q = &wr;
+                                } else
+                                        continue;
+
+                                l += strspn(l, WHITESPACE);
+                                r = safe_atou64(l, &k);
+                                if (r < 0)
+                                        continue;
+
+                                *q += k;
+                        }
                 }
 
                 timestamp = now_nsec(CLOCK_MONOTONIC);
@@ -364,7 +378,7 @@ static int refresh_one(
                 Group **ret) {
 
         _cleanup_closedir_ DIR *d = NULL;
-        Group *ours;
+        Group *ours = NULL;
         int r;
 
         assert(controller);
@@ -439,6 +453,9 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration)
         if (r < 0)
                 return r;
         r = refresh_one("memory", root, a, b, iteration, 0, NULL);
+        if (r < 0)
+                return r;
+        r = refresh_one("io", root, a, b, iteration, 0, NULL);
         if (r < 0)
                 return r;
         r = refresh_one("blkio", root, a, b, iteration, 0, NULL);
@@ -542,7 +559,7 @@ static void display(Hashmap *a) {
 
         assert(a);
 
-        if (on_tty())
+        if (!terminal_is_dumb())
                 fputs(ANSI_HOME_CLEAR, stdout);
 
         array = alloca(sizeof(Group*) * hashmap_size(a));
@@ -637,7 +654,7 @@ static void display(Hashmap *a) {
 }
 
 static void help(void) {
-        printf("%s [OPTIONS...]\n\n"
+        printf("%s [OPTIONS...] [CGROUP]\n\n"
                "Show top control groups by their resource usage.\n\n"
                "  -h --help           Show this help\n"
                "     --version        Show package version\n"
@@ -819,7 +836,13 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
-        if (optind < argc) {
+        if (optind == argc-1) {
+                if (arg_machine) {
+                        log_error("Specifying a control group path together with the -M option is not allowed");
+                        return -EINVAL;
+                }
+                arg_root = argv[optind];
+        } else if (optind < argc) {
                 log_error("Too many arguments.");
                 return -EINVAL;
         }
@@ -848,6 +871,17 @@ static int get_cgroup_root(char **ret) {
         const char *m;
         int r;
 
+        if (arg_root) {
+                char *aux;
+
+                aux = strdup(arg_root);
+                if (!aux)
+                        return log_oom();
+
+                *ret = aux;
+                return 0;
+        }
+
         if (!arg_machine) {
                 r = cg_get_root_path(ret);
                 if (r < 0)