Blame SOURCES/0035-v2v-Allow-output-to-block-devices-RHBZ-1868690.patch

62f9b7
From 704e86cb3bd4ddc3b7c207967f0413b4637be1f3 Mon Sep 17 00:00:00 2001
62f9b7
From: "Richard W.M. Jones" <rjones@redhat.com>
62f9b7
Date: Tue, 1 Sep 2020 14:44:17 +0100
62f9b7
Subject: [PATCH] v2v: Allow output to block devices (RHBZ#1868690).
62f9b7
62f9b7
We previously implicitly supported writing to block devices instead of
62f9b7
local files, but there were several problems:
62f9b7
62f9b7
* Block devices could be deleted, especially if virt-v2v failed during
62f9b7
  a conversion.
62f9b7
62f9b7
* Block devices could be overwritten by a file with the same name,
62f9b7
  although I believe this is just an observed consequence of the
62f9b7
  previous point, or at least I was not able to reproduce this until
62f9b7
  virt-v2v failed for another reason and then I noticed that because
62f9b7
  the block device was deleted, the next run overwrote it with a file.
62f9b7
62f9b7
* It was not documented anywhere how to do it.
62f9b7
62f9b7
This commit makes the small code change needed to allow virt-v2v to
62f9b7
write to a block device, only for existing outputs which write to
62f9b7
local files (ie. using TargetFile).  Also it avoids deleting block
62f9b7
devices accidentally on failure.
62f9b7
62f9b7
Note this commit intentionally does not prevent you from writing qcow2
62f9b7
to a block device.  RHV uses this so it is a thing that people do.
62f9b7
62f9b7
(cherry picked from commit 9a5974fa3bc038e5e5dbb9605a6db77d06e7bf77)
62f9b7
---
62f9b7
 docs/virt-v2v.pod | 33 ++++++++++++++++++++++++++++++
62f9b7
 v2v/v2v.ml        | 51 ++++++++++++++++++++++++++++-------------------
62f9b7
 2 files changed, 63 insertions(+), 21 deletions(-)
62f9b7
62f9b7
diff --git a/docs/virt-v2v.pod b/docs/virt-v2v.pod
62f9b7
index af69d633..50b0bc8e 100644
62f9b7
--- a/docs/virt-v2v.pod
62f9b7
+++ b/docs/virt-v2v.pod
62f9b7
@@ -1378,8 +1378,41 @@ require either a special user and/or for you to source a script that
62f9b7
 sets authentication environment variables.  Consult the Glance
62f9b7
 documentation.
62f9b7
 
62f9b7
+=item Writing to block devices
62f9b7
+
62f9b7
+This normally requires root.  See the next section.
62f9b7
+
62f9b7
 =back
62f9b7
 
62f9b7
+=head2 Writing to block devices
62f9b7
+
62f9b7
+Some output modes write to local files.  In general these modes also
62f9b7
+let you write to block devices, but before you run virt-v2v you may
62f9b7
+have to arrange for symbolic links to the desired block devices in the
62f9b7
+output directory.
62f9b7
+
62f9b7
+For example if using I<-o local -os /dir> then virt-v2v would normally
62f9b7
+create files called:
62f9b7
+
62f9b7
+ /dir/name-sda     # first disk
62f9b7
+ /dir/name-sdb     # second disk
62f9b7
+ ...
62f9b7
+ /dir/name.xml     # metadata
62f9b7
+
62f9b7
+If you wish the disks to be written to block devices then you would
62f9b7
+need to create F</dir/I<name>-sda> (etc) as symlinks to the block
62f9b7
+devices:
62f9b7
+
62f9b7
+ # lvcreate -L 10G -n VolumeForDiskA VG
62f9b7
+ # lvcreate -L 6G -n VolumeForDiskB VG
62f9b7
+ # ln -sf /dev/VG/VolumeForDiskA /dir/name-sda
62f9b7
+ # ln -sf /dev/VG/VolumeForDiskB /dir/name-sdb
62f9b7
+
62f9b7
+Note that you must precreate the correct number of block devices of
62f9b7
+the correct size.  Typically I<-of raw> has to be used too, but other
62f9b7
+formats such as qcow2 can be useful occasionally so virt-v2v does not
62f9b7
+force you to use raw on block devices.
62f9b7
+
62f9b7
 =head2 Minimal XML for -i libvirtxml option
62f9b7
 
62f9b7
 When using the I<-i libvirtxml> option, you have to supply some
62f9b7
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
62f9b7
index a58ff433..1f8d0138 100644
62f9b7
--- a/v2v/v2v.ml
62f9b7
+++ b/v2v/v2v.ml
62f9b7
@@ -681,7 +681,10 @@ and copy_targets cmdline targets input output =
62f9b7
         fun t ->
62f9b7
           match t.target_file with
62f9b7
           | TargetURI _ -> ()
62f9b7
-          | TargetFile s -> try unlink s with _ -> ()
62f9b7
+          | TargetFile filename ->
62f9b7
+             if not (is_block_device filename) then (
62f9b7
+               try unlink filename with _ -> ()
62f9b7
+             )
62f9b7
       ) targets
