From 2ea8747935fa588544017af0afa0faaa91cc8633 Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Thu, 28 Oct 2021 10:50:02 +0200 Subject: [PATCH] sma: device deletion This patch implements the generic DeleteDevice method as well as its NVMe/TCP implementation. Signed-off-by: Konrad Sztyber Change-Id: Ie7aea6b12c399aec242746e5fae108623a3a161a Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10274 Tested-by: SPDK CI Jenkins Community-CI: Broadcom CI Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- python/spdk/sma/device/nvmf_tcp.py | 22 ++++++++++++++++++++++ python/spdk/sma/sma.py | 30 ++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/python/spdk/sma/device/nvmf_tcp.py b/python/spdk/sma/device/nvmf_tcp.py index 21fe76667..60e741674 100644 --- a/python/spdk/sma/device/nvmf_tcp.py +++ b/python/spdk/sma/device/nvmf_tcp.py @@ -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') diff --git a/python/spdk/sma/sma.py b/python/spdk/sma/sma.py index 02bdadf0e..59b314102 100644 --- a/python/spdk/sma/sma.py +++ b/python/spdk/sma/sma.py @@ -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