X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=lib%2Fvirt_mem_types.ml;h=c3da9328a144abb539d733d87c2e22b8dc8e5ee3;hb=898c12fcca817229061fbe50b88651328ea4ec03;hp=34f3fe7a9176b6b83c8dd7680d372bc7a5694d3d;hpb=643e58b5e26c18f2cfc1c7b9aa676cb44feee847;p=virt-mem.git diff --git a/lib/virt_mem_types.ml b/lib/virt_mem_types.ml index 34f3fe7..c3da932 100644 --- a/lib/virt_mem_types.ml +++ b/lib/virt_mem_types.ml @@ -20,32 +20,32 @@ Common types. *) -(** A kernel image. *) -type image0 = - int option (* Domain ID, if known. *) - * string (* Domain name. *) - * Virt_mem_utils.architecture (* Architecture, eg. i386. *) - * ([`Wordsize], [`Endian], [`HasMapping]) Virt_mem_mmap.t (* Memory map. *) - -(** A kernel symbol. *) +module D = Libvirt.Domain + +open Virt_mem_utils +open Virt_mem_mmap + type ksym = string -(** A kernel image, after finding kernel symbols. *) +module Ksymmap = Map.Make (String) + +type image0 = { + dom : Libvirt.ro D.t option; + domname : string; + arch : Virt_mem_utils.architecture; + mem : ([`Wordsize], [`Endian], [`HasMapping]) Virt_mem_mmap.t; + kernel_min : addr; + kernel_max : addr; +} + type image1 = - int option (* Domain ID, if known. *) - * string (* Domain name. *) - * Virt_mem_utils.architecture (* Architecture, eg. i386. *) - * ([`Wordsize], [`Endian], [`HasMapping]) Virt_mem_mmap.t (* Memory map. *) - * (ksym -> Virt_mem_mmap.addr) (* Kernel symbol lookup function. *) + image0 + * addr Ksymmap.t -(** A kernel image, after finding kernel version (like 'uname'). *) type image2 = - int option (* Domain ID, if known. *) - * string (* Domain name. *) - * Virt_mem_utils.architecture (* Architecture, eg. i386. *) - * ([`Wordsize], [`Endian], [`HasMapping]) Virt_mem_mmap.t (* Memory map. *) - * (ksym -> Virt_mem_mmap.addr) (* Kernel symbol lookup function. *) - * utsname option (* Kernel version, etc., if known. *) + image0 + * addr Ksymmap.t + * utsname option and utsname = { kernel_name : string; @@ -55,3 +55,67 @@ and utsname = { machine : string; domainname : string; } + +(* 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; + + 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 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 } + )