Blame view

tools/accounting/getdelays.c 13.3 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
2
3
4
5
6
7
8
  /* 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 ...
9
   * Copyright (c) Jay Lan, SGI. 2006
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
10
   *
d2f7bf134   Andrew Morton   [PATCH] getdelays...
11
12
   * Compile with
   *	gcc -I/usr/src/linux/include getdelays.c -o getdelays
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
13
14
15
16
17
18
19
20
21
22
23
24
   */
  
  #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:...
25
  #include <sys/wait.h>
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
26
27
28
29
  #include <signal.h>
  
  #include <linux/genetlink.h>
  #include <linux/taskstats.h>
546040dc4   Balbir Singh   make getdelays cg...
30
  #include <linux/cgroupstats.h>
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
31
32
33
34
35
36
37
38
39
40
  
  /*
   * 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...
41
42
43
44
45
46
47
48
49
50
51
  #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...
52
  int print_io_accounting;
b663a79c1   Maxim Uvarov   taskstats: add co...
53
  int print_task_context_switch_counts;
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) {
0de4b9540   Jesper Juhl   doc: getdelays.c:...
105
106
  			fprintf(stderr, "Unable to set socket rcv buf size to %d
  ",
d2f7bf134   Andrew Morton   [PATCH] getdelays...
107
  				rcvbufsz);
0de4b9540   Jesper Juhl   doc: getdelays.c:...
108
  			goto error;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
109
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
110

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

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

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

b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
123
  static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
124
125
  	     __u8 genl_cmd, __u16 nla_type,
  	     void *nla_data, int nla_len)
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
126
  {
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
127
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
  	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-...
160
  }
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
161

a3baf649c   Shailabh Nagar   [PATCH] per-task-...
162
163
164
165
  /*
   * Probe the controller in genetlink to find the family id
   * for the TASKSTATS family
   */
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
166
  static int get_family_id(int sd)
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
167
  {
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
168
169
170
171
172
  	struct {
  		struct nlmsghdr n;
  		struct genlmsghdr g;
  		char buf[256];
  	} ans;
10e6f32bd   Randy Dunlap   getdelays: fix gc...
173
  	int id = 0, rc;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
174
175
176
177
178
179
180
  	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...
181
182
  	if (rc < 0)
  		return 0;	/* sendto() failure? */
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
183
184
185
186
187
  
  	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-...
188

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

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
298
299
300
301
302
303
  		switch (c) {
  		case 'd':
  			printf("print delayacct stats ON
  ");
  			print_delays = 1;
  			break;
cf709844d   Andrew Morton   [PATCH] io-accoun...
304
305
306
307
308
  		case 'i':
  			printf("printing IO accounting
  ");
  			print_io_accounting = 1;
  			break;
b663a79c1   Maxim Uvarov   taskstats: add co...
309
310
311
312
313
  		case 'q':
  			printf("printing task/process context switch rates
  ");
  			print_task_context_switch_counts = 1;
  			break;
546040dc4   Balbir Singh   make getdelays cg...
314
315
  		case 'C':
  			containerset = 1;
8da01af45   Kees Cook   Documentation/acc...
316
  			containerpath = optarg;
546040dc4   Balbir Singh   make getdelays cg...
317
  			break;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
318
  		case 'w':
7f76c4037   Scott Wiersdorf   getdelays.c: fix ...
319
  			logfile = strdup(optarg);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  			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));
88e15ce40   Rickard Strandqvist   Documentation/acc...
334
  			cpumask[sizeof(cpumask) - 1] = '\0';
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
335
336
337
338
339
340
341
342
343
344
  			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

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

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

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
408
409
410
  	mypid = getpid();
  	id = get_family_id(nl_sd);
  	if (!id) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
411
412
  		fprintf(stderr, "Error getting family id, errno %d
  ", errno);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
413
  		goto err;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
414
  	}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
415
416
417
418
419
420
  	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...
421
  			      &cpumask, strlen(cpumask) + 1);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
422
423
424
  		PRINTF("Sent register cpumask, retval %d
  ", rc);
  		if (rc < 0) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
425
426
  			fprintf(stderr, "error sending register cpumask
  ");
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
427
428
  			goto err;
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
429
  	}
546040dc4   Balbir Singh   make getdelays cg...
430
431
432
433
434
  	if (tid && containerset) {
  		fprintf(stderr, "Select either -t or -C, not both
  ");
  		goto err;
  	}
db9e5679d   Mel Gorman   delay-accounting:...
435
436
437
438
439
440
441
442
  	/*
  	 * 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 ...
443
444
445
446
447
448
  	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...
449
450
  			fprintf(stderr, "error sending tid/tgid cmd
  ");
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
451
452
  			goto done;
  		}
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
453
  	}
546040dc4   Balbir Singh   make getdelays cg...
454
455
456
457
458
459
460
461
462
463
464
465
466
  	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...
467
468
469
470
  	if (!maskset && !tid && !containerset) {
  		usage();
  		goto err;
  	}
546040dc4   Balbir Singh   make getdelays cg...
471

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

9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
477
  		if (rep_len < 0) {
d2f7bf134   Andrew Morton   [PATCH] getdelays...
478
479
480
  			fprintf(stderr, "nonfatal reply error: errno %d
  ",
  				errno);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
481
482
483
484
  			continue;
  		}
  		if (msg.n.nlmsg_type == NLMSG_ERROR ||
  		    !NLMSG_OK((&msg.n), rep_len)) {
7d1bdca9b   Balbir Singh   [PATCH] Fix getde...
485
  			struct nlmsgerr *err = NLMSG_DATA(&msg);
d2f7bf134   Andrew Morton   [PATCH] getdelays...
486
487
488
  			fprintf(stderr, "fatal reply error,  errno %d
  ",
  				err->error);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
489
490
  			goto done;
  		}
10e6f32bd   Randy Dunlap   getdelays: fix gc...
491
492
  		PRINTF("nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d
  ",
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
493
494
495
496
497
498
499
  		       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 ...
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
528
  		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...
529
530
  						if (print_io_accounting)
  							print_ioacct((struct taskstats *) NLA_DATA(na));
b663a79c1   Maxim Uvarov   taskstats: add co...
531
532
  						if (print_task_context_switch_counts)
  							task_context_switch_counts((struct taskstats *) NLA_DATA(na));
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
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;
570d8e939   Nicolas Dichtel   taskstats: fix nl...
542
543
  					case TASKSTATS_TYPE_NULL:
  						break;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
544
  					default:
d2f7bf134   Andrew Morton   [PATCH] getdelays...
545
546
547
548
  						fprintf(stderr, "Unknown nested"
  							" nla_type %d
  ",
  							na->nla_type);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
549
550
551
  						break;
  					}
  					len2 += NLA_ALIGN(na->nla_len);
570d8e939   Nicolas Dichtel   taskstats: fix nl...
552
553
  					na = (struct nlattr *)((char *)na +
  							       NLA_ALIGN(na->nla_len));
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
554
555
  				}
  				break;
546040dc4   Balbir Singh   make getdelays cg...
556
557
558
  			case CGROUPSTATS_TYPE_CGROUP_STATS:
  				print_cgroupstats(NLA_DATA(na));
  				break;
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
559
  			default:
d2f7bf134   Andrew Morton   [PATCH] getdelays...
560
561
562
  				fprintf(stderr, "Unknown nla_type %d
  ",
  					na->nla_type);
4be2c95d1   Jeff Mahoney   taskstats: pad ta...
563
  			case TASKSTATS_TYPE_NULL:
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
564
  				break;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
565
  			}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
566
  			na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
567
  		}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
568
569
570
571
572
  	} 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...
573
  			      &cpumask, strlen(cpumask) + 1);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
574
575
576
577
578
  		printf("Sent deregister mask, retval %d
  ", rc);
  		if (rc < 0)
  			err(rc, "error sending deregister cpumask
  ");
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
579
  	}
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
580
581
582
583
  err:
  	close(nl_sd);
  	if (fd)
  		close(fd);
546040dc4   Balbir Singh   make getdelays cg...
584
585
  	if (cfd)
  		close(cfd);
9e06d3f9f   Shailabh Nagar   [PATCH] per task ...
586
  	return 0;
a3baf649c   Shailabh Nagar   [PATCH] per-task-...
587
  }