X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=lib%2Fdiskimage_lvm2.ml;h=2c2fa608a23cc5b7c07b32f6fa686b60515dea29;hb=7a5fc851494dacaae801ef578c2b68d6184543f4;hp=ea127cb3972afbfb97507f2af98585fe20738342;hpb=063c6a300ed7ed6a9ec99d22159b3e246d08a70a;p=virt-df.git diff --git a/lib/diskimage_lvm2.ml b/lib/diskimage_lvm2.ml index ea127cb..2c2fa60 100644 --- a/lib/diskimage_lvm2.ml +++ b/lib/diskimage_lvm2.ml @@ -23,12 +23,12 @@ open Printf open ExtList -open Diskimage_utils +open Diskimage_impl open Diskimage_lvm2_metadata open Int63.Operators -let plugin_id = "LVM2" +let id = "LVM2" let sector_size_int = 512 let sector_size = ~^sector_size_int @@ -64,33 +64,50 @@ object (self) *) method blocksize = extent_size - (* Map block (extent) i to the underlying device. *) - method mapblock i = + method private map i = if i < ~^0 || i >= size_in_extents then invalid_arg "linear_map_device: read outside device"; let rec loop = function | [] -> - [] + None | (start_extent, end_extent, dev, pvoffset) :: rest -> - if start_extent <= i && i < end_extent then - [dev, (pvoffset +^ i) *^ extent_size] - else + if start_extent <= i && i < end_extent then ( + let dev_offset = (pvoffset +^ i) *^ extent_size in + Some (start_extent, end_extent, dev, dev_offset, pvoffset) + ) else loop rest in loop segments + (* Map block (extent) i to the underlying device. *) + method map_block i = + match self#map i with + | Some (_, _, dev, dev_offset, _) -> [dev, dev_offset] + | None -> [] + + (* Continguous span. *) + method contiguous offset = + let offset_in_extents = offset /^ extent_size in + + (* Get the segment that this offset lies in. *) + match self#map offset_in_extents with + | Some (_, end_extent, dev, dev_offset, _) -> + (* Contiguous bytes up to the end of this extent. *) + end_extent *^ extent_size -^ offset + | None -> ~^0 + (* NB. Use the superclass #read method. *) end (*----------------------------------------------------------------------*) (* Probe to see if it's an LVM2 PV. *) -let rec probe lvm_plugin_id dev = +let rec probe dev = try let uuid, _ = read_pv_label dev in if !debug then eprintf "LVM2 detected PV UUID %s\n%!" uuid; - { lvm_plugin_id = lvm_plugin_id; pv_uuid = uuid } + { pv_cb = callbacks; pv_uuid = uuid; pv_dev = dev } with exn -> if !debug then prerr_endline (Printexc.to_string exn); raise Not_found @@ -164,15 +181,17 @@ and read_metadata dev offset len = * (as devices) and return them. Note that we don't try to detect * what is on these LVs - that will be done in the main code. *) -let rec list devs = +and list_lvs pvs = (* Read the UUID and metadata (again) from each device to end up with * an assoc list of PVs, keyed on the UUID. + * + * XXX We've already read this - we should save it in the pv struct. *) let pvs = List.map ( - fun dev -> + fun { pv_dev = dev } -> let uuid, metadata = read_pv_label dev in (uuid, (metadata, dev)) - ) devs in + ) pvs in (* Parse the metadata using the external lexer/parser. *) let pvs = List.map ( @@ -430,3 +449,18 @@ let rec list devs = (* Return the list of LV devices. *) lvs + +(* XXX We don't currently have enough information in the PV + * structure to determine quickly which blocks are used. Need + * to store the parsed metadata in the structure ... + *) +and offset_is_free _ _ = false + +and callbacks = { + lvm_cb_name = id; + lvm_cb_list_lvs = list_lvs; + lvm_cb_offset_is_free = offset_is_free; +} + +(* Register the plugin. *) +let () = register_plugin ~lvm:probe id