Add const for most of the babeltrace APi calls
[lttngtop.git] / src / iostreamtop.c
index 1594df7543e669d75f45c92bb3d0d6b4b9d034b6..e3a643478d7e3608cbd54a071feb912c02879ef3 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- * MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
 #include <babeltrace/babeltrace.h>
 
 #include "lttngtoptypes.h"
 #include "common.h"
 #include "iostreamtop.h"
 
-#include <stdlib.h>
+void add_file(struct processtop *proc, struct files *file, int fd)
+{
+       if (proc->process_files_table->len <= fd) {
+               g_ptr_array_set_size(proc->process_files_table, fd);
+               g_ptr_array_add(proc->process_files_table, file);
+       } else {
+               g_ptr_array_index(proc->process_files_table, fd) = file;
+       }
+       file->fd = fd;
+}
+
+
+void insert_file(struct processtop *proc, int fd)
+{
+       struct files *tmp;
+
+       if (fd >= proc->process_files_table->len) {
+               tmp = g_new0(struct files, 1);
+               tmp->name = "Unknown";
+               add_file(proc, tmp, fd);
+       } else {
+
+               tmp = g_ptr_array_index(proc->process_files_table, fd);
+               if (tmp == NULL) {
+                       tmp = g_new0(struct files, 1);
+                       tmp->name = "Unknown";
+                       tmp->read = 0;
+                       tmp->write = 0;
+                       tmp->fd = fd;
+                       add_file(proc, tmp, fd);
+               }
+       }
+}
+
+void close_file(struct processtop *proc, int fd)
+{
+       int len;
+
+       len = proc->process_files_table->len;
+
+       /*
+        * It is possible that a file was open before taking the trace
+        * and its fd could be greater than all of the others fd
+        * used by the process
+        */
+       if (fd < len) {
+               g_ptr_array_remove_index_fast(proc->process_files_table, fd);
+               g_ptr_array_set_size(proc->process_files_table, len + 1);
+       }
+}
+
+struct files *get_file(struct processtop *proc, int fd)
+{
+       struct files *tmp;
+       tmp = g_ptr_array_index(proc->process_files_table, fd);
+       return tmp;
+}
+
+void show_table(GPtrArray *tab)
+{
+       int i;
+       struct files *file;
+
+       for (i = 0 ; i < tab->len; i++) {
+               file = g_ptr_array_index(tab, i);
+               if (file == NULL)
+                       fprintf(stderr, "NULL, ");
+               else
+                       fprintf(stderr, "%s, ", file->name);
+       }
+       fprintf(stderr, "]\n\n");
+}
 
 int update_iostream_ret(struct lttngtop *ctx, int tid, char *comm,
-               unsigned long timestamp, int cpu_id, int ret)
+               unsigned long timestamp, uint64_t cpu_id, int ret)
 {
        struct processtop *tmp;
+       struct files *tmpfile;
        int err = 0;
 
        tmp = get_proc(ctx, tid, comm, timestamp);
-       if ((tmp->iostream->syscall_info != NULL) && (tmp->iostream->syscall_info->cpu_id == cpu_id)) {
-               if (tmp->iostream->syscall_info->type == __NR_read && ret > 0) {
-                       tmp->iostream->ret_read += ret;
-                       tmp->iostream->ret_total += ret;
-               } else if(tmp->iostream->syscall_info->type == __NR_write && ret > 0) {
-                       tmp->iostream->ret_write += ret;
-                       tmp->iostream->ret_total += ret;
-               } else{
+
+       if (tmp->syscall_info != NULL) {
+               if (tmp->syscall_info->type == __NR_read
+                       && ret > 0) {
+                       tmp->totalfileread += ret;
+                       tmp->fileread += ret;
+                       tmpfile = get_file(tmp, tmp->syscall_info->fd);
+                       tmpfile->read += ret;
+               } else if (tmp->syscall_info->type == __NR_write
+                       && ret > 0) {
+                       tmp->totalfilewrite += ret;
+                       tmp->filewrite += ret;
+                       tmpfile = get_file(tmp, tmp->syscall_info->fd);
+                       tmpfile->write += ret;
+               } else if (tmp->syscall_info->type == __NR_open
+                       && ret > 0) {
+                       add_file(tmp, tmp->files_history->file, ret);
+               } else {
                        err = -1;
                }
-               free(tmp->iostream->syscall_info);
-               tmp->iostream->syscall_info = NULL;
-       }
-
+               g_free(tmp->syscall_info);
+               tmp->syscall_info = NULL;
+       }
        return err;
 }
 
+struct syscalls *create_syscall_info(unsigned int type, uint64_t cpu_id,
+               unsigned int tid, int fd)
+{
+       struct syscalls *syscall_info;
+       
+       syscall_info = g_new0(struct syscalls, 1);
+       syscall_info->type = type;
+       syscall_info->cpu_id = cpu_id;
+       syscall_info->tid = tid;
+       syscall_info->fd = fd;
+
+       return syscall_info;
+}
+
+struct file_history *create_file(struct file_history *history, char *file_name)
+{
+       struct files *new_file;
+       struct file_history *new_history;
+
+       new_file = g_new0(struct files, 1);
+       new_history = g_new0(struct file_history, 1);
+       new_file->name = strdup(file_name);
+       new_file->read = 0;
+       new_file->write = 0;
+       new_history->file = new_file;
+       new_history->next = history;
+
+       return new_history;
+}
+
 enum bt_cb_ret handle_exit_syscall(struct bt_ctf_event *call_data,
                void *private_data)
 {
-       struct definition *scope;
+       const struct definition *scope;
        unsigned long timestamp;
        char *comm;
        uint64_t ret, tid;
-       int64_t cpu_id;
+       uint64_t cpu_id;
 
        timestamp = bt_ctf_get_timestamp(call_data);
        if (timestamp == -1ULL)
                goto error;
 
-       scope = bt_ctf_get_top_level_scope(call_data,
-                       BT_STREAM_EVENT_CONTEXT);
-       comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
-                               scope, "_procname"));
-       if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing procname context info\n");
-               goto error;
-       }
-
-       tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
-                               scope, "_tid"));
-       if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing tid context info\n");
-               goto error;
-       }
+       comm = get_context_comm(call_data);
+       tid = get_context_tid(call_data);
 
        scope = bt_ctf_get_top_level_scope(call_data,
                        BT_EVENT_FIELDS);
