open Virt_mem_utils
open Virt_mem_types
-open Kernel_task_struct
+open Kernel
-let run debug (image, ksymmap, utsname) =
- try
- let { domname = domname } = image in
+let run debug { addrmap = addrmap } =
+ (* Grab all the task_struct structures. *)
+ let tasks = AddrMap.fold (
+ fun _ v tasks ->
+ match v with
+ | _, Some (_, _, Task_struct task) -> task :: tasks
+ | _ -> tasks
+ ) addrmap [] in
- let kernel_version =
- match utsname with
- | None ->
- eprintf (f_"%s: could not guess kernel version\n") domname;
- raise Exit
- | Some { kernel_release = v } -> v in
+ (* 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
- if not (task_struct_known kernel_version) then (
- eprintf (f_"%s: %s: unknown kernel version
-Try a newer version of virt-mem, or if the guest is not from a
-supported Linux distribution, see this page about adding support:
- http://et.redhat.com/~rjones/virt-mem/faq.html\n") domname kernel_version;
- raise Exit
- );
+ printf " PID STAT COMMAND\n";
- let task_struct_size = task_struct_size kernel_version in
-
- let init_task, init_task_addr =
- let init_task_addr =
- try Ksymmap.find "init_task" ksymmap
- with Not_found ->
- eprintf (f_"%s: could not find init_task in kernel image\n") domname;
- raise Exit in
- let init_task =
- get_task_struct kernel_version image.mem init_task_addr in
- init_task, init_task_addr in
-
- (* Starting at init_task, navigate through the linked list of
- * tasks (through tasks.next). Grab each task_struct as we go.
- *)
- let tasks, image =
- let rec loop image acc 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 load_memory image next task_struct_size
- else image in
- let task = get_task_struct kernel_version image.mem next in
- let task = {
- task with
- task_struct_comm = truncate_c_string task.task_struct_comm
- } in
- let acc = task :: acc in
- loop image acc task
- ) else
- acc, image
- in
- loop image [] init_task in
-
- (* 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
-
- with Exit -> ()
+ List.iter (
+ fun { task_struct_pid = pid; task_struct_comm = comm } ->
+ let comm = truncate_c_string comm in
+ printf "%5Ld %s\n" pid 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 ~run
+let () =
+ Virt_mem.register "ps" summary description ~needs_tasks:true ~run