Blame SOURCES/0050-v2v-Don-t-use-target-dev-attribute-use-target-bus-in.patch

0d20ef
From 645d7534bdd8947e22126f6033dbd329f1f9c59e Mon Sep 17 00:00:00 2001
0d20ef
From: "Richard W.M. Jones" <rjones@redhat.com>
0d20ef
Date: Tue, 18 Nov 2014 13:07:42 +0000
0d20ef
Subject: [PATCH] v2v: Don't use <target dev> attribute, use <target bus>
0d20ef
 instead.
0d20ef
0d20ef
The <target dev> attribute in libvirt isn't very informative.  What we
0d20ef
really want to know is whether the source disk used IDE or SCSI, as
0d20ef
that allows us to remap block devices accurately during conversion.
0d20ef
For example, if the source was IDE and RHEL 5, and after conversion
0d20ef
virtio will be supported, then we know that we need to remap
0d20ef
"/dev/hda" to "/dev/vda".
0d20ef
0d20ef
Drop the s_target_dev and s_removable_target_dev fields and replace
0d20ef
them with s_controller and s_removable_controller.
0d20ef
0d20ef
For -i libvirt, use the <target bus> attribute to get this information.
0d20ef
0d20ef
For -i ova, use the OVF disk controller's ResourceType.
0d20ef
(http://blogs.vmware.com/vapp/2009/11/virtual-hardware-in-ovf-part-1.html)
0d20ef
0d20ef
(cherry picked from commit 9ebc12572317efe5c1ae83fcb61c7767dec40203)
0d20ef
---
0d20ef
 p2v/conversion.c                      |  1 +
0d20ef
 v2v/convert_linux.ml                  | 43 ++++++++++++++++------------
0d20ef
 v2v/input_disk.ml                     |  2 +-
0d20ef
 v2v/input_libvirtxml.ml               | 34 ++++++++++++++--------
0d20ef
 v2v/input_ova.ml                      | 54 +++++++++++++++++++----------------
0d20ef
 v2v/output_libvirt.ml                 |  2 +-
0d20ef
 v2v/test-v2v-i-ova-gz.expected        |  4 +--
0d20ef
 v2v/test-v2v-i-ova-two-disks.expected |  6 ++--
0d20ef
 v2v/test-v2v-i-ova-zip.expected       |  4 +--
0d20ef
 v2v/test-v2v-print-source.sh          |  2 +-
0d20ef
 v2v/types.ml                          | 22 ++++++++------
0d20ef
 v2v/types.mli                         | 11 +++++--
0d20ef
 12 files changed, 111 insertions(+), 74 deletions(-)
0d20ef
0d20ef
diff --git a/p2v/conversion.c b/p2v/conversion.c
0d20ef
index 26074b6..6f414de 100644
0d20ef
--- a/p2v/conversion.c
0d20ef
+++ b/p2v/conversion.c
0d20ef
@@ -561,6 +561,7 @@ generate_libvirt_xml (struct config *config, struct data_conn *data_conns)
0d20ef
           } end_element ();
0d20ef
           start_element ("target") {
0d20ef
             attribute ("dev", target_dev);
0d20ef
+            /* XXX Need to set bus to "ide" or "scsi" here. */
0d20ef
           } end_element ();
0d20ef
         } end_element ();
0d20ef
       }
0d20ef
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
0d20ef
index b6335d9..48f351c 100644
0d20ef
--- a/v2v/convert_linux.ml
0d20ef
+++ b/v2v/convert_linux.ml
0d20ef
@@ -1219,26 +1219,33 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
0d20ef
      * particular it assumes all non-removable source disks will be
0d20ef
      * added to the target in the order they appear in the libvirt XML.
0d20ef
      *)
