diff --git a/nvmet/nvme.py b/nvmet/nvme.py index 28633cf8da4cf9a801637b2edc24987c68aa721e..a13eba3b0ef3978c9c2abf6739ab17647dcba401 100644 --- a/nvmet/nvme.py +++ b/nvmet/nvme.py @@ -50,6 +50,7 @@ class CFSNode(object): def __init__(self): self._path = self.configfs_dir + self._enable = 0 self.attr_groups = [] def __eq__(self, other): @@ -137,6 +138,10 @@ class CFSNode(object): if not os.path.isfile(path): raise CFSError("Cannot find attribute: %s" % path) + if self._enable > 0: + raise CFSError("Cannot set attribute while %s is enabled" % + self.__class__.__name__) + try: with open(path, 'w') as file_fd: file_fd.write(str(value)) @@ -158,6 +163,30 @@ class CFSNode(object): with open(path, 'r') as file_fd: return file_fd.read().strip() + def get_enable(self): + self._check_self() + path = "%s/enable" % self.path + if not os.path.isfile(path): + return False + + with open(path, 'r') as file_fd: + self._enable = int(file_fd.read().strip()) + return self._enable + + def set_enable(self, value): + self._check_self() + path = "%s/enable" % self.path + + if not os.path.isfile(path): + raise CFSError("Cannot enable %s" % self.path) + + try: + with open(path, 'w') as file_fd: + file_fd.write(str(value)) + except Exception as e: + raise CFSError("Cannot enable attribute %s: %s (%s)" % (self.path, e, value)) + self._enable = value + def delete(self): ''' If the underlying configFS object does not exist, this method does @@ -182,6 +211,8 @@ class CFSNode(object): for i in self.list_attrs(group, writable=True): a[str(i)] = self.get_attr(group, i) d[str(group)] = a + if self._enable is not None: + d['enable'] = self._enable return d def _setup_attrs(self, attr_dict, err_func): @@ -191,6 +222,9 @@ class CFSNode(object): self.set_attr(group, name, value) except CFSError as e: err_func(str(e)) + enable = attr_dict.get('enable') + if enable is not None: + self.set_enable(enable) class Root(CFSNode): @@ -439,6 +473,7 @@ class Namespace(CFSNode): self._nsid = nsid self._path = "%s/namespaces/%d" % (self.subsystem.path, self.nsid) self._create_in_cfs(mode) + self.get_enable() # XXX should move to baseclass def _get_subsystem(self): return self._subsystem diff --git a/nvmetcli b/nvmetcli index fa2623b9325c18e7dab8290836a3eadca3cc5885..d87bf79b13b68e57d1e3e387800d424c8f245819 100755 --- a/nvmetcli +++ b/nvmetcli @@ -55,6 +55,25 @@ class UINode(configshell.node.ConfigNode): def refresh(self): self._children = set([]) + def status(self): + return "None" + + def ui_command_refresh(self): + ''' + Refreshes and updates the objects tree from the current path. + ''' + self.refresh() + + def ui_command_status(self): + ''' + Displays the current node's status summary. + + SEE ALSO + ======== + B{ls} + ''' + self.shell.log.info("Status for %s: %s" % (self.path, self.status())) + def ui_command_saveconfig(self, savefile=None): ''' Saves the current configuration to a file so that it can be restored @@ -175,6 +194,47 @@ class UINamespaceNode(UINode): def __init__(self, parent, cfnode): UINode.__init__(self, str(cfnode.nsid), parent, cfnode) + def status(self): + if self.cfnode.get_enable(): + return "enabled" + return "disabled" + + def ui_command_enable(self): + ''' + Enables the current Namespace. + + SEE ALSO + ======== + B{disable} + ''' + if self.cfnode.get_enable(): + self.shell.log.info("The Namespace is already enabled.") + else: + try: + self.cfnode.set_enable(1) + self.shell.log.info("The Namespace has been enabled.") + except Exception as e: + raise configshell.ExecutionError( + "The Namespace could not be enabled.") + + def ui_command_disable(self): + ''' + Disables the current Namespace. + + SEE ALSO + ======== + B{enable} + ''' + if not self.cfnode.get_enable(): + self.shell.log.info("The Namespace is already disabled.") + else: + try: + self.cfnode.set_enable(0) + self.shell.log.info("The Namespace has been disabled.") + except Exception as e: + raise configshell.ExecutionError( + "The Namespace could not be dsiabled.") + def usage(): print("syntax: %s save [file_to_save_to]" % sys.argv[0])