Blame SOURCES/0029-v2v-o-null-support-older-qemu-img-RHBZ-1580309.patch

e9bfca
From 62dce61f73b9f0ea9e75a65713a21f4f8368381e Mon Sep 17 00:00:00 2001
e9bfca
From: Pino Toscano <ptoscano@redhat.com>
e9bfca
Date: Mon, 21 May 2018 17:19:25 +0200
e9bfca
Subject: [PATCH] v2v: -o null: support older qemu-img (RHBZ#1580309)
e9bfca
e9bfca
Commit 4699c7b6e126e07c95b67fb95df58aed87a680dd converted the null
e9bfca
output to use the null-co qemu driver with a JSON URL syntax --
e9bfca
especially the latter is only available in newer versions of qemu.
e9bfca
e9bfca
Even if this output mode is mostly for testing, check at runtime whether
e9bfca
the null-co + JSON way is possible, falling back to the creation of
e9bfca
thrown-away temporary files as before.
e9bfca
e9bfca
(cherry picked from commit 1b6a2b221d04e455bdd31cff09015f74487882c1)
e9bfca
---
e9bfca
 v2v/output_null.ml | 66 ++++++++++++++++++++++++++++++++++++++--------
e9bfca
 1 file changed, 55 insertions(+), 11 deletions(-)
e9bfca
e9bfca
diff --git a/v2v/output_null.ml b/v2v/output_null.ml
e9bfca
index b93d53dc5..228c0b631 100644
e9bfca
--- a/v2v/output_null.ml
e9bfca
+++ b/v2v/output_null.ml
e9bfca
@@ -40,9 +40,45 @@ open Utils
e9bfca
  * too small, so we have to set the size.  We could set it to
e9bfca
  * match the input size but it's easier to set it to some huge
e9bfca
  * size instead.
e9bfca
+ *
e9bfca
+ * In case neither the null-co driver nor the JSON syntax for URLs
e9bfca
+ * is supported, fall back by writing the disks to a temporary
e9bfca
+ * directory removed at exit.
e9bfca
  *)
e9bfca
 
e9bfca
+let can_use_qemu_null_co_device () =
e9bfca
+  (* We actually attempt to convert a raw file to the null-co device
e9bfca
+   * using a JSON URL.
e9bfca
+   *)
e9bfca
+  let tmp = Filename.temp_file "v2vqemunullcotst" ".img" in
e9bfca
+  Unix.truncate tmp 1024;
e9bfca
+
e9bfca
+  let json = [
e9bfca
+    "file.driver", JSON.String "null-co";
e9bfca
+    "file.size", JSON.String "1E";
e9bfca
+  ] in
e9bfca
+
e9bfca
+  let cmd =
e9bfca
+    sprintf "qemu-img convert -n -f raw -O raw %s json:%s >/dev/null%s"
e9bfca
+            (quote tmp)
e9bfca
+            (quote (JSON.string_of_doc ~fmt:JSON.Compact json))
e9bfca
+            (if verbose () then "" else " 2>&1") in
e9bfca
+  debug "%s" cmd;
e9bfca
+  let r = 0 = Sys.command cmd in
e9bfca
+  Unix.unlink tmp;
e9bfca
+  debug "qemu-img supports the null-co device: %b" r;
e9bfca
+  r
e9bfca
+
e9bfca
 class output_null =
e9bfca
+  (* Create a temporary directory which is always deleted at exit,
e9bfca
+   * so we can put the drives there in case qemu does not support
e9bfca
+   * the null-co device w/ a JSON URL.
e9bfca
+   *)
e9bfca
+  let tmpdir =
e9bfca
+    let base_dir = (open_guestfs ())#get_cachedir () in
e9bfca
+    let t = Mkdtemp.temp_dir ~base_dir "null." in
e9bfca
+    rmdir_on_exit t;
e9bfca
+    t in
e9bfca
 object
e9bfca
   inherit output
e9bfca
 
e9bfca
@@ -51,19 +87,27 @@ object
e9bfca
   method supported_firmware = [ TargetBIOS; TargetUEFI ]
e9bfca
 
e9bfca
   method prepare_targets source targets =
e9bfca
-    let json_params = [
e9bfca
-      "file.driver", JSON.String "null-co";
e9bfca
-      "file.size", JSON.String "1E";
e9bfca
-    ] in
e9bfca
-    let target_file = TargetURI ("json:" ^ JSON.string_of_doc json_params) in
e9bfca
+    if can_use_qemu_null_co_device () then (
e9bfca
+      let json_params = [
e9bfca
+        "file.driver", JSON.String "null-co";
e9bfca
+        "file.size", JSON.String "1E";
e9bfca
+      ] in
e9bfca
+      let target_file = TargetURI ("json:" ^ JSON.string_of_doc json_params) in
e9bfca
 
e9bfca
-    (* While it's not intended that output drivers can set the
e9bfca
-     * target_format field (thus overriding the -of option), in
e9bfca
-     * this special case of -o null it is reasonable.
e9bfca
-     *)
e9bfca
-    let target_format = "raw" in
e9bfca
+      (* While it's not intended that output drivers can set the
e9bfca
+       * target_format field (thus overriding the -of option), in
e9bfca
+       * this special case of -o null it is reasonable.
e9bfca
+       *)
e9bfca
+      let target_format = "raw" in
e9bfca
 
e9bfca
-    List.map (fun t -> { t with target_file; target_format }) targets
e9bfca
+      List.map (fun t -> { t with target_file; target_format }) targets
e9bfca
+    ) else (
e9bfca
+      List.map (
e9bfca
+        fun t ->
e9bfca
+          let target_file = tmpdir // t.target_overlay.ov_sd in
e9bfca
+          { t with target_file = TargetFile target_file }
e9bfca
+      ) targets
e9bfca
+    )
e9bfca
 
e9bfca
   method create_metadata _ _ _ _ _ _ = ()
e9bfca
 end
e9bfca
-- 
e9bfca
2.17.1
e9bfca