[Libguestfs] [PATCH 6/9] v2v: -i libvirt and -i ova: Record the slot number of removable drives.

Richard W.M. Jones rjones at redhat.com
Wed Jul 1 17:54:48 UTC 2015


When we see libvirt source XML for a removable drive like this:

   <disk type='file' device='cdrom'>
     <driver name='qemu' type='raw'/>
     <target dev='hdc' bus='ide'/>
   </disk>

as well as recording the bus (s_removable_controller) as we do at the
moment, also record the slot number (eg. hdc == 2 in the example
above).

Do the same for OVA input files.
---
 v2v/input_libvirtxml.ml               | 29 ++++++++++++++++++++++++++++-
 v2v/input_ova.ml                      |  8 +++++---
 v2v/test-v2v-i-ova-formats.expected   |  2 +-
 v2v/test-v2v-i-ova-gz.expected        |  2 +-
 v2v/test-v2v-i-ova-two-disks.expected |  2 +-
 v2v/types.ml                          |  7 +++++--
 v2v/types.mli                         |  1 +
 7 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
index 646346d..653bfc5 100644
--- a/v2v/input_libvirtxml.ml
+++ b/v2v/input_libvirtxml.ml
@@ -33,6 +33,19 @@ and parsed_source =
 | P_source_file of string
 | P_dont_rewrite
 
+(* Turn string like "hda" into controller slot number.  See also
+ * src/utils.c:guestfs_int_drive_index which this function calls.
+ *)
+let get_drive_slot str offset =
+  let len = String.length str in
+  if len-offset < 0 then
+    failwith (sprintf "get_drive_slot: offset longer than string length (offset = %d, string = %s)" offset str);
+  let name = String.sub str offset (len-offset) in
+  try Some (drive_index name)
+  with Invalid_argument _ ->
+       warning (f_"could not parse device name '%s' from the source libvirt XML") str;
+       None
+
 let parse_libvirt_xml ?conn xml =
   if verbose () then
     printf "libvirt xml is:\n%s\n" xml;
@@ -291,6 +304,18 @@ let parse_libvirt_xml ?conn xml =
         | "virtio" -> Some Source_virtio_blk
         | _ -> None in
 
+      let slot =
+        let target_dev = xpath_to_string "target/@dev" "" in
+        match target_dev with
+        | "" -> None
+        | s when string_prefix s "hd" -> get_drive_slot s 2
+        | s when string_prefix s "sd" -> get_drive_slot s 2
+        | s when string_prefix s "vd" -> get_drive_slot s 2
+        | s when string_prefix s "xvd" -> get_drive_slot s 3
+        | s ->
+           warning (f_"<target dev='%s'> was ignored because the device name could not be recognized") s;
+           None in
+
       let typ =
         match xpath_to_string "@device" "" with
         | "cdrom" -> CDROM
@@ -298,7 +323,9 @@ let parse_libvirt_xml ?conn xml =
         | _ -> assert false (* libxml2 error? *) in
 
       let disk =
-        { s_removable_type = typ; s_removable_controller = controller } in
+        { s_removable_type = typ;
+          s_removable_controller = controller;
+          s_removable_slot = slot } in
       disks := disk :: !disks
     done;
     List.rev !disks in
diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml
index 0ef349d..d640d4a 100644
--- a/v2v/input_ova.ml
+++ b/v2v/input_ova.ml
@@ -321,9 +321,10 @@ object
         let id = xpath_to_int "rasd:ResourceType/text()" 0 in
         assert (id = 14 || id = 15 || id = 16);
 
-        (* XXX We assume the OVF lists these in order.
-        let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
-        *)
+        let slot =
+          match xpath_to_int "rasd:AddressOnParent/text()" (-1) with
+          | -1 -> None
+          | i -> Some i in
 
         (* Find the parent controller. *)
         let parent_id = xpath_to_int "rasd:Parent/text()" 0 in
@@ -340,6 +341,7 @@ object
         let disk = {
           s_removable_type = typ;
           s_removable_controller = controller;
+          s_removable_slot = slot;
         } in
         removables := disk :: !removables;
       done in
diff --git a/v2v/test-v2v-i-ova-formats.expected b/v2v/test-v2v-i-ova-formats.expected
index 22e6136..c83e5dd 100644
--- a/v2v/test-v2v-i-ova-formats.expected
+++ b/v2v/test-v2v-i-ova-formats.expected
@@ -11,7 +11,7 @@ hypervisor type: vmware
 disks:
 	disk1.vmdk (vmdk) [scsi]
 removable media:
-	CD-ROM [ide]
+	CD-ROM [ide] in slot 0
 NICs:
 	Network "Network adapter 1"
 
diff --git a/v2v/test-v2v-i-ova-gz.expected b/v2v/test-v2v-i-ova-gz.expected
index e6ef699..be6cde3 100644
--- a/v2v/test-v2v-i-ova-gz.expected
+++ b/v2v/test-v2v-i-ova-gz.expected
@@ -11,7 +11,7 @@ hypervisor type: vmware
 disks:
 	.vmdk (vmdk) [scsi]
 removable media:
-	CD-ROM [ide]
+	CD-ROM [ide] in slot 0
 NICs:
 	Network "Network adapter 1"
 
diff --git a/v2v/test-v2v-i-ova-two-disks.expected b/v2v/test-v2v-i-ova-two-disks.expected
index c45f266..dcbd43e 100644
--- a/v2v/test-v2v-i-ova-two-disks.expected
+++ b/v2v/test-v2v-i-ova-two-disks.expected
@@ -12,7 +12,7 @@ disks:
 	disk1.vmdk (vmdk) [scsi]
 	disk2.vmdk (vmdk) [scsi]
 removable media:
-	CD-ROM [ide]
+	CD-ROM [ide] in slot 0
 NICs:
 	Network "Network adapter 1"
 
diff --git a/v2v/types.ml b/v2v/types.ml
index c583554..34e169c 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -55,6 +55,7 @@ and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
 and source_removable = {
   s_removable_type : s_removable_type;
   s_removable_controller : s_controller option;
+  s_removable_slot : int option;
 }
 and s_removable_type = CDROM | Floppy
 and source_nic = {
@@ -175,12 +176,14 @@ and string_of_controller = function
   | Source_virtio_blk -> "virtio"
 
 and string_of_source_removable { s_removable_type = typ;
-                                 s_removable_controller = controller } =
-  sprintf "\t%s%s"
+                                 s_removable_controller = controller;
+                                 s_removable_slot = i } =
+  sprintf "\t%s%s%s"
     (match typ with CDROM -> "CD-ROM" | Floppy -> "Floppy")
     (match controller with
     | None -> ""
     | Some controller -> " [" ^ string_of_controller controller ^ "]")
+    (match i with None -> "" | Some i -> sprintf " in slot %d" i)
 
 and string_of_source_nic { s_mac = mac; s_vnet = vnet; s_vnet_type = typ } =
   sprintf "\t%s \"%s\"%s"
diff --git a/v2v/types.mli b/v2v/types.mli
index b76ef52..6f9bf0d 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -74,6 +74,7 @@ and s_controller = Source_IDE | Source_SCSI | Source_virtio_blk
 and source_removable = {
   s_removable_type : s_removable_type;  (** Type.  *)
   s_removable_controller : s_controller option; (** Controller, eg. IDE, SCSI.*)
+  s_removable_slot : int option; (** Slot, eg. hda = 0, hdc = 2 *)
 }
 (** Removable media. *)
 
-- 
2.3.1




More information about the Libguestfs mailing list