spdkcli: add basic vhost management
Adding: - listing current vhost scsi and blk configuration - add / remove scsi and blk controllers - modify scsi targets and luns - set controller coalescing Change-Id: If00d820d03731f1110f665b14258617d917b9bfd Signed-off-by: Karol Latecki <karol.latecki@intel.com> Signed-off-by: Pawel Kaminski <pawelx.kaminski@intel.com> Reviewed-on: https://review.gerrithub.io/406538 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
parent
fdd6dbc902
commit
5e5cc5ac9c
@ -477,3 +477,191 @@ class UILvsObj(UINode):
|
||||
free = "=".join(["Free", free])
|
||||
info = ", ".join([str(size), str(free)])
|
||||
return info, True
|
||||
|
||||
|
||||
class UIVhosts(UINode):
|
||||
def __init__(self, parent):
|
||||
UINode.__init__(self, "vhost", parent)
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
self.get_root().list_vhost_ctrls()
|
||||
UIVhostBlk(self)
|
||||
UIVhostScsi(self)
|
||||
|
||||
|
||||
class UIVhost(UINode):
|
||||
def __init__(self, name, parent):
|
||||
UINode.__init__(self, name, parent)
|
||||
self.refresh()
|
||||
|
||||
def ui_command_delete(self, name):
|
||||
"""
|
||||
Delete a Vhost controller from configuration.
|
||||
|
||||
Arguments:
|
||||
name - Controller name.
|
||||
"""
|
||||
self.get_root().remove_vhost_controller(ctrlr=name)
|
||||
self.get_root().refresh()
|
||||
self.refresh()
|
||||
|
||||
|
||||
class UIVhostBlk(UIVhost):
|
||||
def __init__(self, parent):
|
||||
UIVhost.__init__(self, "block", parent)
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
for ctrlr in self.get_root().get_vhost_ctrlrs(self.name):
|
||||
UIVhostBlkCtrlObj(ctrlr, self)
|
||||
|
||||
def ui_command_create(self, name, bdev, cpumask=None, readonly=False):
|
||||
"""
|
||||
Construct a Vhost BLK controller.
|
||||
|
||||
Arguments:
|
||||
name - Controller name.
|
||||
bdev - Which bdev to attach to the controller.
|
||||
cpumask - Optional. Integer to specify mask of CPUs to use.
|
||||
Default: 1.
|
||||
readonly - Whether controller should be read only or not.
|
||||
Default: False.
|
||||
"""
|
||||
ret_name = self.get_root().create_vhost_blk_controller(ctrlr=name,
|
||||
dev_name=bdev,
|
||||
cpumask=cpumask,
|
||||
readonly=bool(readonly))
|
||||
self.get_root().refresh()
|
||||
self.refresh()
|
||||
|
||||
|
||||
class UIVhostScsi(UIVhost):
|
||||
def __init__(self, parent):
|
||||
UIVhost.__init__(self, "scsi", parent)
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
for ctrlr in self.get_root().get_vhost_ctrlrs(self.name):
|
||||
UIVhostScsiCtrlObj(ctrlr, self)
|
||||
|
||||
def ui_command_create(self, name, cpumask=None):
|
||||
"""
|
||||
Construct a Vhost SCSI controller.
|
||||
|
||||
Arguments:
|
||||
name - Controller name.
|
||||
cpumask - Optional. Integer to specify mask of CPUs to use.
|
||||
Default: 1.
|
||||
"""
|
||||
ret_name = self.get_root().create_vhost_scsi_controller(ctrlr=name,
|
||||
cpumask=cpumask)
|
||||
self.get_root().refresh()
|
||||
self.refresh()
|
||||
|
||||
|
||||
class UIVhostCtrl(UINode):
|
||||
# Base class for SCSI and BLK controllers, do not instantiate
|
||||
def __init__(self, ctrlr, parent):
|
||||
self.ctrlr = ctrlr
|
||||
UINode.__init__(self, self.ctrlr.ctrlr, parent)
|
||||
self.refresh()
|
||||
|
||||
def ui_command_show_details(self):
|
||||
self.shell.log.info(json.dumps(vars(self.ctrlr), indent=2))
|
||||
|
||||
def ui_command_set_coalescing(self, delay_base_us, iops_threshold):
|
||||
delay_base_us = self.ui_eval_param(delay_base_us, "number", None)
|
||||
iops_threshold = self.ui_eval_param(iops_threshold, "number", None)
|
||||
self.get_root().set_vhost_controller_coalescing(ctrlr=self.ctrlr.ctrlr,
|
||||
delay_base_us=delay_base_us,
|
||||
iops_threshold=iops_threshold)
|
||||
|
||||
|
||||
class UIVhostScsiCtrlObj(UIVhostCtrl):
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
for lun in self.ctrlr.backend_specific["scsi"]:
|
||||
UIVhostTargetObj(lun, self)
|
||||
|
||||
def ui_command_remove_target(self, target_num):
|
||||
"""
|
||||
Remove target node from SCSI controller.
|
||||
|
||||
Arguments:
|
||||
target_num - Integer identifier of target node to delete.
|
||||
"""
|
||||
self.get_root().remove_vhost_scsi_target(ctrlr=self.ctrlr.ctrlr,
|
||||
scsi_target_num=int(target_num))
|
||||
for ctrlr in self.get_root().get_vhost_ctrlrs("scsi"):
|
||||
if ctrlr.ctrlr == self.ctrlr.ctrlr:
|
||||
self.ctrlr = ctrlr
|
||||
|
||||
self.refresh()
|
||||
self.get_root().refresh()
|
||||
|
||||
def ui_command_add_lun(self, target_num, bdev_name):
|
||||
"""
|
||||
Add LUN to SCSI target node.
|
||||
Currently only one LUN (which is LUN ID 0) per target is supported.
|
||||
Adding LUN to not existing target node will create that node.
|
||||
|
||||
Arguments:
|
||||
target_num - Integer identifier of target node to modify.
|
||||
bdev - Which bdev to add as LUN.
|
||||
"""
|
||||
|
||||
self.get_root().add_vhost_scsi_lun(ctrlr=self.ctrlr.ctrlr,
|
||||
scsi_target_num=int(target_num),
|
||||
bdev_name=bdev_name)
|
||||
for ctrlr in self.get_root().get_vhost_ctrlrs("scsi"):
|
||||
if ctrlr.ctrlr == self.ctrlr.ctrlr:
|
||||
self.ctrlr = ctrlr
|
||||
self.refresh()
|
||||
|
||||
def summary(self):
|
||||
info = self.ctrlr.socket
|
||||
return info, True
|
||||
|
||||
|
||||
class UIVhostBlkCtrlObj(UIVhostCtrl):
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
UIVhostLunDevObj(self.ctrlr.backend_specific["block"]["bdev"], self)
|
||||
|
||||
def summary(self):
|
||||
ro = None
|
||||
if self.ctrlr.backend_specific["block"]["readonly"]:
|
||||
ro = "Readonly"
|
||||
info = ", ".join(filter(None, [self.ctrlr.socket, ro]))
|
||||
return info, True
|
||||
|
||||
|
||||
class UIVhostTargetObj(UINode):
|
||||
def __init__(self, target, parent):
|
||||
self.target = target
|
||||
# Next line: configshell does not allow paths with spaces.
|
||||
UINode.__init__(self, target["target_name"].replace(" ", "_"), parent)
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
for target in self.target["luns"]:
|
||||
UIVhostLunDevObj(target["bdev_name"], self)
|
||||
|
||||
def ui_command_show_details(self):
|
||||
self.shell.log.info(json.dumps(self.target, indent=2))
|
||||
|
||||
def summary(self):
|
||||
luns = "LUNs: %s" % len(self.target["luns"])
|
||||
id = "TargetID: %s" % self.target["scsi_dev_num"]
|
||||
info = ",".join([luns, id])
|
||||
return info, True
|
||||
|
||||
|
||||
class UIVhostLunDevObj(UINode):
|
||||
def __init__(self, name, parent):
|
||||
UINode.__init__(self, name, parent)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from .ui_node import UINode, UIBdevs, UILvolStores
|
||||
from .ui_node import UINode, UIBdevs, UILvolStores, UIVhosts
|
||||
import rpc.client
|
||||
import rpc
|
||||
|
||||
@ -11,12 +11,14 @@ class UIRoot(UINode):
|
||||
UINode.__init__(self, "/", shell=shell)
|
||||
self.current_bdevs = []
|
||||
self.current_lvol_stores = []
|
||||
self.current_vhost_ctrls = []
|
||||
self.set_rpc_target(s)
|
||||
|
||||
def refresh(self):
|
||||
self._children = set([])
|
||||
UIBdevs(self)
|
||||
UILvolStores(self)
|
||||
UIVhosts(self)
|
||||
|
||||
def set_rpc_target(self, s):
|
||||
self.client = rpc.client.JSONRPCClient(s)
|
||||
@ -121,6 +123,37 @@ class UIRoot(UINode):
|
||||
response = rpc.bdev.construct_rbd_bdev(self.client, **kwargs)
|
||||
return response
|
||||
|
||||
def list_vhost_ctrls(self):
|
||||
self.current_vhost_ctrls = rpc.vhost.get_vhost_controllers(self.client)
|
||||
|
||||
def get_vhost_ctrlrs(self, ctrlr_type):
|
||||
for ctrlr in filter(lambda x: ctrlr_type in x["backend_specific"].keys(),
|
||||
self.current_vhost_ctrls):
|
||||
yield VhostCtrlr(ctrlr)
|
||||
|
||||
def remove_vhost_controller(self, **kwargs):
|
||||
rpc.vhost.remove_vhost_controller(self.client, **kwargs)
|
||||
self.current_vhost_ctrls = rpc.vhost.get_vhost_controllers(self.client)
|
||||
|
||||
def create_vhost_scsi_controller(self, **kwargs):
|
||||
rpc.vhost.construct_vhost_scsi_controller(self.client, **kwargs)
|
||||
self.current_vhost_ctrls = rpc.vhost.get_vhost_controllers(self.client)
|
||||
|
||||
def create_vhost_blk_controller(self, **kwargs):
|
||||
rpc.vhost.construct_vhost_blk_controller(self.client, **kwargs)
|
||||
self.current_vhost_ctrls = rpc.vhost.get_vhost_controllers(self.client)
|
||||
|
||||
def remove_vhost_scsi_target(self, **kwargs):
|
||||
rpc.vhost.remove_vhost_scsi_target(self.client, **kwargs)
|
||||
self.current_vhost_ctrls = rpc.vhost.get_vhost_controllers(self.client)
|
||||
|
||||
def add_vhost_scsi_lun(self, **kwargs):
|
||||
rpc.vhost.add_vhost_scsi_lun(self.client, **kwargs)
|
||||
self.current_vhost_ctrls = rpc.vhost.get_vhost_controllers(self.client)
|
||||
|
||||
def set_vhost_controller_coalescing(self, **kwargs):
|
||||
rpc.vhost.set_vhost_controller_coalescing(self.client, **kwargs)
|
||||
|
||||
|
||||
class Bdev(object):
|
||||
def __init__(self, bdev_info):
|
||||
@ -144,3 +177,15 @@ class LvolStore(object):
|
||||
"""
|
||||
for i in lvs_info.keys():
|
||||
setattr(self, i, lvs_info[i])
|
||||
|
||||
|
||||
class VhostCtrlr(object):
|
||||
def __init__(self, ctrlr_info):
|
||||
"""
|
||||
All class attributes are set based on what information is received
|
||||
from get_vhost_controllers RPC call.
|
||||
# TODO: Document in docstring parameters which describe bdevs.
|
||||
# TODO: Possible improvement: JSON schema might be used here in future
|
||||
"""
|
||||
for i in ctrlr_info.keys():
|
||||
setattr(self, i, ctrlr_info[i])
|
||||
|
Loading…
Reference in New Issue
Block a user