Vhost: add support of VITRIO_BLK_F_RO
-Add a configuration option: Read-only flag Vhost block controller can be set in read-only mode. Option can be enabled in config file or in RPC call: 'construct_vhost_block_controllerr' with '-r' option Change-Id: I7e58243be00d33bc04120d573fd4ed7775bb9b2c Signed-off-by: Pawel Niedzwiecki <pawelx.niedzwiecki@intel.com> Reviewed-on: https://review.gerrithub.io/366086 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
c303ba2c16
commit
a264d9d2a3
@ -135,6 +135,8 @@
|
||||
#Name vhost.2
|
||||
# Use first partition from the second Malloc device
|
||||
#Dev Malloc2p0
|
||||
# Put controller in read-only mode
|
||||
#ReadOnly no
|
||||
# Start the poller for this vhost controller on one of the cores in
|
||||
# this cpumask. By default, it not specified, will use any core in the
|
||||
# SPDK process.
|
||||
|
@ -74,8 +74,10 @@ struct spdk_scsi_dev *spdk_vhost_scsi_dev_get_dev(struct spdk_vhost_dev *ctrl,
|
||||
int spdk_vhost_scsi_dev_add_dev(const char *name, unsigned scsi_dev_num, const char *lun_name);
|
||||
int spdk_vhost_scsi_dev_remove_dev(struct spdk_vhost_dev *vdev, unsigned scsi_dev_num);
|
||||
|
||||
int spdk_vhost_blk_construct(const char *name, uint64_t cpumask, const char *dev_name);
|
||||
int spdk_vhost_blk_construct(const char *name, uint64_t cpumask, const char *dev_name,
|
||||
bool readonly);
|
||||
int spdk_vhost_blk_destroy(struct spdk_vhost_dev *dev);
|
||||
struct spdk_bdev *spdk_vhost_blk_get_dev(struct spdk_vhost_dev *ctrlr);
|
||||
bool spdk_vhost_blk_get_readonly(struct spdk_vhost_dev *vdev);
|
||||
|
||||
#endif /* SPDK_VHOST_H */
|
||||
|
@ -324,6 +324,7 @@ spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev, const char *name, uint64_t
|
||||
}
|
||||
|
||||
vdev->name = strdup(name);
|
||||
vdev->path = strdup(path);
|
||||
vdev->vid = -1;
|
||||
vdev->lcore = -1;
|
||||
vdev->cpumask = cpumask;
|
||||
@ -379,6 +380,7 @@ spdk_vhost_dev_remove(struct spdk_vhost_dev *vdev)
|
||||
SPDK_NOTICELOG("Controller %s: removed\n", vdev->name);
|
||||
|
||||
free(vdev->name);
|
||||
free(vdev->path);
|
||||
g_spdk_vhost_devices[ctrlr_num] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ struct spdk_vhost_blk_dev {
|
||||
struct spdk_io_channel *bdev_io_channel;
|
||||
struct spdk_poller *requestq_poller;
|
||||
struct spdk_ring *tasks_pool;
|
||||
bool readonly;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -256,10 +257,13 @@ process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev
|
||||
rc = spdk_bdev_readv(bvdev->bdev, bvdev->bdev_io_channel,
|
||||
&task->iovs[1], task->iovcnt, offset,
|
||||
task->length, blk_request_complete_cb, task);
|
||||
} else {
|
||||
} else if (!bvdev->readonly) {
|
||||
rc = spdk_bdev_writev(bvdev->bdev, bvdev->bdev_io_channel,
|
||||
&task->iovs[1], task->iovcnt, offset,
|
||||
task->length, blk_request_complete_cb, task);
|
||||
} else {
|
||||
SPDK_TRACELOG(SPDK_TRACE_VHOST_BLK, "Device is in read-only mode!\n");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
@ -422,6 +426,15 @@ spdk_vhost_blk_get_dev(struct spdk_vhost_dev *vdev)
|
||||
return bvdev->bdev;
|
||||
}
|
||||
|
||||
bool
|
||||
spdk_vhost_blk_get_readonly(struct spdk_vhost_dev *vdev)
|
||||
{
|
||||
struct spdk_vhost_blk_dev *bvdev = to_blk_dev(vdev);
|
||||
|
||||
assert(bvdev != NULL);
|
||||
return bvdev->readonly;
|
||||
}
|
||||
|
||||
static void
|
||||
bdev_remove_cb(void *remove_ctx)
|
||||
{
|
||||
@ -514,6 +527,7 @@ spdk_vhost_blk_controller_construct(void)
|
||||
char *cpumask_str;
|
||||
char *name;
|
||||
uint64_t cpumask;
|
||||
bool readonly;
|
||||
|
||||
for (sp = spdk_conf_first_section(NULL); sp != NULL; sp = spdk_conf_next_section(sp)) {
|
||||
if (!spdk_conf_section_match_prefix(sp, "VhostBlk")) {
|
||||
@ -533,6 +547,7 @@ spdk_vhost_blk_controller_construct(void)
|
||||
}
|
||||
|
||||
cpumask_str = spdk_conf_section_get_val(sp, "Cpumask");
|
||||
readonly = spdk_conf_section_get_boolval(sp, "ReadOnly", false);
|
||||
if (cpumask_str == NULL) {
|
||||
cpumask = spdk_app_get_core_mask();
|
||||
} else if (spdk_vhost_parse_core_mask(cpumask_str, &cpumask)) {
|
||||
@ -545,7 +560,7 @@ spdk_vhost_blk_controller_construct(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spdk_vhost_blk_construct(name, cpumask, bdev_name) < 0) {
|
||||
if (spdk_vhost_blk_construct(name, cpumask, bdev_name, readonly) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -554,7 +569,7 @@ spdk_vhost_blk_controller_construct(void)
|
||||
}
|
||||
|
||||
int
|
||||
spdk_vhost_blk_construct(const char *name, uint64_t cpumask, const char *dev_name)
|
||||
spdk_vhost_blk_construct(const char *name, uint64_t cpumask, const char *dev_name, bool readonly)
|
||||
{
|
||||
struct spdk_vhost_blk_dev *bvdev;
|
||||
struct spdk_bdev *bdev;
|
||||
@ -580,7 +595,7 @@ spdk_vhost_blk_construct(const char *name, uint64_t cpumask, const char *dev_nam
|
||||
}
|
||||
|
||||
bvdev->bdev = bdev;
|
||||
|
||||
bvdev->readonly = readonly;
|
||||
ret = spdk_vhost_dev_construct(&bvdev->vdev, name, cpumask, SPDK_VHOST_DEV_T_BLK,
|
||||
&vhost_blk_device_backend);
|
||||
if (ret != 0) {
|
||||
@ -588,6 +603,17 @@ spdk_vhost_blk_construct(const char *name, uint64_t cpumask, const char *dev_nam
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (readonly && rte_vhost_driver_enable_features(bvdev->vdev.path, (1ULL << VIRTIO_BLK_F_RO))) {
|
||||
SPDK_ERRLOG("Controller %s: failed to set as a readonly\n", name);
|
||||
spdk_bdev_close(bvdev->bdev_desc);
|
||||
|
||||
if (spdk_vhost_dev_remove(&bvdev->vdev) != 0) {
|
||||
SPDK_ERRLOG("Controller %s: failed to remove controller\n", name);
|
||||
}
|
||||
|
||||
goto err;
|
||||
}
|
||||
|
||||
SPDK_NOTICELOG("Controller %s: using bdev '%s'\n",
|
||||
name, dev_name);
|
||||
|
||||
|
@ -67,6 +67,7 @@ enum spdk_vhost_dev_type {
|
||||
struct spdk_vhost_dev {
|
||||
struct rte_vhost_memory *mem;
|
||||
char *name;
|
||||
char *path;
|
||||
|
||||
int vid;
|
||||
int task_cnt;
|
||||
|
@ -373,12 +373,14 @@ struct rpc_vhost_blk_ctrlr {
|
||||
char *ctrlr;
|
||||
char *dev_name;
|
||||
char *cpumask;
|
||||
bool readonly;
|
||||
};
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
static void
|
||||
@ -413,7 +415,7 @@ spdk_rpc_construct_vhost_blk_controller(struct spdk_jsonrpc_server_conn *conn,
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
rc = spdk_vhost_blk_construct(req.ctrlr, cpumask, req.dev_name);
|
||||
rc = spdk_vhost_blk_construct(req.ctrlr, cpumask, req.dev_name, req.readonly);
|
||||
if (rc < 0) {
|
||||
goto invalid;
|
||||
}
|
||||
@ -526,6 +528,9 @@ spdk_rpc_get_vhost_blk_controllers(struct spdk_jsonrpc_server_conn *conn,
|
||||
spdk_json_write_name(w, "cpu_mask");
|
||||
spdk_json_write_string_fmt(w, "%#" PRIx64, spdk_vhost_dev_get_cpumask(vdev));
|
||||
|
||||
spdk_json_write_name(w, "readonly");
|
||||
spdk_json_write_bool(w, spdk_vhost_blk_get_readonly(vdev));
|
||||
|
||||
bdev = spdk_vhost_blk_get_dev(vdev);
|
||||
spdk_json_write_name(w, "bdev");
|
||||
if (bdev)
|
||||
|
@ -536,12 +536,15 @@ def construct_vhost_blk_controller(args):
|
||||
}
|
||||
if args.cpumask:
|
||||
params['cpumask'] = args.cpumask
|
||||
if args.readonly:
|
||||
params['readonly'] = args.readonly
|
||||
jsonrpc_call('construct_vhost_blk_controller', params)
|
||||
|
||||
p = subparsers.add_parser('construct_vhost_blk_controller', help='Add a new vhost block controller')
|
||||
p.add_argument('ctrlr', help='controller name')
|
||||
p.add_argument('dev_name', help='device name')
|
||||
p.add_argument('--cpumask', help='cpu mask for this controller')
|
||||
p.add_argument("-r", "--readonly", action='store_true', help='Set controller as read-only')
|
||||
p.set_defaults(func=construct_vhost_blk_controller)
|
||||
|
||||
def remove_vhost_blk_controller(args):
|
||||
|
Loading…
x
Reference in New Issue
Block a user