mirror of
https://github.com/ceph/ceph
synced 2026-08-02 07:03:18 +00:00
Merge pull request #68257 from avanthakkar/add-cluster-qos-cmd
mgr/smb: add cluster-level QoS update command for CephFS shares Reviewed-by: Anoop C S <anoopcs@cryptolab.net> Reviewed-by: Shwetha Acharya <sacharya@redhat.com> Reviewed-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
commit
8bb89be902
@ -166,6 +166,56 @@ previous example. Set three CTDB public address values and a custom placement:
|
||||
--placement="3 label:smb"
|
||||
|
||||
|
||||
Update Cluster QoS
|
||||
++++++++++++++++++
|
||||
|
||||
.. prompt:: bash #
|
||||
|
||||
ceph smb cluster update cephfs qos <cluster_id> [--read-iops-limit=<int>] [--write-iops-limit=<int>] [--read-bw-limit=<str>] [--write-bw-limit=<str>] [--read-burst-mult=<int>] [--write-burst-mult=<int>]
|
||||
|
||||
Update Quality of Service (QoS) settings for all CephFS-backed shares within a cluster. This command applies the same per-share QoS limits to every share in the specified cluster that has CephFS storage configured. This is particularly useful for clusters with many shares that require uniform QoS policies.
|
||||
|
||||
Options: See :ref:`qos-parameters` for detailed descriptions of all QoS parameters.
|
||||
|
||||
Examples:
|
||||
|
||||
Apply the same IOPS limits to all shares in a cluster:
|
||||
|
||||
.. prompt:: bash #
|
||||
|
||||
ceph smb cluster update cephfs qos prod \
|
||||
--read-iops-limit=1000 \
|
||||
--write-iops-limit=500
|
||||
|
||||
Apply bandwidth limits with human-readable units to all shares:
|
||||
|
||||
.. prompt:: bash #
|
||||
|
||||
ceph smb cluster update cephfs qos prod \
|
||||
--read-bw-limit="10M" \
|
||||
--write-bw-limit="5M"
|
||||
|
||||
Apply QoS limits with burst multipliers to all shares:
|
||||
|
||||
.. prompt:: bash #
|
||||
|
||||
ceph smb cluster update cephfs qos prod \
|
||||
--read-iops-limit=100 \
|
||||
--write-iops-limit=200 \
|
||||
--read-burst-mult=20 \
|
||||
--write-burst-mult=15
|
||||
|
||||
Disable QoS for all shares in a cluster:
|
||||
|
||||
.. prompt:: bash #
|
||||
|
||||
ceph smb cluster update cephfs qos prod \
|
||||
--read-iops-limit=0 \
|
||||
--write-iops-limit=0 \
|
||||
--read-bw-limit=0 \
|
||||
--write-bw-limit=0
|
||||
|
||||
|
||||
Remove Cluster
|
||||
++++++++++++++
|
||||
|
||||
@ -262,16 +312,14 @@ Create a read-only share at a custom path in the CephFS volume:
|
||||
ceph smb share create test1 plans cephfs \
|
||||
--path=/qbranch/top/secret/plans --readonly
|
||||
|
||||
Update Share QoS
|
||||
++++++++++++++++
|
||||
|
||||
.. prompt:: bash #
|
||||
.. _qos-parameters:
|
||||
|
||||
ceph smb share update cephfs qos <cluster_id> <share_id> [--read-iops-limit=<int>] [--write-iops-limit=<int>] [--read-bw-limit=<str>] [--write-bw-limit=<str>] [--read-burst-mult=<int>] [--write-burst-mult=<int>]
|
||||
QoS Parameters
|
||||
++++++++++++++
|
||||
|
||||
Update Quality of Service (QoS) settings for a CephFS-backed share. This allows administrators to apply per-share rate limits on SMB input/output (I/O) operations, specifically limits on IOPS (Input/Output Operations per Second) and bandwidth (in bytes per second) for both read and write operations. Additionally, burst multipliers can be configured to allow temporary bursts above the configured limits.
|
||||
|
||||
Options:
|
||||
The following Quality of Service (QoS) parameters are available for CephFS-backed shares.
|
||||
All parameters are optional and can be used independently.
|
||||
|
||||
read_iops_limit
|
||||
Optional integer. Maximum number of read operations per second (0 = disabled).
|
||||
@ -326,6 +374,18 @@ larger bursts but may temporarily consume more resources.
|
||||
The burst multiplier only affects short-term spikes. The long-term average
|
||||
throughput remains limited by your configured IOPS and bandwidth limits.
|
||||
|
||||
|
||||
Update Share QoS
|
||||
++++++++++++++++
|
||||
|
||||
.. prompt:: bash #
|
||||
|
||||
ceph smb share update cephfs qos <cluster_id> <share_id> [--read-iops-limit=<int>] [--write-iops-limit=<int>] [--read-bw-limit=<str>] [--write-bw-limit=<str>] [--read-burst-mult=<int>] [--write-burst-mult=<int>]
|
||||
|
||||
Update Quality of Service (QoS) settings for a CephFS-backed share. This allows administrators to apply per-share rate limits on SMB input/output (I/O) operations, specifically limits on IOPS (Input/Output Operations per Second) and bandwidth (in bytes per second) for both read and write operations. Additionally, burst multipliers can be configured to allow temporary bursts above the configured limits.
|
||||
|
||||
Options: See :ref:`qos-parameters` for detailed descriptions of all QoS parameters.
|
||||
|
||||
Examples:
|
||||
|
||||
Set QoS limits with burst multipliers for a share:
|
||||
|
||||
@ -345,6 +345,98 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
|
||||
[cluster], password_filter_out=password_filter
|
||||
).one()
|
||||
|
||||
@SMBCLICommand('cluster update cephfs qos', perm='rw')
|
||||
def cluster_update_qos(
|
||||
self,
|
||||
cluster_id: str,
|
||||
read_iops_limit: Optional[int] = None,
|
||||
write_iops_limit: Optional[int] = None,
|
||||
read_bw_limit: Optional[str] = None,
|
||||
write_bw_limit: Optional[str] = None,
|
||||
read_burst_mult: Optional[int] = None,
|
||||
write_burst_mult: Optional[int] = None,
|
||||
) -> Simplified:
|
||||
"""Update QoS settings for all CephFS shares in a cluster"""
|
||||
try:
|
||||
shares = self._handler.matching_resources(
|
||||
[f'ceph.smb.share.{cluster_id}']
|
||||
)
|
||||
|
||||
active_shares = [
|
||||
s for s in shares if isinstance(s, resources.Share)
|
||||
]
|
||||
|
||||
if not active_shares:
|
||||
raise ValueError(f"No shares found for cluster {cluster_id}")
|
||||
|
||||
shares_to_update: List[resources.SMBResource] = []
|
||||
unchanged_shares = []
|
||||
|
||||
for share in active_shares:
|
||||
if not share.cephfs:
|
||||
unchanged_shares.append(share.share_id)
|
||||
continue
|
||||
|
||||
try:
|
||||
updated_cephfs = share.cephfs.update_qos(
|
||||
read_iops_limit=read_iops_limit,
|
||||
write_iops_limit=write_iops_limit,
|
||||
read_bw_limit=read_bw_limit,
|
||||
write_bw_limit=write_bw_limit,
|
||||
read_burst_mult=read_burst_mult,
|
||||
write_burst_mult=write_burst_mult,
|
||||
)
|
||||
|
||||
if updated_cephfs != share.cephfs:
|
||||
updated_share = replace(share, cephfs=updated_cephfs)
|
||||
shares_to_update.append(updated_share)
|
||||
else:
|
||||
unchanged_shares.append(share.share_id)
|
||||
|
||||
except ValueError as e:
|
||||
raise ValueError(
|
||||
f"Error updating share {share.share_id}: {str(e)}"
|
||||
)
|
||||
|
||||
if not shares_to_update:
|
||||
return {
|
||||
"cluster_id": cluster_id,
|
||||
"message": "No shares required QoS updates",
|
||||
"unchanged_shares": unchanged_shares,
|
||||
"total_shares": len(active_shares),
|
||||
}
|
||||
|
||||
result_group = self._apply_res(shares_to_update)
|
||||
|
||||
successful_updates = []
|
||||
failed_updates = []
|
||||
|
||||
for result in result_group:
|
||||
if result.success and hasattr(result.src, 'share_id'):
|
||||
successful_updates.append(result.src.share_id)
|
||||
elif hasattr(result.src, 'share_id'):
|
||||
failed_updates.append(
|
||||
{"share_id": result.src.share_id, "error": result.msg}
|
||||
)
|
||||
|
||||
return {
|
||||
"cluster_id": cluster_id,
|
||||
"successful_updates": successful_updates,
|
||||
"failed_updates": failed_updates,
|
||||
"unchanged_shares": unchanged_shares,
|
||||
"total_shares": len(active_shares),
|
||||
"success": len(failed_updates) == 0,
|
||||
}
|
||||
|
||||
except resources.InvalidResourceError as err:
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(err),
|
||||
"resource": err.resource_data,
|
||||
}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
@SMBCLICommand('share ls', perm='r')
|
||||
def share_ls(self, cluster_id: str) -> List[str]:
|
||||
"""List smb shares in a cluster by ID"""
|
||||
|
||||
@ -1030,6 +1030,80 @@ def test_cmd_share_update_qos(tmodule):
|
||||
assert updated_share.cephfs.qos.write_burst_mult == 15 # Default
|
||||
|
||||
|
||||
def test_cmd_cluster_update_qos(tmodule):
|
||||
cluster = _cluster(
|
||||
cluster_id='qoscluster',
|
||||
auth_mode=smb.enums.AuthMode.USER,
|
||||
user_group_settings=[
|
||||
smb.resources.UserGroupSource(
|
||||
source_type=smb.resources.UserGroupSourceType.EMPTY,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
share1 = smb.resources.Share(
|
||||
cluster_id='qoscluster',
|
||||
share_id='share1',
|
||||
name='Share One',
|
||||
cephfs=smb.resources.CephFSStorage(
|
||||
volume='cephfs',
|
||||
path='/share1',
|
||||
),
|
||||
)
|
||||
share2 = smb.resources.Share(
|
||||
cluster_id='qoscluster',
|
||||
share_id='share2',
|
||||
name='Share Two',
|
||||
cephfs=smb.resources.CephFSStorage(
|
||||
volume='cephfs',
|
||||
path='/share2',
|
||||
),
|
||||
)
|
||||
share3 = smb.resources.Share(
|
||||
cluster_id='qoscluster',
|
||||
share_id='share3',
|
||||
name='Share Three',
|
||||
cephfs=smb.resources.CephFSStorage(
|
||||
volume='cephfs',
|
||||
path='/share3',
|
||||
),
|
||||
)
|
||||
|
||||
rg = tmodule._handler.apply([cluster, share1, share2, share3])
|
||||
assert rg.success, rg.to_simplified()
|
||||
|
||||
res, body, status = tmodule.cluster_update_qos.command(
|
||||
cluster_id='qoscluster',
|
||||
read_iops_limit=100,
|
||||
write_iops_limit=200,
|
||||
read_bw_limit="1048576",
|
||||
write_bw_limit="2097152",
|
||||
read_burst_mult=20,
|
||||
write_burst_mult=15,
|
||||
)
|
||||
assert res == 0
|
||||
bdata = json.loads(body)
|
||||
assert bdata['success']
|
||||
assert bdata['cluster_id'] == 'qoscluster'
|
||||
assert bdata['total_shares'] == 3
|
||||
assert len(bdata['successful_updates']) == 3
|
||||
assert len(bdata['failed_updates']) == 0
|
||||
|
||||
for share_id in ['share1', 'share2', 'share3']:
|
||||
updated_shares = tmodule._handler.matching_resources(
|
||||
[f'ceph.smb.share.qoscluster.{share_id}']
|
||||
)
|
||||
assert len(updated_shares) == 1
|
||||
updated_share = updated_shares[0]
|
||||
assert updated_share.cephfs.qos is not None
|
||||
assert updated_share.cephfs.qos.read_iops_limit == 100
|
||||
assert updated_share.cephfs.qos.write_iops_limit == 200
|
||||
assert updated_share.cephfs.qos.read_bw_limit == "1048576"
|
||||
assert updated_share.cephfs.qos.write_bw_limit == "2097152"
|
||||
assert updated_share.cephfs.qos.read_burst_mult == 20
|
||||
assert updated_share.cephfs.qos.write_burst_mult == 15
|
||||
|
||||
|
||||
def _keybridge_example():
|
||||
return [
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user