[Libguestfs] [PATCH v3 02/13] v2v: factor out overlay creation
Richard W.M. Jones
rjones at redhat.com
Tue Oct 20 14:00:40 UTC 2015
On Tue, Oct 20, 2015 at 04:08:10PM +0300, Roman Kagan wrote:
> Iterating over source disks and creating temporary overlays for easy
> rollback fits nicely into a separate function. In addition, determining
> their size doesn't need to wait until the guestfs is launched: the size
> can be obtained via disk_virtual_size() method.
>
> Signed-off-by: Roman Kagan <rkagan at virtuozzo.com>
> ---
> v2v/v2v.ml | 91 +++++++++++++++++++++++++++++---------------------------------
> 1 file changed, 42 insertions(+), 49 deletions(-)
>
> diff --git a/v2v/v2v.ml b/v2v/v2v.ml
> index 564c5da..155eb83 100644
> --- a/v2v/v2v.ml
> +++ b/v2v/v2v.ml
> @@ -57,40 +57,7 @@ let rec main () =
>
> let source = open_source input print_source in
> let source = amend_source source output_name network_map in
> -
> - (* Create a qcow2 v3 overlay to protect the source image(s). There
> - * is a specific reason to use the newer qcow2 variant: Because the
> - * L2 table can store zero clusters efficiently, and because
> - * discarded blocks are stored as zero clusters, this should allow us
> - * to fstrim/blkdiscard and avoid copying significant parts of the
> - * data over the wire.
> - *)
> - message (f_"Creating an overlay to protect the source from being modified");
> - let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
> - let overlays =
> - List.map (
> - fun ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
> - let overlay_file =
> - Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
> - unlink_on_exit overlay_file;
> -
> - let options =
> - "compat=1.1" ^
> - (match format with None -> ""
> - | Some fmt -> ",backing_fmt=" ^ fmt) in
> - let cmd =
> - sprintf "qemu-img create -q -f qcow2 -b %s -o %s %s"
> - (quote qemu_uri) (quote options) overlay_file in
> - if verbose () then printf "%s\n%!" cmd;
> - if Sys.command cmd <> 0 then
> - error (f_"qemu-img command failed, see earlier errors");
> -
> - (* Sanity check created overlay (see below). *)
> - if not ((new G.guestfs ())#disk_has_backing_file overlay_file) then
> - error (f_"internal error: qemu-img did not create overlay with backing file");
> -
> - overlay_file, source
> - ) source.s_disks in
> + let overlays = create_overlays source.s_disks in
>
> (* Open the guestfs handle. *)
> message (f_"Opening the overlay");
> @@ -100,7 +67,7 @@ let rec main () =
> if verbose () then g#set_verbose true;
> g#set_network true;
> List.iter (
> - fun (overlay_file, _) ->
> + fun ({ov_overlay_file = overlay_file}) ->
> g#add_drive_opts overlay_file
> ~format:"qcow2" ~cachemode:"unsafe" ~discard:"besteffort"
> ~copyonread:true
> @@ -108,20 +75,6 @@ let rec main () =
>
> g#launch ();
>
> - (* Create the list of overlays structs. Query each disk for its
> - * virtual size, and fill in a few other fields.
> - *)
> - let overlays =
> - mapi (
> - fun i (overlay_file, source) ->
> - let sd = "sd" ^ drive_name i in
> - let dev = "/dev/" ^ sd in
> - let vsize = g#blockdev_getsize64 dev in
> -
> - { ov_overlay_file = overlay_file; ov_sd = sd;
> - ov_virtual_size = vsize; ov_source = source }
> - ) overlays in
> -
> (* Work out where we will write the final output. Do this early
> * just so we can display errors to the user before doing too much
> * work.
> @@ -385,6 +338,7 @@ let rec main () =
>
> (* Save overlays if --debug-overlays option was used. *)
> if debug_overlays then (
> + let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
> List.iter (
> fun ov ->
> let saved_filename =
> @@ -460,6 +414,45 @@ and amend_source source output_name network_map =
>
> { source with s_nics = nics }
>
> +and create_overlays src_disks =
> + (* Create a qcow2 v3 overlay to protect the source image(s). There
> + * is a specific reason to use the newer qcow2 variant: Because the
> + * L2 table can store zero clusters efficiently, and because
> + * discarded blocks are stored as zero clusters, this should allow us
> + * to fstrim/blkdiscard and avoid copying significant parts of the
> + * data over the wire.
> + *)
> + message (f_"Creating an overlay to protect the source from being modified");
> + let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
> + List.mapi (
> + fun i ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
> + let overlay_file =
> + Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
> + unlink_on_exit overlay_file;
> +
> + let options =
> + "compat=1.1" ^
> + (match format with None -> ""
> + | Some fmt -> ",backing_fmt=" ^ fmt) in
> + let cmd =
> + sprintf "qemu-img create -q -f qcow2 -b %s -o %s %s"
> + (quote qemu_uri) (quote options) overlay_file in
> + if verbose () then printf "%s\n%!" cmd;
> + if Sys.command cmd <> 0 then
> + error (f_"qemu-img command failed, see earlier errors");
> +
> + (* Sanity check created overlay (see below). *)
> + if not ((new G.guestfs ())#disk_has_backing_file overlay_file) then
> + error (f_"internal error: qemu-img did not create overlay with backing file");
> +
> + let sd = "sd" ^ drive_name i in
> +
> + let vsize = (new G.guestfs ())#disk_virtual_size overlay_file in
> +
> + { ov_overlay_file = overlay_file; ov_sd = sd;
> + ov_virtual_size = vsize; ov_source = source }
> + ) src_disks
> +
> and inspect_source g root_choice =
> let roots = g#inspect_os () in
> let roots = Array.to_list roots in
Pretty much refactoring, but you're combining the two loops together
and using #disk_virtual_size instead of #blockdev_getsize64. Looks
good, so:
ACK.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine. Supports Linux and Windows.
http://people.redhat.com/~rjones/virt-df/
More information about the Libguestfs
mailing list