block/blkio: use qemu_open() to support fd passing for virtio-blk

Some virtio-blk drivers (e.g. virtio-blk-vhost-vdpa) supports the fd
passing. Let's expose this to the user, so the management layer
can pass the file descriptor of an already opened path.

If the libblkio virtio-blk driver supports fd passing, let's always
use qemu_open() to open the `path`, so we can handle fd passing
from the management layer through the "/dev/fdset/N" special path.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-id: 20230530071941.8954-2-sgarzare@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefano Garzarella 2023-05-30 09:19:40 +02:00 committed by Stefan Hajnoczi
parent 2a0d7cb6b7
commit cad2ccc395

View File

@ -673,25 +673,60 @@ static int blkio_virtio_blk_common_open(BlockDriverState *bs,
{
const char *path = qdict_get_try_str(options, "path");
BDRVBlkioState *s = bs->opaque;
int ret;
bool fd_supported = false;
int fd, ret;
if (!path) {
error_setg(errp, "missing 'path' option");
return -EINVAL;
}
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;
}
if (!(flags & BDRV_O_NOCACHE)) {
error_setg(errp, "cache.direct=off is not supported");
return -EINVAL;
}
if (blkio_get_int(s->blkio, "fd", &fd) == 0) {
fd_supported = true;
}
/*
* If the libblkio driver supports fd passing, let's always use qemu_open()
* to open the `path`, so we can handle fd passing from the management
* layer through the "/dev/fdset/N" special path.
*/
if (fd_supported) {
int open_flags;
if (flags & BDRV_O_RDWR) {
open_flags = O_RDWR;
} else {
open_flags = O_RDONLY;
}
fd = qemu_open(path, open_flags, errp);
if (fd < 0) {
return -EINVAL;
}
ret = blkio_set_int(s->blkio, "fd", fd);
if (ret < 0) {
error_setg_errno(errp, -ret, "failed to set fd: %s",
blkio_get_error_msg());
qemu_close(fd);
return ret;
}
} else {
ret = blkio_set_str(s->blkio, "path", path);
if (ret < 0) {
error_setg_errno(errp, -ret, "failed to set path: %s",
blkio_get_error_msg());
return ret;
}
}
qdict_del(options, "path");
return 0;
}