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

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