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:
Pawel Niedzwiecki 2017-06-19 16:37:51 +02:00 committed by Jim Harris
parent c303ba2c16
commit a264d9d2a3
7 changed files with 47 additions and 6 deletions

View File

@ -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.

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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):