]> xenbits.xensource.com Git - xcp/xen-api-libs.git/commitdiff
Fix a bug in LV resizing
authorJonathan Ludlam <Jonathan.Ludlam@eu.citrix.com>
Tue, 26 Jan 2010 15:15:05 +0000 (15:15 +0000)
committerJonathan Ludlam <Jonathan.Ludlam@eu.citrix.com>
Tue, 26 Jan 2010 15:15:05 +0000 (15:15 +0000)
Signed-off-by: Jon Ludlam <Jonathan.Ludlam@eu.citrix.com>
mlvm/lv.ml
mlvm/redo.ml
mlvm/vg.ml

index d5e6aae2f579ca1eb52da8a7f4ab19b6aadc8cfd..bbbc1e50393a741f9a0898cb054c6daa9c503e9b 100644 (file)
@@ -45,7 +45,10 @@ let status_of_string s =
     | "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 @@ let write_to_buffer b lv =
   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 @@ let of_metadata name config =
     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 size_in_extents lv =
            
 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)}
index 05b122f5bc2ec6132ad6eb0e4e1617f8f661d8cd..35b2cc3880f4792b8a4e64a45105adc9e8a97237 100644 (file)
@@ -100,12 +100,18 @@ let reset fd offset =
   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
index 250437f3be7de250643a85962ce7b147ba6cf899..0c38f7c6573cf2dbf90b159090d7700b8bb8753a 100644 (file)
@@ -75,6 +75,7 @@ let to_string vg =
 
 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 @@ let do_op vg op =
   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 do_op vg op =
          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 @@ let write_full vg =
          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
 
@@ -455,8 +457,9 @@ let load devices =
   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;