| "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
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;
id=id;
status=status;
tags=tags;
- segments=segments }
+ segments=sort_segments segments }
let allocation_of_segment s =
match s.s_cls with
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)}
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
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 ->
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=[];
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) ->
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
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;