Commit 2ea87479 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

sma: device deletion



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

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ie7aea6b12c399aec242746e5fae108623a3a161a
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10274


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 509241ce
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -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')
+28 −2
Original line number Diff line number Diff line
@@ -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