+(* Memory info command for virtual domains.
+ (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
+ http://libvirt.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
+
+open Printf
+
+open Virt_mem_gettext.Gettext
+open Virt_mem_utils
+open Virt_mem_types
+
+open Kernel_task_struct
+
+let find_tasks debug image ksymmap kernel_version =
+ 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")
+ image.domname kernel_version;
+ image, None
+ ) else (
+ let task_struct_size = task_struct_size kernel_version in
+
+ let init_task_addr =
+ try Some (Ksymmap.find "init_task" ksymmap)
+ with Not_found ->
+ eprintf (f_"%s: could not find init_task in kernel image\n")
+ image.domname;
+ None in
+ match init_task_addr with
+ | None -> image, None
+ | Some init_task_addr ->
+ let init_task =
+ 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.
+ *)
+ 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
+ ) else
+ image
+ in
+ loop image init_task in
+
+ image, Some init_task_addr
+ )