0d20ef
-    let block_prefix =
0d20ef
-      if virtio then "vd"
0d20ef
-      else
0d20ef
-        match family, inspect.i_major_version with
0d20ef
-        | `RHEL_family, v when v < 5 ->
0d20ef
-          (* RHEL < 5 used old ide driver *) "hd"
0d20ef
-        | `RHEL_family, 5 ->
0d20ef
-          (* RHEL 5 uses libata, but udev still uses: *) "hd"
0d20ef
-        | `SUSE_family, _ ->
0d20ef
-          (* SUSE uses libata, but still presents IDE disks as: *) "hd"
0d20ef
-        | _, _ ->
0d20ef
-          (* All modern distros use libata: *) "sd" in
0d20ef
+    let ide_block_prefix =
0d20ef
+      match family, inspect.i_major_version with
0d20ef
+      | `RHEL_family, v when v < 5 ->
0d20ef
+        (* RHEL < 5 used old ide driver *) "hd"
0d20ef
+      | `RHEL_family, 5 ->
0d20ef
+        (* RHEL 5 uses libata, but udev still uses: *) "hd"
0d20ef
+      | `SUSE_family, _ ->
0d20ef
+        (* SUSE uses libata, but still presents IDE disks as: *) "hd"
0d20ef
+      | _, _ ->
0d20ef
+        (* All modern distros use libata: *) "sd" in
0d20ef
+
0d20ef
+    let block_prefix_after_conversion =
0d20ef
+      if virtio then "vd" else ide_block_prefix in
0d20ef
+
0d20ef
     let map =
0d20ef
       mapi (
0d20ef
         fun i disk ->
0d20ef
-          let source_dev =
0d20ef
-            match disk.s_target_dev with (* target/@dev in _source_ HV *)
0d20ef
-            | Some dev -> dev
0d20ef
-            | None -> (* ummm, what? *) block_prefix ^ drive_name i in
0d20ef
-          let target_dev = block_prefix ^ drive_name i in
0d20ef
+          let block_prefix_before_conversion =
0d20ef
+            match disk.s_controller with
0d20ef
+            | Some `IDE -> ide_block_prefix
0d20ef
+            | Some `SCSI -> "sd"
0d20ef
+            | Some `Virtio_blk -> "vd"
0d20ef
+            | None ->
0d20ef
+              (* This is basically a guess.  It assumes the source used IDE. *)
0d20ef
+              ide_block_prefix in
0d20ef
+          let source_dev = block_prefix_before_conversion ^ drive_name i in
0d20ef
+          let target_dev = block_prefix_after_conversion ^ drive_name i in
0d20ef
           source_dev, target_dev
0d20ef
       ) source.s_disks in
0d20ef
 
0d20ef
@@ -1253,7 +1260,7 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
0d20ef
     let map = map @
0d20ef
       mapi (
0d20ef
         fun i disk ->
0d20ef
-          "xvd" ^ drive_name i, block_prefix ^ drive_name i
0d20ef
+          "xvd" ^ drive_name i, block_prefix_after_conversion ^ drive_name i
0d20ef
       ) source.s_disks in
0d20ef
 
0d20ef
     (* Possible Augeas paths to search for device names. *)
0d20ef
diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml
0d20ef
index ef28b43..8393786 100644
0d20ef
--- a/v2v/input_disk.ml
0d20ef
+++ b/v2v/input_disk.ml
0d20ef
@@ -69,7 +69,7 @@ class input_disk verbose input_format disk = object
0d20ef
       s_disk_id = 0;
0d20ef
       s_qemu_uri = disk_absolute;
0d20ef
       s_format = Some format;
0d20ef
-      s_target_dev = None;
0d20ef
+      s_controller = None;
0d20ef
     } in
0d20ef
 
0d20ef
     (* Give the guest a simple generic network interface. *)
0d20ef
diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
0d20ef
index f302b2c..d1146f9 100644
0d20ef
--- a/v2v/input_libvirtxml.ml
0d20ef
+++ b/v2v/input_libvirtxml.ml
0d20ef
@@ -114,12 +114,12 @@ let parse_libvirt_xml ~verbose xml =
0d20ef
     let get_disks, add_disk =
0d20ef
       let disks = ref [] and i = ref 0 in
0d20ef
       let get_disks () = List.rev !disks in
0d20ef
-      let add_disk qemu_uri format target_dev p_source =
0d20ef
+      let add_disk qemu_uri format controller p_source =
0d20ef
         incr i;
0d20ef
         disks :=
0d20ef
           { p_source_disk = { s_disk_id = !i;
0d20ef
                               s_qemu_uri = qemu_uri; s_format = format;
0d20ef
-                              s_target_dev = target_dev };
0d20ef
+                              s_controller = controller };
0d20ef
             p_source = p_source } :: !disks
0d20ef
       in
0d20ef
       get_disks, add_disk
0d20ef
@@ -134,9 +134,14 @@ let parse_libvirt_xml ~verbose xml =
0d20ef
       let node = Xml.xpathobj_node doc obj i in
0d20ef
       Xml.xpathctx_set_current_context xpathctx node;
0d20ef
 
0d20ef
-      let target_dev =
0d20ef
-        let target_dev = xpath_to_string "target/@dev" "" in
0d20ef
-        if target_dev <> "" then Some target_dev else None in
0d20ef
+      let controller =
0d20ef
+        let target_bus = xpath_to_string "target/@bus" "" in
0d20ef
+        match target_bus with
0d20ef
+        | "" -> None
0d20ef
+        | "ide" -> Some `IDE
0d20ef
+        | "scsi" -> Some `SCSI
0d20ef
+        | "virtio" -> Some `Virtio_blk
0d20ef
+        | _ -> None in
0d20ef
 
0d20ef
       let format =
0d20ef
         match xpath_to_string "driver/@type" "" with
0d20ef
@@ -151,11 +156,11 @@ let parse_libvirt_xml ~verbose xml =
0d20ef
       | "block" ->
0d20ef
         let path = xpath_to_string "source/@dev" "" in
0d20ef
         if path <> "" then
0d20ef
-          add_disk path format target_dev (P_source_dev path)
0d20ef
+          add_disk path format controller (P_source_dev path)
0d20ef
       | "file" ->
0d20ef
         let path = xpath_to_string "source/@file" "" in
0d20ef
         if path <> "" then
0d20ef
-          add_disk path format target_dev (P_source_file path)
0d20ef
+          add_disk path format controller (P_source_file path)
0d20ef
       | "network" ->
0d20ef
         (* We only handle <source protocol="nbd"> here, and that is
0d20ef
          * intended only for virt-p2v.  Any other network disk is
0d20ef
@@ -170,7 +175,7 @@ let parse_libvirt_xml ~verbose xml =
0d20ef
              * XXX Quoting, although it's not needed for virt-p2v.
0d20ef
              *)
0d20ef
             let path = sprintf "nbd:%s:%d" host port in
0d20ef
-            add_disk path format target_dev P_dont_rewrite
0d20ef
+            add_disk path format controller P_dont_rewrite
0d20ef
           )
