diff --git a/include/spdk/vhost.h b/include/spdk/vhost.h index aa4944bf8..990b2f0e6 100644 --- a/include/spdk/vhost.h +++ b/include/spdk/vhost.h @@ -312,14 +312,16 @@ int spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tg * is allowed but not required. The mask itself can be constructed as: * ((1 << cpu0) | (1 << cpu1) | ... | (1 << cpuN)). * \param dev_name bdev name to associate with this vhost device - * \param readonly if set, all writes to the device will fail with + * \param params JSON value object containing variables: + * readonly if set, all writes to the device will fail with * \c VIRTIO_BLK_S_IOERR error code. - * \param packed_ring this controller supports packed ring if set. + * packed_ring this controller supports packed ring if set. + * packed_ring_recovery * * \return 0 on success, negative errno on error. */ int spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_name, - bool readonly, bool packed_ring); + const struct spdk_json_val *params); /** * Remove a vhost device. The device must not have any open connections on it's socket. diff --git a/lib/vhost/vhost_blk.c b/lib/vhost/vhost_blk.c index 362604286..76bea817c 100644 --- a/lib/vhost/vhost_blk.c +++ b/lib/vhost/vhost_blk.c @@ -107,6 +107,18 @@ struct spdk_vhost_blk_session { struct spdk_poller *stop_poller; }; +struct rpc_vhost_blk { + bool readonly; + bool packed_ring; + bool packed_ring_recovery; +}; + +static const struct spdk_json_object_decoder rpc_construct_vhost_blk[] = { + {"readonly", offsetof(struct rpc_vhost_blk, readonly), spdk_json_decode_bool, true}, + {"packed_ring", offsetof(struct rpc_vhost_blk, packed_ring), spdk_json_decode_bool, true}, + {"packed_ring_recovery", offsetof(struct rpc_vhost_blk, packed_ring_recovery), spdk_json_decode_bool, true}, +}; + /* forward declaration */ static const struct spdk_vhost_dev_backend vhost_blk_device_backend; @@ -1534,8 +1546,9 @@ static const struct spdk_vhost_dev_backend vhost_blk_device_backend = { int spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_name, - bool readonly, bool packed_ring) + const struct spdk_json_val *params) { + struct rpc_vhost_blk req = {0}; struct spdk_vhost_blk_dev *bvdev = NULL; struct spdk_vhost_dev *vdev; struct spdk_bdev *bdev; @@ -1543,6 +1556,15 @@ spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_ spdk_vhost_lock(); + if (spdk_json_decode_object_relaxed(params, rpc_construct_vhost_blk, + SPDK_COUNTOF(rpc_construct_vhost_blk), + &req)) { + SPDK_DEBUGLOG(vhost_blk, "spdk_json_decode_object failed\n"); + ret = -EINVAL; + goto out; + } + g_packed_ring_recovery = req.packed_ring_recovery; + bvdev = calloc(1, sizeof(*bvdev)); if (bvdev == NULL) { ret = -ENOMEM; @@ -1562,7 +1584,7 @@ spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_ vdev->disabled_features = SPDK_VHOST_BLK_DISABLED_FEATURES; vdev->protocol_features = SPDK_VHOST_BLK_PROTOCOL_FEATURES; - vdev->virtio_features |= (uint64_t)packed_ring << VIRTIO_F_RING_PACKED; + vdev->virtio_features |= (uint64_t)req.packed_ring << VIRTIO_F_RING_PACKED; if (spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_UNMAP)) { vdev->virtio_features |= (1ULL << VIRTIO_BLK_F_DISCARD); @@ -1570,7 +1592,7 @@ spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_ if (spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_WRITE_ZEROES)) { vdev->virtio_features |= (1ULL << VIRTIO_BLK_F_WRITE_ZEROES); } - if (readonly) { + if (req.readonly) { vdev->virtio_features |= (1ULL << VIRTIO_BLK_F_RO); } if (spdk_bdev_io_type_supported(bdev, SPDK_BDEV_IO_TYPE_FLUSH)) { @@ -1591,7 +1613,7 @@ spdk_vhost_blk_construct(const char *name, const char *cpumask, const char *dev_ bvdev->dummy_io_channel = spdk_bdev_get_io_channel(bvdev->bdev_desc); bvdev->bdev = bdev; - bvdev->readonly = readonly; + bvdev->readonly = req.readonly; ret = vhost_dev_register(vdev, name, cpumask, &vhost_blk_device_backend); if (ret != 0) { spdk_put_io_channel(bvdev->dummy_io_channel); diff --git a/lib/vhost/vhost_rpc.c b/lib/vhost/vhost_rpc.c index b1555f2fb..f5e3fc13a 100644 --- a/lib/vhost/vhost_rpc.c +++ b/lib/vhost/vhost_rpc.c @@ -235,18 +235,12 @@ struct rpc_vhost_blk_ctrlr { char *ctrlr; char *dev_name; char *cpumask; - bool readonly; - bool packed_ring; - bool packed_ring_recovery; }; static const struct spdk_json_object_decoder rpc_construct_vhost_blk_ctrlr[] = { {"ctrlr", offsetof(struct rpc_vhost_blk_ctrlr, ctrlr), spdk_json_decode_string }, {"dev_name", offsetof(struct rpc_vhost_blk_ctrlr, dev_name), spdk_json_decode_string }, {"cpumask", offsetof(struct rpc_vhost_blk_ctrlr, cpumask), spdk_json_decode_string, true}, - {"readonly", offsetof(struct rpc_vhost_blk_ctrlr, readonly), spdk_json_decode_bool, true}, - {"packed_ring", offsetof(struct rpc_vhost_blk_ctrlr, packed_ring), spdk_json_decode_bool, true}, - {"packed_ring_recovery", offsetof(struct rpc_vhost_blk_ctrlr, packed_ring_recovery), spdk_json_decode_bool, true}, }; static void @@ -264,18 +258,15 @@ rpc_vhost_create_blk_controller(struct spdk_jsonrpc_request *request, struct rpc_vhost_blk_ctrlr req = {0}; int rc; - if (spdk_json_decode_object(params, rpc_construct_vhost_blk_ctrlr, - SPDK_COUNTOF(rpc_construct_vhost_blk_ctrlr), - &req)) { + if (spdk_json_decode_object_relaxed(params, rpc_construct_vhost_blk_ctrlr, + SPDK_COUNTOF(rpc_construct_vhost_blk_ctrlr), + &req)) { SPDK_DEBUGLOG(vhost_rpc, "spdk_json_decode_object failed\n"); rc = -EINVAL; goto invalid; } - g_packed_ring_recovery = req.packed_ring_recovery; - - rc = spdk_vhost_blk_construct(req.ctrlr, req.cpumask, req.dev_name, - req.readonly, req.packed_ring); + rc = spdk_vhost_blk_construct(req.ctrlr, req.cpumask, req.dev_name, params); if (rc < 0) { goto invalid; }