In in-place mode, the decisions on which interfaces to use are made and
the source VM configuration is created by the outside entity. So in
that case v2v needs to look it up in the source configuraion, and try to
follow.
For that, the source VM configuration is used to populate requested caps
object which is then passed to the convert routine.
It's assumed that the configuration has exactly one type of storage
devices and no more than one type of network and video adapters;
anything else is rejected.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
Notes:
v3:
- assume that source config in --in-place mode can't have more than one
storage, network, and video types
v2:
- accept catch-all variants of source net and video as no preference
v2v/types.mli | 4 +++-
v2v/v2v.ml | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/v2v/types.mli b/v2v/types.mli
index 0e40668..4595a1f 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -120,8 +120,10 @@ and source_sound_model =
val string_of_source : source -> string
val string_of_source_disk : source_disk -> string
-
+val string_of_controller : s_controller -> string
+val string_of_nic_model : s_nic_model -> string
val string_of_source_sound_model : source_sound_model -> string
+val string_of_source_video : source_video -> string
val string_of_source_hypervisor : source_hypervisor -> string
val source_hypervisor_of_string : string -> source_hypervisor
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index c828e48..9bf0afe 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -82,11 +82,16 @@ let rec main () =
);
let keep_serial_console = output#keep_serial_console in
- let rcaps = {
- rcaps_block_bus = None;
- rcaps_net_bus = None;
- rcaps_video = None;
- } in
+ let rcaps =
+ match conversion_mode with
+ | Copying _ ->
+ {
+ rcaps_block_bus = None;
+ rcaps_net_bus = None;
+ rcaps_video = None;
+ }
+ | In_place ->
+ rcaps_from_source source in
let guestcaps = do_convert g inspect source keep_serial_console rcaps in
g#umount_all ();
@@ -974,4 +979,52 @@ and preserve_overlays overlays src_name =
printf (f_"Overlay saved as %s [--debug-overlays]\n") saved_filename
) overlays
+and rcaps_from_source source =
+ (* Request guest caps based on source configuration. *)
+
+ let source_block_types =
+ List.map (fun sd -> sd.s_controller) source.s_disks in
+ let source_block_type =
+ match List.sort_uniq compare source_block_types with
+ | [] -> error (f_"source has no hard disks!")
+ | [t] -> t
+ | _ -> error (f_"source has multiple hard disk types!") in
+ let block_type =
+ match source_block_type with
+ | Some Source_virtio_blk -> Some Virtio_blk
+ | Some Source_IDE -> Some IDE
+ | Some t -> error (f_"source has unsupported hard disk type
'%s'")
+ (string_of_controller t)
+ | None -> error (f_"source has unrecognized hard disk type") in
+
+ let source_net_types =
+ List.map (fun nic -> nic.s_nic_model) source.s_nics in
+ let source_net_type =
+ match List.sort_uniq compare source_net_types with
+ | [] -> None
+ | [t] -> t
+ | _ -> error (f_"source has multiple network adapter model!") in
+ let net_type =
+ match source_net_type with
+ | Some Source_virtio_net -> Some Virtio_net
+ | Some Source_e1000 -> Some E1000
+ | Some Source_rtl8139 -> Some RTL8139
+ | Some t -> error (f_"source has unsupported network adapter model
'%s'")
+ (string_of_nic_model t)
+ | None -> None in
+
+ let video =
+ match source.s_video with
+ | Some Source_QXL -> Some QXL
+ | Some Source_Cirrus -> Some Cirrus
+ | Some t -> error (f_"source has unsupported video adapter model
'%s'")
+ (string_of_source_video t)
+ | None -> None in
+
+ {
+ rcaps_block_bus = block_type;
+ rcaps_net_bus = net_type;
+ rcaps_video = video;
+ }
+
let () = run_main_and_handle_errors main
--
2.5.0