move obsolete ltt-modules to attic
authorpmf <pmf@04897980-b3bd-0310-b5e0-8ef037075253>
Wed, 6 Aug 2008 17:46:53 +0000 (17:46 +0000)
committerpmf <pmf@04897980-b3bd-0310-b5e0-8ef037075253>
Wed, 6 Aug 2008 17:46:53 +0000 (17:46 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@2986 04897980-b3bd-0310-b5e0-8ef037075253

trunk/attic/ltt-modules/Makefile [new file with mode: 0644]
trunk/attic/ltt-modules/ltt-control.c [new file with mode: 0644]
trunk/attic/ltt-modules/ltt-control.h [new file with mode: 0644]
trunk/attic/ltt-modules/ltt-statedump.c [new file with mode: 0644]
trunk/ltt-modules/Makefile [deleted file]
trunk/ltt-modules/ltt-control.c [deleted file]
trunk/ltt-modules/ltt-control.h [deleted file]
trunk/ltt-modules/ltt-statedump.c [deleted file]

diff --git a/trunk/attic/ltt-modules/Makefile b/trunk/attic/ltt-modules/Makefile
new file mode 100644 (file)
index 0000000..0c56ebb
--- /dev/null
@@ -0,0 +1,24 @@
+ifneq ($(KERNELRELEASE),)
+ifneq ($(CONFIG_LTT),)
+       obj-m := ltt-control.o ltt-statedump.o
+endif
+
+else
+       KERNELDIR ?= /lib/modules/$(shell uname -r)/build
+       PWD := $(shell pwd)
+       KERNELRELEASE = $(shell cat $(KERNELDIR)/$(KBUILD_OUTPUT)/include/linux/version.h | sed -n 's/.*UTS_RELEASE.*\"\(.*\)\".*/\1/p')
+ifneq ($(INSTALL_MOD_PATH),)
+       DEPMOD_OPT := -b $(INSTALL_MOD_PATH)
+endif
+
+default:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
+
+modules_install:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
+       if [ -f $(KERNELDIR)/$(KBUILD_OUTPUT)/System.map ] ; then /sbin/depmod -ae -F $(KERNELDIR)/$(KBUILD_OUTPUT)/System.map $(DEPMOD_OPT) $(KERNELRELEASE) ; fi
+
+
+clean:
+       $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
+endif
diff --git a/trunk/attic/ltt-modules/ltt-control.c b/trunk/attic/ltt-modules/ltt-control.c
new file mode 100644 (file)
index 0000000..45b44f0
--- /dev/null
@@ -0,0 +1,115 @@
+/* ltt-control.c
+ *
+ * LTT control module over a netlink socket.
+ *
+ * Inspired from Relay Apps, by Tom Zanussi and iptables
+ *
+ * Copyright 2005 -
+ * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ltt-core.h>
+#include <linux/netlink.h>
+#include <linux/inet.h>
+#include <linux/ip.h>
+#include <linux/security.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <net/sock.h>
+#include "ltt-control.h"
+
+
+#define LTTCTLM_BASE   0x10
+#define LTTCTLM_CONTROL        (LTTCTLM_BASE + 1)      /* LTT control message */
+
+static struct sock *socket;
+
+void ltt_control_input(struct sock *sk, int len)
+{
+       struct sk_buff *skb;
+       struct nlmsghdr *nlh = NULL;
+       u8 *payload = NULL;
+       lttctl_peer_msg_t *msg;
+       int err;
+
+       printk(KERN_ALERT "ltt-control ltt_control_input\n");
+
+       while ((skb = skb_dequeue(&sk->sk_receive_queue)) 
+                                       != NULL) {
+    
+               nlh = (struct nlmsghdr *)skb->data;
+
+    if(security_netlink_recv(skb)) {
+                       netlink_ack(skb, nlh, EPERM);
+                       kfree_skb(skb);
+                       continue;
+    }
+    
+               /* process netlink message pointed by skb->data */
+               err = EINVAL;
+               payload = NLMSG_DATA(nlh);
+               /* process netlink message with header pointed by 
+                * nlh and payload pointed by payload
+                */
+               if(nlh->nlmsg_len != sizeof(lttctl_peer_msg_t) + sizeof(struct nlmsghdr)) {
+                       printk(KERN_ALERT "ltt-control bad message length\n");
+                       netlink_ack(skb, nlh, EINVAL);
+                       kfree_skb(skb);
+                       continue;
+               }
+               msg = (lttctl_peer_msg_t*)payload;
+
+               switch(msg->op) {
+                       case OP_CREATE:
+                               err = ltt_control(LTT_CONTROL_CREATE_TRACE, msg->trace_name,
+                                                                                                                       msg->args);
+                               break;
+                       case OP_DESTROY:
+                               err = ltt_control(LTT_CONTROL_DESTROY_TRACE, msg->trace_name,
+                                               msg->args);
+                               break;
+                       case OP_START:
+                               err = ltt_control(LTT_CONTROL_START, msg->trace_name,
+                                               msg->args);
+                               break;
+                       case OP_STOP:
+                               err = ltt_control(LTT_CONTROL_STOP, msg->trace_name,
+                                               msg->args);
+                               break;
+                       default:
+                               err = EBADRQC;
+                               printk(KERN_INFO "ltt-control invalid operation\n");
+               }
+               netlink_ack(skb, nlh, err);
+               kfree_skb(skb);
+       }
+}
+
+
+static int ltt_control_init(void)
+{
+       printk(KERN_ALERT "ltt-control init\n");
+
+       socket = netlink_kernel_create(NETLINK_LTT, 1,
+                       ltt_control_input, THIS_MODULE);
+       if(socket == NULL) return -EPERM;
+       else return 0;
+}
+
+static void ltt_control_exit(void)
+{
+       printk(KERN_ALERT "ltt-control exit\n");
+
+       sock_release(socket->sk_socket);
+}
+
+
+module_init(ltt_control_init)
+module_exit(ltt_control_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Linux Trace Toolkit Controller");
+
diff --git a/trunk/attic/ltt-modules/ltt-control.h b/trunk/attic/ltt-modules/ltt-control.h
new file mode 100644 (file)
index 0000000..430d5d1
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _LTT_CONTROL_H
+#define _LTT_CONTROL_H
+
+
+//enum trace_mode {
+//     TRACE_NORMAL,
+//     TRACE_FLIGHT
+//};
+
+enum trace_op {
+  OP_CREATE,
+  OP_DESTROY,
+  OP_START,
+  OP_STOP,
+       OP_ALIGN,
+  OP_NONE
+};
+
+typedef struct lttctl_peer_msg {
+       char trace_name[NAME_MAX];
+       enum trace_op op;
+       union ltt_control_args args;
+} lttctl_peer_msg_t;
+
+#endif //_LTT_CONTROL_H
+
diff --git a/trunk/attic/ltt-modules/ltt-statedump.c b/trunk/attic/ltt-modules/ltt-statedump.c
new file mode 100644 (file)
index 0000000..d6c0321
--- /dev/null
@@ -0,0 +1,352 @@
+/* ltt-state-dump.c
+ *
+ * Lunix Trace Toolkit Kernel State Dump
+ *
+ * Copyright 2005 -
+ * Jean-Hugues Deschenes <jean-hugues.deschenes@polymtl.ca>
+ *
+ * Changes:
+ *     Eric Clement:            add listing of network IP interface
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ltt-core.h>
+#include <linux/netlink.h>
+#include <linux/inet.h>
+#include <linux/ip.h>
+#include <linux/kthread.h>
+#include <linux/proc_fs.h>
+#include <linux/file.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/cpu.h>
+#include <linux/ltt/ltt-facility-statedump.h>
+
+#define NB_PROC_CHUNK 20
+
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+
+/* in modules.c */
+extern int ltt_enumerate_modules(void);
+
+static inline int ltt_enumerate_network_ip_interface(void)
+{
+  struct net_device *list;
+  struct in_device *in_dev = NULL;
+  struct in_ifaddr *ifa = NULL;
+       
+  read_lock(&dev_base_lock);
+  for(list=dev_base; list != NULL; list=list->next) {
+
+    if(list->flags & IFF_UP) {  
+      in_dev = in_dev_get(list);
+
+      if(in_dev) {
+        for (ifa = in_dev->ifa_list; ifa != NULL; ifa = ifa->ifa_next) {
+          trace_statedump_enumerate_network_ip_interface(list->name, 
+                                                                                                                                                                                                                               ifa->ifa_address,
+                                                                                                                                                                                                                                       LTTNG_UP);
+                               }
+                               in_dev_put(in_dev);    
+      }
+    } else {
+      trace_statedump_enumerate_network_ip_interface(list->name,
+                                                                                                                                                                                                                                       0,
+                                                                                                                                                                                                                                       LTTNG_DOWN);
+               }
+  }
+  read_unlock(&dev_base_lock);
+  
+  return 0;
+}
+
+static inline int ltt_enumerate_file_descriptors(void)
+{
+  struct task_struct * t = &init_task;
+       unsigned int    i;
+       struct file *           filp;
+       char                            *tmp = (char*)__get_free_page(GFP_KERNEL), *path;
+  struct fdtable *fdt;
+
+       /* Enumerate active file descriptors */
+
+       do {
+         read_lock(&tasklist_lock);
+    if(t != &init_task) atomic_dec(&t->usage);
+         t = next_task(t);
+    atomic_inc(&t->usage);
+    read_unlock(&tasklist_lock);
+   
+               task_lock(t);
+               if (t->files) {
+                       spin_lock(&t->files->file_lock);
+                       fdt = files_fdtable(t->files);
+                       for (i=0; i < fdt->max_fds; i++) {
+                               filp = fcheck_files(t->files, i);
+                               if (!filp)
+                                continue;
+                               path = d_path(filp->f_dentry, filp->f_vfsmnt, tmp, PAGE_SIZE);
+
+                               /* Make sure we give at least some info */
+                               if(IS_ERR(path))
+                                       trace_statedump_enumerate_file_descriptors(filp->f_dentry->d_name.name, t->pid, i);
+                               else
+                                trace_statedump_enumerate_file_descriptors(path, t->pid, i);
+                }
+                spin_unlock(&t->files->file_lock);
+               }
+               task_unlock(t);
+
+  } while( t != &init_task );
+
+       free_page((unsigned long)tmp);
+       
+       return 0;
+}
+
+static inline int ltt_enumerate_vm_maps(void)
+{
+       struct mm_struct *mm;
+  struct task_struct *  t = &init_task;
+       struct vm_area_struct * map;
+       unsigned long                   ino = 0;
+       
+       do {
+    read_lock(&tasklist_lock);
+    if(t != &init_task) atomic_dec(&t->usage);
+         t = next_task(t);
+    atomic_inc(&t->usage);
+    read_unlock(&tasklist_lock);
+    
+               /* get_task_mm does a task_lock... */
+
+               mm = get_task_mm(t);
+
+               if (mm)
+               {
+                       map = mm->mmap;
+       
+                       if(map)
+                       {
+                               down_read(&mm->mmap_sem);
+               
+                               while (map) {
+                                       if (map->vm_file) {
+                                               ino = map->vm_file->f_dentry->d_inode->i_ino;
+                                       } else {
+                                               ino = 0;
+                                       }
+               
+                                       trace_statedump_enumerate_vm_maps(t->pid, (void *)map->vm_start, (void *)map->vm_end, map->vm_flags, map->vm_pgoff << PAGE_SHIFT, ino);
+                                       map = map->vm_next;
+                               }
+               
+                               up_read(&mm->mmap_sem);
+                       }
+       
+                       mmput(mm);
+               }  
+
+       } while( t != &init_task );
+
+       return 0;
+}
+
+#if defined( CONFIG_ARM )
+/* defined in arch/arm/kernel/irq.c because of dependency on statically-defined lock & irq_desc */
+int ltt_enumerate_interrupts(void);
+#else
+static inline int ltt_enumerate_interrupts(void)
+{
+  unsigned int i;
+  unsigned long flags = 0;
+
+  /* needs irq_desc */
+  
+  for(i = 0; i < NR_IRQS; i++)
+  {
+    struct irqaction * action;
+
+    spin_lock_irqsave(&irq_desc[i].lock, flags);
+
+    
+    for (action=irq_desc[i].action; action; action = action->next)
+      trace_statedump_enumerate_interrupts(
+        irq_desc[i].handler->typename,
+        action->name,
+        i );
+
+    spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+  }
+  
+  return 0;
+}
+#endif
+
+static inline int ltt_enumerate_process_states(void)
+{
+  struct task_struct *          t = &init_task;
+  struct task_struct *          p = t;
+  enum lttng_process_status     status;
+  enum lttng_thread_type        type;
+  enum lttng_execution_mode     mode;
+  enum lttng_execution_submode  submode;
+  
+  do {
+    mode = LTTNG_MODE_UNKNOWN;
+    submode = LTTNG_UNKNOWN;
+
+    read_lock(&tasklist_lock);
+    if(t != &init_task) {
+      atomic_dec(&t->usage);
+      t = next_thread(t);
+    }
+    if(t == p) {
+      t = p = next_task(t);
+    }
+    atomic_inc(&t->usage);
+    read_unlock(&tasklist_lock);
+    
+    task_lock(t);
+    
+    if(t->exit_state == EXIT_ZOMBIE)
+      status = LTTNG_ZOMBIE;
+    else if(t->exit_state == EXIT_DEAD)
+      status = LTTNG_DEAD;
+    else if(t->state == TASK_RUNNING)
+    {
+      /* Is this a forked child that has not run yet? */
+      if( list_empty(&t->run_list) )
+      {
+        status = LTTNG_WAIT_FORK;
+      }
+      else
+      {
+        /* All tasks are considered as wait_cpu; the viewer will sort out if the task was relly running at this time. */
+        status = LTTNG_WAIT_CPU;
+      }
+    }
+    else if(t->state & (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE))
+    {
+      /* Task is waiting for something to complete */
+      status = LTTNG_WAIT;
+    }
+    else
+      status = LTTNG_UNNAMED;
+
+    submode = LTTNG_NONE;
+
+
+    /* Verification of t->mm is to filter out kernel threads;
+       Viewer will further filter out if a user-space thread was in syscall mode or not */
+    if(t->mm)
+      type = LTTNG_USER_THREAD;
+    else
+      type = LTTNG_KERNEL_THREAD;
+      
+    trace_statedump_enumerate_process_state(t->pid, t->parent->pid, t->comm,
+                                            type, mode, submode, status);
+    
+    task_unlock(t);
+
+  } while( t != &init_task );
+
+  return 0;
+}
+
+void ltt_statedump_work_func(void *sem)
+{
+  /* Our job is just to release the semaphore so
+     that we are sure that each CPU has been in syscall
+     mode before the end of ltt_statedump_thread */
+  up((struct semaphore *)sem);
+}
+
+static struct work_struct cpu_work[NR_CPUS];
+
+int ltt_statedump_thread(void *data)
+{
+  struct semaphore work_sema4;
+  int cpu;
+
+  printk("ltt_statedump_thread\n");
+
+       ltt_enumerate_process_states();
+  
+  ltt_enumerate_file_descriptors();
+
+       ltt_enumerate_modules();
+  
+       ltt_enumerate_vm_maps();
+  
+       ltt_enumerate_interrupts();
+       
+       ltt_enumerate_network_ip_interface();
+  
+  /* Fire off a work queue on each CPU. Their sole purpose in life
+   * is to guarantee that each CPU has been in a state where is was in syscall
+   * mode (i.e. not in a trap, an IRQ or a soft IRQ) */
+  sema_init(&work_sema4, 1 - num_online_cpus());
+  
+  lock_cpu_hotplug();
+  for_each_online_cpu(cpu)
+  {
+    INIT_WORK(&cpu_work[cpu], ltt_statedump_work_func, &work_sema4);
+
+    schedule_delayed_work_on(cpu,&cpu_work[cpu],0);
+  }
+  unlock_cpu_hotplug();
+  
+  /* Wait for all work queues to have completed */
+  down(&work_sema4);
+  
+  /* Our work is done */
+  printk("trace_statedump_statedump_end\n");
+  trace_statedump_statedump_end();
+       
+       do_exit(0);
+
+       return 0;
+}
+
+int ltt_statedump_start(struct ltt_trace_struct *trace)
+{
+       printk("ltt_statedump_start\n");
+
+       kthread_run(    ltt_statedump_thread,
+                                                               NULL,
+                                                               "ltt_statedump");
+       
+       return 0;
+}
+
+
+/* Dynamic facility. */
+
+static int __init statedump_init(void)
+{
+       int ret;
+       printk(KERN_INFO "LTT : ltt-facility-statedump init\n");
+
+       ret = ltt_module_register(LTT_FUNCTION_STATEDUMP,
+                                                                                                               ltt_statedump_start,THIS_MODULE);
+       
+       return ret;
+}
+
+static void __exit statedump_exit(void)
+{
+       ltt_module_unregister(LTT_FUNCTION_STATEDUMP);
+}
+
+module_init(statedump_init)
+module_exit(statedump_exit)
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jean-Hugues Deschenes");
+MODULE_DESCRIPTION("Linux Trace Toolkit Statedump");
+
diff --git a/trunk/ltt-modules/Makefile b/trunk/ltt-modules/Makefile
deleted file mode 100644 (file)
index 0c56ebb..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-ifneq ($(KERNELRELEASE),)
-ifneq ($(CONFIG_LTT),)
-       obj-m := ltt-control.o ltt-statedump.o
-endif
-
-else
-       KERNELDIR ?= /lib/modules/$(shell uname -r)/build
-       PWD := $(shell pwd)
-       KERNELRELEASE = $(shell cat $(KERNELDIR)/$(KBUILD_OUTPUT)/include/linux/version.h | sed -n 's/.*UTS_RELEASE.*\"\(.*\)\".*/\1/p')
-ifneq ($(INSTALL_MOD_PATH),)
-       DEPMOD_OPT := -b $(INSTALL_MOD_PATH)
-endif
-
-default:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
-
-modules_install:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
-       if [ -f $(KERNELDIR)/$(KBUILD_OUTPUT)/System.map ] ; then /sbin/depmod -ae -F $(KERNELDIR)/$(KBUILD_OUTPUT)/System.map $(DEPMOD_OPT) $(KERNELRELEASE) ; fi
-
-
-clean:
-       $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
-endif
diff --git a/trunk/ltt-modules/ltt-control.c b/trunk/ltt-modules/ltt-control.c
deleted file mode 100644 (file)
index 45b44f0..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* ltt-control.c
- *
- * LTT control module over a netlink socket.
- *
- * Inspired from Relay Apps, by Tom Zanussi and iptables
- *
- * Copyright 2005 -
- * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ltt-core.h>
-#include <linux/netlink.h>
-#include <linux/inet.h>
-#include <linux/ip.h>
-#include <linux/security.h>
-#include <linux/skbuff.h>
-#include <linux/types.h>
-#include <net/sock.h>
-#include "ltt-control.h"
-
-
-#define LTTCTLM_BASE   0x10
-#define LTTCTLM_CONTROL        (LTTCTLM_BASE + 1)      /* LTT control message */
-
-static struct sock *socket;
-
-void ltt_control_input(struct sock *sk, int len)
-{
-       struct sk_buff *skb;
-       struct nlmsghdr *nlh = NULL;
-       u8 *payload = NULL;
-       lttctl_peer_msg_t *msg;
-       int err;
-
-       printk(KERN_ALERT "ltt-control ltt_control_input\n");
-
-       while ((skb = skb_dequeue(&sk->sk_receive_queue)) 
-                                       != NULL) {
-    
-               nlh = (struct nlmsghdr *)skb->data;
-
-    if(security_netlink_recv(skb)) {
-                       netlink_ack(skb, nlh, EPERM);
-                       kfree_skb(skb);
-                       continue;
-    }
-    
-               /* process netlink message pointed by skb->data */
-               err = EINVAL;
-               payload = NLMSG_DATA(nlh);
-               /* process netlink message with header pointed by 
-                * nlh and payload pointed by payload
-                */
-               if(nlh->nlmsg_len != sizeof(lttctl_peer_msg_t) + sizeof(struct nlmsghdr)) {
-                       printk(KERN_ALERT "ltt-control bad message length\n");
-                       netlink_ack(skb, nlh, EINVAL);
-                       kfree_skb(skb);
-                       continue;
-               }
-               msg = (lttctl_peer_msg_t*)payload;
-
-               switch(msg->op) {
-                       case OP_CREATE:
-                               err = ltt_control(LTT_CONTROL_CREATE_TRACE, msg->trace_name,
-                                                                                                                       msg->args);
-                               break;
-                       case OP_DESTROY:
-                               err = ltt_control(LTT_CONTROL_DESTROY_TRACE, msg->trace_name,
-                                               msg->args);
-                               break;
-                       case OP_START:
-                               err = ltt_control(LTT_CONTROL_START, msg->trace_name,
-                                               msg->args);
-                               break;
-                       case OP_STOP:
-                               err = ltt_control(LTT_CONTROL_STOP, msg->trace_name,
-                                               msg->args);
-                               break;
-                       default:
-                               err = EBADRQC;
-                               printk(KERN_INFO "ltt-control invalid operation\n");
-               }
-               netlink_ack(skb, nlh, err);
-               kfree_skb(skb);
-       }
-}
-
-
-static int ltt_control_init(void)
-{
-       printk(KERN_ALERT "ltt-control init\n");
-
-       socket = netlink_kernel_create(NETLINK_LTT, 1,
-                       ltt_control_input, THIS_MODULE);
-       if(socket == NULL) return -EPERM;
-       else return 0;
-}
-
-static void ltt_control_exit(void)
-{
-       printk(KERN_ALERT "ltt-control exit\n");
-
-       sock_release(socket->sk_socket);
-}
-
-
-module_init(ltt_control_init)
-module_exit(ltt_control_exit)
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mathieu Desnoyers");
-MODULE_DESCRIPTION("Linux Trace Toolkit Controller");
-
diff --git a/trunk/ltt-modules/ltt-control.h b/trunk/ltt-modules/ltt-control.h
deleted file mode 100644 (file)
index 430d5d1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _LTT_CONTROL_H
-#define _LTT_CONTROL_H
-
-
-//enum trace_mode {
-//     TRACE_NORMAL,
-//     TRACE_FLIGHT
-//};
-
-enum trace_op {
-  OP_CREATE,
-  OP_DESTROY,
-  OP_START,
-  OP_STOP,
-       OP_ALIGN,
-  OP_NONE
-};
-
-typedef struct lttctl_peer_msg {
-       char trace_name[NAME_MAX];
-       enum trace_op op;
-       union ltt_control_args args;
-} lttctl_peer_msg_t;
-
-#endif //_LTT_CONTROL_H
-
diff --git a/trunk/ltt-modules/ltt-statedump.c b/trunk/ltt-modules/ltt-statedump.c
deleted file mode 100644 (file)
index d6c0321..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/* ltt-state-dump.c
- *
- * Lunix Trace Toolkit Kernel State Dump
- *
- * Copyright 2005 -
- * Jean-Hugues Deschenes <jean-hugues.deschenes@polymtl.ca>
- *
- * Changes:
- *     Eric Clement:            add listing of network IP interface
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/ltt-core.h>
-#include <linux/netlink.h>
-#include <linux/inet.h>
-#include <linux/ip.h>
-#include <linux/kthread.h>
-#include <linux/proc_fs.h>
-#include <linux/file.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/cpu.h>
-#include <linux/ltt/ltt-facility-statedump.h>
-
-#define NB_PROC_CHUNK 20
-
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-
-/* in modules.c */
-extern int ltt_enumerate_modules(void);
-
-static inline int ltt_enumerate_network_ip_interface(void)
-{
-  struct net_device *list;
-  struct in_device *in_dev = NULL;
-  struct in_ifaddr *ifa = NULL;
-       
-  read_lock(&dev_base_lock);
-  for(list=dev_base; list != NULL; list=list->next) {
-
-    if(list->flags & IFF_UP) {  
-      in_dev = in_dev_get(list);
-
-      if(in_dev) {
-        for (ifa = in_dev->ifa_list; ifa != NULL; ifa = ifa->ifa_next) {
-          trace_statedump_enumerate_network_ip_interface(list->name, 
-                                                                                                                                                                                                                               ifa->ifa_address,
-                                                                                                                                                                                                                                       LTTNG_UP);
-                               }
-                               in_dev_put(in_dev);    
-      }
-    } else {
-      trace_statedump_enumerate_network_ip_interface(list->name,
-                                                                                                                                                                                                                                       0,
-                                                                                                                                                                                                                                       LTTNG_DOWN);
-               }
-  }
-  read_unlock(&dev_base_lock);
-  
-  return 0;
-}
-
-static inline int ltt_enumerate_file_descriptors(void)
-{
-  struct task_struct * t = &init_task;
-       unsigned int    i;
-       struct file *           filp;
-       char                            *tmp = (char*)__get_free_page(GFP_KERNEL), *path;
-  struct fdtable *fdt;
-
-       /* Enumerate active file descriptors */
-
-       do {
-         read_lock(&tasklist_lock);
-    if(t != &init_task) atomic_dec(&t->usage);
-         t = next_task(t);
-    atomic_inc(&t->usage);
-    read_unlock(&tasklist_lock);
-   
-               task_lock(t);
-               if (t->files) {
-                       spin_lock(&t->files->file_lock);
-                       fdt = files_fdtable(t->files);
-                       for (i=0; i < fdt->max_fds; i++) {
-                               filp = fcheck_files(t->files, i);
-                               if (!filp)
-                                continue;
-                               path = d_path(filp->f_dentry, filp->f_vfsmnt, tmp, PAGE_SIZE);
-
-                               /* Make sure we give at least some info */
-                               if(IS_ERR(path))
-                                       trace_statedump_enumerate_file_descriptors(filp->f_dentry->d_name.name, t->pid, i);
-                               else
-                                trace_statedump_enumerate_file_descriptors(path, t->pid, i);
-                }
-                spin_unlock(&t->files->file_lock);
-               }
-               task_unlock(t);
-
-  } while( t != &init_task );
-
-       free_page((unsigned long)tmp);
-       
-       return 0;
-}
-
-static inline int ltt_enumerate_vm_maps(void)
-{
-       struct mm_struct *mm;
-  struct task_struct *  t = &init_task;
-       struct vm_area_struct * map;
-       unsigned long                   ino = 0;
-       
-       do {
-    read_lock(&tasklist_lock);
-    if(t != &init_task) atomic_dec(&t->usage);
-         t = next_task(t);
-    atomic_inc(&t->usage);
-    read_unlock(&tasklist_lock);
-    
-               /* get_task_mm does a task_lock... */
-
-               mm = get_task_mm(t);
-
-               if (mm)
-               {
-                       map = mm->mmap;
-       
-                       if(map)
-                       {
-                               down_read(&mm->mmap_sem);
-               
-                               while (map) {
-                                       if (map->vm_file) {
-                                               ino = map->vm_file->f_dentry->d_inode->i_ino;
-                                       } else {
-                                               ino = 0;
-                                       }
-               
-                                       trace_statedump_enumerate_vm_maps(t->pid, (void *)map->vm_start, (void *)map->vm_end, map->vm_flags, map->vm_pgoff << PAGE_SHIFT, ino);
-                                       map = map->vm_next;
-                               }
-               
-                               up_read(&mm->mmap_sem);
-                       }
-       
-                       mmput(mm);
-               }  
-
-       } while( t != &init_task );
-
-       return 0;
-}
-
-#if defined( CONFIG_ARM )
-/* defined in arch/arm/kernel/irq.c because of dependency on statically-defined lock & irq_desc */
-int ltt_enumerate_interrupts(void);
-#else
-static inline int ltt_enumerate_interrupts(void)
-{
-  unsigned int i;
-  unsigned long flags = 0;
-
-  /* needs irq_desc */
-  
-  for(i = 0; i < NR_IRQS; i++)
-  {
-    struct irqaction * action;
-
-    spin_lock_irqsave(&irq_desc[i].lock, flags);
-
-    
-    for (action=irq_desc[i].action; action; action = action->next)
-      trace_statedump_enumerate_interrupts(
-        irq_desc[i].handler->typename,
-        action->name,
-        i );
-
-    spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-  }
-  
-  return 0;
-}
-#endif
-
-static inline int ltt_enumerate_process_states(void)
-{
-  struct task_struct *          t = &init_task;
-  struct task_struct *          p = t;
-  enum lttng_process_status     status;
-  enum lttng_thread_type        type;
-  enum lttng_execution_mode     mode;
-  enum lttng_execution_submode  submode;
-  
-  do {
-    mode = LTTNG_MODE_UNKNOWN;
-    submode = LTTNG_UNKNOWN;
-
-    read_lock(&tasklist_lock);
-    if(t != &init_task) {
-      atomic_dec(&t->usage);
-      t = next_thread(t);
-    }
-    if(t == p) {
-      t = p = next_task(t);
-    }
-    atomic_inc(&t->usage);
-    read_unlock(&tasklist_lock);
-    
-    task_lock(t);
-    
-    if(t->exit_state == EXIT_ZOMBIE)
-      status = LTTNG_ZOMBIE;
-    else if(t->exit_state == EXIT_DEAD)
-      status = LTTNG_DEAD;
-    else if(t->state == TASK_RUNNING)
-    {
-      /* Is this a forked child that has not run yet? */
-      if( list_empty(&t->run_list) )
-      {
-        status = LTTNG_WAIT_FORK;
-      }
-      else
-      {
-        /* All tasks are considered as wait_cpu; the viewer will sort out if the task was relly running at this time. */
-        status = LTTNG_WAIT_CPU;
-      }
-    }
-    else if(t->state & (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE))
-    {
-      /* Task is waiting for something to complete */
-      status = LTTNG_WAIT;
-    }
-    else
-      status = LTTNG_UNNAMED;
-
-    submode = LTTNG_NONE;
-
-
-    /* Verification of t->mm is to filter out kernel threads;
-       Viewer will further filter out if a user-space thread was in syscall mode or not */
-    if(t->mm)
-      type = LTTNG_USER_THREAD;
-    else
-      type = LTTNG_KERNEL_THREAD;
-      
-    trace_statedump_enumerate_process_state(t->pid, t->parent->pid, t->comm,
-                                            type, mode, submode, status);
-    
-    task_unlock(t);
-
-  } while( t != &init_task );
-
-  return 0;
-}
-
-void ltt_statedump_work_func(void *sem)
-{
-  /* Our job is just to release the semaphore so
-     that we are sure that each CPU has been in syscall
-     mode before the end of ltt_statedump_thread */
-  up((struct semaphore *)sem);
-}
-
-static struct work_struct cpu_work[NR_CPUS];
-
-int ltt_statedump_thread(void *data)
-{
-  struct semaphore work_sema4;
-  int cpu;
-
-  printk("ltt_statedump_thread\n");
-
-       ltt_enumerate_process_states();
-  
-  ltt_enumerate_file_descriptors();
-
-       ltt_enumerate_modules();
-  
-       ltt_enumerate_vm_maps();
-  
-       ltt_enumerate_interrupts();
-       
-       ltt_enumerate_network_ip_interface();
-  
-  /* Fire off a work queue on each CPU. Their sole purpose in life
-   * is to guarantee that each CPU has been in a state where is was in syscall
-   * mode (i.e. not in a trap, an IRQ or a soft IRQ) */
-  sema_init(&work_sema4, 1 - num_online_cpus());
-  
-  lock_cpu_hotplug();
-  for_each_online_cpu(cpu)
-  {
-    INIT_WORK(&cpu_work[cpu], ltt_statedump_work_func, &work_sema4);
-
-    schedule_delayed_work_on(cpu,&cpu_work[cpu],0);
-  }
-  unlock_cpu_hotplug();
-  
-  /* Wait for all work queues to have completed */
-  down(&work_sema4);
-  
-  /* Our work is done */
-  printk("trace_statedump_statedump_end\n");
-  trace_statedump_statedump_end();
-       
-       do_exit(0);
-
-       return 0;
-}
-
-int ltt_statedump_start(struct ltt_trace_struct *trace)
-{
-       printk("ltt_statedump_start\n");
-
-       kthread_run(    ltt_statedump_thread,
-                                                               NULL,
-                                                               "ltt_statedump");
-       
-       return 0;
-}
-
-
-/* Dynamic facility. */
-
-static int __init statedump_init(void)
-{
-       int ret;
-       printk(KERN_INFO "LTT : ltt-facility-statedump init\n");
-
-       ret = ltt_module_register(LTT_FUNCTION_STATEDUMP,
-                                                                                                               ltt_statedump_start,THIS_MODULE);
-       
-       return ret;
-}
-
-static void __exit statedump_exit(void)
-{
-       ltt_module_unregister(LTT_FUNCTION_STATEDUMP);
-}
-
-module_init(statedump_init)
-module_exit(statedump_exit)
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jean-Hugues Deschenes");
-MODULE_DESCRIPTION("Linux Trace Toolkit Statedump");
-
This page took 0.035103 seconds and 4 git commands to generate.