Skip to content

Commit ef95303

Browse files
author
gitlab
committed
Merge branch 'fix-nvme-connect' into '5.1.0'
<fix>[nvme]: fix nvme connect error See merge request zstackio/zstack-utility!4628
2 parents 8fa0e68 + 025b5dd commit ef95303

File tree

1 file changed

+58
-17
lines changed

1 file changed

+58
-17
lines changed

kvmagent/kvmagent/plugins/storage_device.py

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
130138
class 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

Comments
 (0)