--- /dev/null
+(* 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 Virt_mem_mmap
+
+(* Truncate an OCaml string at the first ASCII NUL character, ie. as
+ * if it were a C string.
+ *)
+let truncate str =
+ try
+ let i = String.index str '\000' in
+ String.sub str 0 i
+ with
+ Not_found -> str
+
+let parse_utsname bits =
+ (* Expect the first (sysname) field to always be "Linux", which is
+ * also a good way to tell if we're synchronized to the right bit of
+ * memory.
+ *)
+ bitmatch bits with
+ | { "Linux\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" : 65*8 : string;
+ nodename : 65*8 : string;
+ release : 65*8 : string;
+ version : 65*8 : string;
+ machine : 65*8 : string;
+ domainname : 65*8 : string } ->
+ Some {
+ kernel_name = "Linux";
+ nodename = truncate nodename;
+ kernel_release = truncate release;
+ kernel_version = truncate version;
+ machine = truncate machine;
+ domainname = truncate domainname
+ }
+ | { _ } ->
+ None
+
+let find_utsname debug (domid, name, arch, mem, lookup_ksym) =
+ let utsname =
+ (* In Linux 2.6.25, the symbol is init_uts_ns.
+ * http://lxr.linux.no/linux/init/version.c
+ *)
+ try
+ let addr = lookup_ksym "init_uts_ns" in
+
+ let bs = Bitstring.bitstring_of_string (get_bytes mem addr (65*6+4)) in
+ (bitmatch bs with
+ | { _ : 32 : int; (* the kref, atomic_t, always 32 bits *)
+ new_utsname : -1 : bitstring } ->
+ parse_utsname new_utsname
+ | { _ } ->
+ if debug then
+ eprintf (f_"%s: unexpected init_uts_ns in kernel image\n") name;
+ None
+ )
+ with
+ Not_found ->
+ (* In Linux 2.6.9, the symbol is system_utsname.
+ * http://lxr.linux.no/linux-bk+v2.6.9/include/linux/utsname.h#L24
+ *)
+ try
+ let addr = lookup_ksym "system_utsname" in
+
+ let bits =
+ Bitstring.bitstring_of_string (get_bytes mem addr (65*6)) in
+ parse_utsname bits
+ with
+ Not_found ->
+ eprintf (f_"%s: could not find utsname in kernel image\n") name
+ in
+ (domid, name, arch, mem, lookup_ksym, utsname)