[Libguestfs] [PATCH virt-v2v 2/2] -o qemu: Fix vsock device by choosing a semi-random guest-cid

Richard W.M. Jones rjones at redhat.com
Wed Apr 13 09:21:41 UTC 2022


If a virtio-vsock device was installed or present in the guest kernel
then -o qemu mode would add the parameter -device vhost-vsock-pci to
the qemu command line.  This fails with:

  qemu-system-x86_64: -device vhost-vsock-pci: guest-cid property must be greater than 2

Thanks: Stefano Garzarella
Fixes: commit 4f6b143c1cb32a29cbd3ff04635ba220e5db82ed
---
 output/output_qemu.ml | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/output/output_qemu.ml b/output/output_qemu.ml
index 4e0a3de6f0..da7278b88b 100644
--- a/output/output_qemu.ml
+++ b/output/output_qemu.ml
@@ -292,8 +292,30 @@ module QEMU = struct
       arg "-device" "virtio-balloon";
     if guestcaps.gcaps_isa_pvpanic then
       arg_list "-device" ["pvpanic"; "ioport=0x505"];
-    if guestcaps.gcaps_virtio_socket then
-      arg "-device" "vhost-vsock-pci";
+    if guestcaps.gcaps_virtio_socket then (
+      (* qemu requires a free guest CID to be chosen.  If you use libvirt
+       * then it does this by iterating over the CIDs doing
+       * ioctl(fd, VHOST_VSOCK_SET_GUEST_CID, &val) on each one until
+       * it finds a free CID.  See:
+       * https://bugzilla.redhat.com/show_bug.cgi?id=1291851#c6
+       *
+       * As that is essentially impossible to do from the shell script,
+       * instead assign a semi-random one here.  Using the PID of
+       * virt-v2v means that we're most likely to assign an unused
+       * CID, especially with modern Linux which has a very large
+       * PID space.  Note that CID must be [3..UINT32_MAX-1] and
+       * max PID in Linux is 2^22.
+       *)
+      let pid = getpid () in
+      let pid = max 3 pid in
+      (* In OCaml 4.13 we could use this, if we were worried about a
+         future system having very large PIDs:
+         let pid = Int64.( min (max 3L (of_int (getpid ())))
+                               (of_int32 Int32.max_int) ) in
+       *)
+      let guest_cid = sprintf "guest-cid=%d" pid in
+      arg_list "-device" ["vhost-vsock-pci"; guest_cid ]
+    );
 
     (* Add a serial console to Linux guests. *)
     if inspect.i_type = "linux" then
-- 
2.35.1



More information about the Libguestfs mailing list