Blame view

Documentation/accounting/getdelays.c 13.2 KB
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
1
2
3
4
5
6
7
  /* getdelays.c
   *
   * Utility to get per-pid and per-tgid delay accounting statistics
   * Also illustrates usage of the taskstats interface
   *
   * Copyright (C) Shailabh Nagar, IBM Corp. 2005
   * Copyright (C) Balbir Singh, IBM Corp. 2006
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
8
   * Copyright (c) Jay Lan, SGI. 2006
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
9
   *
d2f7bf134   Andrew Morton   [PATCH] getdelays...
10
11
   * Compile with
   *	gcc -I/usr/src/linux/include getdelays.c -o getdelays
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
12
13
14
15
16
17
18
19
20
21
22
23
   */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <errno.h>
  #include <unistd.h>
  #include <poll.h>
  #include <string.h>
  #include <fcntl.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/socket.h>
db9e5679d   Mel Gorman   delay-accounting:...
24
  #include <sys/wait.h>
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
25
26
27
28
  #include <signal.h>
  
  #include <linux/genetlink.h>
  #include <linux/taskstats.h>
546040dc4   Balbir Singh   make getdelays cg...
29
  #include <linux/cgroupstats.h>
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
30
31
32
33
34
35
36
37
38
39
  
  /*
   * Generic macros for dealing with netlink sockets. Might be duplicated
   * elsewhere. It is recommended that commercial grade applications use
   * libnl or libnetlink and use the interfaces provided by the library
   */
  #define GENLMSG_DATA(glh)	((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
  #define GENLMSG_PAYLOAD(glh)	(NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
  #define NLA_DATA(na)		((void *)((char*)(na) + NLA_HDRLEN))
  #define NLA_PAYLOAD(len)	(len - NLA_HDRLEN)
