diff options
-rw-r--r-- | Documentation/accounting/getdelays.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index ab82b7f53312..d6cb1a86fd61 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/genetlink.h> | 26 | #include <linux/genetlink.h> |
27 | #include <linux/taskstats.h> | 27 | #include <linux/taskstats.h> |
28 | #include <linux/cgroupstats.h> | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Generic macros for dealing with netlink sockets. Might be duplicated | 31 | * Generic macros for dealing with netlink sockets. Might be duplicated |
@@ -78,6 +79,7 @@ static void usage(void) | |||
78 | fprintf(stderr, " -i: print IO accounting (works only with -p)\n"); | 79 | fprintf(stderr, " -i: print IO accounting (works only with -p)\n"); |
79 | fprintf(stderr, " -l: listen forever\n"); | 80 | fprintf(stderr, " -l: listen forever\n"); |
80 | fprintf(stderr, " -v: debug on\n"); | 81 | fprintf(stderr, " -v: debug on\n"); |
82 | fprintf(stderr, " -C: container path\n"); | ||
81 | } | 83 | } |
82 | 84 | ||
83 | /* | 85 | /* |
@@ -212,6 +214,14 @@ void task_context_switch_counts(struct taskstats *t) | |||
212 | t->nvcsw, t->nivcsw); | 214 | t->nvcsw, t->nivcsw); |
213 | } | 215 | } |
214 | 216 | ||
217 | void print_cgroupstats(struct cgroupstats *c) | ||
218 | { | ||
219 | printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, " | ||
220 | "uninterruptible %llu\n", c->nr_sleeping, c->nr_io_wait, | ||
221 | c->nr_running, c->nr_stopped, c->nr_uninterruptible); | ||
222 | } | ||
223 | |||
224 | |||
215 | void print_ioacct(struct taskstats *t) | 225 | void print_ioacct(struct taskstats *t) |
216 | { | 226 | { |
217 | printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n", | 227 | printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n", |
@@ -239,11 +249,14 @@ int main(int argc, char *argv[]) | |||
239 | int maskset = 0; | 249 | int maskset = 0; |
240 | char *logfile = NULL; | 250 | char *logfile = NULL; |
241 | int loop = 0; | 251 | int loop = 0; |
252 | int containerset = 0; | ||
253 | char containerpath[1024]; | ||
254 | int cfd = 0; | ||
242 | 255 | ||
243 | struct msgtemplate msg; | 256 | struct msgtemplate msg; |
244 | 257 | ||
245 | while (1) { | 258 | while (1) { |
246 | c = getopt(argc, argv, "qdiw:r:m:t:p:vl"); | 259 | c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:"); |
247 | if (c < 0) | 260 | if (c < 0) |
248 | break; | 261 | break; |
249 | 262 | ||
@@ -260,6 +273,10 @@ int main(int argc, char *argv[]) | |||
260 | printf("printing task/process context switch rates\n"); | 273 | printf("printing task/process context switch rates\n"); |
261 | print_task_context_switch_counts = 1; | 274 | print_task_context_switch_counts = 1; |
262 | break; | 275 | break; |
276 | case 'C': | ||
277 | containerset = 1; | ||
278 | strncpy(containerpath, optarg, strlen(optarg) + 1); | ||
279 | break; | ||
263 | case 'w': | 280 | case 'w': |
264 | logfile = strdup(optarg); | 281 | logfile = strdup(optarg); |
265 | printf("write to file %s\n", logfile); | 282 | printf("write to file %s\n", logfile); |
@@ -334,6 +351,11 @@ int main(int argc, char *argv[]) | |||
334 | } | 351 | } |
335 | } | 352 | } |
336 | 353 | ||
354 | if (tid && containerset) { | ||
355 | fprintf(stderr, "Select either -t or -C, not both\n"); | ||
356 | goto err; | ||
357 | } | ||
358 | |||
337 | if (tid) { | 359 | if (tid) { |
338 | rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, | 360 | rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, |
339 | cmd_type, &tid, sizeof(__u32)); | 361 | cmd_type, &tid, sizeof(__u32)); |
@@ -344,6 +366,20 @@ int main(int argc, char *argv[]) | |||
344 | } | 366 | } |
345 | } | 367 | } |
346 | 368 | ||
369 | if (containerset) { | ||
370 | cfd = open(containerpath, O_RDONLY); | ||
371 | if (cfd < 0) { | ||
372 | perror("error opening container file"); | ||
373 | goto err; | ||
374 | } | ||
375 | rc = send_cmd(nl_sd, id, mypid, CGROUPSTATS_CMD_GET, | ||
376 | CGROUPSTATS_CMD_ATTR_FD, &cfd, sizeof(__u32)); | ||
377 | if (rc < 0) { | ||
378 | perror("error sending cgroupstats command"); | ||
379 | goto err; | ||
380 | } | ||
381 | } | ||
382 | |||
347 | do { | 383 | do { |
348 | int i; | 384 | int i; |
349 | 385 | ||
@@ -422,6 +458,9 @@ int main(int argc, char *argv[]) | |||
422 | } | 458 | } |
423 | break; | 459 | break; |
424 | 460 | ||
461 | case CGROUPSTATS_TYPE_CGROUP_STATS: | ||
462 | print_cgroupstats(NLA_DATA(na)); | ||
463 | break; | ||
425 | default: | 464 | default: |
426 | fprintf(stderr, "Unknown nla_type %d\n", | 465 | fprintf(stderr, "Unknown nla_type %d\n", |
427 | na->nla_type); | 466 | na->nla_type); |
@@ -443,5 +482,7 @@ err: | |||
443 | close(nl_sd); | 482 | close(nl_sd); |
444 | if (fd) | 483 | if (fd) |
445 | close(fd); | 484 | close(fd); |
485 | if (cfd) | ||
486 | close(cfd); | ||
446 | return 0; | 487 | return 0; |
447 | } | 488 | } |