# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1282565810 -3600
# Node ID 24b830d6f50e96b7e78363dd2016278fc268c066
# Parent 9de4d96802c250f68519c26b7c021c41beda995b
CA-43021: More refactorings of the sparse_dd binary.
Split the DD operation into a 'fold' and a 'copy' (where the latter contains
the side-effects, computes stats etc)
Move the substring record type into the Zerocheck module.
Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>
diff -r 9de4d96802c2 -r 24b830d6f50e ocaml/xapi/sparse_dd.ml
--- a/ocaml/xapi/sparse_dd.ml Mon Aug 23 13:16:49 2010 +0100
+++ b/ocaml/xapi/sparse_dd.ml Mon Aug 23 13:16:50 2010 +0100
@@ -4,6 +4,7 @@
open Pervasiveext
open Stringext
open Listext
+open Zerocheck
let ( +* ) = Int64.add
let ( -* ) = Int64.sub
@@ -23,13 +24,6 @@
let quantum = 16384 in
((x + quantum + quantum - 1) / quantum) * quantum
-(** Represents a substring without making a copy *)
-type substring = {
- buf: string;
- offset: int;
- len: int;
-}
-
(** The copying routine has inputs and outputs which both look like a
Unix file-descriptor *)
module type IO = sig
@@ -37,10 +31,10 @@
val op: t -> int64 -> substring -> unit
end
-(* [fold_over_blocks (s, len) skip f initial] applies contiguous (start,
length) pairs to
+(* [partition_into_blocks (s, len) skip f initial] applies contiguous (start,
length) pairs to
[f] starting at [s] up to maximum length [len] where each pair is as large
as possible
up to [skip]. *)
-let fold_over_blocks (s, len) skip f initial =
+let partition_into_blocks (s, len) skip f initial =
let rec inner offset acc =
if offset = s +* len then acc
else
@@ -59,27 +53,32 @@
(** Perform the data duplication ("DD") *)
module DD(Input : IO)(Output : IO) = struct
+ let fold bat sparse (src: Input.t) size f initial =
+ let buf = String.create (Int64.to_int blocksize) in
+ let do_block acc (offset, this_chunk) =
+ Input.op src offset { buf = buf; offset = 0; len =
Int64.to_int this_chunk };
+ begin match sparse with
+ | Some zero -> fold_over_nonzeros buf (Int64.to_int
this_chunk) roundup (f offset) acc
+ | None -> f offset acc { buf = buf; offset = 0; len =
Int64.to_int this_chunk }
+ end in
+ (* For each entry from the BAT, copy it as a sequence of
sub-blocks *)
+ Bat.fold_left (fun acc b -> partition_into_blocks b blocksize
do_block acc) initial bat
+
(** [copy progress_cb bat sparse src dst size] copies blocks of data
from [src] to [dst]
where [bat] represents the allocated / dirty blocks in [src];
where if sparse is None it means don't scan for and skip over
blocks of zeroes in [src]
where if sparse is (Some c) it means do scan for and skip over
blocks of 'c' in [src]
while calling [progress_cb] frequently to report the fraction
complete
*)
- let copy progress_cb bat sparse (src: Input.t) (dst: Output.t) size =
- let buf = String.create (Int64.to_int blocksize) in
- let do_block stats (offset, this_chunk) : stats =
- progress_cb ((Int64.to_float offset) /. (Int64.to_float
size));
- Input.op src offset { buf = buf; offset = 0; len =
Int64.to_int this_chunk };
- let write_extent stats (s, e) =
- Output.op dst (offset +* (Int64.of_int s)) {
buf = buf; offset = s; len = e };
- { stats with writes = stats.writes + 1; bytes =
stats.bytes +* (Int64.of_int e) }
- in
- begin match sparse with
- | Some zero -> Zerocheck.fold_over_nonzeros buf
(Int64.to_int this_chunk) roundup write_extent stats
- | None -> write_extent stats (0, Int64.to_int
this_chunk)
- end in
- (* For each entry from the BAT, copy it as a sequence of
sub-blocks *)
- Bat.fold_left (fun stats b -> fold_over_blocks b blocksize
do_block stats) { writes = 0; bytes = 0L } bat
+ let copy progress_cb bat sparse src dst size =
+ let total_work = Bat.fold_left (fun total (_, size) -> total +*
size) 0L bat in
+ fold bat sparse src size
+ (fun offset stats substr ->
+ Output.op dst (offset +* (Int64.of_int
substr.offset)) substr;
+ let stats' = { writes = stats.writes + 1; bytes
= stats.bytes +* (Int64.of_int substr.len) } in
+ progress_cb (Int64.to_float stats'.bytes /.
(Int64.to_float total_work));
+ stats')
+ { writes = 0; bytes = 0L }
end
(* Helper function to always return a block of zeroes, like /dev/null *)
ocaml/xapi/sparse_dd.ml | 47 +++++++++++++++++++++++------------------------
1 files changed, 23 insertions(+), 24 deletions(-)
xen-api.hg-2.patch
Description: Text Data
_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api
|