X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=ps%2Fvirt_ps.ml;h=a9bcf1fc1b7b743e720204ef25ae0668ca4a4d74;hb=161581270af9d9141cbbde4aa6341448dd678d35;hp=4c995d8f2b7e4917f1ca974431544d90542c6f7f;hpb=b70c967911e197b74d6d7ad98e3df9240d82572f;p=virt-mem.git diff --git a/ps/virt_ps.ml b/ps/virt_ps.ml index 4c995d8..a9bcf1f 100644 --- a/ps/virt_ps.ml +++ b/ps/virt_ps.ml @@ -21,13 +21,81 @@ open Printf open Virt_mem_gettext.Gettext open Virt_mem_utils -open Virt_mem_mmap +open Virt_mem_types -let run debug images = () +open Kernel_task_struct + +let run debug (image, ksymmap, utsname) = + try + let { domname = domname } = image 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 + + 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 + ); + + 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 -> () 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 true run +let () = Virt_mem.register "ps" summary description ~run