62f9b7
     )
62f9b7
   );
62f9b7
@@ -711,27 +714,33 @@ and copy_targets cmdline targets input output =
62f9b7
 
62f9b7
       (match t.target_file with
62f9b7
        | TargetFile filename ->
62f9b7
-          (* It turns out that libguestfs's disk creation code is
62f9b7
-           * considerably more flexible and easier to use than
62f9b7
-           * qemu-img, so create the disk explicitly using libguestfs
62f9b7
-           * then pass the 'qemu-img convert -n' option so qemu reuses
62f9b7
-           * the disk.
62f9b7
-           *
62f9b7
-           * Also we allow the output mode to actually create the disk
62f9b7
-           * image.  This lets the output mode set ownership and
62f9b7
-           * permissions correctly if required.
62f9b7
+          (* As a special case, allow output to a block device or
62f9b7
+           * symlink to a block device.  In this case we don't
62f9b7
+           * create/overwrite the block device.  (RHBZ#1868690).
62f9b7
            *)
62f9b7
-          (* What output preallocation mode should we use? *)
62f9b7
-          let preallocation =
62f9b7
-            match t.target_format, cmdline.output_alloc with
62f9b7
-            | ("raw"|"qcow2"), Sparse -> Some "sparse"
62f9b7
-            | ("raw"|"qcow2"), Preallocated -> Some "full"
62f9b7
-            | _ -> None (* ignore -oa flag for other formats *) in
62f9b7
-          let compat =
62f9b7
-            match t.target_format with "qcow2" -> Some "1.1" | _ -> None in
62f9b7
-          output#disk_create filename t.target_format
62f9b7
-                             t.target_overlay.ov_virtual_size
62f9b7
-                             ?preallocation ?compat
62f9b7
+          if not (is_block_device filename) then (
62f9b7
+            (* It turns out that libguestfs's disk creation code is
62f9b7
+             * considerably more flexible and easier to use than
62f9b7
+             * qemu-img, so create the disk explicitly using libguestfs
62f9b7
+             * then pass the 'qemu-img convert -n' option so qemu reuses
62f9b7
+             * the disk.
62f9b7
+             *
62f9b7
+             * Also we allow the output mode to actually create the disk
62f9b7
+             * image.  This lets the output mode set ownership and
62f9b7
+             * permissions correctly if required.
62f9b7
+             *)
62f9b7
+            (* What output preallocation mode should we use? *)
62f9b7
+            let preallocation =
62f9b7
+              match t.target_format, cmdline.output_alloc with
62f9b7
+              | ("raw"|"qcow2"), Sparse -> Some "sparse"
62f9b7
+              | ("raw"|"qcow2"), Preallocated -> Some "full"
62f9b7
+              | _ -> None (* ignore -oa flag for other formats *) in
62f9b7
+            let compat =
62f9b7
+              match t.target_format with "qcow2" -> Some "1.1" | _ -> None in
62f9b7
+            output#disk_create filename t.target_format
62f9b7
+                               t.target_overlay.ov_virtual_size
62f9b7
+                               ?preallocation ?compat
62f9b7
+          )
62f9b7
 
62f9b7
        | TargetURI _ ->
62f9b7
           (* XXX For the moment we assume that qemu URI outputs