From 89b81dc2ff0665b2bdcf0a9c36934b078ad20d8e Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Tue, 30 Aug 2022 05:52:23 +0200 Subject: [PATCH] sma: support bdev-based QoS for NVMe/TCP devices Signed-off-by: Konrad Sztyber Change-Id: I9634c2492addd3b4848d4b53b9b258dd59b7d1dd Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14269 Tested-by: SPDK CI Jenkins Reviewed-by: Tomasz Zawadzki Reviewed-by: Jim Harris --- python/spdk/sma/device/nvmf_tcp.py | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/python/spdk/sma/device/nvmf_tcp.py b/python/spdk/sma/device/nvmf_tcp.py index 03bd518c6..fad8a9a16 100644 --- a/python/spdk/sma/device/nvmf_tcp.py +++ b/python/spdk/sma/device/nvmf_tcp.py @@ -2,6 +2,7 @@ import grpc import logging import uuid from spdk.rpc.client import JSONRPCException +from spdk.sma import qos from .device import DeviceManager, DeviceException from ..common import format_volume_id, volume_id_to_nguid from ..volume import get_crypto_engine, CryptoException @@ -209,3 +210,37 @@ class NvmfTcpDeviceManager(DeviceManager): def owns_device(self, handle): return handle.startswith('nvmf-tcp') + + def set_qos(self, request): + nqn = self._get_nqn_from_handle(request.device_handle) + volume = format_volume_id(request.volume_id) + if volume is None: + raise DeviceException(grpc.StatusCode.INVALID_ARGUMENT, + 'Invalid volume ID') + try: + with self._client() as client: + # Make sure that a volume exists and is attached to the device + bdev = self._find_bdev(client, volume) + if bdev is None: + raise DeviceException(grpc.StatusCode.NOT_FOUND, + 'No volume associated with volume_id could be found') + try: + subsys = client.call('nvmf_get_subsystems', {'nqn': nqn})[0] + except JSONRPCException: + raise DeviceException(grpc.StatusCode.NOT_FOUND, + 'No device associated with device_handle could be found') + for ns in subsys['namespaces']: + if ns['name'] == bdev['name']: + break + else: + raise DeviceException(grpc.StatusCode.INVALID_ARGUMENT, + 'Specified volume is not attached to the device') + qos.set_volume_bdev_qos(client, request) + except qos.QosException as ex: + raise DeviceException(ex.code, ex.message) + except JSONRPCException: + raise DeviceException(grpc.StatusCode.INTERNAL, + 'Failed to set QoS') + + def get_qos_capabilities(self, request): + return qos.get_bdev_qos_capabilities()