X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=lib%2Fvirt_mem_types.ml;h=2167314a95729c54831ff6582ec98e986b03b625;hb=159e16043bbadc056b6ae193ddf3d31be2810e39;hp=071f6de1e07db93cfafb9c27702d3bad445aa0d7;hpb=e7fad361d3dbf1689a22fdd1ae5f5579d6ef5fb0;p=virt-mem.git diff --git a/lib/virt_mem_types.ml b/lib/virt_mem_types.ml index 071f6de..2167314 100644 --- a/lib/virt_mem_types.ml +++ b/lib/virt_mem_types.ml @@ -22,33 +22,125 @@ module D = Libvirt.Domain +open Virt_mem_utils open Virt_mem_mmap type ksym = string module Ksymmap = Map.Make (String) -type image0 = { +type ksymmap = addr Ksymmap.t + +type image = { dom : Libvirt.ro D.t option; domname : string; - arch : Virt_mem_utils.architecture; + arch : architecture; mem : ([`Wordsize], [`Endian], [`HasMapping]) Virt_mem_mmap.t; + kernel_min : addr; + kernel_max : addr; +} + +type utsname = { + uts_kernel_name : string; + uts_nodename : string; + uts_kernel_release : string; + uts_kernel_version : string; + uts_machine : string; + uts_domainname : string; +} + +type task = { + task_state : int64; + task_prio : int64; + task_normal_prio : int64; + task_static_prio : int64; + task_comm : string; + task_pid : int64; } -type image1 = - image0 - * addr Ksymmap.t - -type image2 = - image0 - * addr Ksymmap.t - * utsname option - -and utsname = { - kernel_name : string; - nodename : string; - kernel_release : string; - kernel_version : string; - machine : string; - domainname : string; +type net_device = { + netdev_name : string; + netdev_flags : int64; + netdev_operstate : int64; + netdev_mtu : int64; + netdev_perm_addr : string; + netdev_addr_len : int64; +} + +type kdata = { + ksyms : ksymmap option; + utsname : utsname option; + tasks : task list option; + net_devices : net_device list option; +} + +exception ParseError of string * string * string + +type fieldsig = { + field_available : bool; + field_offset : int; } + +(* This is the maximum we can download in one go over the libvirt + * remote connection. + * + * XXX Should have a 'D.max_peek' function. + *) +let max_memory_peek = 65536 + +type load_memory_error = + | AddressOutOfRange + | DomIsNull + +exception LoadMemoryError of load_memory_error * string + +let _load_memory mem dom start size = + let str = String.create size in + let rec loop i = + let remaining = size - i in + if remaining > 0 then ( + let size = min remaining max_memory_peek in + D.memory_peek dom [D.Virtual] (start +^ Int64.of_int i) size str i; + loop (i + size) + ) + in + loop 0; + + Virt_mem_mmap.add_string mem str start + +let load_static_memory ~dom ~domname ~arch ~wordsize ~endian + ~kernel_min ~kernel_max start size = + if start < kernel_min then + raise (LoadMemoryError (AddressOutOfRange, + "load_memory: start < kernel_min")) + else if start +^ Int64.of_int size > kernel_max then + raise (LoadMemoryError (AddressOutOfRange, + "load_memory: start+size > kernel_max")) + else ( + let mem = Virt_mem_mmap.create () in + let mem = Virt_mem_mmap.set_wordsize mem wordsize in + let mem = Virt_mem_mmap.set_endian mem endian in + + let mem = _load_memory mem dom start size in + + { dom = Some dom; domname = domname; mem = mem; arch = arch; + kernel_min = kernel_min; kernel_max = kernel_max } + ) + +let load_memory ({ dom = dom; mem = mem; kernel_min = kernel_min; + kernel_max = kernel_max } as image) start size = + if start < kernel_min then + raise (LoadMemoryError (AddressOutOfRange, + "load_memory: start < kernel_min")) + else if start +^ Int64.of_int size > kernel_max then + raise (LoadMemoryError (AddressOutOfRange, + "load_memory: start+size > kernel_max")) + else if Virt_mem_mmap.is_mapped_range mem start size then image + else ( + match dom with + | None -> + raise (LoadMemoryError (DomIsNull, "load_memory: dom = None")) + | Some dom -> + let mem = _load_memory mem dom start size in + { image with mem = mem } + )