7c1d611af8b74b1a7e6aa1ac566b2fbc5c8b52ad
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 struct files
*tmp_file
;
32 struct processtop
*parent
;
35 size
= proc
->process_files_table
->len
;
36 parent
= proc
->threadparent
;
38 insert_file(parent
, fd
);
40 g_ptr_array_set_size(proc
->process_files_table
, fd
);
41 g_ptr_array_add(proc
->process_files_table
, file
);
43 tmp_file
= g_ptr_array_index(proc
->process_files_table
, fd
);
45 g_ptr_array_index(proc
->process_files_table
, fd
) = file
;
47 if (strcmp(tmp_file
->name
, file
->name
) != 0) {
48 size
= proc
->process_files_table
->len
;
49 g_ptr_array_set_size(proc
->process_files_table
,
51 g_ptr_array_index(proc
->process_files_table
,
53 g_ptr_array_index(proc
->process_files_table
,
56 tmp_file
->flag
= __NR_open
;
60 * The file may have be created in the parent
62 if (file
->flag
== -1) {
64 file
->flag
= __NR_open
;
66 lttngtop
.nbnewfiles
++;
72 * Called by handled_statedump_filename
74 void edit_file(struct processtop
*proc
, struct files
*file
, int fd
)
76 int size
= proc
->process_files_table
->len
;
77 struct files
*tmpfile
;
80 add_file(proc
, file
, fd
);
82 tmpfile
= g_ptr_array_index(proc
->process_files_table
, fd
);
84 tmpfile
->name
= strdup(file
->name
);
87 add_file(proc
, file
, fd
);
91 void insert_file(struct processtop
*proc
, int fd
)
94 struct files
*tmp_parent
;
95 struct processtop
*parent
;
99 if (fd
>= proc
->process_files_table
->len
) {
100 tmp
= g_new0(struct files
, 1);
101 tmp
->name
= "Unknown";
106 add_file(proc
, tmp
, fd
);
108 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
110 tmp
= g_new0(struct files
, 1);
111 tmp
->name
= "Unknown";
116 add_file(proc
, tmp
, fd
);
118 parent
= proc
->threadparent
;
120 tmp_parent
= g_ptr_array_index(
121 parent
->process_files_table
, fd
);
123 (strcmp(tmp
->name
, tmp_parent
->name
)) != 0)
124 tmp
->name
= strdup(tmp_parent
->name
);
130 void close_file(struct processtop
*proc
, int fd
)
134 file
= get_file(proc
, fd
);
136 file
->flag
= __NR_close
;
139 lttngtop
.nbclosedfiles
++;
142 struct files
*get_file(struct processtop
*proc
, int fd
)
145 struct files
*tmp
= NULL
;
147 len
= proc
->process_files_table
->len
;
150 * It is possible that a file was open before taking the trace
151 * and its fd could be greater than all of the others fd
152 * used by the process
154 if (fd
< len
&& fd
>= 0)
155 tmp
= g_ptr_array_index(proc
->process_files_table
, fd
);
160 void show_table(GPtrArray
*tab
)
165 for (i
= 0 ; i
< tab
->len
; i
++) {
166 file
= g_ptr_array_index(tab
, i
);
168 fprintf(stderr
, "NULL, ");
170 fprintf(stderr
, "%s, ", file
->name
);
172 fprintf(stderr
, "]\n\n");
175 void show_history(struct file_history
*history
)
177 struct file_history
*tmp
= history
;
179 while (tmp
!= NULL
) {
180 fprintf(stderr
, "fd = %d, name = %s\n", tmp
->file
->fd
,
187 int update_iostream_ret(struct lttngtop
*ctx
, int tid
, char *comm
,
188 unsigned long timestamp
, uint64_t cpu_id
, int ret
)
190 struct processtop
*tmp
;
191 struct files
*tmpfile
;
194 tmp
= get_proc(ctx
, tid
, comm
, timestamp
);
196 if (tmp
->syscall_info
!= NULL
) {
197 if (tmp
->syscall_info
->type
== __NR_read
199 tmp
->totalfileread
+= ret
;
200 tmp
->fileread
+= ret
;
201 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
203 tmpfile
->read
+= ret
;
204 } else if (tmp
->syscall_info
->type
== __NR_write
206 tmp
->totalfilewrite
+= ret
;
207 tmp
->filewrite
+= ret
;
208 tmpfile
= get_file(tmp
, tmp
->syscall_info
->fd
);
210 tmpfile
->write
+= ret
;
211 } else if (tmp
->syscall_info
->type
== __NR_open
213 tmpfile
= tmp
->files_history
->file
;
214 add_file(tmp
, tmpfile
, ret
);
219 g_free(tmp
->syscall_info
);
220 tmp
->syscall_info
= NULL
;
225 struct syscalls
*create_syscall_info(unsigned int type
, uint64_t cpu_id
,
226 unsigned int tid
, int fd
)
228 struct syscalls
*syscall_info
;
230 syscall_info
= g_new0(struct syscalls
, 1);
231 syscall_info
->type
= type
;
232 syscall_info
->cpu_id
= cpu_id
;
233 syscall_info
->tid
= tid
;
234 syscall_info
->fd
= fd
;
239 struct file_history
*create_file(struct file_history
*history
, char *file_name
)
241 struct files
*new_file
;
242 struct file_history
*new_history
;
244 new_file
= g_new0(struct files
, 1);
245 new_history
= g_new0(struct file_history
, 1);
246 new_file
->name
= strdup(file_name
);
250 new_history
->file
= new_file
;
251 new_history
->next
= history
;
256 enum bt_cb_ret
handle_exit_syscall(struct bt_ctf_event
*call_data
,
259 const struct definition
*scope
;
260 unsigned long timestamp
;
265 timestamp
= bt_ctf_get_timestamp(call_data
);
266 if (timestamp
== -1ULL)
269 comm
= get_context_comm(call_data
);
270 tid
= get_context_tid(call_data
);
272 scope
= bt_ctf_get_top_level_scope(call_data
,
274 ret
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
276 if (bt_ctf_field_get_error()) {
277 fprintf(stderr
, "Missing ret context info\n");
281 cpu_id
= get_cpu_id(call_data
);
284 * if we encounter an exit_syscall and
285 * it is not for a syscall read or write
286 * we just abort the execution of this callback
288 if ((update_iostream_ret(<tngtop
, tid
, comm
, timestamp
, cpu_id
, ret
)) < 0)
289 return BT_CB_ERROR_CONTINUE
;
294 return BT_CB_ERROR_STOP
;
298 enum bt_cb_ret
handle_sys_write(struct bt_ctf_event
*call_data
,
301 const struct definition
*scope
;
302 struct processtop
*tmp
;
303 unsigned long timestamp
;
308 timestamp
= bt_ctf_get_timestamp(call_data
);
309 if (timestamp
== -1ULL)
312 tid
= get_context_tid(call_data
);
313 cpu_id
= get_cpu_id(call_data
);
315 pid
= get_context_pid(call_data
);
317 scope
= bt_ctf_get_top_level_scope(call_data
,
319 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
321 if (bt_ctf_field_get_error()) {
322 fprintf(stderr
, "Missing fd context info\n");
326 tmp
= get_proc_pid(<tngtop
, tid
, pid
, timestamp
);
327 tmp
->syscall_info
= create_syscall_info(__NR_write
, cpu_id
, tid
, fd
);
329 insert_file(tmp
, fd
);
334 return BT_CB_ERROR_STOP
;
337 enum bt_cb_ret
handle_sys_read(struct bt_ctf_event
*call_data
,
340 struct processtop
*tmp
;
341 const struct definition
*scope
;
342 unsigned long timestamp
;
347 timestamp
= bt_ctf_get_timestamp(call_data
);
348 if (timestamp
== -1ULL)
351 tid
= get_context_tid(call_data
);
352 cpu_id
= get_cpu_id(call_data
);
354 pid
= get_context_pid(call_data
);
356 scope
= bt_ctf_get_top_level_scope(call_data
,
358 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
360 if (bt_ctf_field_get_error()) {
361 fprintf(stderr
, "Missing fd context info\n");
365 tmp
= get_proc_pid(<tngtop
, tid
, pid
, timestamp
);
366 tmp
->syscall_info
= create_syscall_info(__NR_read
, cpu_id
, tid
, fd
);
368 insert_file(tmp
, fd
);
373 return BT_CB_ERROR_STOP
;
377 enum bt_cb_ret
handle_sys_open(struct bt_ctf_event
*call_data
,
381 struct processtop
*tmp
;
382 const struct definition
*scope
;
383 unsigned long timestamp
;
388 timestamp
= bt_ctf_get_timestamp(call_data
);
389 if (timestamp
== -1ULL)
392 tid
= get_context_tid(call_data
);
393 cpu_id
= get_cpu_id(call_data
);
395 pid
= get_context_pid(call_data
);
397 scope
= bt_ctf_get_top_level_scope(call_data
,
399 file
= bt_ctf_get_string(bt_ctf_get_field(call_data
,
400 scope
, "_filename"));
401 if (bt_ctf_field_get_error()) {
402 fprintf(stderr
, "Missing file name context info\n");
406 tmp
= get_proc_pid(<tngtop
, tid
, pid
, timestamp
);
407 tmp
->syscall_info
= create_syscall_info(__NR_open
, cpu_id
, tid
, -1);
409 tmp
->files_history
= create_file(tmp
->files_history
, file
);
414 return BT_CB_ERROR_STOP
;
418 enum bt_cb_ret
handle_sys_close(struct bt_ctf_event
*call_data
,
421 const struct definition
*scope
;
422 unsigned long timestamp
;
424 struct processtop
*tmp
;
427 timestamp
= bt_ctf_get_timestamp(call_data
);
428 if (timestamp
== -1ULL)
431 tid
= get_context_tid(call_data
);
433 pid
= get_context_pid(call_data
);
435 scope
= bt_ctf_get_top_level_scope(call_data
,
437 fd
= bt_ctf_get_uint64(bt_ctf_get_field(call_data
,
439 if (bt_ctf_field_get_error()) {
440 fprintf(stderr
, "Missing fd context info\n");
444 tmp
= get_proc_pid(<tngtop
, tid
, pid
, timestamp
);
451 return BT_CB_ERROR_STOP
;
454 enum bt_cb_ret
handle_statedump_file_descriptor(struct bt_ctf_event
*call_data
,
457 const struct definition
*scope
;
458 struct processtop
*parent
;
460 unsigned long timestamp
;
465 timestamp
= bt_ctf_get_timestamp(call_data
);
466 if (timestamp
== -1ULL)
469 scope
= bt_ctf_get_top_level_scope(call_data
,
471 pid
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
473 if (bt_ctf_field_get_error()) {
474 fprintf(stderr
, "Missing tid context info\n");
478 scope
= bt_ctf_get_top_level_scope(call_data
,
480 fd
= bt_ctf_get_int64(bt_ctf_get_field(call_data
,
482 if (bt_ctf_field_get_error()) {
483 fprintf(stderr
, "Missing fd context info\n");
487 scope
= bt_ctf_get_top_level_scope(call_data
,
489 file_name
= bt_ctf_get_string(bt_ctf_get_field(call_data
,
490 scope
, "_filename"));
491 if (bt_ctf_field_get_error()) {
492 fprintf(stderr
, "Missing file name context info\n");
496 parent
= get_proc_pid(<tngtop
, pid
, pid
, timestamp
);
497 parent
->files_history
= create_file(parent
->files_history
, file_name
);
498 file
= parent
->files_history
->file
;
499 edit_file(parent
, file
, fd
);
504 return BT_CB_ERROR_STOP
;
This page took 0.041589 seconds and 4 git commands to generate.