0d20ef
         | "" -> ()
0d20ef
         | protocol ->
0d20ef
@@ -193,9 +198,14 @@ let parse_libvirt_xml ~verbose xml =
0d20ef
       let node = Xml.xpathobj_node doc obj i in
0d20ef
       Xml.xpathctx_set_current_context xpathctx node;
0d20ef
 
0d20ef
-      let target_dev =
0d20ef
-        let target_dev = xpath_to_string "target/@dev" "" in
0d20ef
-        if target_dev <> "" then Some target_dev else None in
0d20ef
+      let controller =
0d20ef
+        let target_bus = xpath_to_string "target/@bus" "" in
0d20ef
+        match target_bus with
0d20ef
+        | "" -> None
0d20ef
+        | "ide" -> Some `IDE
0d20ef
+        | "scsi" -> Some `SCSI
0d20ef
+        | "virtio" -> Some `Virtio_blk
0d20ef
+        | _ -> None in
0d20ef
 
0d20ef
       let typ =
0d20ef
         match xpath_to_string "@device" "" with
0d20ef
@@ -204,7 +214,7 @@ let parse_libvirt_xml ~verbose xml =
0d20ef
         | _ -> assert false (* libxml2 error? *) in
0d20ef
 
0d20ef
       let disk =
0d20ef
-        { s_removable_type = typ; s_removable_target_dev = target_dev } in
0d20ef
+        { s_removable_type = typ; s_removable_controller = controller } in
0d20ef
       disks := disk :: !disks
0d20ef
     done;
0d20ef
     List.rev !disks in
0d20ef
diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml
0d20ef
index 836b24e..fe71039 100644
0d20ef
--- a/v2v/input_ova.ml
0d20ef
+++ b/v2v/input_ova.ml
0d20ef
@@ -160,6 +160,24 @@ object
0d20ef
     (* Search for number of vCPUs. *)
0d20ef
     let vcpu = xpath_to_int "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType/text()=3]/rasd:VirtualQuantity/text()" 1 in
0d20ef
 
0d20ef
+    (* Helper function to return the parent controller of a disk. *)
0d20ef
+    let parent_controller id =
0d20ef
+      let expr = sprintf "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:InstanceID/text()=%d]/rasd:ResourceType/text()" id in
0d20ef
+      let controller = xpath_to_int expr 0 in
0d20ef
+
0d20ef
+      (* 6: iscsi controller, 5: ide *)
0d20ef
+      match controller with
0d20ef
+      | 6 -> Some `SCSI
0d20ef
+      | 5 -> Some `IDE
0d20ef
+      | 0 ->
0d20ef
+        warning ~prog (f_"ova hard disk has no parent controller, please report this as a bug supplying the *.ovf file extracted from the ova");
0d20ef
+        None
0d20ef
+      | _ ->
0d20ef
+        warning ~prog (f_"ova hard disk has an unknown VMware controller type (%d), please report this as a bug supplying the *.ovf file extracted from the ova")
0d20ef
+          controller;
0d20ef
+        None
0d20ef
+    in
0d20ef
+
0d20ef
     (* Hard disks (ResourceType = 17). *)
0d20ef
     let disks = ref [] in
0d20ef
     let () =
0d20ef
@@ -169,20 +187,14 @@ object
0d20ef
       for i = 0 to nr_nodes-1 do
0d20ef
         let n = Xml.xpathobj_node doc obj i in
0d20ef
         Xml.xpathctx_set_current_context xpathctx n;
0d20ef
-        let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
0d20ef
         let parent_id = xpath_to_int "rasd:Parent/text()" 0 in
0d20ef
 
0d20ef
-        (* Find the parent controller. *)
0d20ef
-        let expr = sprintf "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:InstanceID/text()=%d]/rasd:ResourceType/text()" parent_id in
0d20ef
-        let controller = xpath_to_int expr 0 in
0d20ef
-
0d20ef
-        (* 6: iscsi controller, 5: ide. assuming scsi or ide *)
0d20ef
-        let target_dev =
0d20ef
-          match controller with
0d20ef
-          | 6 -> "sd"
0d20ef
-          | 0 | 5 | _ (* XXX floppy should be 'fd'? *) -> "hd" in
0d20ef
+        (* XXX We assume the OVF lists these in order.
0d20ef
+        let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
0d20ef
+        *)
0d20ef
 
0d20ef
-        let target_dev = target_dev ^ drive_name address in
0d20ef
+        (* Find the parent controller. *)
0d20ef
+        let controller = parent_controller parent_id in
0d20ef
 
0d20ef
         Xml.xpathctx_set_current_context xpathctx n;
0d20ef
         let file_id = xpath_to_string "rasd:HostResource/text()" "" in
0d20ef
@@ -220,7 +232,7 @@ object
0d20ef
             s_disk_id = i;
0d20ef
             s_qemu_uri = filename;
0d20ef
             s_format = Some "vmdk";
0d20ef
-            s_target_dev = Some target_dev;
0d20ef
+            s_controller = controller;
0d20ef
           } in
0d20ef
           disks := disk :: !disks;
0d20ef
         ) else
0d20ef
@@ -243,20 +255,14 @@ object
0d20ef
         Xml.xpathctx_set_current_context xpathctx n;
0d20ef
         let id = xpath_to_int "rasd:ResourceType/text()" 0 in
0d20ef
         assert (id = 14 || id = 15 || id = 16);
0d20ef
-        let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
0d20ef
         let parent_id = xpath_to_int "rasd:Parent/text()" 0 in
0d20ef
 
0d20ef
-        (* Find the parent controller. *)
0d20ef
-        let expr = sprintf "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:InstanceID/text()=%d]/rasd:ResourceType/text()" parent_id in
0d20ef
-        let controller = xpath_to_int expr 0 in
0d20ef
-
0d20ef
-        (* 6: iscsi controller, 5: ide. assuming scsi or ide *)
0d20ef
-        let target_dev =
0d20ef
-          match controller with
0d20ef
-          | 6 -> "sd"
0d20ef
-          | 0 | 5 | _ (* XXX floppy should be 'fd'? *) -> "hd" in
0d20ef
+        (* XXX We assume the OVF lists these in order.
0d20ef
+        let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
0d20ef
+        *)
0d20ef
 
0d20ef
-        let target_dev = target_dev ^ drive_name address in
0d20ef
+        (* Find the parent controller. *)
0d20ef
+        let controller = parent_controller parent_id in
0d20ef
 
0d20ef
         let typ =
0d20ef
           match id with
0d20ef
@@ -265,7 +271,7 @@ object
0d20ef
             | _ -> assert false in
0d20ef
         let disk = {
0d20ef
           s_removable_type = typ;
0d20ef
-          s_removable_target_dev = Some target_dev
0d20ef
+          s_removable_controller = controller;
0d20ef
         } in
0d20ef
         removables := disk :: !removables;
0d20ef
       done in
0d20ef
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
0d20ef
index 386d777..a27d3e5 100644
0d20ef
--- a/v2v/output_libvirt.ml
0d20ef
+++ b/v2v/output_libvirt.ml
0d20ef
@@ -146,7 +146,7 @@ let create_libvirt_xml ?pool source targets guestcaps target_features =
0d20ef
   let removables =
0d20ef
     (* CDs will be added as IDE devices if we're using virtio, else
0d20ef
      * they will be added as the same as the disk bus.  The original
0d20ef
-     * s_removable_target_dev is ignored (same as old virt-v2v).
0d20ef
+     * s_removable_controller is ignored (same as old virt-v2v).
0d20ef
      *)
0d20ef
     let cdrom_bus, cdrom_block_prefix, cdrom_index =
0d20ef
       match guestcaps.gcaps_block_bus with
0d20ef
diff --git a/v2v/test-v2v-i-ova-gz.expected b/v2v/test-v2v-i-ova-gz.expected
0d20ef
index 7631534..e605afa 100644
0d20ef
--- a/v2v/test-v2v-i-ova-gz.expected
0d20ef
+++ b/v2v/test-v2v-i-ova-gz.expected
0d20ef
@@ -7,9 +7,9 @@ hypervisor type: vmware
0d20ef
    CPU features: 
0d20ef
         display: 
0d20ef
 disks:
0d20ef
-	.vmdk (vmdk) [hda]
0d20ef
+	.vmdk (vmdk) [scsi]
0d20ef
 removable media:
0d20ef
-	CD-ROM [hda]
0d20ef
+	CD-ROM [ide]
0d20ef
 NICs:
0d20ef
 	Network "Network adapter 1"
0d20ef
 
0d20ef
diff --git a/v2v/test-v2v-i-ova-two-disks.expected b/v2v/test-v2v-i-ova-two-disks.expected
0d20ef
index f2200d7..cd31898 100644
0d20ef
--- a/v2v/test-v2v-i-ova-two-disks.expected
0d20ef
+++ b/v2v/test-v2v-i-ova-two-disks.expected
0d20ef
@@ -7,10 +7,10 @@ hypervisor type: vmware
0d20ef
    CPU features: 
0d20ef
         display: 
0d20ef
 disks:
0d20ef
-	disk1.vmdk (vmdk) [hda]
0d20ef
-	disk2.vmdk (vmdk) [hdb]
0d20ef
+	disk1.vmdk (vmdk) [scsi]
0d20ef
+	disk2.vmdk (vmdk) [scsi]
0d20ef
 removable media:
0d20ef
-	CD-ROM [hda]
0d20ef
+	CD-ROM [ide]
0d20ef
 NICs:
0d20ef
 	Network "Network adapter 1"
0d20ef
 
0d20ef
diff --git a/v2v/test-v2v-i-ova-zip.expected b/v2v/test-v2v-i-ova-zip.expected
0d20ef
index a835f00..8b3d62c 100644
0d20ef
--- a/v2v/test-v2v-i-ova-zip.expected
0d20ef
+++ b/v2v/test-v2v-i-ova-zip.expected
0d20ef
@@ -7,9 +7,9 @@ hypervisor type: vmware
0d20ef
    CPU features: 
0d20ef
         display: 
0d20ef
 disks:
0d20ef
-	disk1.vmdk (vmdk) [hda]
0d20ef
+	disk1.vmdk (vmdk) [scsi]
0d20ef
 removable media:
0d20ef
-	CD-ROM [hda]
0d20ef
+	CD-ROM [ide]
0d20ef
 NICs:
0d20ef
 	Network "Network adapter 1"
0d20ef
 
0d20ef
diff --git a/v2v/test-v2v-print-source.sh b/v2v/test-v2v-print-source.sh
0d20ef
index 82b2550..cd32db9 100755
0d20ef
--- a/v2v/test-v2v-print-source.sh
0d20ef
+++ b/v2v/test-v2v-print-source.sh
0d20ef
@@ -60,7 +60,7 @@ hypervisor type: test
0d20ef
    CPU features: 
0d20ef
         display: 
0d20ef
 disks:
0d20ef
-	/windows.img (raw) [vda]
0d20ef
+	/windows.img (raw) [virtio]
0d20ef
 removable media:
0d20ef
 NICs:" ]; then
0d20ef
     echo "$0: unexpected output from test:"
0d20ef
diff --git a/v2v/types.ml b/v2v/types.ml
0d20ef
index c5a05f6..28d62fc 100644
0d20ef
--- a/v2v/types.ml
0d20ef
+++ b/v2v/types.ml
0d20ef
@@ -36,11 +36,12 @@ and source_disk = {
0d20ef
   s_disk_id : int;
0d20ef
   s_qemu_uri : string;
0d20ef
   s_format : string option;
0d20ef
-  s_target_dev : string option;
0d20ef
+  s_controller : s_controller option;
0d20ef
 }
0d20ef
+and s_controller = [`IDE | `SCSI | `Virtio_blk]
0d20ef
 and source_removable = {
0d20ef
   s_removable_type : [`CDROM|`Floppy];
0d20ef
-  s_removable_target_dev : string option;
0d20ef
+  s_removable_controller : s_controller option;
0d20ef
 }
