Skip to contentSkip to conversation

ANA configuration support

PATCH New Hannes Reinecke 3 participants 4 messages Jun 7, 2018 NVMe

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ANA configuration support

Add support for ANA configuration to nvmetcli.

Signed-off-by Hannes Reinecke <hare at suse.com>
---
 nvmet/nvme.py | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 nvmetcli      | 59 +++++++++++++++++++++++++++++++++++
 2 files changed, 158 insertions(+)
nvmet/nvme.py +99 -0
index 8253ea9..baf972c 100644
@@ -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
#1 lore raw

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
#2 lore raw

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

#3 lore raw

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