sma: device deletion

This patch implements the generic DeleteDevice method as well as its
NVMe/TCP implementation.

Signed-off-by: Konrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ie7aea6b12c399aec242746e5fae108623a3a161a
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10274
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Konrad Sztyber 2021-10-28 10:50:02 +02:00 committed by Tomasz Zawadzki
parent 509241cef3
commit 2ea8747935
2 changed files with 50 additions and 2 deletions

View File

@ -50,6 +50,9 @@ class NvmfTcpDeviceManager(DeviceManager):
a['traddr'].lower() == addr['traddr'].lower() and
a['trsvcid'].lower() == addr['trsvcid'].lower()), addrlist), None) is not None
def _get_nqn_from_handle(self, handle):
return handle[len('nvmf-tcp:'):]
@_check_transport
def create_device(self, request):
params = request.nvmf_tcp
@ -104,3 +107,22 @@ class NvmfTcpDeviceManager(DeviceManager):
'Failed to create NVMe/TCP device')
return sma_pb2.CreateDeviceResponse(handle=f'nvmf-tcp:{params.subnqn}')
@_check_transport
def delete_device(self, request):
with self._client() as client:
nqn = self._get_nqn_from_handle(request.handle)
subsystems = client.call('nvmf_get_subsystems')
for subsystem in subsystems:
if subsystem['nqn'] == nqn:
result = client.call('nvmf_delete_subsystem',
{'nqn': nqn})
if not result:
raise DeviceException(grpc.StatusCode.INTERNAL,
'Failed to delete device')
break
else:
logging.info(f'Tried to delete a non-existing device: {nqn}')
def owns_device(self, handle):
return handle.startswith('nvmf-tcp')

View File

@ -28,14 +28,23 @@ class StorageManagementAgent(pb2_grpc.StorageManagementAgentServicer):
self._server.start()
self._server.wait_for_termination()
def _find_device(self, name):
def _find_device_by_name(self, name):
return self._devices.get(name)
def _find_device_by_handle(self, handle):
for device in self._devices.values():
try:
if device.owns_device(handle):
return device
except NotImplementedError:
pass
return None
@_grpc_method
def CreateDevice(self, request, context):
response = pb2.CreateDeviceResponse()
try:
manager = self._find_device(request.WhichOneof('params'))
manager = self._find_device_by_name(request.WhichOneof('params'))
if manager is None:
raise DeviceException(grpc.StatusCode.INVALID_ARGUMENT,
'Unsupported device type')
@ -47,3 +56,20 @@ class StorageManagementAgent(pb2_grpc.StorageManagementAgentServicer):
context.set_details('Method is not implemented by selected device type')
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
return response
@_grpc_method
def DeleteDevice(self, request, context):
response = pb2.DeleteDeviceResponse()
try:
device = self._find_device_by_handle(request.handle)
if device is None:
raise DeviceException(grpc.StatusCode.NOT_FOUND,
'Invalid device handle')
device.delete_device(request)
except DeviceException as ex:
context.set_details(ex.message)
context.set_code(ex.code)
except NotImplementedError:
context.set_details('Method is not implemented by selected device type')
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
return response