Blame SOURCES/0016-RHV-outputs-limit-copied-disk-count-to-23.patch

696189
From 50a74177b3577952159d87335cf40c0ad3e51b4d Mon Sep 17 00:00:00 2001
696189
From: Laszlo Ersek <lersek@redhat.com>
696189
Date: Fri, 17 Jun 2022 11:53:37 +0200
696189
Subject: [PATCH] RHV outputs: limit copied disk count to 23
696189
696189
We currently support virtio-blk (commonly) or IDE (unusually) for exposing
696189
disks to the converted guest; refer to "guestcaps.gcaps_block_bus" in
696189
"lib/create_ovf.ml". When using virtio-blk (i.e., in the common case), RHV
696189
can deal with at most 23 disks, as it plugs each virtio-blk device in a
696189
separate slot on the PCI(e) root bus; and the other slots are reserved for
696189
various purposes. When a domain has too many disks, the problem only
696189
becomes apparent once the copying finishes and an import is attempted.
696189
Modify the RHV outputs to fail relatively early when a domain has more
696189
than 23 disks that need to be copied.
696189
696189
Notes:
696189
696189
- With IDE, the theoretical limit may even be as low as 4. However, in the
696189
  "Output_module.setup" function, we don't have access to
696189
  "guestcaps.gcaps_block_bus", and in practice the IDE limitation has not
696189
  caused surprises. So for now stick with 23, assuming virtio-blk.
696189
  Modifying the "Output_module.setup" parameter list just for this seems
696189
  overkill.
696189
696189
- We could move the new check to an even earlier step, namely
696189
  "Output_module.parse_options", due to the v2v directory deliberately
696189
  existing (and having been populated with input sockets) at that time.
696189
  However, even discounting the fact that "parse_options" is not a good
696189
  name for including this kind of step, "parse_options" does not have
696189
  access to the v2v directory name, and modifying the signature just for
696189
  this is (again) overkill.
696189
696189
- By adding the check to "Output_module.setup", we waste *some* effort
696189
  (namely, the conversion occurs between "parse_options" and "setup"),
696189
  but: (a) the "rhv-disk-uuid" count check (against the disk count) is
696189
  already being done in the rhv-upload module's "setup" function, (b) in
696189
  practice the slowest step ought to be the copying, and placing the new
696189
  check in "setup" is early enough to prevent that.
696189
696189
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2051564
696189
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
696189
Message-Id: <20220617095337.9122-1-lersek@redhat.com>
696189
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
696189
(cherry picked from commit e186cc2bea99a077990f192953e1bf6c9ba70e79)
696189
---
696189
 output/output.ml            | 5 +++++
696189
 output/output.mli           | 7 +++++++
696189
 output/output_rhv.ml        | 1 +
696189
 output/output_rhv_upload.ml | 1 +
696189
 output/output_vdsm.ml       | 1 +
696189
 5 files changed, 15 insertions(+)
696189
696189
diff --git a/output/output.ml b/output/output.ml
696189
index 10e685c4..5c6670b9 100644
696189
--- a/output/output.ml
696189
+++ b/output/output.ml
696189
@@ -64,6 +64,11 @@ let get_disks dir =
696189
   in
696189
   loop [] 0
696189
 
696189
+let error_if_disk_count_gt dir n =
696189
+  let socket = sprintf "%s/in%d" dir n in
696189
+  if Sys.file_exists socket then
696189
+    error (f_"this output module doesn't support copying more than %d disks") n
696189
+
696189
 let output_to_local_file ?(changeuid = fun f -> f ())
696189
       output_alloc output_format filename size socket =
696189
   (* Check nbdkit is installed and has the required plugin. *)
696189
diff --git a/output/output.mli b/output/output.mli
696189
index 533a0c51..8d3d6865 100644
696189
--- a/output/output.mli
696189
+++ b/output/output.mli
696189
@@ -76,6 +76,13 @@ val get_disks : string -> (int * int64) list
696189
 (** Examines the v2v directory and opens each input socket (in0 etc),
696189
     returning a list of input disk index and size. *)
696189
 
696189
+val error_if_disk_count_gt : string -> int -> unit
696189
+(** This function lets an output module enforce a maximum disk count.
696189
+    [error_if_disk_count_gt dir n] checks whether the domain has more than [n]
696189
+    disks that need to be copied, by examining the existence of input NBD socket
696189
+    "in[n]" in the v2v directory [dir].  If the socket exists, [error] is
696189
+    called. *)
696189
+
696189
 val output_to_local_file : ?changeuid:((unit -> unit) -> unit) ->
696189
                            Types.output_allocation ->
696189
                            string -> string -> int64 -> string ->
696189
diff --git a/output/output_rhv.ml b/output/output_rhv.ml
696189
index 119207fd..8571e07b 100644
696189
--- a/output/output_rhv.ml
696189
+++ b/output/output_rhv.ml
696189
@@ -56,6 +56,7 @@ module RHV = struct
696189
     (options.output_alloc, options.output_format, output_name, output_storage)
696189
 
696189
   let rec setup dir options source =
696189
+    error_if_disk_count_gt dir 23;
696189
     let disks = get_disks dir in
696189
     let output_alloc, output_format, output_name, output_storage = options in
696189
 
696189
diff --git a/output/output_rhv_upload.ml b/output/output_rhv_upload.ml
696189
index 828996b3..f2ced4f4 100644
696189
--- a/output/output_rhv_upload.ml
696189
+++ b/output/output_rhv_upload.ml
696189
@@ -133,6 +133,7 @@ after their uploads (if you do, you must supply one for each disk):
696189
     else PCRE.matches (Lazy.force rex_uuid) uuid
696189
 
696189
   let rec setup dir options source =
696189
+    error_if_disk_count_gt dir 23;
696189
     let disks = get_disks dir in
696189
     let output_conn, output_format,
696189
         output_password, output_name, output_storage,
696189
diff --git a/output/output_vdsm.ml b/output/output_vdsm.ml
696189
index a1e8c246..23d1b9cd 100644
696189
--- a/output/output_vdsm.ml
696189
+++ b/output/output_vdsm.ml
696189
@@ -119,6 +119,7 @@ For each disk you must supply one of each of these options:
696189
      compat, ovf_flavour)
696189
 
696189
   let setup dir options source =
696189
+    error_if_disk_count_gt dir 23;
696189
     let disks = get_disks dir in
696189
     let output_alloc, output_format,
696189
         output_name, output_storage,