@@ -86,17 +188,11 @@ enum bt_cb_ret handle_exit_syscall(struct bt_ctf_event *call_data,
                goto error;
        }
 
-       scope = bt_ctf_get_top_level_scope(call_data,
-                       BT_STREAM_PACKET_CONTEXT);
-       cpu_id = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
-                               scope, "cpu_id"));
-       if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing cpu_id context info\n");
-               goto error;
-       }
+       cpu_id = get_cpu_id(call_data);
 
        /*
-        * if we encounter an exit_syscall and it is not for a syscall read or write
+        * if we encounter an exit_syscall and
+        * it is not for a syscall read or write
         * we just abort the execution of this callback
         */
        if ((update_iostream_ret(&lttngtop, tid, comm, timestamp, cpu_id, ret)) < 0)
@@ -112,49 +208,74 @@ error:
 enum bt_cb_ret handle_sys_write(struct bt_ctf_event *call_data,
                void *private_data)
 {
-       struct definition *scope;
+       const struct definition *scope;
        struct processtop *tmp;
-       struct syscalls *syscall_info;
        unsigned long timestamp;
        uint64_t cpu_id;
        char *comm;
        int64_t tid;
+       int fd;
 
        timestamp = bt_ctf_get_timestamp(call_data);
        if (timestamp == -1ULL)
                goto error;
 
+       comm = get_context_comm(call_data);
+       tid = get_context_tid(call_data);
+       cpu_id = get_cpu_id(call_data);
+
        scope = bt_ctf_get_top_level_scope(call_data,
-                       BT_STREAM_EVENT_CONTEXT);
-       comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
-                               scope, "_procname"));
+                       BT_EVENT_FIELDS);
+       fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
+                               scope, "_fd"));
        if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing procname context info\n");
+               fprintf(stderr, "Missing fd context info\n");
                goto error;
        }
 
-       tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
-                               scope, "_tid"));
-       if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing tid context info\n");
+       tmp = get_proc(&lttngtop, tid, comm, timestamp);
+       tmp->syscall_info = create_syscall_info(__NR_write, cpu_id, tid, fd);
+
+       insert_file(tmp, fd);
+
+       return BT_CB_OK;
+
+error:
+       return BT_CB_ERROR_STOP;
+}
+
+enum bt_cb_ret handle_sys_read(struct bt_ctf_event *call_data,
+               void *private_data)
+{
+       struct processtop *tmp;
+       const struct definition *scope;
+       unsigned long timestamp;
+       uint64_t cpu_id;
+       char *comm;
+       int64_t tid;
+       int fd;
+
+       timestamp = bt_ctf_get_timestamp(call_data);
+       if (timestamp == -1ULL)
                goto error;
-       }
+
+       comm = get_context_comm(call_data);
+       tid = get_context_tid(call_data);
+       cpu_id = get_cpu_id(call_data);
 
        scope = bt_ctf_get_top_level_scope(call_data,
-                       BT_STREAM_PACKET_CONTEXT);
-       cpu_id = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
-                               scope, "cpu_id"));
+                       BT_EVENT_FIELDS);
+       fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
+                               scope, "_fd"));
        if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing cpu_id context info\n");
