v2v: vCenter: Replace qemu block curl driver with nbdkit-curl-plugin.

Because of the self-configuring readahead plugin we can entirely get
rid of input#adjust_overlay_parameters, which is definitely a good
thing.
This commit is contained in:
Richard W.M. Jones
2019-04-05 16:26:01 +01:00
parent bded1ee837
commit 0aa3545e4d
8 changed files with 16 additions and 93 deletions

View File

@@ -284,6 +284,7 @@ COPY_TO_LOCAL_BOBJECTS = \
uefi.cmo \
utils.cmo \
libvirt_utils.cmo \
nbdkit.cmo \
vCenter.cmo \
copy_to_local.cmo
COPY_TO_LOCAL_XOBJECTS = $(COPY_TO_LOCAL_BOBJECTS:.cmo=.cmx)

View File

@@ -24,7 +24,6 @@ class virtual input_libvirt : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> o
method precheck : unit -> unit
method as_options : string
method virtual source : unit -> Types.source
method adjust_overlay_parameters : Types.overlay -> unit
method private conn : Libvirt.rw Libvirt.Connect.t
end

View File

@@ -30,17 +30,12 @@ open Input_libvirt_other
open Printf
(* See RHBZ#1151033 and RHBZ#1153589. *)
let readahead_for_conversion = None
let readahead_for_copying = Some (64 * 1024 * 1024)
(* Subclass specialized for handling VMware vCenter over https. *)
class input_libvirt_vcenter_https
libvirt_conn input_password parsed_uri server guest =
object (self)
inherit input_libvirt libvirt_conn guest
val saved_source_paths = Hashtbl.create 13
val mutable dcPath = ""
method precheck () =
@@ -50,9 +45,9 @@ object (self)
debug "input_libvirt_vcenter_https: source: server %s" server;
(* Remove proxy environment variables so curl doesn't try to use
* them. Libvirt doesn't use the proxy anyway, and using a proxy
* is generally a bad idea because vCenter is slow enough as it is
* without putting another device in the way (RHBZ#1354507).
* them. Using a proxy is generally a bad idea because vCenter
* is slow enough as it is without putting another device in
* the way (RHBZ#1354507).
*)
unsetenv "https_proxy";
unsetenv "all_proxy";
@@ -77,28 +72,13 @@ object (self)
error (f_"vcenter: <vmware:datacenterpath> was not found in the XML. You need to upgrade to libvirt ≥ 1.2.20.")
);
(* Save the original source paths, so that we can remap them again
* in [#adjust_overlay_parameters].
*)
List.iter (
function
| { p_source = P_source_dev _ } ->
(* Should never happen ... *)
error (f_"source disk has <source dev=...> attribute in XML")
| { p_source_disk = { s_disk_id = id }; p_source = P_dont_rewrite } ->
Hashtbl.add saved_source_paths id None
| { p_source_disk = { s_disk_id = id }; p_source = P_source_file path } ->
Hashtbl.add saved_source_paths id (Some path)
) disks;
let readahead = readahead_for_conversion in
let disks = List.map (
function
| { p_source = P_source_dev _ } -> assert false
| { p_source_disk = disk; p_source = P_dont_rewrite } -> disk
| { p_source_disk = disk; p_source = P_source_file path } ->
let { VCenter.qemu_uri } =
VCenter.map_source ?readahead ?password_file:input_password
VCenter.map_source ?password_file:input_password
dcPath parsed_uri server path in
(* The libvirt ESX driver doesn't normally specify a format, but
@@ -108,25 +88,6 @@ object (self)
) disks in
{ source with s_disks = disks }
(* See RHBZ#1151033 and RHBZ#1153589 for why this is necessary. *)
method adjust_overlay_parameters overlay =
let orig_path =
try Hashtbl.find saved_source_paths overlay.ov_source.s_disk_id
with Not_found -> failwith "internal error in adjust_overlay_parameters" in
match orig_path with
| None -> ()
| Some orig_path ->
let readahead = readahead_for_copying in
let { VCenter.qemu_uri = backing_qemu_uri } =
VCenter.map_source ?readahead ?password_file:input_password
dcPath parsed_uri server orig_path in
(* Rebase the qcow2 overlay to adjust the readahead parameter. *)
let cmd = [ "qemu-img"; "rebase"; "-u"; "-b"; backing_qemu_uri;
overlay.ov_overlay_file ] in
if run_command cmd <> 0 then
warning (f_"qemu-img rebase failed (ignored)")
end
let input_libvirt_vcenter_https = new input_libvirt_vcenter_https

View File

@@ -510,7 +510,6 @@ class virtual input = object
method precheck () = ()
method virtual as_options : string
method virtual source : unit -> source
method adjust_overlay_parameters (_ : overlay) = ()
end
class virtual output = object

View File

@@ -384,10 +384,6 @@ type output_allocation = Sparse | Preallocated
input#adjust_overlay_parameters Optional method for adjusting
│ QEMU overlay parameters ready for copying
(eg. using a larger readahead setting).
copying Guest data is copied to the target disks
by running qemu-img convert.
v}
@@ -404,9 +400,6 @@ class virtual input : object
This is just used for pretty-printing log messages. *)
method virtual source : unit -> source
(** Examine the source hypervisor and create a source struct. *)
method adjust_overlay_parameters : overlay -> unit
(** Called just before copying to allow the input module to adjust
parameters of the overlay disk. *)
end
(** Encapsulates all [-i], etc input arguments as an object. *)

View File

@@ -700,13 +700,6 @@ and copy_targets cmdline targets input output =
if not ((open_guestfs ())#disk_has_backing_file overlay_file) then
error (f_"internal error: qemu corrupted the overlay file");
(* Give the input module a chance to adjust the parameters
* of the overlay/backing file. This allows us to increase
* the readahead parameter when copying (see RHBZ#1151033 and
* RHBZ#1153589 for the gruesome details).
*)
input#adjust_overlay_parameters t.target_overlay;
(match t.target_file with
| TargetFile filename ->
(* It turns out that libguestfs's disk creation code is

View File

@@ -35,7 +35,7 @@ type remote_resource = {
let source_re = PCRE.compile "^\\[(.*)\\] (.*)\\.vmdk$"
let snapshot_re = PCRE.compile "^(.*)-\\d{6}(\\.vmdk)$"
let rec map_source ?readahead ?password_file dcPath uri server path =
let rec map_source ?password_file dcPath uri server path =
(* If no_verify=1 was passed in the libvirt URI, then we have to
* turn off certificate verification here too.
*)
@@ -72,38 +72,15 @@ let rec map_source ?readahead ?password_file dcPath uri server path =
let session_cookie =
get_session_cookie password_file uri sslverify https_url in
let qemu_uri =
(* Construct the JSON parameters for the qemu URI. *)
let json_params = [
"file.driver", JSON.String "https";
"file.url", JSON.String https_url;
(* https://bugzilla.redhat.com/show_bug.cgi?id=1146007#c10 *)
"file.timeout", JSON.Int 2000_L;
] in
let password =
match password_file with
| None -> Nbdkit.NoPassword
| Some password_file -> Nbdkit.PasswordFile password_file in
let json_params =
match readahead with
| None -> json_params
| Some readahead ->
("file.readahead", JSON.Int (Int64.of_int readahead)) :: json_params in
let json_params =
if sslverify then json_params
else ("file.sslverify", JSON.String "off") :: json_params in
let json_params =
match session_cookie with
| None -> json_params
| Some cookie -> ("file.cookie", JSON.String cookie) :: json_params in
debug "vcenter: json parameters: %s" (JSON.string_of_doc json_params);
(* Turn the JSON parameters into a 'json:' protocol string.
* Note this requires qemu-img >= 2.1.0.
*)
let qemu_uri = "json: " ^ JSON.string_of_doc json_params in
qemu_uri in
let nbdkit =
Nbdkit.create_curl ?cookie:session_cookie ~password ~sslverify
https_url in
let qemu_uri = Nbdkit.run nbdkit in
(* Return the struct. *)
{ https_url = https_url;

View File

@@ -54,8 +54,8 @@ type remote_resource = {
(** The "remote resource" is the structure returned by the {!map_source}
function. *)
val map_source : ?readahead:int -> ?password_file:string -> string -> Xml.uri -> string -> string -> remote_resource
(** [map_source ?readahead ?password_file dcPath uri server path]
val map_source : ?password_file:string -> string -> Xml.uri -> string -> string -> remote_resource
(** [map_source ?password_file dcPath uri server path]
maps the [<source path=...>] string to a {!remote_resource}
structure containing both an [https://] URL and a qemu URI,
both pointing the guest disk.