[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 4 of 8] CA-43021: When copying a VDI and using the BATs for acceleration, remember to union the BATs of the whole vhd chain



# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1282565811 -3600
# Node ID 980bea836c4e7e93b586f42e632bdf3c4a863cdb
# Parent  5205cfa6a3251017698baffa7825024823705314
CA-43021: When copying a VDI and using the BATs for acceleration, remember to 
union the BATs of the whole vhd chain.

If anything goes wrong in the chain analysis, fall back to normal copy.

Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>

diff -r 5205cfa6a325 -r 980bea836c4e ocaml/xapi/OMakefile
--- a/ocaml/xapi/OMakefile      Mon Aug 23 13:16:51 2010 +0100
+++ b/ocaml/xapi/OMakefile      Mon Aug 23 13:16:51 2010 +0100
@@ -1,4 +1,4 @@
-OCAMLPACKS    = xml-light2 cdrom pciutil sexpr log stunnel http-svr rss 
xen-utils netdev tapctl vhd
+OCAMLPACKS    = xml-light2 cdrom pciutil sexpr log stunnel http-svr rss 
xen-utils netdev tapctl vhd xs
 OCAML_LIBS    =  ../util/version ../util/vm_memory_constraints 
../util/sanitycheck ../util/stats \
        ../idl/ocaml_backend/common ../idl/ocaml_backend/client 
../idl/ocaml_backend/server ../util/ocamltest
 OCAMLINCLUDES = ../idl ../idl/ocaml_backend \
@@ -33,6 +33,7 @@
 
 OCamlProgram(http_test, http_test)
 OCamlProgram(sparse_dd, sparse_dd)
+OCamlProgram(show_bat, show_bat)
 
 COMMON = \
        xapi_templates \
diff -r 5205cfa6a325 -r 980bea836c4e ocaml/xapi/sparse_dd.ml
--- a/ocaml/xapi/sparse_dd.ml   Mon Aug 23 13:16:51 2010 +0100
+++ b/ocaml/xapi/sparse_dd.ml   Mon Aug 23 13:16:51 2010 +0100
@@ -237,7 +237,7 @@
                                        let backend = xs.Xs.read 
(Printf.sprintf "device/vbd/%d/backend" id) in
                                        let params = xs.Xs.read (Printf.sprintf 
"%s/params" backend) in
                                        match String.split '/' backend with
-                                       | "local" :: "domain" :: bedomid :: _ ->
+                                       | "" :: "local" :: "domain" :: bedomid 
:: _ ->
                                                assert (self = bedomid);
                                                Some params
                                        | _ -> raise Not_found
@@ -263,15 +263,43 @@
                | None -> None
                end
 
+let deref_symlinks path = 
+       let rec inner seen_already path = 
+               if List.mem path seen_already
+               then failwith "Circular symlink";
+               let stats = Unix.lstat path in
+               if stats.Unix.st_kind = Unix.S_LNK
+               then inner (path :: seen_already) (Unix.readlink path)
+               else path in
+       inner [] path
+
+let with_rdonly_vhd path f = 
+       let h = Vhd._open path [ Vhd.Open_rdonly ] in
+       finally
+       (fun () -> f h)
+       (fun () -> Vhd.close h)
+
+let parent_of_vhd vhd = 
+       let vhd' = deref_symlinks vhd in
+       let parent = with_rdonly_vhd vhd' Vhd.get_parent in
+       (* Make path absolute *)
+       if String.length parent > 0 && String.startswith "./" parent
+       then Filename.concat (Filename.dirname vhd') parent
+       else parent
+
+let rec chain_of_vhd vhd = 
+       try
+               let p = parent_of_vhd vhd in
+               vhd :: (chain_of_vhd p)
+       with (Failure "Disk is not a differencing disk") -> [ vhd ]
+
 (** Given a vhd filename, return the BAT *)
 let bat vhd = 
-       let h = Vhd._open vhd [ Vhd.Open_rdonly ] in
-       finally
-       (fun () -> 
+       with_rdonly_vhd vhd
+       (fun h ->
                let b = Vhd.get_bat h in
                let b' = List.map_tr (fun (s, l) -> 2L ** mib ** (Int64.of_int 
s), 2L ** mib ** (Int64.of_int l)) b in
                Bat.of_list b')
-       (fun () -> Vhd.close h)
 
 (* Record when the binary started for performance measuring *)
 let start = Unix.gettimeofday ()
@@ -338,9 +366,19 @@
         let size = Some !size in
        let src_vhd = vhd_of_device !src and dest_vhd = vhd_of_device !dest in
        Printf.printf "auto-detect src vhd:  %s\n" (Opt.default "None" (Opt.map 
(fun x -> "Some " ^ x) src_vhd));
-       let src_bat = Opt.map bat src_vhd in 
+       let bat = match src_vhd with
+       | Some vhd ->
+               (try
+                       let chain = chain_of_vhd vhd in
+                       Printf.printf "chain: %s\n" (String.concat "; " chain);
+                       let empty = Bat.of_list [] in
+                       Some (List.fold_left Bat.union empty (List.map bat 
chain))
+               with e ->
+                       Printf.printf "Caught exception: %s while calculating 
BAT. Ignoring all BAT information\n" (Printexc.to_string e);
+                       None)
+       | None -> None in
        progress_cb 0.;
-       let stats = file_dd ~progress_cb ?size ?bat:src_bat !prezeroed !src 
!dest in
+       let stats = file_dd ~progress_cb ?size ?bat !prezeroed !src !dest in
        Printf.printf "Time: %.2f seconds\n" (Unix.gettimeofday () -. start);
        Printf.printf "\nNumber of writes: %d\n" stats.writes;
        Printf.printf "Number of bytes: %Ld\n" stats.bytes
 ocaml/xapi/OMakefile    |   3 +-
 ocaml/xapi/sparse_dd.ml |  52 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 47 insertions(+), 8 deletions(-)


Attachment: xen-api.hg-4.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.