Reactivate header counters
[lttngtop.git] / src / iostreamtop.c
CommitLineData
1fc22eb4
JD
1/*
2 * Copyright (C) 2011 Mathieu Bain <mathieu.bain@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
71bd7ce1
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1fc22eb4
JD
16 */
17
b093de8a
MB
18#include <stdlib.h>
19#include <unistd.h>
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <string.h>
1fc22eb4
JD
23#include <babeltrace/babeltrace.h>
24
25#include "lttngtoptypes.h"
26#include "common.h"
27#include "iostreamtop.h"
28
b093de8a
MB
29void add_file(struct processtop *proc, struct files *file, int fd)
30{
ceb3a221
MB
31 struct files *tmp_file;
32 int size;
33
34 size = proc->process_files_table->len;
35
36 if (size <= fd) {
b093de8a
MB
37 g_ptr_array_set_size(proc->process_files_table, fd);
38 g_ptr_array_add(proc->process_files_table, file);
39 } else {
ceb3a221
MB
40 tmp_file = g_ptr_array_index(proc->process_files_table, fd);
41 if (tmp_file == NULL)
42 g_ptr_array_index(proc->process_files_table, fd) = file;
43 else {
44 if (strcmp(tmp_file->name, file->name) != 0) {
45 size = proc->process_files_table->len;
46 g_ptr_array_set_size(proc->process_files_table,
47 size+1);
48 g_ptr_array_index(proc->process_files_table,
49 size) = tmp_file;
50 g_ptr_array_index(proc->process_files_table,
51 fd) = file;
52 } else
53 tmp_file->flag = __NR_open;
54 }
b093de8a
MB
55 }
56 file->fd = fd;
ceb3a221 57 file->flag = __NR_open;
e05a35a6
JD
58 lttngtop.nbfiles++;
59 lttngtop.nbnewfiles++;
b093de8a
MB
60}
61
ceb3a221
MB
62/* TODO */
63/* To be done */
64void edit_file(struct processtop *proc, struct files *file, int fd)
65{
66 int size = proc->process_files_table->len;
67 struct files *tmpfile;
68
69 if (size <= fd)
70 return;
71 else {
72 tmpfile = g_ptr_array_index(proc->process_files_table, fd);
73 tmpfile->name = strdup(file->name);
74 free(file);
75 }
76}
b093de8a
MB
77
78void insert_file(struct processtop *proc, int fd)
79{
80 struct files *tmp;
81
82 if (fd >= proc->process_files_table->len) {
83 tmp = g_new0(struct files, 1);
84 tmp->name = "Unknown";
ceb3a221
MB
85 tmp->read = 0;
86 tmp->write = 0;
87 tmp->fd = fd;
b093de8a
MB
88 add_file(proc, tmp, fd);
89 } else {
b093de8a
MB
90 tmp = g_ptr_array_index(proc->process_files_table, fd);
91 if (tmp == NULL) {
92 tmp = g_new0(struct files, 1);
93 tmp->name = "Unknown";
94 tmp->read = 0;
95 tmp->write = 0;
96 tmp->fd = fd;
97 add_file(proc, tmp, fd);
98 }
99 }
100}
101
102void close_file(struct processtop *proc, int fd)
ceb3a221
MB
103{
104 struct files *file;
105
ceb3a221 106 file = get_file(proc, fd);
e05a35a6 107 if (file != NULL) {
ceb3a221 108 file->flag = __NR_close;
e05a35a6
JD
109 lttngtop.nbfiles--;
110 }
111 lttngtop.nbclosedfiles++;
ceb3a221
MB
112}
113
114struct files *get_file(struct processtop *proc, int fd)
b093de8a
MB
115{
116 int len;
ceb3a221 117 struct files *tmp = NULL;
b093de8a
MB
118
119 len = proc->process_files_table->len;
120
121 /*
122 * It is possible that a file was open before taking the trace
123 * and its fd could be greater than all of the others fd
124 * used by the process
125 */
ceb3a221
MB
126 if (fd < len && fd >= 0)
127 tmp = g_ptr_array_index(proc->process_files_table, fd);
b093de8a 128
b093de8a
MB
129 return tmp;
130}
131
132void show_table(GPtrArray *tab)
133{
134 int i;
135 struct files *file;
136
137 for (i = 0 ; i < tab->len; i++) {
138 file = g_ptr_array_index(tab, i);
139 if (file == NULL)
140 fprintf(stderr, "NULL, ");
141 else
142 fprintf(stderr, "%s, ", file->name);
143 }
144 fprintf(stderr, "]\n\n");
145}
1fc22eb4 146
ceb3a221
MB
147void show_history(struct file_history *history)
148{
149 struct file_history *tmp = history;
150
151 while (tmp != NULL) {
152 fprintf(stderr, "fd = %d, name = %s\n", tmp->file->fd,
153 tmp->file->name);
154 tmp = tmp->next;
155 }
156
157}
158
1fc22eb4 159int update_iostream_ret(struct lttngtop *ctx, int tid, char *comm,
d67167cd 160 unsigned long timestamp, uint64_t cpu_id, int ret)
1fc22eb4
JD
161{
162 struct processtop *tmp;
b093de8a 163 struct files *tmpfile;
1fc22eb4
JD
164 int err = 0;
165
166 tmp = get_proc(ctx, tid, comm, timestamp);
b093de8a
MB
167
168 if (tmp->syscall_info != NULL) {
169 if (tmp->syscall_info->type == __NR_read
170 && ret > 0) {
171 tmp->totalfileread += ret;
172 tmp->fileread += ret;
173 tmpfile = get_file(tmp, tmp->syscall_info->fd);
174 tmpfile->read += ret;
175 } else if (tmp->syscall_info->type == __NR_write
176 && ret > 0) {
177 tmp->totalfilewrite += ret;
178 tmp->filewrite += ret;
179 tmpfile = get_file(tmp, tmp->syscall_info->fd);
180 tmpfile->write += ret;
181 } else if (tmp->syscall_info->type == __NR_open
182 && ret > 0) {
ceb3a221
MB
183 tmpfile = tmp->files_history->file;
184 add_file(tmp, tmpfile, ret);
185 tmpfile->fd = ret;
b093de8a 186 } else {
1fc22eb4
JD
187 err = -1;
188 }
b093de8a
MB
189 g_free(tmp->syscall_info);
190 tmp->syscall_info = NULL;
191 }
1fc22eb4
JD
192 return err;
193}
194
d67167cd 195struct syscalls *create_syscall_info(unsigned int type, uint64_t cpu_id,
b093de8a
MB
196 unsigned int tid, int fd)
197{
198 struct syscalls *syscall_info;
199
200 syscall_info = g_new0(struct syscalls, 1);
201 syscall_info->type = type;
202 syscall_info->cpu_id = cpu_id;
203 syscall_info->tid = tid;
204 syscall_info->fd = fd;
205
206 return syscall_info;
207}
208
209struct file_history *create_file(struct file_history *history, char *file_name)
210{
211 struct files *new_file;
212 struct file_history *new_history;
213
214 new_file = g_new0(struct files, 1);
215 new_history = g_new0(struct file_history, 1);
216 new_file->name = strdup(file_name);
217 new_file->read = 0;
218 new_file->write = 0;
219 new_history->file = new_file;
220 new_history->next = history;
221
222 return new_history;
223}
224
1fc22eb4
JD
225enum bt_cb_ret handle_exit_syscall(struct bt_ctf_event *call_data,
226 void *private_data)
227{
3ba84bed 228 const struct definition *scope;
1fc22eb4
JD
229 unsigned long timestamp;
230 char *comm;
231 uint64_t ret, tid;
d67167cd 232 uint64_t cpu_id;
1fc22eb4
JD
233
234 timestamp = bt_ctf_get_timestamp(call_data);
235 if (timestamp == -1ULL)
236 goto error;
237
1dec520a
JD
238 comm = get_context_comm(call_data);
239 tid = get_context_tid(call_data);
1fc22eb4
JD
240
241 scope = bt_ctf_get_top_level_scope(call_data,
242 BT_EVENT_FIELDS);
243 ret = bt_ctf_get_int64(bt_ctf_get_field(call_data,
244 scope, "_ret"));
245 if (bt_ctf_field_get_error()) {
246 fprintf(stderr, "Missing ret context info\n");
247 goto error;
248 }
249
d67167cd 250 cpu_id = get_cpu_id(call_data);
1fc22eb4
JD
251
252 /*
b093de8a
MB
253 * if we encounter an exit_syscall and
254 * it is not for a syscall read or write
1fc22eb4
JD
255 * we just abort the execution of this callback
256 */
257 if ((update_iostream_ret(&lttngtop, tid, comm, timestamp, cpu_id, ret)) < 0)
258 return BT_CB_ERROR_CONTINUE;
259
260 return BT_CB_OK;
261
262error:
263 return BT_CB_ERROR_STOP;
264}
265
266
267enum bt_cb_ret handle_sys_write(struct bt_ctf_event *call_data,
268 void *private_data)
269{
3ba84bed 270 const struct definition *scope;
1fc22eb4 271 struct processtop *tmp;
1fc22eb4
JD
272 unsigned long timestamp;
273 uint64_t cpu_id;
274 char *comm;
275 int64_t tid;
b093de8a 276 int fd;
1fc22eb4
JD
277
278 timestamp = bt_ctf_get_timestamp(call_data);
279 if (timestamp == -1ULL)
280 goto error;
281
1dec520a
JD
282 comm = get_context_comm(call_data);
283 tid = get_context_tid(call_data);
d67167cd 284 cpu_id = get_cpu_id(call_data);
1fc22eb4 285
b093de8a
MB
286 scope = bt_ctf_get_top_level_scope(call_data,
287 BT_EVENT_FIELDS);
288 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
289 scope, "_fd"));
290 if (bt_ctf_field_get_error()) {
291 fprintf(stderr, "Missing fd context info\n");
292 goto error;
293 }
294
1fc22eb4 295 tmp = get_proc(&lttngtop, tid, comm, timestamp);
b093de8a
MB
296 tmp->syscall_info = create_syscall_info(__NR_write, cpu_id, tid, fd);
297
298 insert_file(tmp, fd);
1fc22eb4
JD
299
300 return BT_CB_OK;
301
302error:
303 return BT_CB_ERROR_STOP;
304}
305
306enum bt_cb_ret handle_sys_read(struct bt_ctf_event *call_data,
307 void *private_data)
308{
309 struct processtop *tmp;
3ba84bed 310 const struct definition *scope;
1fc22eb4
JD
311 unsigned long timestamp;
312 uint64_t cpu_id;
313 char *comm;
314 int64_t tid;
b093de8a 315 int fd;
1fc22eb4
JD
316
317 timestamp = bt_ctf_get_timestamp(call_data);
318 if (timestamp == -1ULL)
319 goto error;
320
1dec520a
JD
321 comm = get_context_comm(call_data);
322 tid = get_context_tid(call_data);
d67167cd 323 cpu_id = get_cpu_id(call_data);
1fc22eb4 324
b093de8a
MB
325 scope = bt_ctf_get_top_level_scope(call_data,
326 BT_EVENT_FIELDS);
327 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
328 scope, "_fd"));
329 if (bt_ctf_field_get_error()) {
330 fprintf(stderr, "Missing fd context info\n");
331 goto error;
332 }
333
334 tmp = get_proc(&lttngtop, tid, comm, timestamp);
335 tmp->syscall_info = create_syscall_info(__NR_read, cpu_id, tid, fd);
336
337 insert_file(tmp, fd);
338
339 return BT_CB_OK;
340
341error:
342 return BT_CB_ERROR_STOP;
343}
344
345
346enum bt_cb_ret handle_sys_open(struct bt_ctf_event *call_data,
347 void *private_data)
348{
349
350 struct processtop *tmp;
3ba84bed 351 const struct definition *scope;
b093de8a
MB
352 unsigned long timestamp;
353 uint64_t cpu_id;
354 char *comm;
355 int64_t tid;
356 char *file;
357
358 timestamp = bt_ctf_get_timestamp(call_data);
359 if (timestamp == -1ULL)
360 goto error;
361
1dec520a
JD
362 comm = get_context_comm(call_data);
363 tid = get_context_tid(call_data);
d67167cd 364 cpu_id = get_cpu_id(call_data);
b093de8a
MB
365
366 scope = bt_ctf_get_top_level_scope(call_data,
367 BT_EVENT_FIELDS);
368 file = bt_ctf_get_string(bt_ctf_get_field(call_data,
369 scope, "_filename"));
370 if (bt_ctf_field_get_error()) {
ceb3a221 371 fprintf(stderr, "Missing file name context info\n");
b093de8a
MB
372 goto error;
373 }
374
1fc22eb4 375 tmp = get_proc(&lttngtop, tid, comm, timestamp);
b093de8a
MB
376 tmp->syscall_info = create_syscall_info(__NR_open, cpu_id, tid, -1);
377
378 tmp->files_history = create_file(tmp->files_history, file);
1fc22eb4
JD
379
380 return BT_CB_OK;
381
382error:
383 return BT_CB_ERROR_STOP;
384}
385
b093de8a
MB
386
387enum bt_cb_ret handle_sys_close(struct bt_ctf_event *call_data,
388 void *private_data)
389{
3ba84bed 390 const struct definition *scope;
b093de8a
MB
391 unsigned long timestamp;
392 int64_t tid;
393 struct processtop *tmp;
394 char *comm;
395 int fd;
396
397 timestamp = bt_ctf_get_timestamp(call_data);
398 if (timestamp == -1ULL)
399 goto error;
400
1dec520a
JD
401 comm = get_context_comm(call_data);
402 tid = get_context_tid(call_data);
b093de8a
MB
403
404 scope = bt_ctf_get_top_level_scope(call_data,
405 BT_EVENT_FIELDS);
406 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
407 scope, "_fd"));
408 if (bt_ctf_field_get_error()) {
409 fprintf(stderr, "Missing fd context info\n");
410 goto error;
411 }
412
413 tmp = get_proc(&lttngtop, tid, comm, timestamp);
ceb3a221 414
b093de8a
MB
415 close_file(tmp, fd);
416
417 return BT_CB_OK;
418
419error:
420 return BT_CB_ERROR_STOP;
421}
ceb3a221
MB
422/*
423enum bt_cb_ret handle_statedump_file_descriptor(struct bt_ctf_event *call_data,
424 void *private_data)
425{
426 struct definition *scope;
427 struct files *file;
428 unsigned long timestamp;
429 int64_t tid;
430 struct processtop *tmp;
431 char *comm, *file_name;
432 int fd;
433
434 timestamp = bt_ctf_get_timestamp(call_data);
435 if (timestamp == -1ULL)
436 goto error;
437
438 comm = get_context_comm(call_data);
439
440 scope = bt_ctf_get_top_level_scope(call_data,
441 BT_EVENT_FIELDS);
442 tid = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
443 scope, "_tid"));
444 if (bt_ctf_field_get_error()) {
445 fprintf(stderr, "Missing tid context info\n");
446 goto error;
447 }
448
449 scope = bt_ctf_get_top_level_scope(call_data,
450 BT_EVENT_FIELDS);
451 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
452 scope, "_fd"));
453 if (bt_ctf_field_get_error()) {
454 fprintf(stderr, "Missing fd context info\n");
455 goto error;
456 }
457
458 scope = bt_ctf_get_top_level_scope(call_data,
459 BT_EVENT_FIELDS);
460 file_name = bt_ctf_get_string(bt_ctf_get_field(call_data,
461 scope, "_filename"));
462 if (bt_ctf_field_get_error()) {
463 fprintf(stderr, "Missing file name context info\n");
464 goto error;
465 }
466
467 file = g_new0(struct files, 1);
468 file->name = strdup(file_name);
469 file->fd = fd;
470 tmp = find_process_tid(&lttngtop, tid, comm);
471 edit_file(tmp, file, fd);
472
473 fprintf(stderr, "%lu %s\n", tmp->tid, file_name);
474
475 return BT_CB_OK;
476
477error:
478 return BT_CB_ERROR_STOP;
479}
480*/
This page took 0.064491 seconds and 4 git commands to generate.