mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone
Blob Blame History Raw
From 8bd7c9c0d10699757e4edd6d3b5b9ae8667fb4a4 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Wed, 22 Jun 2016 15:04:26 +0100
Subject: [PATCH] v2v: Fix conversion of floppy removable devices
 (RHBZ#1309706).

The previous code treated floppy disks and CD-ROMs as the same kind of
thing, resulting in malformed libvirt XML.  You would see the
following error when importing a guest into libvirt:

  error: Failed to define domain from /tmp/v2vlibvirt063486.xml
  error: internal error: Invalid floppy device name: hdb

because we incorrectly generated this bogus libvirt XML fragment:

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

This commit models floppy devices as a distinct type, occupying their
own bus ("/dev/fdX").  When writing to libvirt, we generate correct
XML fragments, looking like this:

  <disk device='floppy' type='file'>
    <driver name='qemu' type='raw'/>
    <target dev='fda'/>
  </disk>

Miscellaneous other changes were required in the code.  There is also
a regression test (see following commit).

Note this ignores floppy disks in '-o qemu' mode.

(cherry picked from commit b9613acb94e3328204d96efab0dfc8b8ed1d3368)
---
 v2v/input_libvirtxml.ml      |  1 +
 v2v/output_libvirt.ml        |  6 ++++--
 v2v/output_qemu.ml           |  4 ++++
 v2v/target_bus_assignment.ml | 20 ++++++++++++--------
 v2v/test-v2v-i-ova.xml       |  2 +-
 v2v/types.ml                 |  1 +
 v2v/types.mli                | 10 +++++++---
 7 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
index 1202302..a547edd 100644
--- a/v2v/input_libvirtxml.ml
+++ b/v2v/input_libvirtxml.ml
@@ -297,6 +297,7 @@ let parse_libvirt_xml ?conn xml =
         | Some s when String.is_prefix s "sd" -> get_drive_slot s 2
         | Some s when String.is_prefix s "vd" -> get_drive_slot s 2
         | Some s when String.is_prefix s "xvd" -> get_drive_slot s 3
+        | Some s when String.is_prefix s "fd" -> get_drive_slot s 2
         | Some s ->
            warning (f_"<target dev='%s'> was ignored because the device name could not be recognized") s;
            None in
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
index 05ad931..5a404ee 100644
--- a/v2v/output_libvirt.ml
+++ b/v2v/output_libvirt.ml
@@ -173,7 +173,6 @@ let create_libvirt_xml ?pool source target_buses guestcaps
           e "driver" [ "name", "qemu"; "type", "raw" ] [];
           e "target" [
             "dev", drive_prefix ^ drive_name i;
-            "bus", bus_name
           ] []
         ]
     in
@@ -187,7 +186,10 @@ let create_libvirt_xml ?pool source target_buses guestcaps
                     target_buses.target_ide_bus);
       Array.to_list
         (Array.mapi (make_disk "scsi" "sd")
-                    target_buses.target_scsi_bus)
+                    target_buses.target_scsi_bus);
+      Array.to_list
+        (Array.mapi (make_disk "floppy" "fd")
+                    target_buses.target_floppy_bus)
     ] in
   append devices disks;
 
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
index d079ccd..94f80c2 100644
--- a/v2v/output_qemu.ml
+++ b/v2v/output_qemu.ml
@@ -137,6 +137,10 @@ object
     in
     Array.iteri make_scsi target_buses.target_scsi_bus;
 
+    (* XXX Highly unlikely that anyone cares, but the current
+     * code ignores target_buses.target_floppy_bus.
+     *)
+
     let net_bus =
       match guestcaps.gcaps_net_bus with
       | Virtio_net -> "virtio-net-pci"
diff --git a/v2v/target_bus_assignment.ml b/v2v/target_bus_assignment.ml
index 5ad8582..bce3a88 100644
--- a/v2v/target_bus_assignment.ml
+++ b/v2v/target_bus_assignment.ml
@@ -21,11 +21,11 @@ open Common_gettext.Gettext
 
 open Types
 