d2f7bf134   Andrew Morton   [PATCH] getdelays...
40
41
42
43
44
45
46
47
48
49
50
  #define err(code, fmt, arg...)			\
  	do {					\
  		fprintf(stderr, fmt, ##arg);	\
  		exit(code);			\
  	} while (0)
  
  int done;
  int rcvbufsz;
  char name[100];
  int dbg;
  int print_delays;
cf709844d   Andrew Morton   [PATCH] io-accoun...
51
  int print_io_accounting;
b663a79c1   Maxim Uvarov   taskstats: add co...
52
  int print_task_context_switch_counts;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
53
  __u64 stime, utime;
d2f7bf134   Andrew Morton   [PATCH] getdelays...
54

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
55
56
57
58
59
60
61
  #define PRINTF(fmt, arg...) {			\
  	    if (dbg) {				\
  		printf(fmt, ##arg);		\
  	    }					\
  	}
  
  /* Maximum size of response requested or message sent */
880402306   Oleg Nesterov   [PATCH] fix Docum...
62
  #define MAX_MSG_SIZE	1024
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
63
64
  /* Maximum number of cpus expected to be specified in a cpumask */
  #define MAX_CPUS	32
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
65
66
67
68
69
70
71
72
  
  struct msgtemplate {
  	struct nlmsghdr n;
  	struct genlmsghdr g;
  	char buf[MAX_MSG_SIZE];
  };
  
  char cpumask[100+6*MAX_CPUS];
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
73

f16825bbe   Randy Dunlap   Taskstats: fix ge...
74
75
76
77
78
79
80
81
82
83
84
85
86
  static void usage(void)
  {
  	fprintf(stderr, "getdelays [-dilv] [-w logfile] [-r bufsize] "
  			"[-m cpumask] [-t tgid] [-p pid]
  ");
  	fprintf(stderr, "  -d: print delayacct stats
  ");
  	fprintf(stderr, "  -i: print IO accounting (works only with -p)
  ");
  	fprintf(stderr, "  -l: listen forever
  ");
  	fprintf(stderr, "  -v: debug on
  ");
546040dc4   Balbir Singh   make getdelays cg...
87
88
  	fprintf(stderr, "  -C: container path
  ");
f16825bbe   Randy Dunlap   Taskstats: fix ge...
89
  }
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
90
91
92
  /*
   * Create a raw netlink socket and bind
   */
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
93
  static int create_nl_socket(int protocol)
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
94
  {
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
95
96
97
98
99
100
101
102
103
104
  	int fd;
  	struct sockaddr_nl local;
  
  	fd = socket(AF_NETLINK, SOCK_RAW, protocol);
  	if (fd < 0)
  		return -1;
  
  	if (rcvbufsz)
  		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
  				&rcvbufsz, sizeof(rcvbufsz)) < 0) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
105
106
107
108
  			fprintf(stderr, "Unable to set socket rcv buf size "
  					"to %d
  ",
  				rcvbufsz);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
109
110
  			return -1;
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
111

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
112
113
  	memset(&local, 0, sizeof(local));
  	local.nl_family = AF_NETLINK;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
114

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
115
116
  	if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
  		goto error;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
117

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
118
119
120
121
  	return fd;
  error:
  	close(fd);
  	return -1;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
122
  }
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
123

b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
124
  static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
125
126
  	     __u8 genl_cmd, __u16 nla_type,
  	     void *nla_data, int nla_len)
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
127
  {
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
  	struct nlattr *na;
  	struct sockaddr_nl nladdr;
  	int r, buflen;
  	char *buf;
  
  	struct msgtemplate msg;
  
  	msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
  	msg.n.nlmsg_type = nlmsg_type;
  	msg.n.nlmsg_flags = NLM_F_REQUEST;
  	msg.n.nlmsg_seq = 0;
  	msg.n.nlmsg_pid = nlmsg_pid;
  	msg.g.cmd = genl_cmd;
  	msg.g.version = 0x1;
  	na = (struct nlattr *) GENLMSG_DATA(&msg);
  	na->nla_type = nla_type;
  	na->nla_len = nla_len + 1 + NLA_HDRLEN;
  	memcpy(NLA_DATA(na), nla_data, nla_len);
  	msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
  
  	buf = (char *) &msg;
  	buflen = msg.n.nlmsg_len ;
  	memset(&nladdr, 0, sizeof(nladdr));
  	nladdr.nl_family = AF_NETLINK;
  	while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
  			   sizeof(nladdr))) < buflen) {
  		if (r > 0) {
  			buf += r;
  			buflen -= r;
  		} else if (errno != EAGAIN)
  			return -1;
  	}
  	return 0;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
161
  }
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
162

a3baf649c   Shailabh Nagar   [PATCH] per-task-...
163
164
165
166
  /*
   * Probe the controller in genetlink to find the family id
   * for the TASKSTATS family
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
167
  static int get_family_id(int sd)
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
168
  {
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
169
170
171
172
173
  	struct {
  		struct nlmsghdr n;
  		struct genlmsghdr g;
  		char buf[256];
  	} ans;
10e6f32bd   Randy Dunlap   getdelays: fix gc...
174
  	int id = 0, rc;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
175
176
177
178
179
180
181
  	struct nlattr *na;
  	int rep_len;
  
  	strcpy(name, TASKSTATS_GENL_NAME);
  	rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
  			CTRL_ATTR_FAMILY_NAME, (void *)name,
  			strlen(TASKSTATS_GENL_NAME)+1);
4ed960b14   Andrew Morton   Documentation/acc...
182
183
  	if (rc < 0)
  		return 0;	/* sendto() failure? */
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
184
185
186
187
188
  
  	rep_len = recv(sd, &ans, sizeof(ans), 0);
  	if (ans.n.nlmsg_type == NLMSG_ERROR ||
  	    (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
  		return 0;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
189

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
190
191
192
193
194
195
  	na = (struct nlattr *) GENLMSG_DATA(&ans);
  	na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
  	if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
  		id = *(__u16 *) NLA_DATA(na);
  	}
  	return id;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
196
  }
02d54f092   Wu Fengguang   getdelays: show a...
197
  #define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
198
  static void print_delayacct(struct taskstats *t)
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
199
  {
02d54f092   Wu Fengguang   getdelays: show a...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
  	printf("
  
  CPU   %15s%15s%15s%15s%15s
  "
  	       "      %15llu%15llu%15llu%15llu%15.3fms
  "
  	       "IO    %15s%15s%15s
  "
  	       "      %15llu%15llu%15llums
  "
  	       "SWAP  %15s%15s%15s
  "
  	       "      %15llu%15llu%15llums
  "
  	       "RECLAIM  %12s%15s%15s
  "
  	       "      %15llu%15llu%15llums
  ",
  	       "count", "real total", "virtual total",
  	       "delay total", "delay average",
666593137   Randy Dunlap   docsrc: fix getde...
220
221
222
223
  	       (unsigned long long)t->cpu_count,
  	       (unsigned long long)t->cpu_run_real_total,
  	       (unsigned long long)t->cpu_run_virtual_total,
  	       (unsigned long long)t->cpu_delay_total,
02d54f092   Wu Fengguang   getdelays: show a...
224
225
  	       average_ms((double)t->cpu_delay_total, t->cpu_count),
  	       "count", "delay total", "delay average",
666593137   Randy Dunlap   docsrc: fix getde...
226
227
  	       (unsigned long long)t->blkio_count,
  	       (unsigned long long)t->blkio_delay_total,
02d54f092   Wu Fengguang   getdelays: show a...
228
229
  	       average_ms(t->blkio_delay_total, t->blkio_count),
  	       "count", "delay total", "delay average",
666593137   Randy Dunlap   docsrc: fix getde...
230
231
  	       (unsigned long long)t->swapin_count,
  	       (unsigned long long)t->swapin_delay_total,
02d54f092   Wu Fengguang   getdelays: show a...
232
233
  	       average_ms(t->swapin_delay_total, t->swapin_count),
  	       "count", "delay total", "delay average",
666593137   Randy Dunlap   docsrc: fix getde...
234
  	       (unsigned long long)t->freepages_count,
02d54f092   Wu Fengguang   getdelays: show a...
235
236
  	       (unsigned long long)t->freepages_delay_total,
  	       average_ms(t->freepages_delay_total, t->freepages_count));
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
237
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
238
  static void task_context_switch_counts(struct taskstats *t)
b663a79c1   Maxim Uvarov   taskstats: add co...
239
240
241
242
243
  {
  	printf("
  
  Task   %15s%15s
  "
10e6f32bd   Randy Dunlap   getdelays: fix gc...
244
245
  	       "       %15llu%15llu
  ",
b663a79c1   Maxim Uvarov   taskstats: add co...
246
  	       "voluntary", "nonvoluntary",
666593137   Randy Dunlap   docsrc: fix getde...
247
  	       (unsigned long long)t->nvcsw, (unsigned long long)t->nivcsw);
b663a79c1   Maxim Uvarov   taskstats: add co...
248
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
249
  static void print_cgroupstats(struct cgroupstats *c)
546040dc4   Balbir Singh   make getdelays cg...
250
251
  {
  	printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, "
666593137   Randy Dunlap   docsrc: fix getde...
252
253
254
255
256
257
  		"uninterruptible %llu
  ", (unsigned long long)c->nr_sleeping,
  		(unsigned long long)c->nr_io_wait,
  		(unsigned long long)c->nr_running,
  		(unsigned long long)c->nr_stopped,
  		(unsigned long long)c->nr_uninterruptible);
546040dc4   Balbir Singh   make getdelays cg...
258
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
259
  static void print_ioacct(struct taskstats *t)
cf709844d   Andrew Morton   [PATCH] io-accoun...
260
261
262
263
264
265
266
267
  {
  	printf("%s: read=%llu, write=%llu, cancelled_write=%llu
  ",
  		t->ac_comm,
  		(unsigned long long)t->read_bytes,
  		(unsigned long long)t->write_bytes,
  		(unsigned long long)t->cancelled_write_bytes);
  }
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
268
269
  int main(int argc, char *argv[])
  {
b8d9a8659   Jaswinder Singh Rajput   Documentation/acc...
270
271
  	int c, rc, rep_len, aggr_len, len2;
  	int cmd_type = TASKSTATS_CMD_ATTR_UNSPEC;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
272
273
274
275
276
277
278
279
280
281
282
283
284
  	__u16 id;
  	__u32 mypid;
  
  	struct nlattr *na;
  	int nl_sd = -1;
  	int len = 0;
  	pid_t tid = 0;
  	pid_t rtid = 0;
  
  	int fd = 0;
  	int count = 0;
  	int write_file = 0;
  	int maskset = 0;
7f76c4037   Scott Wiersdorf   getdelays.c: fix ...
285
  	char *logfile = NULL;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
286
  	int loop = 0;
546040dc4   Balbir Singh   make getdelays cg...
287
288
289
  	int containerset = 0;
  	char containerpath[1024];
  	int cfd = 0;
db9e5679d   Mel Gorman   delay-accounting:...
290
291
  	int forking = 0;
  	sigset_t sigset;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
292
293
  
  	struct msgtemplate msg;
db9e5679d   Mel Gorman   delay-accounting:...
294
295
  	while (!forking) {
  		c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:");
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
296
297
  		if (c < 0)
  			break;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
298

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
299
300
301
302
303
304
  		switch (c) {
  		case 'd':
  			printf("print delayacct stats ON
  ");
  			print_delays = 1;
  			break;
cf709844d   Andrew Morton   [PATCH] io-accoun...
305
306
307
308
309
  		case 'i':
  			printf("printing IO accounting
  ");
  			print_io_accounting = 1;
  			break;
b663a79c1   Maxim Uvarov   taskstats: add co...
310
311
312
313
314
  		case 'q':
  			printf("printing task/process context switch rates
  ");
  			print_task_context_switch_counts = 1;
  			break;
546040dc4   Balbir Singh   make getdelays cg...
315
316
317
318
  		case 'C':
  			containerset = 1;
  			strncpy(containerpath, optarg, strlen(optarg) + 1);
  			break;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
319
  		case 'w':
7f76c4037   Scott Wiersdorf   getdelays.c: fix ...
320
  			logfile = strdup(optarg);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  			printf("write to file %s
  ", logfile);
  			write_file = 1;
  			break;
  		case 'r':
  			rcvbufsz = atoi(optarg);
  			printf("receive buf size %d
  ", rcvbufsz);
  			if (rcvbufsz < 0)
  				err(1, "Invalid rcv buf size
  ");
  			break;
  		case 'm':
  			strncpy(cpumask, optarg, sizeof(cpumask));
  			maskset = 1;
  			printf("cpumask %s maskset %d
  ", cpumask, maskset);
  			break;
  		case 't':
  			tid = atoi(optarg);
  			if (!tid)
  				err(1, "Invalid tgid
  ");
  			cmd_type = TASKSTATS_CMD_ATTR_TGID;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
345
346
347
348
349
350
351
  			break;
  		case 'p':
  			tid = atoi(optarg);
  			if (!tid)
  				err(1, "Invalid pid
  ");
  			cmd_type = TASKSTATS_CMD_ATTR_PID;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
352
  			break;
db9e5679d   Mel Gorman   delay-accounting:...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  		case 'c':
  
  			/* Block SIGCHLD for sigwait() later */
  			if (sigemptyset(&sigset) == -1)
  				err(1, "Failed to empty sigset");
  			if (sigaddset(&sigset, SIGCHLD))
  				err(1, "Failed to set sigchld in sigset");
  			sigprocmask(SIG_BLOCK, &sigset, NULL);
  
  			/* fork/exec a child */
  			tid = fork();
  			if (tid < 0)
  				err(1, "Fork failed
  ");
  			if (tid == 0)
  				if (execvp(argv[optind - 1],
  				    &argv[optind - 1]) < 0)
  					exit(-1);
  
  			/* Set the command type and avoid further processing */
  			cmd_type = TASKSTATS_CMD_ATTR_PID;
  			forking = 1;
  			break;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
376
377
378
379
380
381
382
383
384
385
386
  		case 'v':
  			printf("debug on
  ");
  			dbg = 1;
  			break;
  		case 'l':
  			printf("listen forever
  ");
  			loop = 1;
  			break;
  		default:
f16825bbe   Randy Dunlap   Taskstats: fix ge...
387
  			usage();
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
388
  			exit(-1);
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
389
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
390
  	}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
391

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
392
393
394
395
396
397
398
399
400
  	if (write_file) {
  		fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC,
  			  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  		if (fd == -1) {
  			perror("Cannot open output file
  ");
  			exit(1);
  		}
  	}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
401

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
402
403
404
  	if ((nl_sd = create_nl_socket(NETLINK_GENERIC)) < 0)
  		err(1, "error creating Netlink socket
  ");
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
405

a3baf649c   Shailabh Nagar   [PATCH] per-task-...
406

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
407
408
409
  	mypid = getpid();
  	id = get_family_id(nl_sd);
  	if (!id) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
410
411
  		fprintf(stderr, "Error getting family id, errno %d
  ", errno);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
412
  		goto err;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
413
  	}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
414
415
416
417
418
419
  	PRINTF("family id %d
  ", id);
  
  	if (maskset) {
  		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
  			      TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
7d1bdca9b   Balbir Singh   [PATCH] Fix getde...
420
  			      &cpumask, strlen(cpumask) + 1);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
421
422
423
  		PRINTF("Sent register cpumask, retval %d
  ", rc);
  		if (rc < 0) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
424
425
  			fprintf(stderr, "error sending register cpumask
  ");
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
426
427
  			goto err;
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
428
  	}
546040dc4   Balbir Singh   make getdelays cg...
429
430
431
432
433
  	if (tid && containerset) {
  		fprintf(stderr, "Select either -t or -C, not both
  ");
  		goto err;
  	}
db9e5679d   Mel Gorman   delay-accounting:...
434
435
436
437
438
439
440
441
  	/*
  	 * If we forked a child, wait for it to exit. Cannot use waitpid()
  	 * as all the delicious data would be reaped as part of the wait
  	 */
  	if (tid && forking) {
  		int sig_received;
  		sigwait(&sigset, &sig_received);
  	}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
442
443
444
445
446
447
  	if (tid) {
  		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
  			      cmd_type, &tid, sizeof(__u32));
  		PRINTF("Sent pid/tgid, retval %d
  ", rc);
  		if (rc < 0) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
448
449
  			fprintf(stderr, "error sending tid/tgid cmd
  ");
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
450
451
  			goto done;
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
452
  	}
546040dc4   Balbir Singh   make getdelays cg...
453
454
455
456
457
458
459
460
461
462
463
464
465
  	if (containerset) {
  		cfd = open(containerpath, O_RDONLY);
  		if (cfd < 0) {
  			perror("error opening container file");
  			goto err;
  		}
  		rc = send_cmd(nl_sd, id, mypid, CGROUPSTATS_CMD_GET,
  			      CGROUPSTATS_CMD_ATTR_FD, &cfd, sizeof(__u32));
  		if (rc < 0) {
  			perror("error sending cgroupstats command");
  			goto err;
  		}
  	}
65a67bd26   Marcus Meissner   Documentation/acc...
466
467
468
469
  	if (!maskset && !tid && !containerset) {
  		usage();
  		goto err;
  	}
546040dc4   Balbir Singh   make getdelays cg...
470

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
471
  	do {
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
472
473
474
  		rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
  		PRINTF("received %d bytes
  ", rep_len);
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
475

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
476
  		if (rep_len < 0) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
477
478
479
  			fprintf(stderr, "nonfatal reply error: errno %d
  ",
  				errno);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
480
481
482
483
  			continue;
  		}
  		if (msg.n.nlmsg_type == NLMSG_ERROR ||
  		    !NLMSG_OK((&msg.n), rep_len)) {
7d1bdca9b   Balbir Singh   [PATCH] Fix getde...
484
  			struct nlmsgerr *err = NLMSG_DATA(&msg);
d2f7bf134   Andrew Morton   [PATCH] getdelays...
485
486
487
  			fprintf(stderr, "fatal reply error,  errno %d
  ",
  				err->error);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
488
489
  			goto done;
  		}
10e6f32bd   Randy Dunlap   getdelays: fix gc...
490
491
  		PRINTF("nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d
  ",
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
492
493
494
495
496
497
498
  		       sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);
  
  
  		rep_len = GENLMSG_PAYLOAD(&msg.n);
  
  		na = (struct nlattr *) GENLMSG_DATA(&msg);
  		len = 0;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
  		while (len < rep_len) {
  			len += NLA_ALIGN(na->nla_len);
  			switch (na->nla_type) {
  			case TASKSTATS_TYPE_AGGR_TGID:
  				/* Fall through */
  			case TASKSTATS_TYPE_AGGR_PID:
  				aggr_len = NLA_PAYLOAD(na->nla_len);
  				len2 = 0;
  				/* For nested attributes, na follows */
  				na = (struct nlattr *) NLA_DATA(na);
  				done = 0;
  				while (len2 < aggr_len) {
  					switch (na->nla_type) {
  					case TASKSTATS_TYPE_PID:
  						rtid = *(int *) NLA_DATA(na);
  						if (print_delays)
  							printf("PID\t%d
  ", rtid);
  						break;
  					case TASKSTATS_TYPE_TGID:
  						rtid = *(int *) NLA_DATA(na);
  						if (print_delays)
  							printf("TGID\t%d
  ", rtid);
  						break;
  					case TASKSTATS_TYPE_STATS:
  						count++;
  						if (print_delays)
  							print_delayacct((struct taskstats *) NLA_DATA(na));
cf709844d   Andrew Morton   [PATCH] io-accoun...
528
529
  						if (print_io_accounting)
  							print_ioacct((struct taskstats *) NLA_DATA(na));
b663a79c1   Maxim Uvarov   taskstats: add co...
530
531
  						if (print_task_context_switch_counts)
  							task_context_switch_counts((struct taskstats *) NLA_DATA(na));
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
532
533
534
535
536
537
538
539
540
541
  						if (fd) {
  							if (write(fd, NLA_DATA(na), na->nla_len) < 0) {
  								err(1,"write error
  ");
  							}
  						}
  						if (!loop)
  							goto done;
  						break;
  					default:
d2f7bf134   Andrew Morton   [PATCH] getdelays...
542
543
544
545
  						fprintf(stderr, "Unknown nested"
  							" nla_type %d
  ",
  							na->nla_type);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
546
547
548
549
550
551
  						break;
  					}
  					len2 += NLA_ALIGN(na->nla_len);
  					na = (struct nlattr *) ((char *) na + len2);
  				}
  				break;
546040dc4   Balbir Singh   make getdelays cg...
552
553
554
  			case CGROUPSTATS_TYPE_CGROUP_STATS:
  				print_cgroupstats(NLA_DATA(na));
  				break;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
555
  			default:
d2f7bf134   Andrew Morton   [PATCH] getdelays...
556
557
558
  				fprintf(stderr, "Unknown nla_type %d
  ",
  					na->nla_type);
4be2c95d1   Jeff Mahoney   taskstats: pad ta...
559
  			case TASKSTATS_TYPE_NULL:
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
560
  				break;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
561
  			}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
562
  			na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
563
  		}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
564
565
566
567
568
  	} while (loop);
  done:
  	if (maskset) {
  		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
  			      TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
7d1bdca9b   Balbir Singh   [PATCH] Fix getde...
569
  			      &cpumask, strlen(cpumask) + 1);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
570
571
572
573
574
  		printf("Sent deregister mask, retval %d
  ", rc);
  		if (rc < 0)
  			err(rc, "error sending deregister cpumask
  ");
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
575
  	}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
576
577
578
579
  err:
  	close(nl_sd);
  	if (fd)
  		close(fd);
546040dc4   Balbir Singh   make getdelays cg...
580
581
  	if (cfd)
  		close(cfd);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
582
  	return 0;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
583
  }