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;
static enum {
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;
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 = ≀
- } 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 = ≀
+ } else
+ continue;
+
+ l += strspn(l, WHITESPACE);
+ r = safe_atou64(l, &k);
+ if (r < 0)
+ continue;
+
+ *q += k;
+ }
}
timestamp = now_nsec(CLOCK_MONOTONIC);
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);
assert(a);
- if (on_tty())
+ if (!terminal_is_dumb())
fputs(ANSI_HOME_CLEAR, stdout);
array = alloca(sizeof(Group*) * hashmap_size(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"
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;
}
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)