Skip to content

Commit

Permalink
ccloud: Enable logical space reporting for new shares (#51)
Browse files Browse the repository at this point in the history
This pr patches NetApp driver to set the Volume's space attributes `is_space_reporting_logical` and `is_space_enforcement_logical`. When a new Share is created, the attributes are set to True values. When a Volume is created based on an existing Volume, for example when creating a Share from Snapshot, or when creating a Share replica, the attributes are set to the same values as the source Volume.

Change-Id: I64bf5d915edac6784b114127958bcb612dd2ba48
  • Loading branch information
chuan137 authored and Carthaca committed Oct 29, 2024
1 parent e7241b3 commit 66b9d00
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 33 deletions.
62 changes: 56 additions & 6 deletions manila/share/drivers/netapp/dataontap/client/client_cmode.py
Original file line number Diff line number Diff line change
Expand Up @@ -2233,7 +2233,7 @@ def create_volume(self, aggregate_name, volume_name, size_gb,
compression_enabled=False, max_files=None,
snapshot_reserve=None, volume_type='rw', comment='',
qos_policy_group=None, adaptive_qos_policy_group=None,
encrypt=None, **options):
encrypt=None, logical_space_reporting=None, **options):
"""Creates a volume."""
if adaptive_qos_policy_group and not self.features.ADAPTIVE_QOS:
msg = 'Adaptive QoS not supported on this backend ONTAP version.'
Expand All @@ -2246,7 +2246,7 @@ def create_volume(self, aggregate_name, volume_name, size_gb,
api_args.update(self._get_create_volume_api_args(
volume_name, size_gb, thin_provisioned, snapshot_policy, language,
snapshot_reserve, volume_type, comment, qos_policy_group, encrypt,
adaptive_qos_policy_group, **options))
adaptive_qos_policy_group, logical_space_reporting, **options))

self.send_request('volume-create', api_args)

Expand All @@ -2271,7 +2271,8 @@ def create_volume_async(self, aggregate_list, volume_name, size_gb,
volume_type='rw', comment='',
qos_policy_group=None, encrypt=False,
adaptive_qos_policy_group=None,
auto_provisioned=False, **options):
auto_provisioned=False,
logical_space_reporting=None, **options):
"""Creates a volume asynchronously."""

if adaptive_qos_policy_group and not self.features.ADAPTIVE_QOS:
Expand All @@ -2289,7 +2290,7 @@ def create_volume_async(self, aggregate_list, volume_name, size_gb,
api_args.update(self._get_create_volume_api_args(
volume_name, size_gb, thin_provisioned, snapshot_policy, language,
snapshot_reserve, volume_type, comment, qos_policy_group, encrypt,
adaptive_qos_policy_group, **options))
adaptive_qos_policy_group, logical_space_reporting, **options))

