ANA configuration support
PATCH 1/1 ANA configuration support
Add support for ANA configuration to nvmetcli.
--- nvmet/nvme.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nvmetcli | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+)
nvmet/nvme.py +99 -0
@@ -566,6 +566,24 @@ class Namespace(CFSNode): def _get_nsid(self): return self._nsid + def _get_grpid(self): + self._check_self() + _grpid = 0 + path = "%s/ana_grpid" % self.path + if os.path.isfile(path): + with open(path, 'r') as file_fd: + _grpid = int(file_fd.read().strip()) + return _grpid + + def set_grpid(self, grpid): + self._check_self() + path = "%s/ana_grpid" % self.path + if os.path.isfile(path): + with open(path, 'w') as file_fd: + file_fd.write(str(grpid)) + + grpid = property(_get_grpid, doc="Get the ANA Group ID.") + subsystem = property(_get_subsystem, doc="Get the parent Subsystem object.") nsid = property(_get_nsid, doc="Get the NSID as an int.")
@@ -589,10 +607,12 @@ class Namespace(CFSNode): return ns._setup_attrs(n, err_func) + ns.set_grpid(int(n['ana_grpid'])) def dump(self): d = super(Namespace, self).dump() d['nsid'] = self.nsid + d['ana_grpid'] = self.grpid return d
@@ -652,6 +672,8 @@ class Port(CFSNode): self._check_self() for s in self.subsystems: self.remove_subsystem(s) + for a in self.ana_groups: + a.delete() for r in self.referrals: r.delete() super(Port, self).delete()
@@ -664,6 +686,14 @@ class Port(CFSNode): referrals = property(_list_referrals, doc="Get the list of Referrals for this Port.") + def _list_ana_groups(self): + self._check_self() + for d in os.listdir("%s/ana_groups/" % self._path): + yield ANA_Group(self, int(d), 'lookup') + + ana_groups = property(_list_ana_groups, + doc="Get the list of ANA Groups for this Port.") + @classmethod def setup(cls, root, n, err_func): '''
@@ -685,6 +715,8 @@ class Port(CFSNode): port._setup_attrs(n, err_func) for s in n.get('subsystems', []): port.add_subsystem(s) + for a in n.get('ana_groups', []): + ANA_Group.setup(port, a, err_func) for r in n.get('referrals', []): Referral.setup(port, r, err_func)
@@ -692,6 +724,7 @@ class Port(CFSNode): d = super(Port, self).dump() d['portid'] = self.portid d['subsystems'] = self.subsystems + d['ana_groups'] = [a.dump() for a in self.ana_groups] d['referrals'] = [r.dump() for r in self.referrals] return d
@@ -747,6 +780,72 @@ class Referral(CFSNode): return d +class ANA_Group(CFSNode): + ''' + This is an interface to a NVMe ANA Group in configFS. + ''' + + MAX_GRPID = 128 + + def __repr__(self): + return "<ANA Group %d>" % self.grpid + + def __init__(self, port, grpid, mode='any'): + super(ANA_Group, self).__init__() + + if grpid is None: + if mode == 'lookup': + raise CFSError("Need grpid for lookup") + + grpids = [n.grpid for n in port.ana_groups] + for index in xrange(2, self.MAX_GRPID + 1): + if index not in grpids: + grpid = index + break + if grpid is None: + raise CFSError("All ANA Group IDs 1-%d in use" % self.MAX_GRPID) + else: + grpid = int(grpid) + if grpid < 1 or grpid > self.MAX_GRPID: + raise CFSError("GRPID %d must be 1 to %d" % (grpid, self.MAX_GRPID)) + + self.attr_groups = ['ana'] + self._port = port + self._grpid = grpid + self._path = "%s/ana_groups/%d" % (self._port.path, self.grpid) + self._create_in_cfs(mode) + + def _get_grpid(self): + return self._grpid + + grpid = property(_get_grpid, doc="Get the ANA Group ID.") + + @classmethod + def setup(cls, port, n, err_func): + ''' + Set up an ANA Group object based upon n dict, from saved config. + Guard against missing or bad dict items, but keep going. + Call 'err_func' for each error. + ''' + + if 'grpid' not in n: + err_func("'grpid' not defined for ANA Group") + return + + try: + a = ANA_Group(port, n['grpid']) + except CFSError as e: + err_func("Could not create ANA Group object: %s" % e) + return + + a._setup_attrs(n, err_func) + + def dump(self): + d = super(ANA_Group, self).dump() + d['grpid'] = self.grpid + return d + + class Host(CFSNode): ''' This is an interface to a NVMe Host in configFS.
nvmetcli +59 -0
83 lines not on this page · raw message
Signature · 1 line
2.13.6
PATCH 1/1 ANA configuration support
Quoted 1 line · Hannes Reinecke
+class
ANA_Group(CFSNode):
Please use ANAGroup to be consistent with the rest and Python's PEP8 guidelines.
Signature · 6 lines
Johannes Thumshirn Storage jthumshirn at suse.de +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg GF: Felix Imend?rffer, Jane Smithard, Graham Norton HRB 21284 (AG N?rnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
Christoph Hellwig
maintainerPATCH 1/1 ANA configuration support
Quoted 5 lines · Johannes Thumshirn
Quoted 1 line · Hannes Reinecke
+class
ANA_Group(CFSNode):Please use ANAGroup to be consistent with the rest and Python's PEP8 guidelines.
Agreed. Please run the code through pep8 and pylint in general. There are a few warnings, especially from the latter, but nothing crazy should be introduced.
Also we'll need to cover the ANA code in the unit tests.
PATCH 1/1 ANA configuration support
Quoted 4 lines · On Thu, 7 Jun 2018 14:12:45 +0200 Christoph Hellwig <[email protected]> wrote:
Quoted 3 lines · Johannes Thumshirn
Quoted 1 line · Hannes Reinecke
+class
ANA_Group(CFSNode):
Quoted 9 lines
Quoted 2 lines
Please use ANAGroup to be consistent with the rest and Python's PEP8 guidelines.
Agreed. Please run the code through pep8 and pylint in general. There are a few warnings, especially from the latter, but nothing crazy should be introduced.
Also we'll need to cover the ANA code in the unit tests.
No problem. First time for me to send a substantial python patch, so I guess I have still a learning curve here.
Cheers,
Hannes