0d20ef
 and source_nic = {
0d20ef
   s_mac : string option;
0d20ef
@@ -82,23 +83,28 @@ NICs:
0d20ef
     (String.concat "\n" (List.map string_of_source_nic s.s_nics))
0d20ef
 
0d20ef
 and string_of_source_disk { s_qemu_uri = qemu_uri; s_format = format;
0d20ef
-                            s_target_dev = target_dev } =
0d20ef
+                            s_controller = controller } =
0d20ef
   sprintf "\t%s%s%s"
0d20ef
     qemu_uri
0d20ef
     (match format with
0d20ef
     | None -> ""
0d20ef
     | Some format -> " (" ^ format ^ ")")
0d20ef
-    (match target_dev with
0d20ef
+    (match controller with
0d20ef
     | None -> ""
0d20ef
-    | Some target_dev -> " [" ^ target_dev ^ "]")
0d20ef
+    | Some controller -> " [" ^ string_of_controller controller ^ "]")
0d20ef
+
0d20ef
+and string_of_controller = function
0d20ef
+  | `IDE -> "ide"
0d20ef
+  | `SCSI -> "scsi"
0d20ef
+  | `Virtio_blk -> "virtio"
0d20ef
 
0d20ef
 and string_of_source_removable { s_removable_type = typ;
0d20ef
-                                 s_removable_target_dev = target_dev } =
0d20ef
+                                 s_removable_controller = controller } =
0d20ef
   sprintf "\t%s%s"
0d20ef
     (match typ with `CDROM -> "CD-ROM" | `Floppy -> "Floppy")
0d20ef
-    (match target_dev with
0d20ef
+    (match controller with
0d20ef
     | None -> ""
0d20ef
-    | Some target_dev -> " [" ^ target_dev ^ "]")
0d20ef
+    | Some controller -> " [" ^ string_of_controller controller ^ "]")
0d20ef
 
0d20ef
 and string_of_source_nic { s_mac = mac; s_vnet = vnet; s_vnet_type = typ } =
0d20ef
   sprintf "\t%s \"%s\"%s"
0d20ef
diff --git a/v2v/types.mli b/v2v/types.mli
0d20ef
index 2123a41..07eec98 100644
0d20ef
--- a/v2v/types.mli
0d20ef
+++ b/v2v/types.mli
0d20ef
@@ -38,13 +38,20 @@ and source_disk = {
0d20ef
   s_disk_id : int;                      (** A unique ID for each source disk. *)
0d20ef
   s_qemu_uri : string;                  (** QEMU URI of source disk. *)
0d20ef
   s_format : string option;             (** Format. *)
0d20ef
-  s_target_dev : string option;         (** Target @dev from libvirt XML. *)
0d20ef
+  s_controller : s_controller option;   (** Controller, eg. IDE, SCSI. *)
0d20ef
 }
0d20ef
 (** A source disk. *)
0d20ef
 
0d20ef
+and s_controller = [`IDE | `SCSI | `Virtio_blk]
0d20ef
+(** Source disk controller.
0d20ef
+
0d20ef
+    For the purposes of this field, we can treat virtio-scsi as
0d20ef
+    [`SCSI].  However we don't support conversions from virtio in any
0d20ef
+    case so virtio is here only to make it work for testing. *)
0d20ef
+
0d20ef
 and source_removable = {
0d20ef
   s_removable_type : [`CDROM|`Floppy];  (** Type.  *)
0d20ef
-  s_removable_target_dev : string option; (** Target @dev from libvirt XML. *)
0d20ef
+  s_removable_controller : s_controller option; (** Controller, eg. IDE, SCSI.*)
0d20ef
 }
0d20ef
 (** Removable media. *)
0d20ef
 
0d20ef
-- 
0d20ef
1.8.3.1
0d20ef