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 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.
20 #include <sys/types.h>
23 #include <babeltrace/babeltrace.h>
25 #include "lttngtoptypes.h"
27 #include "iostreamtop.h"
29 void add_file(struct processtop
*proc
, struct files
*file
, int fd
)
31 if (proc
->process_files_table
->len
<= fd
) {
32 g_ptr_array_set_size(proc
->process_files_table
, fd
);
33 g_ptr_array_add(proc
->process_files_table
, file
);
35 g_ptr_array_index(proc
->process_files_table
, fd
) = file
;
41 void insert_file(struct processtop
*proc
, int fd
)
45 if (fd
>= proc
->process_files_table
->len
) {
46 tmp
= g_new0(struct files
, 1);
47 tmp
->name
= "Unknown";
48 add_file(proc
, tmp
, fd
);
51 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
53 tmp
= g_new0(struct files
, 1);
54 tmp
->name
= "Unknown";
58 add_file(proc
, tmp
, fd
);
63 void close_file(struct processtop
*proc
, int fd
)
67 len
= proc
->process_files_table
->len
;
70 * It is possible that a file was open before taking the trace
71 * and its fd could be greater than all of the others fd
75 g_ptr_array_remove_index_fast(proc
->process_files_table
, fd
);
76 g_ptr_array_set_size(proc
->process_files_table
, len
+ 1);
80 struct files
*get_file(struct processtop
*proc
, int fd
)
83 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
87 void show_table(GPtrArray
*tab
)
92 for (i
= 0 ; i
< tab
->len
; i
++) {
93 file
= g_ptr_array_index(tab
, i
);
95 fprintf(stderr
, "NULL, ");
97 fprintf(stderr
, "%s, ", file
->name
);
99 fprintf(stderr
, "]\n\n");
102 int update_iostream_ret(struct lttngtop
*ctx
, int tid
, char *comm
,
103 unsigned long timestamp
, uint64_t cpu_id
, int ret
)
105 struct processtop
*tmp
;
106 struct files
*tmpfile
;
109 tmp
= get_proc(ctx
, tid
, comm
, timestamp
);
111 if (tmp
->syscall_info
!= NULL
) {
112 if (tmp
->syscall_info
->type
== __NR_read
114 tmp
->totalfileread
+= ret
;
115 tmp
->fileread
+= ret
;
116 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
117 tmpfile
->read
+= ret
;
118 } else if (tmp
->syscall_info
->type
== __NR_write
120 tmp
->totalfilewrite
+= ret
;
121 tmp
->filewrite
+= ret
;
122 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
123 tmpfile
->write
+= ret
;
124 } else if (tmp
->syscall_info
->type
== __NR_open
126 add_file(tmp
, tmp
->files_history
->file
, ret
);
130 g_free(tmp
->syscall_info
);
131 tmp
->syscall_info
= NULL
;
136 struct syscalls
*create_syscall_info(unsigned int type
, uint64_t cpu_id
,
137 unsigned int tid
, int fd
)
139 struct syscalls
*syscall_info
;
141 syscall_info
= g_new0(struct syscalls
, 1);
142 syscall_info
->type
= type
;
143 syscall_info
->cpu_id
= cpu_id
;
144 syscall_info
->tid
= tid
;
145 syscall_info
->fd
= fd
;
150 struct file_history
*create_file(struct file_history
*history
, char *file_name
)
152 struct files
*new_file
;
153 struct file_history
*new_history
;
155 new_file
= g_new0(struct files
, 1);
156 new_history
= g_new0(struct file_history
, 1);
157 new_file
->name
= strdup(file_name
);
160 new_history
->file
= new_file
;
161 new_history
->next
= history
;
166 enum bt_cb_ret
handle_exit_syscall(struct bt_ctf_event
*call_data
,
169 struct definition
*scope
;
170 unsigned long timestamp
;
175 timestamp
= bt_ctf_get_timestamp(call_data
);
176 if (timestamp
== -1ULL)
179 comm
= get_context_comm(call_data
);
180 tid
= get_context_tid(call_data
);
182 scope
= bt_ctf_get_top_level_scope(call_data
,
184 ret
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
186 if (bt_ctf_field_get_error()) {
187 fprintf(stderr
, "Missing ret context info\n");
191 cpu_id
= get_cpu_id(call_data
);
194 * if we encounter an exit_syscall and
195 * it is not for a syscall read or write
196 * we just abort the execution of this callback
198 if ((update_iostream_ret(<tngtop
, tid
, comm
, timestamp
, cpu_id
, ret
)) < 0)
199 return BT_CB_ERROR_CONTINUE
;
204 return BT_CB_ERROR_STOP
;
208 enum bt_cb_ret
handle_sys_write(struct bt_ctf_event
*call_data
,
211 struct definition
*scope
;
212 struct processtop
*tmp
;
213 unsigned long timestamp
;
219 timestamp
= bt_ctf_get_timestamp(call_data
);
220 if (timestamp
== -1ULL)
223 comm
= get_context_comm(call_data
);
224 tid
= get_context_tid(call_data
);
225 cpu_id
= get_cpu_id(call_data
);
227 scope
= bt_ctf_get_top_level_scope(call_data
,
229 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
231 if (bt_ctf_field_get_error()) {
232 fprintf(stderr
, "Missing fd context info\n");
236 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
237 tmp
->syscall_info
= create_syscall_info(__NR_write
, cpu_id
, tid
, fd
);
239 insert_file(tmp
, fd
);
244 return BT_CB_ERROR_STOP
;
247 enum bt_cb_ret
handle_sys_read(struct bt_ctf_event
*call_data
,
250 struct processtop
*tmp
;
251 struct definition
*scope
;
252 unsigned long timestamp
;
258 timestamp
= bt_ctf_get_timestamp(call_data
);
259 if (timestamp
== -1ULL)
262 comm
= get_context_comm(call_data
);
263 tid
= get_context_tid(call_data
);
264 cpu_id
= get_cpu_id(call_data
);
266 scope
= bt_ctf_get_top_level_scope(call_data
,
268 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
270 if (bt_ctf_field_get_error()) {
271 fprintf(stderr
, "Missing fd context info\n");
275 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
276 tmp
->syscall_info
= create_syscall_info(__NR_read
, cpu_id
, tid
, fd
);
278 insert_file(tmp
, fd
);
283 return BT_CB_ERROR_STOP
;
287 enum bt_cb_ret
handle_sys_open(struct bt_ctf_event
*call_data
,
291 struct processtop
*tmp
;
292 struct definition
*scope
;
293 unsigned long timestamp
;
299 timestamp
= bt_ctf_get_timestamp(call_data
);
300 if (timestamp
== -1ULL)
303 comm
= get_context_comm(call_data
);
304 tid
= get_context_tid(call_data
);
305 cpu_id
= get_cpu_id(call_data
);
307 scope
= bt_ctf_get_top_level_scope(call_data
,
309 file
= bt_ctf_get_string(bt_ctf_get_field(call_data
,
310 scope
, "_filename"));
311 if (bt_ctf_field_get_error()) {
312 fprintf(stderr
, "Missing fd context info\n");
316 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
317 tmp
->syscall_info
= create_syscall_info(__NR_open
, cpu_id
, tid
, -1);
319 tmp
->files_history
= create_file(tmp
->files_history
, file
);
324 return BT_CB_ERROR_STOP
;
328 enum bt_cb_ret
handle_sys_close(struct bt_ctf_event
*call_data
,
331 struct definition
*scope
;
332 unsigned long timestamp
;
334 struct processtop
*tmp
;
338 timestamp
= bt_ctf_get_timestamp(call_data
);
339 if (timestamp
== -1ULL)
342 comm
= get_context_comm(call_data
);
343 tid
= get_context_tid(call_data
);
345 scope
= bt_ctf_get_top_level_scope(call_data
,
347 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
349 if (bt_ctf_field_get_error()) {
350 fprintf(stderr
, "Missing fd context info\n");
354 tmp
= get_proc(<tngtop
, tid
, comm
, timestamp
);
360 return BT_CB_ERROR_STOP
;
This page took 0.038245 seconds and 5 git commands to generate.