@@ -127,6 +127,14 @@ def __init__(self):
127127 self .storageWwnn = ""
128128
129129
130+ class NvmeController ():
131+ def __init__ (self ):
132+ self .name = ''
133+ self .transport = ''
134+ self .address = ''
135+ self .wwids = set ()
136+
137+
130138class NvmeLunStruct (ScsiLunStruct ):
131139 def __init__ (self ):
132140 super (NvmeLunStruct , self ).__init__ ()
@@ -573,15 +581,15 @@ def connect_nvme_devices(self, req):
573581 cmd = jsonobject .loads (req [http .REQUEST_BODY ])
574582 rsp = NvmeServerConnectRsp ()
575583
576- rsp .nvmeLunStructs = self .connect_nvme_server (cmd )
584+ rsp .nvmeLunStructs = self .connect_nvme_controller (cmd )
577585 return jsonobject .dumps (rsp )
578586
579587 @kvmagent .replyerror
580588 def disconnect_nvme_devices (self , req ):
581589 cmd = jsonobject .loads (req [http .REQUEST_BODY ])
582590 rsp = AgentRsp ()
583591
584- self .disconnect_nvme_server (cmd )
592+ self .disconnect_nvme_controller (cmd )
585593 return jsonobject .dumps (rsp )
586594
587595 @kvmagent .replyerror
@@ -1219,8 +1227,36 @@ def get_nqns(self):
12191227 logger .debug ("found existing nqns: %s" % str (nqns ))
12201228 return nqns
12211229
1230+ def get_nvme_subsystem_controllers (self , subsysnqn ):
1231+ nvme_subsystems = []
1232+ controllers = []
1233+ if os .path .exists ("/sys/class/nvme-subsystem" ):
1234+ nvme_subsystems = os .listdir ("/sys/class/nvme-subsystem" )
1235+
1236+ for target in nvme_subsystems :
1237+ nqn = linux .read_file ("/sys/class/nvme-subsystem/%s/subsysnqn" % target ).strip ()
1238+ if nqn != subsysnqn :
1239+ continue
1240+ parent_dir = "/sys/class/nvme-subsystem/%s" % target
1241+ for f in os .listdir (parent_dir ):
1242+ if not (os .path .basename (f ).startswith ("nvme" ) and os .path .exists ("%s/%s/address" % (parent_dir , f ))):
1243+ continue
1244+ controller = NvmeController ()
1245+ controller .name = f
1246+ controller .address = linux .read_file ("%s/%s/address" % (parent_dir , f )).strip ()
1247+ controller .transport = linux .read_file ("%s/%s/transport" % (parent_dir , f )).strip ()
1248+ controller .wwids = set ()
1249+ for ff in os .listdir ("%s/%s/" % (parent_dir , f )):
1250+ if not (os .path .basename (ff ).startswith ("nvme" ) and os .path .exists ("%s/%s/%s/wwid" % (parent_dir , f , ff ))):
1251+ continue
1252+ controller .wwids .add (linux .read_file ("%s/%s/%s/wwid" % (parent_dir , f , ff )).strip ())
1253+ controllers .append (controller )
1254+
1255+
1256+ return controllers
1257+
12221258 @bash .in_bash
1223- def connect_nvme_server (self , cmd ):
1259+ def connect_nvme_controller (self , cmd ):
12241260 r , o , e = bash .bash_roe ("timeout 60 nvme discover -a %s -s %s -t %s | grep subnqn:" % (cmd .ip , cmd .port , cmd .transport ))
12251261 if r != 0 :
12261262 raise Exception ("unable find any nqn on server[%s:%s, transport:%s], error: %s" % (cmd .ip , cmd .port , cmd .transport , str (e )))
@@ -1229,23 +1265,26 @@ def connect_nvme_server(self, cmd):
12291265 for line in o .splitlines ():
12301266 discovered_nqns .add (line .strip ().split ()[1 ])
12311267
1232- existing_nqns = self .get_nqns ()
1233- connected_nqn_cnt = 0
1268+ wwids = set ()
1269+ any_nqn_connected = False
1270+ error = ""
12341271 for nqn in discovered_nqns :
1235- if nqn in existing_nqns :
1236- connected_nqn_cnt = connected_nqn_cnt + 1
1237- continue
12381272 r , o , e = bash .bash_roe ("timeout 60 nvme connect -a %s -s %s -t %s --nqn %s" % (cmd .ip , cmd .port , cmd .transport , nqn ))
1239- if r == 0 :
1240- connected_nqn_cnt = connected_nqn_cnt + 1
1273+ for controller in self .get_nvme_subsystem_controllers (nqn ):
1274+ if controller .transport == cmd .transport and controller .address == "traddr=%s,trsvcid=%s" % (cmd .ip , cmd .port ):
1275+ any_nqn_connected = True
1276+ wwids = wwids .union (controller .wwids )
1277+ break
1278+ if not any_nqn_connected :
1279+ error = e
12411280
1242- if connected_nqn_cnt == 0 :
1243- raise Exception ("unable connect any nqn on server[%s:%s, transport:%s], error: %s" % (cmd .ip , cmd .port , cmd .transport , str (e )))
1281+ if not any_nqn_connected :
1282+ raise Exception ("unable connect any nqn on server[%s:%s, transport:%s], error: %s" % (cmd .ip , cmd .port , cmd .transport , str (error )))
12441283
1245- return filter (lambda l : l .nqn in discovered_nqns , self .get_nvme_luns (rescan = True ))
1284+ return filter (lambda l : l .nqn in discovered_nqns and set ( l . wwids ). intersection ( wwids ) , self .get_nvme_luns (rescan = True ))
12461285
12471286 @bash .in_bash
1248- def disconnect_nvme_server (self , cmd ):
1287+ def disconnect_nvme_controller (self , cmd ):
12491288 r , o , e = bash .bash_roe ("timeout 60 nvme discover -a %s -s %s -t %s | grep subnqn:" % (cmd .ip , cmd .port , cmd .transport ))
12501289 if r != 0 :
12511290 logger .warn ("unable find any nqn on server[%s:%s, transport:%s], %s" % (cmd .ip , cmd .port , cmd .transport , str (e )))
@@ -1256,9 +1295,11 @@ def disconnect_nvme_server(self, cmd):
12561295 discovered_nqns .add (line .strip ().split ()[1 ])
12571296
12581297 for nqn in discovered_nqns :
1259- r , o , e = bash .bash_roe ("timeout 60 nvme disconnect --nqn %s" % nqn )
1260- if r != 0 :
1261- logger .warn ("disconnect nvme nqn[%s] failed: %s" % (nqn , e ))
1298+ for controller in self .get_nvme_subsystem_controllers (nqn ):
1299+ if controller .transport == cmd .transport and controller .address == "traddr=%s,trsvcid=%s" % (cmd .ip , cmd .port ):
1300+ r , o , e = bash .bash_roe ("timeout 60 nvme disconnect -d %s" % controller .name )
1301+ if r != 0 :
1302+ logger .warn ("disconnect nvme nqn[%s] failed: %s" % (nqn , e ))
12621303
12631304 @bash .in_bash
12641305 def get_megaraid_devices_storcli (self , smart_scan_result ):
0 commit comments