For input methods which use nbdkit, we can cheaply add nbdkit-rate-filter to control input-side network bandwidth. These options control that filter. We can choose to set the bandwidth statically and optionally change it dynamically:
--bandwidth 10M # static bandwidth of 10 Mbps, no dynamic adjustment possible --bandwidth 5M --bandwidth-file /tmp/bw # initial static bandwidth of 5 Mbps, adjustable by writing to /tmp/bw --bandwidth-file /tmp/bw # no initial bandwidth cap, can be added later by writing to /tmp/bw It only makes sense to control the input side since virt-v2v writes a lot less data than it reads. --- v2v/Makefile.am | 1 + v2v/cmdline.ml | 17 ++++++++++-- v2v/cmdline.mli | 1 + v2v/input_disk.ml | 2 +- v2v/input_libvirt_other.ml | 4 +-- v2v/input_libvirt_other.mli | 2 +- v2v/input_libvirt_vcenter_https.ml | 6 ++-- v2v/input_libvirt_vddk.ml | 6 ++-- v2v/input_libvirt_xen_ssh.ml | 6 ++-- v2v/input_libvirtxml.ml | 2 +- v2v/input_ova.ml | 2 +- v2v/input_vmx.ml | 26 ++++++++++-------- v2v/nbdkit.ml | 34 +++++++++++++++++------ v2v/nbdkit.mli | 9 ++++-- v2v/parse_libvirt_xml.ml | 9 +++--- v2v/parse_libvirt_xml.mli | 4 +-- v2v/types.ml | 6 +++- v2v/types.mli | 7 ++++- v2v/v2v.ml | 3 +- v2v/vCenter.ml | 4 +-- v2v/vCenter.mli | 3 +- v2v/virt-v2v.pod | 44 ++++++++++++++++++++++++++++++ 22 files changed, 146 insertions(+), 52 deletions(-) diff --git a/v2v/Makefile.am b/v2v/Makefile.am index 55b966efa..63d9b963a 100644 --- a/v2v/Makefile.am +++ b/v2v/Makefile.am @@ -281,6 +281,7 @@ virt_v2v_copy_to_local_CFLAGS = \ $(LIBVIRT_CFLAGS) COPY_TO_LOCAL_BOBJECTS = \ + types.cmo \ uefi.cmo \ utils.cmo \ libvirt_utils.cmo \ diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml index 4d390f249..641eed017 100644 --- a/v2v/cmdline.ml +++ b/v2v/cmdline.ml @@ -29,6 +29,7 @@ open Types open Utils type cmdline = { + bandwidth : bandwidth option; compressed : bool; debug_overlays : bool; do_copy : bool; @@ -47,6 +48,8 @@ type cmdline = { let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge):(.*)" let parse_cmdline () = + let bandwidth = ref None in + let bandwidth_file = ref None in let compressed = ref false in let debug_overlays = ref false in let do_copy = ref true in @@ -191,6 +194,10 @@ let parse_cmdline () = and ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in let argspec = [ + [ L"bandwidth" ], Getopt.String ("bps", set_string_option_once "--bandwidth" bandwidth), + s_"Set bandwidth to bits per sec"; + [ L"bandwidth-file" ], Getopt.String ("filename", set_string_option_once "--bandwidth-file" bandwidth_file), + s_"Set bandwidth dynamically from file"; [ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge), s_"Map bridge ‘in’ to ‘out’"; [ L"compressed" ], Getopt.Set compressed, @@ -304,6 +311,11 @@ read the man page virt-v2v(1). (* Dereference the arguments. *) let args = List.rev !args in + let bandwidth = + match !bandwidth, !bandwidth_file with + | None, None -> None + | Some rate, None -> Some (StaticBandwidth rate) + | rate, Some filename -> Some (DynamicBandwidth (rate, filename)) in let compressed = !compressed in let debug_overlays = !debug_overlays in let do_copy = !do_copy in @@ -351,6 +363,7 @@ read the man page virt-v2v(1). pr "in-place\n"; pr "io/oo\n"; pr "mac-option\n"; + pr "bandwidth-option\n"; List.iter (pr "input:%s\n") (Modules_list.input_modules ()); List.iter (pr "output:%s\n") (Modules_list.output_modules ()); List.iter (pr "convert:%s\n") (Modules_list.convert_modules ()); @@ -683,8 +696,8 @@ read the man page virt-v2v(1). output_format, output_alloc in { - compressed; debug_overlays; do_copy; in_place; network_map; - output_alloc; output_format; output_name; + bandwidth; compressed; debug_overlays; do_copy; in_place; + network_map; output_alloc; output_format; output_name; print_estimate; print_source; root_choice; ks = opthandle.ks; }, diff --git a/v2v/cmdline.mli b/v2v/cmdline.mli index 78601e191..1c9e6c258 100644 --- a/v2v/cmdline.mli +++ b/v2v/cmdline.mli @@ -19,6 +19,7 @@ (** Command line argument parsing. *) type cmdline = { + bandwidth : Types.bandwidth option; compressed : bool; debug_overlays : bool; do_copy : bool; diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml index 8321a2a8c..52f40a31b 100644 --- a/v2v/input_disk.ml +++ b/v2v/input_disk.ml @@ -36,7 +36,7 @@ class input_disk input_format disk = object | Some fmt -> " -if " ^ fmt) disk - method source () = + method source ?bandwidth () = (* Check the input file exists and is readable. *) Unix.access disk [Unix.R_OK]; diff --git a/v2v/input_libvirt_other.ml b/v2v/input_libvirt_other.ml index 5ff3cfc43..504c72600 100644 --- a/v2v/input_libvirt_other.ml +++ b/v2v/input_libvirt_other.ml @@ -58,10 +58,10 @@ class input_libvirt_other libvirt_conn guest = object (self) inherit input_libvirt libvirt_conn guest - method source () = + method source ?bandwidth () = debug "input_libvirt_other: source ()"; - let source, disks, _ = parse_libvirt_domain self#conn guest in + let source, disks, _ = parse_libvirt_domain ?bandwidth self#conn guest in let disks = List.map (fun { p_source_disk = disk } -> disk) disks in { source with s_disks = disks } end diff --git a/v2v/input_libvirt_other.mli b/v2v/input_libvirt_other.mli index d48987e46..1aac92ad6 100644 --- a/v2v/input_libvirt_other.mli +++ b/v2v/input_libvirt_other.mli @@ -23,7 +23,7 @@ val error_if_libvirt_does_not_support_json_backingfile : unit -> unit class virtual input_libvirt : Libvirt.rw Libvirt.Connect.t Lazy.t -> string -> object method precheck : unit -> unit method as_options : string - method virtual source : unit -> Types.source + method virtual source : ?bandwidth:Types.bandwidth -> unit -> Types.source method private conn : Libvirt.rw Libvirt.Connect.t end diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml index bfe5e8e9d..280febf98 100644 --- a/v2v/input_libvirt_vcenter_https.ml +++ b/v2v/input_libvirt_vcenter_https.ml @@ -41,7 +41,7 @@ object (self) method precheck () = error_if_libvirt_does_not_support_json_backingfile () - method source () = + method source ?bandwidth () = debug "input_libvirt_vcenter_https: source: server %s" server; (* Remove proxy environment variables so curl doesn't try to use @@ -56,7 +56,7 @@ object (self) unsetenv "ALL_PROXY"; unsetenv "NO_PROXY"; - let source, disks, xml = parse_libvirt_domain self#conn guest in + let source, disks, xml = parse_libvirt_domain ?bandwidth self#conn guest in (* Find the <vmware:datacenterpath> element from the XML. This * was added in libvirt >= 1.2.20. @@ -78,7 +78,7 @@ object (self) | { 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 ?password_file:input_password + VCenter.map_source ?bandwidth ?password_file:input_password dcPath parsed_uri server path in (* The libvirt ESX driver doesn't normally specify a format, but diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml index 1f54ee511..19b4166c7 100644 --- a/v2v/input_libvirt_vddk.ml +++ b/v2v/input_libvirt_vddk.ml @@ -113,8 +113,8 @@ object (self) super#as_options (* superclass prints "-i libvirt etc" *) pt_options - method source () = - let source, disks, xml = parse_libvirt_domain self#conn guest in + method source ?bandwidth () = + let source, disks, xml = parse_libvirt_domain ?bandwidth self#conn guest in (* Find the <vmware:moref> element from the XML. This was added * in libvirt >= 3.7 and is required. @@ -183,7 +183,7 @@ object (self) * directly in this form to VDDK. *) let nbdkit = - Nbdkit.create_vddk ?config ?cookie ?libdir ~moref + Nbdkit.create_vddk ?bandwidth ?config ?cookie ?libdir ~moref ?nfchostport ?password_file:input_password ?port ~server ?snapshot ~thumbprint ?transports ?user path in diff --git a/v2v/input_libvirt_xen_ssh.ml b/v2v/input_libvirt_xen_ssh.ml index 9a941d070..f5877b054 100644 --- a/v2v/input_libvirt_xen_ssh.ml +++ b/v2v/input_libvirt_xen_ssh.ml @@ -40,10 +40,10 @@ object (self) error_if_libvirt_does_not_support_json_backingfile (); error_if_no_ssh_agent () - method source () = + method source ?bandwidth () = debug "input_libvirt_xen_ssh: source: server %s" server; - let source, disks, _ = parse_libvirt_domain self#conn guest in + let source, disks, _ = parse_libvirt_domain ?bandwidth self#conn guest in let port = match parsed_uri.uri_port with @@ -61,7 +61,7 @@ object (self) disk | { p_source_disk = disk; p_source = P_source_dev path } | { p_source_disk = disk; p_source = P_source_file path } -> - let nbdkit = Nbdkit.create_ssh ~password:NoPassword + let nbdkit = Nbdkit.create_ssh ?bandwidth ~password:NoPassword ?port ~server ?user path in let qemu_uri = Nbdkit.run nbdkit in { disk with s_qemu_uri = qemu_uri } diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml index a44b41fce..efffb28b0 100644 --- a/v2v/input_libvirtxml.ml +++ b/v2v/input_libvirtxml.ml @@ -31,7 +31,7 @@ object method as_options = "-i libvirtxml " ^ file - method source () = + method source ?bandwidth () = let xml = read_whole_file file in let source, disks = parse_libvirt_xml xml in diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml index 6309ff9a5..872796137 100644 --- a/v2v/input_ova.ml +++ b/v2v/input_ova.ml @@ -75,7 +75,7 @@ class input_ova ova = object method as_options = "-i ova " ^ ova - method source () = + method source ?bandwidth () = (* Extract ova file. *) let ova_t = parse_ova ova in diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml index 0db1945ea..1a7b331ee 100644 --- a/v2v/input_vmx.ml +++ b/v2v/input_vmx.ml @@ -112,8 +112,9 @@ let remote_file_exists uri path = eprintf "%s\n%!" cmd; Sys.command cmd = 0 -let rec find_disks vmx vmx_source = - find_scsi_disks vmx vmx_source @ find_ide_disks vmx vmx_source +let rec find_disks ?bandwidth vmx vmx_source = + find_scsi_disks ?bandwidth vmx vmx_source + @ find_ide_disks ?bandwidth vmx vmx_source (* Find all SCSI hard disks. * @@ -123,7 +124,7 @@ let rec find_disks vmx vmx_source = * | omitted * scsi0:0.fileName = "guest.vmdk" *) -and find_scsi_disks vmx vmx_source = +and find_scsi_disks ?bandwidth vmx vmx_source = let get_scsi_controller_target ns = sscanf ns "scsi%d:%d" (fun c t -> c, t) in @@ -135,7 +136,7 @@ and find_scsi_disks vmx vmx_source = Some "scsi-harddisk"; None ] in let scsi_controller = Source_SCSI in - find_hdds vmx vmx_source + find_hdds ?bandwidth vmx vmx_source get_scsi_controller_target is_scsi_controller_target scsi_device_types scsi_controller @@ -145,7 +146,7 @@ and find_scsi_disks vmx vmx_source = * ide0:0.deviceType = "ata-hardDisk" * ide0:0.fileName = "guest.vmdk" *) -and find_ide_disks vmx vmx_source = +and find_ide_disks ?bandwidth vmx vmx_source = let get_ide_controller_target ns = sscanf ns "ide%d:%d" (fun c t -> c, t) in @@ -156,11 +157,11 @@ and find_ide_disks vmx vmx_source = let ide_device_types = [ Some "ata-harddisk" ] in let ide_controller = Source_IDE in - find_hdds vmx vmx_source + find_hdds ?bandwidth vmx vmx_source get_ide_controller_target is_ide_controller_target ide_device_types ide_controller -and find_hdds vmx vmx_source +and find_hdds ?bandwidth vmx vmx_source get_controller_target is_controller_target device_types controller = (* Find namespaces matching '(ide|scsi)X:Y' with suitable deviceType. *) @@ -186,7 +187,8 @@ and find_hdds vmx vmx_source match path, v with | [ns; "filename"], Some filename -> let c, t = get_controller_target ns in - let uri, format = qemu_uri_of_filename vmx_source filename in + let uri, format = qemu_uri_of_filename ?bandwidth + vmx_source filename in let s = { s_disk_id = (-1); s_qemu_uri = uri; s_format = Some format; s_controller = Some controller } in @@ -213,7 +215,7 @@ and find_hdds vmx vmx_source * This constructs a QEMU URI of the filename relative to the * vmx file (which might be remote over SSH). *) -and qemu_uri_of_filename vmx_source filename = +and qemu_uri_of_filename ?bandwidth vmx_source filename = match vmx_source with | File vmx_filename -> (* Always ensure this returns an absolute path to avoid @@ -240,7 +242,7 @@ and qemu_uri_of_filename vmx_source filename = let port = Option.map string_of_int (port_of_uri uri) in let user = uri.Xml.uri_user in - let nbdkit = Nbdkit.create_ssh ~password:NoPassword ~server + let nbdkit = Nbdkit.create_ssh ?bandwidth ~password:NoPassword ~server ?port ?user abs_path in let qemu_uri = Nbdkit.run nbdkit in qemu_uri, format @@ -392,7 +394,7 @@ object method as_options = "-i vmx " ^ arg - method source () = + method source ?bandwidth () = let vmx_source = vmx_source_of_arg input_transport arg in (* If the transport is SSH, fetch the file from remote, else @@ -486,7 +488,7 @@ object None | None -> None in - let disks = find_disks vmx vmx_source in + let disks = find_disks ?bandwidth vmx vmx_source in let removables = find_removables vmx in let nics = find_nics vmx in diff --git a/v2v/nbdkit.ml b/v2v/nbdkit.ml index b2d77f963..776eedce0 100644 --- a/v2v/nbdkit.ml +++ b/v2v/nbdkit.ml @@ -24,6 +24,7 @@ open Std_utils open Tools_utils open Unix_utils +open Types open Utils let nbdkit_min_version = (1, 12) @@ -88,7 +89,7 @@ let error_unless_nbdkit_compiled_with_selinux dump_config = error (f_"nbdkit was compiled without SELinux support. You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.") ) -let common_create plugin_name plugin_args plugin_env = +let common_create ?bandwidth plugin_name plugin_args plugin_env = error_unless_nbdkit_working (); (* Environment. We always add LANG=C. *) @@ -150,7 +151,24 @@ let common_create plugin_name plugin_args plugin_env = add_arg "--filter"; add_arg "readahead" ); - let args = get_args () @ [ plugin_name ] @ plugin_args in + (* Add the rate filter. *) + let rate_args = + if Sys.file_exists (filterdir // "nbdkit-rate-filter.so") then ( + match bandwidth with + | None -> [] + | Some bandwidth -> + add_arg "--filter"; add_arg "rate"; + match bandwidth with + | StaticBandwidth rate -> + [ "rate=" ^ rate ] + | DynamicBandwidth (None, filename) -> + [ "rate-file=" ^ filename ] + | DynamicBandwidth (Some rate, filename) -> + [ "rate=" ^ rate; "rate-file=" ^ filename ] + ) + else [] in + + let args = get_args () @ [ plugin_name ] @ plugin_args @ rate_args in { plugin_name; args; env; dump_config; dump_plugin; filterdir } @@ -160,7 +178,7 @@ let common_create plugin_name plugin_args plugin_env = let libNN = sprintf "lib%d" Sys.word_size (* Create an nbdkit module specialized for reading from VDDK sources. *) -let create_vddk ?config ?cookie ?libdir ~moref +let create_vddk ?bandwidth ?config ?cookie ?libdir ~moref ?nfchostport ?password_file ?port ~server ?snapshot ~thumbprint ?transports ?user path = (* Compute the LD_LIBRARY_PATH that we may have to pass to nbdkit. *) @@ -255,10 +273,10 @@ See also the virt-v2v-input-vmware(1) manual.") libNN add_arg (sprintf "thumbprint=%s" thumbprint); Option.may (fun s -> add_arg (sprintf "transports=%s" s)) transports; - common_create "vddk" (get_args ()) env + common_create ?bandwidth "vddk" (get_args ()) env (* Create an nbdkit module specialized for reading from SSH sources. *) -let create_ssh ~password ?port ~server ?user path = +let create_ssh ?bandwidth ~password ?port ~server ?user path = let add_arg, get_args = let args = ref [] in let add_arg a = List.push_front a args in @@ -276,10 +294,10 @@ let create_ssh ~password ?port ~server ?user path = ); add_arg (sprintf "path=%s" path); - common_create "ssh" (get_args ()) [] + common_create ?bandwidth "ssh" (get_args ()) [] (* Create an nbdkit module specialized for reading from Curl sources. *) -let create_curl ?cookie ~password ?(sslverify=true) ?user url = +let create_curl ?bandwidth ?cookie ~password ?(sslverify=true) ?user url = let add_arg, get_args = let args = ref [] in let add_arg a = List.push_front a args in @@ -299,7 +317,7 @@ let create_curl ?cookie ~password ?(sslverify=true) ?user url = if not sslverify then add_arg "sslverify=false"; add_arg (sprintf "url=%s" url); - common_create "curl" (get_args ()) [] + common_create ?bandwidth "curl" (get_args ()) [] let run { args; env } = (* Create a temporary directory where we place the sockets. *) diff --git a/v2v/nbdkit.mli b/v2v/nbdkit.mli index efbb62f98..627c78c11 100644 --- a/v2v/nbdkit.mli +++ b/v2v/nbdkit.mli @@ -20,7 +20,8 @@ type t -val create_vddk : ?config:string -> +val create_vddk : ?bandwidth:Types.bandwidth -> + ?config:string -> ?cookie:string -> ?libdir:string -> moref:string -> @@ -46,7 +47,8 @@ type password = | AskForPassword | PasswordFile of string -val create_ssh : password:password -> +val create_ssh : ?bandwidth:Types.bandwidth -> + password:password -> ?port:string -> server:string -> ?user:string -> @@ -59,7 +61,8 @@ val create_ssh : password:password -> Note this doesn't run nbdkit yet, it just creates the object. *) -val create_curl : ?cookie:string -> +val create_curl : ?bandwidth:Types.bandwidth -> + ?cookie:string -> password:password -> ?sslverify:bool -> ?user:string -> diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml index 97d8a5cd8..86990aeb3 100644 --- a/v2v/parse_libvirt_xml.ml +++ b/v2v/parse_libvirt_xml.ml @@ -46,7 +46,7 @@ let get_drive_slot str offset = warning (f_"could not parse device name ‘%s’ from the source libvirt XML") str; None -let parse_libvirt_xml ?conn xml = +let parse_libvirt_xml ?bandwidth ?conn xml = debug "libvirt xml is:\n%s" xml; (* Create a default libvirt connection on request, to not open one @@ -319,7 +319,8 @@ let parse_libvirt_xml ?conn xml = | _, Some port -> invalid_arg "invalid port number in libvirt XML" in sprintf "%s://%s%s%s" driver host port (uri_quote path) in - let nbdkit = Nbdkit.create_curl ~password:NoPassword url in + let nbdkit = Nbdkit.create_curl ?bandwidth ~password:NoPassword + url in let qemu_uri = Nbdkit.run nbdkit in add_disk qemu_uri format controller P_dont_rewrite | Some protocol, _, _ -> @@ -537,9 +538,9 @@ let parse_libvirt_xml ?conn xml = }, disks) -let parse_libvirt_domain conn guest = +let parse_libvirt_domain ?bandwidth conn guest = let dom = Libvirt_utils.get_domain conn guest in (* Use XmlSecure to get passwords (RHBZ#1174123). *) let xml = Libvirt.Domain.get_xml_desc_flags dom [Libvirt.Domain.XmlSecure] in - let source, disks = parse_libvirt_xml ~conn xml in + let source, disks = parse_libvirt_xml ?bandwidth ~conn xml in source, disks, xml diff --git a/v2v/parse_libvirt_xml.mli b/v2v/parse_libvirt_xml.mli index 2d81e0d99..658ebc5eb 100644 --- a/v2v/parse_libvirt_xml.mli +++ b/v2v/parse_libvirt_xml.mli @@ -27,7 +27,7 @@ and parsed_source = | P_source_file of string (** <source file> *) | P_dont_rewrite (** s_qemu_uri is already set. *) -val parse_libvirt_domain : Libvirt.rw Libvirt.Connect.t -> string -> Types.source * parsed_disk list * string +val parse_libvirt_domain : ?bandwidth:Types.bandwidth -> Libvirt.rw Libvirt.Connect.t -> string -> Types.source * parsed_disk list * string (** [parse_libvirt_domain conn dom] loads the XML of the domain [dom] from the libvirt connection [conn]. The result is a tuple with a {!Types.source} structure, a list of @@ -36,7 +36,7 @@ val parse_libvirt_domain : Libvirt.rw Libvirt.Connect.t -> string -> Types.sourc {b Note} the [source.s_disks] field is an empty list. The caller must map over the parsed disks and update the [source.s_disks] field. *) -val parse_libvirt_xml : ?conn:Libvirt.rw Libvirt.Connect.t -> string -> Types.source * parsed_disk list +val parse_libvirt_xml : ?bandwidth:Types.bandwidth -> ?conn:Libvirt.rw Libvirt.Connect.t -> string -> Types.source * parsed_disk list (** Take libvirt XML and parse it into a {!Types.source} structure and a list of source disks. diff --git a/v2v/types.ml b/v2v/types.ml index 1100dd2a6..d406caeb9 100644 --- a/v2v/types.ml +++ b/v2v/types.ml @@ -506,10 +506,14 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string type output_allocation = Sparse | Preallocated +type bandwidth = +| StaticBandwidth of string +| DynamicBandwidth of string option * string + class virtual input = object method precheck () = () method virtual as_options : string - method virtual source : unit -> source + method virtual source : ?bandwidth:bandwidth -> unit -> source end class virtual output = object diff --git a/v2v/types.mli b/v2v/types.mli index d605b1ad4..556f6930f 100644 --- a/v2v/types.mli +++ b/v2v/types.mli @@ -361,6 +361,11 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string type output_allocation = Sparse | Preallocated (** Type of [-oa] (output allocation) option. *) +type bandwidth = +| StaticBandwidth of string +| DynamicBandwidth of string option * string +(** [--bandwidth] and [--bandwidth-file] options. *) + (** {2 Input object} This is subclassed for the various input [-i] options. @@ -398,7 +403,7 @@ class virtual input : object method virtual as_options : string (** Converts the input object back to the equivalent command line options. This is just used for pretty-printing log messages. *) - method virtual source : unit -> source + method virtual source : ?bandwidth:bandwidth -> unit -> source (** Examine the source hypervisor and create a source struct. *) end (** Encapsulates all [-i], etc input arguments as an object. *) diff --git a/v2v/v2v.ml b/v2v/v2v.ml index afe46cd9b..e4b4dfe37 100644 --- a/v2v/v2v.ml +++ b/v2v/v2v.ml @@ -198,7 +198,8 @@ let rec main () = and open_source cmdline input = message (f_"Opening the source %s") input#as_options; - let source = input#source () in + let bandwidth = cmdline.bandwidth in + let source = input#source ?bandwidth () in (* Print source and stop. *) if cmdline.print_source then ( diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml index 2563ad0ed..89c5579b9 100644 --- a/v2v/vCenter.ml +++ b/v2v/vCenter.ml @@ -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 ?password_file dcPath uri server path = +let rec map_source ?bandwidth ?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. *) @@ -78,7 +78,7 @@ let rec map_source ?password_file dcPath uri server path = | Some password_file -> Nbdkit.PasswordFile password_file in let nbdkit = - Nbdkit.create_curl ?cookie:session_cookie ~password ~sslverify + Nbdkit.create_curl ?bandwidth ?cookie:session_cookie ~password ~sslverify https_url in let qemu_uri = Nbdkit.run nbdkit in diff --git a/v2v/vCenter.mli b/v2v/vCenter.mli index d72d5686e..5620cad45 100644 --- a/v2v/vCenter.mli +++ b/v2v/vCenter.mli @@ -54,7 +54,8 @@ type remote_resource = { (** The "remote resource" is the structure returned by the {!map_source} function. *) -val map_source : ?password_file:string -> string -> Xml.uri -> string -> string -> remote_resource +val map_source : ?bandwidth:Types.bandwidth -> ?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, diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod index 9a555c3be..8ba141be9 100644 --- a/v2v/virt-v2v.pod +++ b/v2v/virt-v2v.pod @@ -155,6 +155,50 @@ qemu, do: Display help. +=item B<--bandwidth> bps + +=item B<--bandwidth-file> filename + +Some input methods are able to limit the network bandwidth they will +use statically or dynamically. In the first variant this sets the +bandwidth limit statically in bits per second. Formats like C<10M> +may be used (meaning 10 megabits per second). + +In the second variant the bandwidth is limited dynamically from the +content of the file (also in bits per second, in the same formats +supported by the first variant). You may use both parameters +together, meaning: first limit to a static rate, then you can create +the file while virt-v2v is running to adjust the rate dynamically. + +This is only supported for: + +=over 4 + +=item * + +L<input from Xen|virt-v2v-input-xen(1)> + +=item * + +L<input from VMware VMX|virt-v2v-input-vmware(1)/INPUT FROM VMWARE VMX> +when using the SSH transport method + +=item * + +L<input from VDDK|virt-v2v-input-vmware(1)/INPUT FROM VDDK> + +=item * + +I<-i libvirtxml> when using HTTP or HTTPS disks + +=item * + +L<input from VMware vCenter server|virt-v2v-input-vmware(1)/INPUT FROM VMWARE VCENTER SERVER> + +=back + +The options are silently ignored for other input methods. + =item B<-b> ... =item B<--bridge> ... -- 2.23.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs