# HG changeset patch # User Jonathan Ludlam # Date 1264518905 0 # Node ID 9a60ccc5aea5594267996f4396368d7823ad1af3 # Parent d0f12ff65c469f979b5773eb3e01be0103858785 Fix a bug in LV resizing Signed-off-by: Jon Ludlam diff -r d0f12ff65c46 -r 9a60ccc5aea5 mlvm/lv.ml --- a/mlvm/lv.ml Tue Jan 26 15:09:34 2010 +0000 +++ b/mlvm/lv.ml Tue Jan 26 15:15:05 2010 +0000 @@ -45,7 +45,10 @@ | "WRITE" -> Write | "VISIBLE" -> Visible | _ -> failwith "Bad LV status string" - + +let sort_segments s = + List.sort (fun s1 s2 -> compare s1.s_start_extent s2.s_start_extent) s + let write_to_buffer b lv = let bprintf = Printf.bprintf in bprintf b "\n%s {\nid = \"%s\"\nstatus = [%s]\n" lv.name lv.id @@ -53,7 +56,7 @@ if List.length lv.tags > 0 then bprintf b "tags = [%s]\n" (String.concat ", " (List.map quote lv.tags)); bprintf b "segment_count = %d\n\n" (List.length lv.segments); - Listext.List.iteri_right + Listext.List.iteri (fun i s -> bprintf b "segment%d {\nstart_extent = %Ld\nextent_count = %Ld\n\n" (i+1) s.s_start_extent s.s_extent_count; @@ -116,7 +119,7 @@ id=id; status=status; tags=tags; - segments=segments } + segments=sort_segments segments } let allocation_of_segment s = match s.s_cls with @@ -150,17 +153,20 @@ let reduce_size_to lv new_seg_count = let cur_size = size_in_extents lv in + Debug.debug "Beginning reduce_size_to:"; if cur_size < new_seg_count then (failwith (Printf.sprintf "Cannot reduce size: current size (%Ld) is less than requested size (%Ld)" cur_size new_seg_count)); let rec doit segs left acc = match segs with | s::ss -> + Debug.debug (Printf.sprintf "Lv.reduce_size_to: s.s_start_extent=%Ld s.s_extent_count=%Ld left=%Ld" + s.s_start_extent s.s_extent_count left); if left > s.s_extent_count then doit ss (Int64.sub left s.s_extent_count) (s::acc) else {s with s_extent_count = left}::acc | _ -> acc in - {lv with segments = (doit lv.segments new_seg_count [])} + {lv with segments = sort_segments (doit lv.segments new_seg_count [])} let increase_allocation lv new_segs = - {lv with segments=lv.segments @ new_segs} + {lv with segments = sort_segments (lv.segments @ new_segs)} diff -r d0f12ff65c46 -r 9a60ccc5aea5 mlvm/redo.ml --- a/mlvm/redo.ml Tue Jan 26 15:09:34 2010 +0000 +++ b/mlvm/redo.ml Tue Jan 26 15:15:05 2010 +0000 @@ -100,12 +100,18 @@ write_initial_pos fd offset (Int64.add offset 12L) let redo_to_human_readable op = + let lvcreate_t_to_string l = + Printf.sprintf "{id:'%s', segments:[%s]}" l.lvc_id (Allocator.to_string l.lvc_segments) + in + let lvexpand_t_to_string l = + Printf.sprintf "[%s]" (Allocator.to_string l.lvex_segments) + in let opstr = match op.so_op with - | LvCreate (name,_) -> Printf.sprintf "LvCreate(%s)" name - | LvRemove name -> Printf.sprintf "LvRemove(%s)" name - | LvReduce (name,_) -> Printf.sprintf "LvReduce(%s)" name - | LvExpand (name,_) -> Printf.sprintf "LvExpand(%s)" name - | LvRename (name,_) -> Printf.sprintf "LvRename(%s)" name + | LvCreate (name,lvc) -> Printf.sprintf "LvCreate(%s,%s)" name (lvcreate_t_to_string lvc) + | LvRemove name -> Printf.sprintf "LvRemove(%s)" name + | LvReduce (name,lvrd) -> Printf.sprintf "LvReduce(%s,%Ld)" name lvrd.lvrd_new_extent_count + | LvExpand (name,lvex) -> Printf.sprintf "LvExpand(%s,%s)" name (lvexpand_t_to_string lvex) + | LvRename (name,lvmv) -> Printf.sprintf "LvRename(%s,%s)" name lvmv.lvmv_new_name in Printf.sprintf "{seqno=%d; op=%s}" op.so_seqno opstr diff -r d0f12ff65c46 -r 9a60ccc5aea5 mlvm/vg.ml --- a/mlvm/vg.ml Tue Jan 26 15:09:34 2010 +0000 +++ b/mlvm/vg.ml Tue Jan 26 15:15:05 2010 +0000 @@ -75,6 +75,7 @@ let do_op vg op = (if vg.seqno <> op.so_seqno then failwith "Failing to do VG operation out-of-order"); + Unixext.write_string_to_file (Printf.sprintf "/tmp/redo_op.%d" op.so_seqno) (Redo.redo_to_human_readable op); let rec createsegs ss lstart = match ss with | a::ss -> @@ -96,7 +97,7 @@ match op.so_op with | LvCreate (name,l) -> let new_free_space = Allocator.alloc_specified_areas vg.free_space l.lvc_segments in - let segments = (createsegs l.lvc_segments 0L) in + let segments = Lv.sort_segments (createsegs l.lvc_segments 0L) in let lv = { Lv.name=name; id=l.lvc_id; tags=[]; @@ -111,7 +112,7 @@ let old_size = Lv.size_in_extents lv in let free_space = Allocator.alloc_specified_areas vg.free_space l.lvex_segments in let segments = createsegs l.lvex_segments old_size in - let lv = { lv with Lv.segments = segments @ lv.Lv.segments } in + let lv = { lv with Lv.segments = Lv.sort_segments (segments @ lv.Lv.segments) } in { vg with lvs = lv::others; free_space=free_space}) | LvReduce (name,l) -> @@ -358,6 +359,7 @@ List.map (fun mdah -> Pv.MDAHeader.write_md pv.Pv.real_device mdah md) pv.Pv.mda_headers}) pvs} in + Unixext.write_string_to_file (Printf.sprintf "/tmp/metadata.%d" vg.seqno) md; (match vg.redo_lv with Some _ -> reset_redo vg | None -> ()); vg @@ -453,8 +455,9 @@ let md = fst (List.hd mds_and_pvdatas) in let pvdatas = List.map snd mds_and_pvdatas in let oc = open_out "/tmp/metadata" in - Printf.fprintf oc "%s" md; - parse md pvdatas + Printf.fprintf oc "%s" md; + close_out oc; + parse md pvdatas let set_dummy_mode base_dir mapper_name full_provision = Constants.dummy_mode := true;