The virtio-blk-vhost-vdpa driver in libblkio 1.3.0 supports the new
'fd' property. Let's expose this to the user, so the management layer
can pass the file descriptor of an already opened vhost-vdpa character
device. This is useful especially when the device can only be accessed
with certain privileges.

Signed-off-by: Stefano Garzarella <sgarz...@redhat.com>
---

Notes:
    As an alternative we could support passing `/dev/fdset/N` via 'path',
    always opening the path with qemu_open() and passing the fd to the
    libblkio driver.
    I preferred to add a new parameter though, because the code is
    simpler without changing how path works (alternatively we should check
    first if fd is supported by the driver or not).
    
    What do you think?
    
    Thanks,
    Stefano

 qapi/block-core.json |  6 +++++-
 block/blkio.c        | 45 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/qapi/block-core.json b/qapi/block-core.json
index b57978957f..9f70777d49 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3841,10 +3841,14 @@
 #
 # @path: path to the vhost-vdpa character device.
 #
+# @fd: file descriptor of an already opened vhost-vdpa character device.
+#      (Since 8.1)
+#
 # Since: 7.2
 ##
 { 'struct': 'BlockdevOptionsVirtioBlkVhostVdpa',
-  'data': { 'path': 'str' },
+  'data': { '*path': 'str',
+            '*fd': 'str' },
   'if': 'CONFIG_BLKIO' }
 
 ##
diff --git a/block/blkio.c b/block/blkio.c
index 0cdc99a729..98394b5745 100644
--- a/block/blkio.c
+++ b/block/blkio.c
@@ -694,6 +694,49 @@ static int blkio_virtio_blk_common_open(BlockDriverState 
*bs,
     return 0;
 }
 
+static int blkio_virtio_blk_vhost_vdpa_open(BlockDriverState *bs,
+        QDict *options, int flags, Error **errp)
+{
+    const char *path = qdict_get_try_str(options, "path");
+    const char *fd_str = qdict_get_try_str(options, "fd");
+    BDRVBlkioState *s = bs->opaque;
+    int ret;
+
+    if (path && fd_str) {
+        error_setg(errp, "'path' and 'fd' options are mutually exclusive");
+        return -EINVAL;
+    }
+
+    if (!path && !fd_str) {
+        error_setg(errp, "none of 'path' or 'fd' options was specified");
+        return -EINVAL;
+    }
+
+    if (path) {
+        ret = blkio_set_str(s->blkio, "path", path);
+        qdict_del(options, "path");
+        if (ret < 0) {
+            error_setg_errno(errp, -ret, "failed to set path: %s",
+                             blkio_get_error_msg());
+            return ret;
+        }
+    } else {
+        ret = blkio_set_str(s->blkio, "fd", fd_str);
+        qdict_del(options, "fd");
+        if (ret < 0) {
+            error_setg_errno(errp, -ret, "failed to set fd: %s",
+                             blkio_get_error_msg());
+            return ret;
+        }
+    }
+
+    if (!(flags & BDRV_O_NOCACHE)) {
+        error_setg(errp, "cache.direct=off is not supported");
+        return -EINVAL;
+    }
+    return 0;
+}
+
 static int blkio_file_open(BlockDriverState *bs, QDict *options, int flags,
                            Error **errp)
 {
@@ -717,7 +760,7 @@ static int blkio_file_open(BlockDriverState *bs, QDict 
*options, int flags,
     } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VHOST_USER) == 0) {
         ret = blkio_virtio_blk_common_open(bs, options, flags, errp);
     } else if (strcmp(blkio_driver, DRIVER_VIRTIO_BLK_VHOST_VDPA) == 0) {
-        ret = blkio_virtio_blk_common_open(bs, options, flags, errp);
+        ret = blkio_virtio_blk_vhost_vdpa_open(bs, options, flags, errp);
     } else {
         g_assert_not_reached();
     }
-- 
2.40.1


Reply via email to