Change to using internal format for kernel structures.
[virt-mem.git] / lib / virt_mem_tasks.ml
index c16e660..c2ae54e 100644 (file)
@@ -25,6 +25,8 @@ open Virt_mem_types
 
 open Kernel_task_struct
 
 
 open Kernel_task_struct
 
+let max_tasks = 10000
+
 let find_tasks debug image ksymmap kernel_version =
   if not (task_struct_known kernel_version) then (
     eprintf (f_"%s: %s: unknown kernel version
 let find_tasks debug image ksymmap kernel_version =
   if not (task_struct_known kernel_version) then (
     eprintf (f_"%s: %s: unknown kernel version
@@ -49,26 +51,40 @@ supported Linux distribution, see this page about adding support:
          get_task_struct kernel_version image.mem init_task_addr in
 
        (* Starting at init_task, navigate through the linked list of
          get_task_struct kernel_version image.mem init_task_addr in
 
        (* Starting at init_task, navigate through the linked list of
-        * tasks (through tasks.next).  Just make sure they are mapped
-        * into memory.
+        * tasks (through tasks.next).  Map them into memory and load
+        * them into a list.
         *)
         *)
-       let image =
-         let rec loop image task =
-           let next = task.task_struct_tasks'next in
-           if next <> init_task_addr then (
-             let mapped =
-               Virt_mem_mmap.is_mapped_range image.mem next task_struct_size in
-             let image =
-               if not mapped then
-                 Virt_mem_types.load_memory image next task_struct_size
-               else
-                 image in
-             let task = get_task_struct kernel_version image.mem next in
-             loop image task
+       let image, tasks =
+         let rec loop i image acc task =
+           if i <= max_tasks then (
+             let next = task.task_struct_tasks'next in
+             if next <> init_task_addr then (
+               let mapped =
+                 Virt_mem_mmap.is_mapped_range image.mem next task_struct_size in
+               let image =
+                 if not mapped then
+                   Virt_mem_types.load_memory image next task_struct_size
+                 else
+                   image in
+               let task = get_task_struct kernel_version image.mem next in
+               loop (i+1) image (task :: acc) task
+             ) else
+               image, acc
            ) else
            ) else
-             image
+             failwith (sprintf (f_"%s: too many tasks") image.domname)
          in
          in
-         loop image init_task in
+         loop 0 image [] init_task in
+
+       (* Convert to the internal format. *)
+       let tasks = List.rev_map (
+         fun task ->
+           { task_state = task.task_struct_state;
+             task_prio = task.task_struct_prio;
+             task_normal_prio = task.task_struct_normal_prio;
+             task_static_prio = task.task_struct_static_prio;
+             task_comm = truncate_c_string task.task_struct_comm;
+             task_pid = task.task_struct_pid }
+       ) tasks in
 
 
-       image, Some init_task_addr
+       image, Some tasks
   )
   )