displaying closed files
[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;
b093de8a
MB
58}
59
ceb3a221
MB
60/* TODO */
61/* To be done */
62void edit_file(struct processtop *proc, struct files *file, int fd)
63{
64 int size = proc->process_files_table->len;
65 struct files *tmpfile;
66
67 if (size <= fd)
68 return;
69 else {
70 tmpfile = g_ptr_array_index(proc->process_files_table, fd);
71 tmpfile->name = strdup(file->name);
72 free(file);
73 }
74}
b093de8a
MB
75
76void insert_file(struct processtop *proc, int fd)
77{
78 struct files *tmp;
79
80 if (fd >= proc->process_files_table->len) {
81 tmp = g_new0(struct files, 1);
82 tmp->name = "Unknown";
ceb3a221
MB
83 tmp->read = 0;
84 tmp->write = 0;
85 tmp->fd = fd;
b093de8a
MB
86 add_file(proc, tmp, fd);
87 } else {
88
89 tmp = g_ptr_array_index(proc->process_files_table, fd);
90 if (tmp == NULL) {
91 tmp = g_new0(struct files, 1);
92 tmp->name = "Unknown";
93 tmp->read = 0;
94 tmp->write = 0;
95 tmp->fd = fd;
96 add_file(proc, tmp, fd);
97 }
98 }
99}
100
101void close_file(struct processtop *proc, int fd)
ceb3a221
MB
102{
103 struct files *file;
104
105
106 file = get_file(proc, fd);
107 if (file != NULL)
108 file->flag = __NR_close;
109}
110
111struct files *get_file(struct processtop *proc, int fd)
b093de8a
MB
112{
113 int len;
ceb3a221 114 struct files *tmp = NULL;
b093de8a
MB
115
116 len = proc->process_files_table->len;
117
118 /*
119 * It is possible that a file was open before taking the trace
120 * and its fd could be greater than all of the others fd
121 * used by the process
122 */
ceb3a221
MB
123 if (fd < len && fd >= 0)
124 tmp = g_ptr_array_index(proc->process_files_table, fd);
b093de8a 125
b093de8a
MB
126 return tmp;
127}
128
129void show_table(GPtrArray *tab)
130{
131 int i;
132 struct files *file;
133
134 for (i = 0 ; i < tab->len; i++) {
135 file = g_ptr_array_index(tab, i);
136 if (file == NULL)
137 fprintf(stderr, "NULL, ");
138 else
139 fprintf(stderr, "%s, ", file->name);
140 }
141 fprintf(stderr, "]\n\n");
142}
1fc22eb4 143
ceb3a221
MB
144void show_history(struct file_history *history)
145{
146 struct file_history *tmp = history;
147
148 while (tmp != NULL) {
149 fprintf(stderr, "fd = %d, name = %s\n", tmp->file->fd,
150 tmp->file->name);
151 tmp = tmp->next;
152 }
153
154}
155
1fc22eb4 156int update_iostream_ret(struct lttngtop *ctx, int tid, char *comm,
d67167cd 157 unsigned long timestamp, uint64_t cpu_id, int ret)
1fc22eb4
JD
158{
159 struct processtop *tmp;
b093de8a 160 struct files *tmpfile;
1fc22eb4
JD
161 int err = 0;
162
163 tmp = get_proc(ctx, tid, comm, timestamp);
b093de8a
MB
164
165 if (tmp->syscall_info != NULL) {
166 if (tmp->syscall_info->type == __NR_read
167 && ret > 0) {
168 tmp->totalfileread += ret;
169 tmp->fileread += ret;
170 tmpfile = get_file(tmp, tmp->syscall_info->fd);
171 tmpfile->read += ret;
172 } else if (tmp->syscall_info->type == __NR_write
173 && ret > 0) {
174 tmp->totalfilewrite += ret;
175 tmp->filewrite += ret;
176 tmpfile = get_file(tmp, tmp->syscall_info->fd);
177 tmpfile->write += ret;
178 } else if (tmp->syscall_info->type == __NR_open
179 && ret > 0) {
ceb3a221
MB
180 tmpfile = tmp->files_history->file;
181 add_file(tmp, tmpfile, ret);
182 tmpfile->fd = ret;
b093de8a 183 } else {
1fc22eb4
JD
184 err = -1;
185 }
b093de8a
MB
186 g_free(tmp->syscall_info);
187 tmp->syscall_info = NULL;
188 }
1fc22eb4
JD
189 return err;
190}
191
d67167cd 192struct syscalls *create_syscall_info(unsigned int type, uint64_t cpu_id,
b093de8a
MB
193 unsigned int tid, int fd)
194{
195 struct syscalls *syscall_info;
196
197 syscall_info = g_new0(struct syscalls, 1);
198 syscall_info->type = type;
199 syscall_info->cpu_id = cpu_id;
200 syscall_info->tid = tid;
201 syscall_info->fd = fd;
202
203 return syscall_info;
204}
205
206struct file_history *create_file(struct file_history *history, char *file_name)
207{
208 struct files *new_file;
209 struct file_history *new_history;
210
211 new_file = g_new0(struct files, 1);
212 new_history = g_new0(struct file_history, 1);
213 new_file->name = strdup(file_name);
214 new_file->read = 0;
215 new_file->write = 0;
216 new_history->file = new_file;
217 new_history->next = history;
218
219 return new_history;
220}
221
1fc22eb4
JD
222enum bt_cb_ret handle_exit_syscall(struct bt_ctf_event *call_data,
223 void *private_data)
224{
3ba84bed 225 const struct definition *scope;
1fc22eb4
JD
226 unsigned long timestamp;
227 char *comm;
228 uint64_t ret, tid;
d67167cd 229 uint64_t cpu_id;
1fc22eb4
JD
230
231 timestamp = bt_ctf_get_timestamp(call_data);
232 if (timestamp == -1ULL)
233 goto error;
234
1dec520a
JD
235 comm = get_context_comm(call_data);
236 tid = get_context_tid(call_data);
1fc22eb4
JD
237
238 scope = bt_ctf_get_top_level_scope(call_data,
239 BT_EVENT_FIELDS);
240 ret = bt_ctf_get_int64(bt_ctf_get_field(call_data,
241 scope, "_ret"));
242 if (bt_ctf_field_get_error()) {
243 fprintf(stderr, "Missing ret context info\n");
244 goto error;
245 }
246
d67167cd 247 cpu_id = get_cpu_id(call_data);
1fc22eb4
JD
248
249 /*
b093de8a
MB
250 * if we encounter an exit_syscall and
251 * it is not for a syscall read or write
1fc22eb4
JD
252 * we just abort the execution of this callback
253 */
254 if ((update_iostream_ret(&lttngtop, tid, comm, timestamp, cpu_id, ret)) < 0)
255 return BT_CB_ERROR_CONTINUE;
256
257 return BT_CB_OK;
258
259error:
260 return BT_CB_ERROR_STOP;
261}
262
263
264enum bt_cb_ret handle_sys_write(struct bt_ctf_event *call_data,
265 void *private_data)
266{
3ba84bed 267 const struct definition *scope;
1fc22eb4 268 struct processtop *tmp;
1fc22eb4
JD
269 unsigned long timestamp;
270 uint64_t cpu_id;
271 char *comm;
272 int64_t tid;
b093de8a 273 int fd;
1fc22eb4
JD
274
275 timestamp = bt_ctf_get_timestamp(call_data);
276 if (timestamp == -1ULL)
277 goto error;
278
1dec520a
JD
279 comm = get_context_comm(call_data);
280 tid = get_context_tid(call_data);
d67167cd 281 cpu_id = get_cpu_id(call_data);
1fc22eb4 282
b093de8a
MB
283 scope = bt_ctf_get_top_level_scope(call_data,
284 BT_EVENT_FIELDS);
285 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
286 scope, "_fd"));
287 if (bt_ctf_field_get_error()) {
288 fprintf(stderr, "Missing fd context info\n");
289 goto error;
290 }
291
1fc22eb4 292 tmp = get_proc(&lttngtop, tid, comm, timestamp);
b093de8a
MB
293 tmp->syscall_info = create_syscall_info(__NR_write, cpu_id, tid, fd);
294
295 insert_file(tmp, fd);
1fc22eb4
JD
296
297 return BT_CB_OK;
298
299error:
300 return BT_CB_ERROR_STOP;
301}
302
303enum bt_cb_ret handle_sys_read(struct bt_ctf_event *call_data,
304 void *private_data)
305{
306 struct processtop *tmp;
3ba84bed 307 const struct definition *scope;
1fc22eb4
JD
308 unsigned long timestamp;
309 uint64_t cpu_id;
310 char *comm;
311 int64_t tid;
b093de8a 312 int fd;
1fc22eb4
JD
313
314 timestamp = bt_ctf_get_timestamp(call_data);
315 if (timestamp == -1ULL)
316 goto error;
317
1dec520a
JD
318 comm = get_context_comm(call_data);
319 tid = get_context_tid(call_data);
d67167cd 320 cpu_id = get_cpu_id(call_data);
1fc22eb4 321
b093de8a
MB
322 scope = bt_ctf_get_top_level_scope(call_data,
323 BT_EVENT_FIELDS);
324 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
325 scope, "_fd"));
326 if (bt_ctf_field_get_error()) {
327 fprintf(stderr, "Missing fd context info\n");
328 goto error;
329 }
330
331 tmp = get_proc(&lttngtop, tid, comm, timestamp);
332 tmp->syscall_info = create_syscall_info(__NR_read, cpu_id, tid, fd);
333
334 insert_file(tmp, fd);
335
336 return BT_CB_OK;
337
338error:
339 return BT_CB_ERROR_STOP;
340}
341
342
343enum bt_cb_ret handle_sys_open(struct bt_ctf_event *call_data,
344 void *private_data)
345{
346
347 struct processtop *tmp;
3ba84bed 348 const struct definition *scope;
b093de8a
MB
349 unsigned long timestamp;
350 uint64_t cpu_id;
351 char *comm;
352 int64_t tid;
353 char *file;
354
355 timestamp = bt_ctf_get_timestamp(call_data);
356 if (timestamp == -1ULL)
357 goto error;
358
1dec520a
JD
359 comm = get_context_comm(call_data);
360 tid = get_context_tid(call_data);
d67167cd 361 cpu_id = get_cpu_id(call_data);
b093de8a
MB
362
363 scope = bt_ctf_get_top_level_scope(call_data,
364 BT_EVENT_FIELDS);
365 file = bt_ctf_get_string(bt_ctf_get_field(call_data,
366 scope, "_filename"));
367 if (bt_ctf_field_get_error()) {
ceb3a221 368 fprintf(stderr, "Missing file name context info\n");
b093de8a
MB
369 goto error;
370 }
371
1fc22eb4 372 tmp = get_proc(&lttngtop, tid, comm, timestamp);
b093de8a
MB
373 tmp->syscall_info = create_syscall_info(__NR_open, cpu_id, tid, -1);
374
375 tmp->files_history = create_file(tmp->files_history, file);
1fc22eb4
JD
376
377 return BT_CB_OK;
378
379error:
380 return BT_CB_ERROR_STOP;
381}
382
b093de8a
MB
383
384enum bt_cb_ret handle_sys_close(struct bt_ctf_event *call_data,
385 void *private_data)
386{
3ba84bed 387 const struct definition *scope;
b093de8a
MB
388 unsigned long timestamp;
389 int64_t tid;
390 struct processtop *tmp;
391 char *comm;
392 int fd;
393
394 timestamp = bt_ctf_get_timestamp(call_data);
395 if (timestamp == -1ULL)
396 goto error;
397
1dec520a
JD
398 comm = get_context_comm(call_data);
399 tid = get_context_tid(call_data);
b093de8a
MB
400
401 scope = bt_ctf_get_top_level_scope(call_data,
402 BT_EVENT_FIELDS);
403 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
404 scope, "_fd"));
405 if (bt_ctf_field_get_error()) {
406 fprintf(stderr, "Missing fd context info\n");
407 goto error;
408 }
409
410 tmp = get_proc(&lttngtop, tid, comm, timestamp);
ceb3a221 411
b093de8a
MB
412 close_file(tmp, fd);
413
414 return BT_CB_OK;
415
416error:
417 return BT_CB_ERROR_STOP;
418}
ceb3a221
MB
419/*
420enum bt_cb_ret handle_statedump_file_descriptor(struct bt_ctf_event *call_data,
421 void *private_data)
422{
423 struct definition *scope;
424 struct files *file;
425 unsigned long timestamp;
426 int64_t tid;
427 struct processtop *tmp;
428 char *comm, *file_name;
429 int fd;
430
431 timestamp = bt_ctf_get_timestamp(call_data);
432 if (timestamp == -1ULL)
433 goto error;
434
435 comm = get_context_comm(call_data);
436
437 scope = bt_ctf_get_top_level_scope(call_data,
438 BT_EVENT_FIELDS);
439 tid = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
440 scope, "_tid"));
441 if (bt_ctf_field_get_error()) {
442 fprintf(stderr, "Missing tid context info\n");
443 goto error;
444 }
445
446 scope = bt_ctf_get_top_level_scope(call_data,
447 BT_EVENT_FIELDS);
448 fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
449 scope, "_fd"));
450 if (bt_ctf_field_get_error()) {
451 fprintf(stderr, "Missing fd context info\n");
452 goto error;
453 }
454
455 scope = bt_ctf_get_top_level_scope(call_data,
456 BT_EVENT_FIELDS);
457 file_name = bt_ctf_get_string(bt_ctf_get_field(call_data,
458 scope, "_filename"));
459 if (bt_ctf_field_get_error()) {
460 fprintf(stderr, "Missing file name context info\n");
461 goto error;
462 }
463
464 file = g_new0(struct files, 1);
465 file->name = strdup(file_name);
466 file->fd = fd;
467 tmp = find_process_tid(&lttngtop, tid, comm);
468 edit_file(tmp, file, fd);
469
470 fprintf(stderr, "%lu %s\n", tmp->tid, file_name);
471
472 return BT_CB_OK;
473
474error:
475 return BT_CB_ERROR_STOP;
476}
477*/
This page took 0.064657 seconds and 4 git commands to generate.