21 #include <sys/types.h>
23 #include <sys/socket.h>
27 #include <linux/genetlink.h>
36 #define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
37 #define GENLMSG_PAYLOAD(glh) (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
38 #define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN))
39 #define NLA_PAYLOAD(len) (len - NLA_HDRLEN)
41 #define err(code, fmt, arg...) \
43 fprintf(stderr, fmt, ##arg); \
56 #define PRINTF(fmt, arg...) { \
63 #define MAX_MSG_SIZE 1024
75 static void usage(
void)
77 fprintf(stderr,
"getdelays [-dilv] [-w logfile] [-r bufsize] "
78 "[-m cpumask] [-t tgid] [-p pid]\n");
79 fprintf(stderr,
" -d: print delayacct stats\n");
80 fprintf(stderr,
" -i: print IO accounting (works only with -p)\n");
81 fprintf(stderr,
" -l: listen forever\n");
82 fprintf(stderr,
" -v: debug on\n");
83 fprintf(stderr,
" -C: container path\n");
89 static int create_nl_socket(
int protocol)
101 fprintf(stderr,
"Unable to set socket rcv buf size to %d\n",
106 memset(&local, 0,
sizeof(local));
109 if (bind(fd, (
struct sockaddr *) &local,
sizeof(local)) < 0)
119 static int send_cmd(
int sd,
__u16 nlmsg_type,
__u32 nlmsg_pid,
121 void *nla_data,
int nla_len)
131 msg.n.nlmsg_type = nlmsg_type;
134 msg.n.nlmsg_pid = nlmsg_pid;
144 buflen =
msg.n.nlmsg_len ;
145 memset(&nladdr, 0,
sizeof(nladdr));
147 while ((r = sendto(sd, buf, buflen, 0, (
struct sockaddr *) &nladdr,
148 sizeof(nladdr))) < buflen) {
152 }
else if (errno !=
EAGAIN)
163 static int get_family_id(
int sd)
182 rep_len = recv(sd, &ans,
sizeof(ans), 0);
184 (rep_len < 0) || !
NLMSG_OK((&ans.n), rep_len))
195 #define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))
197 static void print_delayacct(
struct taskstats *
t)
199 printf(
"\n\nCPU %15s%15s%15s%15s%15s\n"
200 " %15llu%15llu%15llu%15llu%15.3fms\n"
202 " %15llu%15llu%15llums\n"
203 "SWAP %15s%15s%15s\n"
204 " %15llu%15llu%15llums\n"
205 "RECLAIM %12s%15s%15s\n"
206 " %15llu%15llu%15llums\n",
207 "count",
"real total",
"virtual total",
208 "delay total",
"delay average",
209 (
unsigned long long)t->cpu_count,
214 "count",
"delay total",
"delay average",
218 "count",
"delay total",
"delay average",
222 "count",
"delay total",
"delay average",
228 static void task_context_switch_counts(
struct taskstats *
t)
230 printf(
"\n\nTask %15s%15s\n"
232 "voluntary",
"nonvoluntary",
233 (
unsigned long long)t->
nvcsw, (
unsigned long long)t->
nivcsw);
238 printf(
"sleeping %llu, blocked %llu, running %llu, stopped %llu, "
239 "uninterruptible %llu\n", (
unsigned long long)c->
nr_sleeping,
247 static void print_ioacct(
struct taskstats *t)
249 printf(
"%s: read=%llu, write=%llu, cancelled_write=%llu\n",
258 int c,
rc, rep_len, aggr_len, len2;
273 char *logfile =
NULL;
275 int containerset = 0;
276 char containerpath[1024];
284 c = getopt(argc, argv,
"qdiw:r:m:t:p:vlC:c:");
290 printf(
"print delayacct stats ON\n");
294 printf(
"printing IO accounting\n");
298 printf(
"printing task/process context switch rates\n");
306 logfile = strdup(optarg);
307 printf(
"write to file %s\n", logfile);
314 err(1,
"Invalid rcv buf size\n");
324 err(1,
"Invalid tgid\n");
330 err(1,
"Invalid pid\n");
336 if (sigemptyset(&sigset) == -1)
337 err(1,
"Failed to empty sigset");
338 if (sigaddset(&sigset,
SIGCHLD))
339 err(1,
"Failed to set sigchld in sigset");
345 err(1,
"Fork failed\n");
347 if (execvp(argv[optind - 1],
348 &argv[optind - 1]) < 0)
360 printf(
"listen forever\n");
373 perror(
"Cannot open output file\n");
379 err(1,
"error creating Netlink socket\n");
383 id = get_family_id(nl_sd);
385 fprintf(stderr,
"Error getting family id, errno %d\n",
errno);
388 PRINTF(
"family id %d\n",
id);
394 PRINTF(
"Sent register cpumask, retval %d\n", rc);
396 fprintf(stderr,
"error sending register cpumask\n");
401 if (tid && containerset) {
402 fprintf(stderr,
"Select either -t or -C, not both\n");
410 if (tid && forking) {
412 sigwait(&sigset, &sig_received);
417 cmd_type, &tid,
sizeof(
__u32));
418 PRINTF(
"Sent pid/tgid, retval %d\n", rc);
420 fprintf(stderr,
"error sending tid/tgid cmd\n");
428 perror(
"error opening container file");
434 perror(
"error sending cgroupstats command");
438 if (!maskset && !tid && !containerset) {
444 rep_len = recv(nl_sd, &msg,
sizeof(msg), 0);
445 PRINTF(
"received %d bytes\n", rep_len);
448 fprintf(stderr,
"nonfatal reply error: errno %d\n",
455 fprintf(stderr,
"fatal reply error, errno %d\n",
460 PRINTF(
"nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d\n",
461 sizeof(
struct nlmsghdr), msg.
n.nlmsg_len, rep_len);
468 while (len < rep_len) {
479 while (len2 < aggr_len) {
484 printf(
"PID\t%d\n", rtid);
489 printf(
"TGID\t%d\n", rtid);
501 err(1,
"write error\n");
508 fprintf(stderr,
"Unknown nested"
514 na = (
struct nlattr *) ((
char *) na + len2);
522 fprintf(stderr,
"Unknown nla_type %d\n",
535 printf(
"Sent deregister mask, retval %d\n", rc);
537 err(rc,
"error sending deregister cpumask\n");