-(* XXX This doesn't do the right thing for PC legacy floppy devices. *)
 let rec target_bus_assignment source targets guestcaps =
   let virtio_blk_bus = ref [| |]
   and ide_bus = ref [| |]
-  and scsi_bus = ref [| |] in
+  and scsi_bus = ref [| |]
+  and floppy_bus = ref [| |] in
 
   (* Add the fixed disks (targets) to either the virtio-blk or IDE bus,
    * depending on whether the guest has virtio drivers or not.
@@ -65,11 +65,14 @@ let rec target_bus_assignment source targets guestcaps =
       fun r ->
         let t = BusSlotRemovable r in
         let bus =
-          match r.s_removable_controller with
-          | None -> ide_bus (* Wild guess, but should be safe. *)
-          | Some Source_virtio_blk -> virtio_blk_bus
-          | Some Source_IDE -> ide_bus
-          | Some Source_SCSI -> scsi_bus in
+          match r.s_removable_type with
+          | Floppy -> floppy_bus
+          | CDROM ->
+             match r.s_removable_controller with
+             | None -> ide_bus (* Wild guess, but should be safe. *)
+             | Some Source_virtio_blk -> virtio_blk_bus
+             | Some Source_IDE -> ide_bus
+             | Some Source_SCSI -> scsi_bus in
 
         match r.s_removable_slot with
         | None ->
@@ -88,7 +91,8 @@ let rec target_bus_assignment source targets guestcaps =
 
   { target_virtio_blk_bus = !virtio_blk_bus;
     target_ide_bus = !ide_bus;
-    target_scsi_bus = !scsi_bus }
+    target_scsi_bus = !scsi_bus;
+    target_floppy_bus = !floppy_bus }
 
 (* Insert a slot into the bus array, making the array bigger if necessary. *)
 and insert bus i slot =
diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml
index bb765e3..6dcfc31 100644
--- a/v2v/test-v2v-i-ova.xml
+++ b/v2v/test-v2v-i-ova.xml
@@ -27,7 +27,7 @@
     </disk>
     <disk device='floppy' type='file'>
       <driver name='qemu' type='raw'/>
-      <target dev='hdb' bus='ide'/>
+      <target dev='fda'/>
     </disk>
     <interface type='network'>
       <source network='Ethernet 1'/>
diff --git a/v2v/types.ml b/v2v/types.ml
index d082594..7491be4 100644
--- a/v2v/types.ml
+++ b/v2v/types.ml
@@ -363,6 +363,7 @@ type target_buses = {
   target_virtio_blk_bus : target_bus_slot array;
   target_ide_bus : target_bus_slot array;
   target_scsi_bus : target_bus_slot array;
+  target_floppy_bus : target_bus_slot array;
 }
 
 and target_bus_slot =
diff --git a/v2v/types.mli b/v2v/types.mli
index 18ac138..c1cb245 100644
--- a/v2v/types.mli
+++ b/v2v/types.mli
@@ -254,10 +254,11 @@ type target_buses = {
   target_virtio_blk_bus : target_bus_slot array;
   target_ide_bus : target_bus_slot array;
   target_scsi_bus : target_bus_slot array;
+  target_floppy_bus : target_bus_slot array;
 }
 (** Mapping of fixed and removable disks to buses.
 
-    As shown in the diagram below, there are (currently) three buses
+    As shown in the diagram below, there are (currently) four buses
     attached to the target VM.  Each contains a chain of fixed or
     removable disks.  Slots can also be empty.
 
@@ -276,8 +277,11 @@ type target_buses = {
    ├────┤ hda ├───┤ hdb ├───┤ hdc ├───┤ hdd │  IDE bus
    │    └─────┘   └─────┘   └─────┘   └─────┘
    │    ┌─────┐   ┌─────┐
-   └────┤  -  ├───┤ vdb │  Virtio-blk bus
-        └─────┘   └─────┘
+   ├────┤  -  ├───┤ vdb │  Virtio-blk bus
+   │    └─────┘   └─────┘
+   │    ┌─────┐
+   └────┤ fda │  Floppy disks
+        └─────┘
 v}
  *)
 
-- 
1.8.3.1