Fix 'make doc' rule.
[virt-mem.git] / ps / virt_ps.ml
index 94301ce..5c53dbf 100644 (file)
@@ -21,16 +21,52 @@ open Printf
 
 open Virt_mem_gettext.Gettext
 open Virt_mem_utils
-open Virt_mem_mmap
+open Virt_mem_types
 
-let usage = s_"NAME
-  virt-ps - process listing command for virtual machines
+open Kernel_task_struct
 
-SUMMARY
-  virt-ps [-options] [domains]
+let run debug { domname = domname; mem = mem }
+    { utsname = utsname; tasks = tasks } =
+  let utsname = Option.get utsname in
+  let kernel_version = utsname.kernel_release in
+  let init_task_addr = Option.get tasks in
 
-DESCRIPTION
-  virt-ps prints a process listing for virtual machines running under
-  libvirt."
+  (* Starting at init_task, navigate through the linked list of
+   * tasks (through tasks.next).  The main program has already made
+   * sure these are mapped into memory.
+   *)
+  let tasks =
+    let rec loop acc task =
+      let next = task.task_struct_tasks'next in
+      if next <> init_task_addr then (
+       let task = get_task_struct kernel_version mem next in
+       let task = {
+         task with
+           task_struct_comm = truncate_c_string task.task_struct_comm
+       } in
+       let acc = task :: acc in
+       loop acc task
+      ) else
+       acc
+    in
+    loop [] (get_task_struct kernel_version mem init_task_addr) in
 
-let debug, images = Virt_mem.start usage
+  (* Sort tasks by PID. *)
+  let cmp { task_struct_pid = p1 } { task_struct_pid = p2 } = compare p1 p2 in
+  let tasks = List.sort cmp tasks in
+
+  printf "  PID STAT COMMAND\n";
+
+  List.iter (
+    fun task ->
+      printf "%5Ld      %s\n" task.task_struct_pid task.task_struct_comm
+  ) tasks
+
+let summary = s_"list processes in virtual machine"
+let description = s_"\
+virt-ps prints a process listing for virtual machines running under
+libvirt."
+
+let () =
+  Virt_mem.register "ps" summary description
+    ~needs_utsname:true ~needs_tasks:true ~run