2 * Copyright (C) 2011 Mathieu Bain <mathieu.bain@polymtl.ca>
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;
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.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 #include <sys/types.h>
24 #include <babeltrace/babeltrace.h>
26 #include "lttngtoptypes.h"
28 #include "iostreamtop.h"
30 void add_file(struct processtop
*proc
, struct files
*file
, int fd
)
32 if (proc
->process_files_table
->len
<= fd
) {
33 g_ptr_array_set_size(proc
->process_files_table
, fd
);
34 g_ptr_array_add(proc
->process_files_table
, file
);
36 g_ptr_array_index(proc
->process_files_table
, fd
) = file
;
42 void insert_file(struct processtop
*proc
, int fd
)
46 if (fd
>= proc
->process_files_table
->len
) {
47 tmp
= g_new0(struct files
, 1);
48 tmp
->name
= "Unknown";
49 add_file(proc
, tmp
, fd
);
52 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
54 tmp
= g_new0(struct files
, 1);
55 tmp
->name
= "Unknown";
59 add_file(proc
, tmp
, fd
);
64 void close_file(struct processtop
*proc
, int fd
)
68 len
= proc
->process_files_table
->len
;
71 * It is possible that a file was open before taking the trace
72 * and its fd could be greater than all of the others fd
76 g_ptr_array_remove_index_fast(proc
->process_files_table
, fd
);
77 g_ptr_array_set_size(proc
->process_files_table
, len
+ 1);
81 struct files
*get_file(struct processtop
*proc
, int fd
)
84 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
88 void show_table(GPtrArray
*tab
)
93 for (i
= 0 ; i
< tab
->len
; i
++) {
94 file
= g_ptr_array_index(tab
, i
);
96 fprintf(stderr
, "NULL, ");
98 fprintf(stderr
, "%s, ", file
->name
);
100 fprintf(stderr
, "]\n\n");
103 int update_iostream_ret(struct lttngtop
*ctx
, int tid
, char *comm
,
104 unsigned long timestamp
, int cpu_id
, int ret
)
106 struct processtop
*tmp
;
107 struct files
*tmpfile
;
110 tmp
= get_proc(ctx
, tid
, comm
, timestamp
);
112 if (tmp
->syscall_info
!= NULL
) {
113 if (tmp
->syscall_info
->type
== __NR_read
115 tmp
->totalfileread
+= ret
;
116 tmp
->fileread
+= ret
;
117 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
118 tmpfile
->read
+= ret
;
119 } else if (tmp
->syscall_info
->type
== __NR_write
121 tmp
->totalfilewrite
+= ret
;
122 tmp
->filewrite
+= ret
;
123 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
124 tmpfile
->write
+= ret
;
125 } else if (tmp
->syscall_info
->type
== __NR_open
127 add_file(tmp
, tmp
->files_history
->file
, ret
);
131 g_free(tmp
->syscall_info
);
132 tmp
->syscall_info
= NULL
;
137 struct syscalls
*create_syscall_info(unsigned int type
, unsigned int cpu_id
,
138 unsigned int tid
, int fd
)
140 struct syscalls
*syscall_info
;
142 syscall_info
= g_new0(struct syscalls
, 1);
143 syscall_info
->type
= type
;
144 syscall_info
->cpu_id
= cpu_id
;
145 syscall_info
->tid
= tid
;
146 syscall_info
->fd
= fd
;
151 struct file_history
*create_file(struct file_history
*history
, char *file_name
)
153 struct files
*new_file
;
154 struct file_history
*new_history
;
156 new_file
= g_new0(struct files
, 1);
157 new_history
= g_new0(struct file_history
, 1);
158 new_file
->name
= strdup(file_name
);
161 new_history
->file
= new_file
;
162 new_history
->next
= history
;
167 enum bt_cb_ret
handle_exit_syscall(struct bt_ctf_event
*call_data
,
170 struct definition
*scope
;
171 unsigned long timestamp
;
176 timestamp
= bt_ctf_get_timestamp(call_data
);
177 if (timestamp
== -1ULL)
180 scope
= bt_ctf_get_top_level_scope(call_data
,
181 BT_STREAM_EVENT_CONTEXT
);
182 comm
= bt_ctf_get_char_array(bt_ctf_get_field(call_data
,
183 scope
, "_procname"));
184 if (bt_ctf_field_get_error()) {
185 fprintf(stderr
, "Missing procname context info\n");
189 tid
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
191 if (bt_ctf_field_get_error()) {
192 fprintf(stderr
, "Missing tid context info\n");
196 scope
= bt_ctf_get_top_level_scope(call_data
,
198 ret
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
200 if (bt_ctf_field_get_error()) {
201 fprintf(stderr
, "Missing ret context info\n");
205 scope
= bt_ctf_get_top_level_scope(call_data
,
206 BT_STREAM_PACKET_CONTEXT
);
207 cpu_id
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
209 if (bt_ctf_field_get_error()) {
210 fprintf(stderr
, "Missing cpu_id context info\n");
215 * if we encounter an exit_syscall and
216 * it is not for a syscall read or write
217 * we just abort the execution of this callback
219 if ((update_iostream_ret(<tngtop
, tid
, comm
, timestamp
, cpu_id
, ret
)) < 0)
220 return BT_CB_ERROR_CONTINUE
;
225 return BT_CB_ERROR_STOP
;
229 enum bt_cb_ret
handle_sys_write(struct bt_ctf_event
*call_data
,
232 struct definition
*scope
;
233 struct processtop
*tmp
;
234 unsigned long timestamp
;
240 timestamp
= bt_ctf_get_timestamp(call_data
);
241 if (timestamp
== -1ULL)
244 scope
= bt_ctf_get_top_level_scope(call_data
,
245 BT_STREAM_EVENT_CONTEXT
);
246 comm
= bt_ctf_get_char_array(bt_ctf_get_field(call_data
,
247 scope
, "_procname"));
248 if (bt_ctf_field_get_error()) {
249 fprintf(stderr
, "Missing procname context info\n");
253 tid
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
255 if (bt_ctf_field_get_error()) {
256 fprintf(stderr
, "Missing tid context info\n");
260 scope
= bt_ctf_get_top_level_scope(call_data
,
261 BT_STREAM_PACKET_CONTEXT
);
262 cpu_id
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
264 if (bt_ctf_field_get_error()) {
265 fprintf(stderr
, "Missing cpu_id context info\n");
269 scope
= bt_ctf_get_top_level_scope(call_data
,
271 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
273 if (bt_ctf_field_get_error()) {
274 fprintf(stderr
, "Missing fd context info\n");
278 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
279 tmp
->syscall_info
= create_syscall_info(__NR_write
, cpu_id
, tid
, fd
);
281 insert_file(tmp
, fd
);
286 return BT_CB_ERROR_STOP
;
289 enum bt_cb_ret
handle_sys_read(struct bt_ctf_event
*call_data
,
292 struct processtop
*tmp
;
293 struct definition
*scope
;
294 unsigned long timestamp
;
300 timestamp
= bt_ctf_get_timestamp(call_data
);
301 if (timestamp
== -1ULL)
304 scope
= bt_ctf_get_top_level_scope(call_data
,
305 BT_STREAM_EVENT_CONTEXT
);
306 comm
= bt_ctf_get_char_array(bt_ctf_get_field(call_data
,
307 scope
, "_procname"));
308 if (bt_ctf_field_get_error()) {
309 fprintf(stderr
, "Missing procname context info\n");
313 tid
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
315 if (bt_ctf_field_get_error()) {
316 fprintf(stderr
, "Missing tid context info\n");
320 scope
= bt_ctf_get_top_level_scope(call_data
,
321 BT_STREAM_PACKET_CONTEXT
);
322 cpu_id
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
324 if (bt_ctf_field_get_error()) {
325 fprintf(stderr
, "Missing cpu_id context info\n");
329 scope
= bt_ctf_get_top_level_scope(call_data
,
331 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
333 if (bt_ctf_field_get_error()) {
334 fprintf(stderr
, "Missing fd context info\n");
338 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
339 tmp
->syscall_info
= create_syscall_info(__NR_read
, cpu_id
, tid
, fd
);
341 insert_file(tmp
, fd
);
346 return BT_CB_ERROR_STOP
;
350 enum bt_cb_ret
handle_sys_open(struct bt_ctf_event
*call_data
,
354 struct processtop
*tmp
;
355 struct definition
*scope
;
356 unsigned long timestamp
;
362 timestamp
= bt_ctf_get_timestamp(call_data
);
363 if (timestamp
== -1ULL)
366 scope
= bt_ctf_get_top_level_scope(call_data
,
367 BT_STREAM_EVENT_CONTEXT
);
368 comm
= bt_ctf_get_char_array(bt_ctf_get_field(call_data
,
369 scope
, "_procname"));
370 if (bt_ctf_field_get_error()) {
371 fprintf(stderr
, "Missing procname context info\n");
375 tid
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
377 if (bt_ctf_field_get_error()) {
378 fprintf(stderr
, "Missing tid context info\n");
382 scope
= bt_ctf_get_top_level_scope(call_data
,
383 BT_STREAM_PACKET_CONTEXT
);
384 cpu_id
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
386 if (bt_ctf_field_get_error()) {
387 fprintf(stderr
, "Missing cpu_id context info\n");
391 scope
= bt_ctf_get_top_level_scope(call_data
,
393 file
= bt_ctf_get_string(bt_ctf_get_field(call_data
,
394 scope
, "_filename"));
395 if (bt_ctf_field_get_error()) {
396 fprintf(stderr
, "Missing fd context info\n");
400 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
401 tmp
->syscall_info
= create_syscall_info(__NR_open
, cpu_id
, tid
, -1);
403 tmp
->files_history
= create_file(tmp
->files_history
, file
);
408 return BT_CB_ERROR_STOP
;
412 enum bt_cb_ret
handle_sys_close(struct bt_ctf_event
*call_data
,
415 struct definition
*scope
;
416 unsigned long timestamp
;
418 struct processtop
*tmp
;
422 timestamp
= bt_ctf_get_timestamp(call_data
);
423 if (timestamp
== -1ULL)
426 scope
= bt_ctf_get_top_level_scope(call_data
,
427 BT_STREAM_EVENT_CONTEXT
);
428 comm
= bt_ctf_get_char_array(bt_ctf_get_field(call_data
,
429 scope
, "_procname"));
430 if (bt_ctf_field_get_error()) {
431 fprintf(stderr
, "Missing procname context info\n");
435 tid
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
437 if (bt_ctf_field_get_error()) {
438 fprintf(stderr
, "Missing tid context info\n");
442 scope
= bt_ctf_get_top_level_scope(call_data
,
444 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
446 if (bt_ctf_field_get_error()) {
447 fprintf(stderr
, "Missing fd context info\n");
451 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
457 return BT_CB_ERROR_STOP
;
This page took 0.040924 seconds and 4 git commands to generate.