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

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