X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=lib%2Fdiskimage_lvm2.ml;h=4432e90e845d4f3d2a19eac9d6c99c7594e7a9f3;hb=091ddc2dd90ad9985aca308657d8120781defc11;hp=0f00e1f20867c634bf3d9bbcac78b57b79d44500;hpb=4cb1be48118971ebe749c4030f871aa25d26c520;p=virt-df.git diff --git a/lib/diskimage_lvm2.ml b/lib/diskimage_lvm2.ml index 0f00e1f..4432e90 100644 --- a/lib/diskimage_lvm2.ml +++ b/lib/diskimage_lvm2.ml @@ -26,10 +26,12 @@ open ExtList open Diskimage_utils open Diskimage_lvm2_metadata +open Int63.Operators + let plugin_id = "LVM2" -let sector_size = 512 -let sector_size64 = 512L +let sector_size_int = 512 +let sector_size = ~^sector_size_int (*----------------------------------------------------------------------*) (* Block device which can do linear maps, same as the kernel dm-linear.c *) @@ -48,7 +50,7 @@ class linear_map_device name extent_size segments = * satisfy any read request up to the full size. *) let size_in_extents = - List.fold_left max 0L + List.fold_left max ~^0 (List.map (fun (_, end_extent, _, _) -> end_extent) segments) in let size = size_in_extents *^ extent_size in object (self) @@ -60,24 +62,41 @@ object (self) * NB. Throws a runtime exception if the extent size is bigger * than an int (only likely to matter on 32 bit). *) - method blocksize = Int64.to_int extent_size + method blocksize = extent_size - (* Map block (extent) i to the underlying device. *) - method mapblock i = - if i < 0L || i >= size_in_extents then + 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 @@ -99,24 +118,24 @@ and read_pv_label dev = * the nineth sector contains some additional information about * the location of the current metadata. *) - let bits = dev#read_bitstring 0L (9 * sector_size) in + let bits = dev#read_bitstring ~^0 (~^9 *^ sector_size) in (*Bitmatch.hexdump_bitstring stdout bits;*) bitmatch bits with | { (* sector 0 *) - sector0 : sector_size*8 : bitstring; + sector0 : sector_size_int*8 : bitstring; (* sector 1 *) "LABELONE" : 64 : string; (* "LABELONE" *) _ : 128 : bitstring; (* Seems to contain something. *) "LVM2 001" : 64 : string; (* "LVM2 001" *) uuid : 256 : string; (* UUID *) - endsect : (sector_size-64)*8 : bitstring; (* to end of second sector *) + endsect : (sector_size_int-64)*8 : bitstring;(* to end of second sector *) (* sectors 2-7 *) - sectors234567 : sector_size*8 * 6 : bitstring; + sectors234567 : sector_size_int*8 * 6 : bitstring; (* sector 8 *) _ : 320 : bitstring; (* start of sector 8 *) @@ -126,11 +145,11 @@ and read_pv_label dev = } -> (* Metadata offset is relative to end of PV label. *) - let metadata_offset = metadata_offset +* 0x1000_l in + let metadata_offset = Int63.of_int32 metadata_offset +^ ~^0x1000 in (* Metadata length appears to include the trailing \000 which * we don't want. *) - let metadata_length = metadata_length -* 1_l in + let metadata_length = Int63.of_int32 metadata_length -^ ~^1 in let metadata = read_metadata dev metadata_offset metadata_length in @@ -141,26 +160,20 @@ and read_pv_label dev = (sprintf "LVM2: read_pv_label: %s: not an LVM2 physical volume" dev#name) -and read_metadata dev offset32 len32 = +and read_metadata dev offset len = if !debug then - eprintf "metadata: offset 0x%lx len %ld bytes\n%!" offset32 len32; + eprintf "metadata: offset %s len %s bytes\n%!" + (Int63.to_string offset) (Int63.to_string len); (* Check the offset and length are sensible. *) - let offset64 = - if offset32 <= Int32.max_int then Int64.of_int32 offset32 - else invalid_arg "LVM2: read_metadata: metadata offset too large" in - let len64 = - if len32 <= 2_147_483_647_l then Int64.of_int32 len32 - else invalid_arg "LVM2: read_metadata: metadata length too large" in - - if offset64 <= 0x1200L || offset64 >= dev#size - || len64 <= 0L || offset64 +^ len64 >= dev#size then + if offset <= ~^0x1200 || offset >= dev#size + || len <= ~^0 || offset +^ len >= dev#size then invalid_arg "LVM2: read_metadata: bad metadata offset or length"; (* If it is outside the disk boundaries, this will throw an exception, * otherwise it will read and return the metadata string. *) - dev#read offset64 (Int64.to_int len64) + dev#read offset len (*----------------------------------------------------------------------*) (* We are passed a list of devices which we previously identified @@ -231,14 +244,13 @@ let rec list devs = (* Some useful getter functions. If these can't get a value * from the metadata or if the type is wrong they raise Not_found. *) - let rec get_int64 field meta = + let rec get_int63 field meta = match List.assoc field meta with | Int i -> i | _ -> raise Not_found - and get_int field meta min max = + and get_int_bounded field meta max = match List.assoc field meta with - | Int i when Int64.of_int min <= i && i <= Int64.of_int max -> - Int64.to_int i + | Int i when i >= ~^0 && i <= Int63.of_int max -> Int63.to_int i | _ -> raise Not_found and get_string field meta = match List.assoc field meta with @@ -276,8 +288,10 @@ let rec list devs = let pvdevs, extent_size = try (* NB: extent_size is in sectors here - we convert to bytes. *) - let extent_size = get_int "extent_size" vgmeta 0 (1024*1024) in - let extent_size = Int64.of_int extent_size *^ sector_size64 in + let extent_size = + get_int_bounded "extent_size" vgmeta (1024*1024) in + let extent_size = Int63.of_int extent_size in + let extent_size = extent_size *^ sector_size in (* Get the physical_volumes section of the metadata. *) let pvdevs = get_meta "physical_volumes" vgmeta in @@ -293,16 +307,16 @@ let rec list devs = let _, dev = List.assoc pvuuid pvs in (* Construct a PV device. *) - let pe_start = get_int64 "pe_start" meta in - let pe_start = pe_start *^ sector_size64 in - let pe_count = get_int64 "pe_count" meta in + let pe_start = get_int63 "pe_start" meta in + let pe_start = pe_start *^ sector_size in + let pe_count = get_int63 "pe_count" meta in let pe_count = pe_count *^ extent_size in let pvdev = new offset_device pvuuid (* name *) pe_start pe_count (* start, size in bytes *) (* don't really have a natural block size ... *) - (Int64.to_int extent_size) + extent_size dev (* underlying device *) in Some (pvname, pvdev) @@ -311,7 +325,7 @@ let rec list devs = ) pvdevs, extent_size with (* Something went wrong - just return an empty map. *) - Not_found -> [], 0L in + Not_found -> [], ~^0 in (vgname, (pvuuids, vgmeta, pvdevs, extent_size)) ) vgs in @@ -328,7 +342,8 @@ let rec list devs = function | lvname, Metadata lvmeta -> (try - let segment_count = get_int "segment_count" lvmeta 0 1024 in + let segment_count = + get_int_bounded "segment_count" lvmeta 1024 in (* Get the segments for this LV. *) let segments = range 1 (segment_count+1) in @@ -341,9 +356,9 @@ let rec list devs = List.map ( fun segmeta -> let start_extent = - get_int64 "start_extent" segmeta in + get_int63 "start_extent" segmeta in let extent_count = - get_int64 "extent_count" segmeta in + get_int63 "extent_count" segmeta in let segtype = get_string "type" segmeta in (* Can only handle striped segments at the @@ -352,7 +367,7 @@ let rec list devs = if segtype <> "striped" then raise Not_found; let stripe_count = - get_int "stripe_count" segmeta 0 1024 in + get_int_bounded "stripe_count" segmeta 1024 in let stripes = get_stripes "stripes" segmeta in if List.length stripes <> stripe_count then @@ -386,14 +401,17 @@ let rec list devs = if !debug then ( List.iter ( fun (vgname, (pvuuids, vgmeta, pvdevs, extent_size, lvs)) -> - eprintf "VG %s: (extent_size = %Ld bytes)\n" vgname extent_size; + eprintf "VG %s: (extent_size = %s bytes)\n" vgname + (Int63.to_string extent_size); List.iter ( fun (lvname, segments) -> eprintf " %s/%s:\n" vgname lvname; List.iter ( fun (start_extent, extent_count, pvname, pvoffset) -> - eprintf " start %Ld count %Ld at %s:%Ld\n" - start_extent extent_count pvname pvoffset + eprintf " start %s count %s at %s:%s\n" + (Int63.to_string start_extent) + (Int63.to_string extent_count) + pvname (Int63.to_string pvoffset) ) segments ) lvs ) vgs;