result = self.send_request('volume-create-async', api_args)
job_info = {
Expand All @@ -2305,7 +2306,9 @@ def _get_create_volume_api_args(self, volume_name, size_gb,
snapshot_policy, language,
snapshot_reserve, volume_type, comment,
qos_policy_group, encrypt,
adaptive_qos_policy_group, **options):
adaptive_qos_policy_group,
logical_space_reporting,
**options):
api_args = {
'volume-type': volume_type,
'volume-comment': comment,
Expand Down Expand Up @@ -2347,6 +2350,12 @@ def _get_create_volume_api_args(self, volume_name, size_gb,
else:
api_args['encrypt'] = 'false'

# SAPCC Ignore when logical_space_reporting is None. The attribue
# will be the same of its parent vserver.
if logical_space_reporting in (True, False):
api_args['is-space-reporting-logical'] = logical_space_reporting
api_args['is-space-enforcement-logical'] = logical_space_reporting

return api_args

@na_utils.trace
Expand Down Expand Up @@ -2709,7 +2718,8 @@ def modify_volume(self, aggregate_name, volume_name,
compression_enabled=False, max_files=None,
qos_policy_group=None, hide_snapdir=None,
autosize_attributes=None, comment=None, replica=False,
adaptive_qos_policy_group=None, **options):
adaptive_qos_policy_group=None,
logical_space_reporting=None, **options):
"""Update backend volume for a share as necessary.
:param aggregate_name: either a list or a string. List for aggregate
Expand Down Expand Up @@ -2796,6 +2806,13 @@ def modify_volume(self, aggregate_name, volume_name,
api_args['attributes']['volume-attributes'][
'volume-id-attributes'][
'comment'] = comment
if logical_space_reporting in (True, False):
api_args['attributes']['volume-attributes'][
'volume-space-attributes'][
'is-space-reporting-logical'] = logical_space_reporting
api_args['attributes']['volume-attributes'][
'volume-space-attributes'][
'is-space-enforcement-logical'] = logical_space_reporting

self.send_request('volume-modify-iter', api_args)

Expand Down Expand Up @@ -2840,6 +2857,29 @@ def update_volume_efficiency_attributes(self, volume_name, dedup_enabled,
else:
self.disable_compression(volume_name)

def update_volume_space_attributes(self, volume_name,
logical_space_reporting):
api_args = {
'query': {
'volume-attributes': {
'volume-id-attributes': {
'name': volume_name,
},
},
},
'attributes': {
'volume-attributes': {
'volume-space-attributes': {
'is-space-reporting-logical':
logical_space_reporting,
'is-space-enforcement-logical':
logical_space_reporting,
},
},
},
}
self.send_request('volume-modify-iter', api_args)

@na_utils.trace
def volume_exists(self, volume_name):
"""Checks if volume exists."""
Expand Down Expand Up @@ -3121,6 +3161,8 @@ def get_volume(self, volume_name):
},
'volume-space-attributes': {
'size': None,
'is-space-enforcement-logical': None,
'is-space-reporting-logical': None,
},
},
},
Expand Down Expand Up @@ -3173,6 +3215,14 @@ def get_volume(self, volume_name):
'style-extended': volume_id_attributes.get_child_content(
'style-extended')
}
volume.update({
'is-space-reporting-logical':
volume_space_attributes.get_child_content(
'is-space-reporting-logical'),
'is-space-enforcement-logical':
volume_space_attributes.get_child_content(
'is-space-enforcement-logical')
})
return volume

@na_utils.trace
Expand Down
82 changes: 69 additions & 13 deletions manila/share/drivers/netapp/dataontap/cluster_mode/lib_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,11 +732,23 @@ def get_pool(self, share):

return pool

def _get_logical_space_options(self, vserver_client, share_name):
src_volume = vserver_client.get_volume(share_name)
return {
'logical_space_reporting':
src_volume.get('is-space-reporting-logical')
}

@na_utils.trace
def create_share(self, context, share, share_server):
"""Creates new share."""
vserver, vserver_client = self._get_vserver(share_server=share_server)
self._allocate_container(share, vserver, vserver_client)
# SAPCC
# Force enabling logical-space-reporting on new Volumes.
# Disable cross volume dedupe in neo projects.
provisioning_options = {'logical_space_reporting': True}
self._allocate_container(share, vserver, vserver_client,
**provisioning_options)
return self._create_export(share, share_server, vserver,
vserver_client)

Expand All @@ -754,8 +766,13 @@ def create_share_from_snapshot(self, context, share, snapshot,
src_vserver, src_vserver_client = self._get_vserver(
share_server=share_server)
# Creating a new share from snapshot in the source share's pool
# SAPCC Get attribuets from parent Share and apply.
src_share_name = self._get_backend_share_name(snapshot['share_id'])
logical_opts = self._get_logical_space_options(
src_vserver_client, src_share_name)
self._allocate_container_from_snapshot(
share, snapshot, src_vserver, src_vserver_client)
share, snapshot, src_vserver, src_vserver_client,
**logical_opts)
return self._create_export(share, share_server, src_vserver,
src_vserver_client)

Expand Down Expand Up @@ -834,6 +851,10 @@ def create_share_from_snapshot(self, context, share, snapshot,
parent_aggr = share_utils.extract_host(parent_share['host'],
level='pool')

# SAPCC Get attributes from parent share
logical_opts = self._get_logical_space_options(src_vserver_client,
parent_share_name)

try:
# NOTE(felipe_rodrigues): no support to move volumes that are
# FlexGroup or without the cluster credential. So, performs the
Expand All @@ -849,7 +870,7 @@ def create_share_from_snapshot(self, context, share, snapshot,
# 2. Create a replica in destination host.
self._allocate_container(
dest_share, dest_vserver, dest_vserver_client,
replica=True, set_qos=False)
replica=True, set_qos=False, **logical_opts)
# 3. Initialize snapmirror relationship with cloned share.
src_share_instance['replica_state'] = (
constants.REPLICA_STATE_ACTIVE)
Expand All @@ -867,8 +888,8 @@ def create_share_from_snapshot(self, context, share, snapshot,
# its parent in order to move it to a different aggregate or
# vserver.
self._allocate_container_from_snapshot(
dest_share, snapshot, src_vserver,
src_vserver_client, split=True)
dest_share, snapshot, src_vserver, src_vserver_client,
split=True, **logical_opts)
# The split volume clone operation can take some time to be
# concluded and we'll answer the call asynchronously.
state = self.STATE_SPLITTING_VOLUME_CLONE
Expand Down Expand Up @@ -1058,15 +1079,18 @@ def _create_from_snapshot_continue(self, share, share_server=None):
if return_values['status'] == constants.STATUS_AVAILABLE:
if apply_qos_on_dest:
extra_specs = share_types.get_extra_specs_from_share(share)
share_name = self._get_backend_share_name(share['id'])
provisioning_options = self._get_provisioning_options(
extra_specs)
provisioning_options.update(
self._get_logical_space_options(src_vserver_client,
share_name))
qos_policy_group_name = (
self._modify_or_create_qos_for_existing_share(
share, extra_specs, dest_vserver, dest_vserver_client))
if qos_policy_group_name:
provisioning_options['qos_policy_group'] = (
qos_policy_group_name)
share_name = self._get_backend_share_name(share['id'])
# Modify volume to match extra specs
dest_vserver_client.modify_volume(
dest_aggr, share_name, **provisioning_options)
Expand All @@ -1085,8 +1109,8 @@ def _create_from_snapshot_continue(self, share, share_server=None):

@na_utils.trace
def _allocate_container(self, share, vserver, vserver_client,
replica=False, create_fpolicy=True,
set_qos=True):
replica=False, create_fpolicy=True, set_qos=True,
**force_provisioning_options):
"""Create new share on aggregate."""
share_name = self._get_backend_share_name(share['id'])
share_comment = self._get_backend_share_comment(share)
Expand All @@ -1098,7 +1122,8 @@ def _allocate_container(self, share, vserver, vserver_client,
raise exception.InvalidHost(reason=msg)

provisioning_options = self._get_provisioning_options_for_share(
share, vserver, vserver_client=vserver_client, set_qos=set_qos)
share, vserver, vserver_client=vserver_client, set_qos=set_qos,
**force_provisioning_options)

if replica:
# If this volume is intended to be a replication destination,
Expand Down Expand Up @@ -1479,8 +1504,9 @@ def _create_qos_policy_group(self, share, vserver, qos_specs,
return qos_policy_group_name

@na_utils.trace
def _get_provisioning_options_for_share(
self, share, vserver, vserver_client=None, set_qos=True):
def _get_provisioning_options_for_share(self, share, vserver,
vserver_client=None, set_qos=True,
**force_provisioning_options):
"""Return provisioning options from a share.
Starting with a share, this method gets the extra specs, rationalizes
Expand All @@ -1506,6 +1532,10 @@ def _get_provisioning_options_for_share(
if self._is_multi_protocol_share(share):
provisioning_options['unix-permissions'] = '0777'

# SAPCC override share type specs by force_provisioning_options
for k, v in force_provisioning_options.items():
provisioning_options[k] = v

return provisioning_options

@na_utils.trace
Expand Down Expand Up @@ -1614,7 +1644,7 @@ def _check_aggregate_extra_specs_validity(self, pool_name, specs):
def _allocate_container_from_snapshot(
self, share, snapshot, vserver, vserver_client,
snapshot_name_func=_get_backend_snapshot_name, split=None,
create_fpolicy=True):
create_fpolicy=True, **force_provisioning_options):
"""Clones existing share."""
share_name = self._get_backend_share_name(share['id'])
parent_share_name = self._get_backend_share_name(snapshot['share_id'])
Expand All @@ -1626,7 +1656,8 @@ def _allocate_container_from_snapshot(
parent_snapshot_name = snapshot['provider_location']

provisioning_options = self._get_provisioning_options_for_share(
share, vserver, vserver_client=vserver_client)
share, vserver, vserver_client=vserver_client,
**force_provisioning_options)

hide_snapdir = provisioning_options.pop('hide_snapdir')

Expand Down Expand Up @@ -2516,6 +2547,10 @@ def update_share(self, share, share_comment=None, share_server=None):
provisioning_options = self._get_provisioning_options_for_share(
share, vserver, vserver_client=vserver_client, set_qos=False)

# SAPCC Keep logical space reporting attributes while update share
provisioning_options.update(
self._get_logical_space_options(vserver_client, share_name))

qos_policy_group_name = self._modify_or_create_qos_for_existing_share(
share, extra_specs, vserver, vserver_client)
if qos_policy_group_name:
Expand Down Expand Up @@ -2918,6 +2953,19 @@ def promote_replica(self, context, replica_list, replica, access_rules,

dm_session = data_motion.DataMotionSession()

# SAPCC Get space logical reporting settings from original replica.
orig_active_vserver = dm_session.get_vserver_from_share(
orig_active_replica)
orig_active_replica_backend = share_utils.extract_host(
orig_active_replica['host'], level='backend_name')
orig_active_replica_name = self._get_backend_share_name(
orig_active_replica['id'])
orig_active_vserver_client = data_motion.get_client_for_backend(
orig_active_replica_backend, vserver_name=orig_active_vserver)
logical_opts = self._get_logical_space_options(
orig_active_vserver_client, orig_active_replica_name)
is_logical_space_reporting = logical_opts['logical_space_reporting']

new_replica_list = []

# Setup the new active replica
Expand Down Expand Up @@ -3002,6 +3050,14 @@ def promote_replica(self, context, replica_list, replica, access_rules,
vserver_client.set_volume_max_files(new_active_replica_share_name,
max_files)

# SAPCC update new replica
_, new_active_vserver_client = self._get_vserver(
share_server=share_server)
new_active_replica_name = self._get_backend_share_name(
new_active_replica['id'])
new_active_vserver_client.update_volume_space_attributes(
new_active_replica_name, is_logical_space_reporting)

return new_replica_list

def _unmount_orig_active_replica(self, orig_active_replica,
Expand Down
Loading

0 comments on commit 66b9d00

Please sign in to comment.