xref: /spdk/python/spdk/sma/qos.py (revision 588dfe314bb83d86effdf67ec42837b11c2620bf)
1#  SPDX-License-Identifier: BSD-3-Clause
2#  Copyright (C) 2022 Intel Corporation.
3#  All rights reserved.
4
5import grpc
6
7from spdk.rpc.client import JSONRPCException
8from .common import format_volume_id
9from .proto import sma_pb2
10
11
12LIMIT_UNDEFINED = (1 << 64) - 1
13
14
15class QosException(Exception):
16    def __init__(self, code, message):
17        self.code = code
18        self.message = message
19
20
21def set_volume_bdev_qos(client, params):
22    class BdevLimit:
23        def __init__(self, name, transform=lambda v: v):
24            self.name = name
25            self._transform = transform
26
27        def get_value(self, value):
28            return self._transform(value)
29
30    supported_limits = {
31            'rw_iops': BdevLimit('rw_ios_per_sec', lambda v: v * 1000),
32            'rd_bandwidth': BdevLimit('r_mbytes_per_sec'),
33            'wr_bandwidth': BdevLimit('w_mbytes_per_sec'),
34            'rw_bandwidth': BdevLimit('rw_mbytes_per_sec')
35    }
36    # Check that none of the unsupported fields aren't set either
37    if params.HasField('maximum'):
38        for field, value in params.maximum.ListFields():
39            if field.name in supported_limits.keys():
40                continue
41            if value != 0 and value != LIMIT_UNDEFINED:
42                raise QosException(grpc.StatusCode.INVALID_ARGUMENT,
43                                   f'Unsupported QoS limit: maximum.{field.name}')
44    try:
45        rpc_params = {'name': format_volume_id(params.volume_id)}
46        for name, limit in supported_limits.items():
47            value = getattr(params.maximum, name)
48            if value != LIMIT_UNDEFINED:
49                rpc_params[limit.name] = limit.get_value(value)
50        client.call('bdev_set_qos_limit', rpc_params)
51    except JSONRPCException:
52        raise QosException(grpc.StatusCode.INTERNAL, 'Failed to set QoS')
53
54
55def get_bdev_qos_capabilities():
56    return sma_pb2.GetQosCapabilitiesResponse(
57            max_volume_caps=sma_pb2.GetQosCapabilitiesResponse.QosCapabilities(
58                rw_iops=True,
59                rw_bandwidth=True,
60                rd_bandwidth=True,
61                wr_bandwidth=True
62                ),
63            )
64