don't duplicate FD in get region info (#715)

This is out of spec.

Signed-off-by: Thanos Makatos <thanos.makatos@nutanix.com>
Reviewed-by: John Levon <john.levon@nutanix.com>
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 5bcb0c2..6359d5d 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -140,13 +140,6 @@
             sparse = (struct vfio_region_info_cap_sparse_mmap*)header;
         }
 
-        if (nr_mmap_areas > vfu_ctx->client_max_fds) {
-            vfu_log(vfu_ctx, LOG_DEBUG, "%s: region has nr_mmap_areas=%d, "
-                    "but client only supports %d fds", __func__,
-                    nr_mmap_areas, vfu_ctx->client_max_fds);
-            return ERROR_INT(ENOSPC);
-        }
-
         *fds = malloc(nr_mmap_areas * sizeof(int));
         if (*fds == NULL) {
             return ERROR_INT(ENOMEM);
@@ -154,7 +147,9 @@
         sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
         sparse->header.version = 1;
         sparse->header.next = 0;
-        sparse->nr_areas = *nr_fds = nr_mmap_areas;
+        sparse->nr_areas = nr_mmap_areas;
+        *nr_fds = 1;
+        (*fds)[0] = vfu_reg->fd;
 
         for (i = 0; i < nr_mmap_areas; i++) {
             struct iovec *iov = &vfu_reg->mmap_areas[i];
@@ -162,7 +157,6 @@
             vfu_log(vfu_ctx, LOG_DEBUG, "%s: area %d [%p, %p)", __func__,
                     i, iov->iov_base, iov_end(iov));
 
-            (*fds)[i] = vfu_reg->fd;
             sparse->areas[i].offset = (uintptr_t)iov->iov_base;
             sparse->areas[i].size = iov->iov_len;
         }
diff --git a/test/py/test_device_get_region_info.py b/test/py/test_device_get_region_info.py
index 3260193..5df33d4 100644
--- a/test/py/test_device_get_region_info.py
+++ b/test/py/test_device_get_region_info.py
@@ -120,17 +120,6 @@
         expect=errno.EINVAL)
 
 
-# python tests use max client fds of 8, but this region has 9 mmap areas.
-def test_device_get_region_info_caps_too_few_fds():
-    payload = vfio_region_info(argsz=192, flags=0,
-                          index=VFU_PCI_DEV_BAR3_REGION_IDX, cap_offset=0,
-                          size=0, offset=0)
-    payload = bytes(payload) + b'\0' * (192 - 32)
-
-    msg(ctx, sock, VFIO_USER_DEVICE_GET_REGION_INFO, payload,
-        expect=errno.ENOSPC)
-
-
 def test_device_get_region_info_larger_argsz():
 
     payload = vfio_region_info(argsz=argsz + 8, flags=0,
@@ -191,7 +180,7 @@
                           size=0, offset=0)
     payload = bytes(payload) + b'\0' * (80 - 32)
 
-    result = msg(ctx, sock, VFIO_USER_DEVICE_GET_REGION_INFO, payload)
+    fds, result = msg_fds(ctx, sock, VFIO_USER_DEVICE_GET_REGION_INFO, payload)
 
     info, result = vfio_region_info.pop_from_buffer(result)
     cap, result = vfio_region_info_cap_sparse_mmap.pop_from_buffer(result)
@@ -213,7 +202,7 @@
     assert area2.offset == 0x4000
     assert area2.size == 0x2000
 
-    # skip reading the SCM_RIGHTS
+    assert(len(fds) == 1)
     disconnect_client(ctx, sock)