+               fprintf(stderr, "Missing fd context info\n");
                goto error;
        }
 
-       syscall_info = malloc(sizeof(struct syscalls));
-       syscall_info->cpu_id = cpu_id;
-       syscall_info->type = __NR_write;
-       syscall_info->tid =  tid;
        tmp = get_proc(&lttngtop, tid, comm, timestamp);
-       tmp->iostream->syscall_info = syscall_info;
+       tmp->syscall_info = create_syscall_info(__NR_read, cpu_id, tid, fd);
+
+       insert_file(tmp, fd);
 
        return BT_CB_OK;
 
@@ -162,56 +283,79 @@ error:
        return BT_CB_ERROR_STOP;
 }
 
-enum bt_cb_ret handle_sys_read(struct bt_ctf_event *call_data,
+
+enum bt_cb_ret handle_sys_open(struct bt_ctf_event *call_data,
                void *private_data)
 {
+
        struct processtop *tmp;
-       struct definition *scope;
-       struct syscalls * syscall_info;
+       const struct definition *scope;
        unsigned long timestamp;
        uint64_t cpu_id;
        char *comm;
        int64_t tid;
+       char *file;
 
        timestamp = bt_ctf_get_timestamp(call_data);
        if (timestamp == -1ULL)
                goto error;
 
+       comm = get_context_comm(call_data);
+       tid = get_context_tid(call_data);
+       cpu_id = get_cpu_id(call_data);
+
        scope = bt_ctf_get_top_level_scope(call_data,
-                       BT_STREAM_EVENT_CONTEXT);
-       comm = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
-                               scope, "_procname"));
+                       BT_EVENT_FIELDS);
+       file = bt_ctf_get_string(bt_ctf_get_field(call_data,
+                               scope, "_filename"));
        if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing procname context info\n");
+               fprintf(stderr, "Missing fd context info\n");
                goto error;
        }
 
-       tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
-                               scope, "_tid"));
-       if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing tid context info\n");
+       tmp = get_proc(&lttngtop, tid, comm, timestamp);
+       tmp->syscall_info = create_syscall_info(__NR_open, cpu_id, tid, -1);
+
+       tmp->files_history = create_file(tmp->files_history, file);
+
+       return BT_CB_OK;
+
+error:
+       return BT_CB_ERROR_STOP;
+}
+
+
+enum bt_cb_ret handle_sys_close(struct bt_ctf_event *call_data,
+               void *private_data)
+{
+       const struct definition *scope;
+       unsigned long timestamp;
+       int64_t tid;
+       struct processtop *tmp;
+       char *comm;
+       int fd;
+
+       timestamp = bt_ctf_get_timestamp(call_data);
+       if (timestamp == -1ULL)
                goto error;
-       }
+
+       comm = get_context_comm(call_data);
+       tid = get_context_tid(call_data);
 
        scope = bt_ctf_get_top_level_scope(call_data,
-                       BT_STREAM_PACKET_CONTEXT);
-       cpu_id = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
-                               scope, "cpu_id"));
+                       BT_EVENT_FIELDS);
+       fd = bt_ctf_get_uint64(bt_ctf_get_field(call_data,
+                               scope, "_fd"));
        if (bt_ctf_field_get_error()) {
-               fprintf(stderr, "Missing cpu_id context info\n");
+               fprintf(stderr, "Missing fd context info\n");
                goto error;
        }
 
-       syscall_info = malloc(sizeof(struct syscalls));
-       syscall_info->cpu_id = cpu_id;
-       syscall_info->type = __NR_read;
-       syscall_info->tid =  tid;
        tmp = get_proc(&lttngtop, tid, comm, timestamp);
-       tmp->iostream->syscall_info = syscall_info;
+       close_file(tmp, fd);
 
        return BT_CB_OK;
 
 error:
        return BT_CB_ERROR_STOP;
 }
-
This page took 0.02697 seconds and 4 git commands to generate.