Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
NetApp fix for 7mode iscsi volume stats
This fixes the bug for reporting correct
capacity information in case of 7mode
iscsi drivers.

Change-Id: Ie41009eca866830173809211d58470025be847e3
Closes-Bug: #1238967
(cherry picked from commit e4bde7a)
  • Loading branch information
singn committed Oct 21, 2013
1 parent eedc8ed commit 553a921
Showing 1 changed file with 74 additions and 6 deletions.
80 changes: 74 additions & 6 deletions cinder/volume/drivers/netapp/iscsi.py
Expand Up @@ -30,6 +30,7 @@
from cinder import exception
from cinder.openstack.common import excutils
from cinder.openstack.common import log as logging
from cinder.openstack.common import timeutils
from cinder import units
from cinder import utils
from cinder.volume import driver
Expand All @@ -45,6 +46,7 @@
from cinder.volume.drivers.netapp import ssc_utils
from cinder.volume.drivers.netapp.utils import get_volume_extra_specs
from cinder.volume.drivers.netapp.utils import provide_ems
from cinder.volume.drivers.netapp.utils import set_safe_attr
from cinder.volume.drivers.netapp.utils import validate_instantiation
from cinder.volume import volume_types
from oslo.config import cfg
Expand Down Expand Up @@ -1120,6 +1122,14 @@ def _do_custom_setup(self):
self.client.set_api_version(major, minor)
if self.vfiler:
self.client.set_vfiler(self.vfiler)
self.vol_refresh_time = None
self.vol_refresh_interval = 1800
self.vol_refresh_running = False
self.vol_refresh_voluntary = False
# Setting it infinite at set up
# This will not rule out backend from scheduling
self.total_gb = 'infinite'
self.free_gb = 'infinite'

def check_for_setup_error(self):
"""Check that the driver is working and can communicate."""
Expand Down Expand Up @@ -1148,13 +1158,22 @@ def _create_lun_on_eligible_vol(self, name, size, metadata,
metadata['Path'] = '/vol/%s/%s' % (volume['name'], name)
metadata['Volume'] = volume['name']
metadata['Qtree'] = None
self.vol_refresh_voluntary = True

def _get_avl_volume_by_size(self, size):
"""Get the available volume by size."""
def _get_filer_volumes(self, volume=None):
"""Returns list of filer volumes in api format."""
vol_request = NaElement('volume-list-info')
if volume:
vol_request.add_new_child('volume', volume)
res = self.client.invoke_successfully(vol_request, True)
volumes = res.get_child_by_name('volumes')
vols = volumes.get_children()
if volumes:
return volumes.get_children()
return []

def _get_avl_volume_by_size(self, size):
"""Get the available volume by size."""
vols = self._get_filer_volumes()
for vol in vols:
avl_size = vol.get_child_content('size-available')
state = vol.get_child_content('state')
Expand Down Expand Up @@ -1310,6 +1329,7 @@ def _clone_lun(self, name, new_name, space_reserved='true',
clone_id = cl_id_info.get_child_content('clone-op-id')
if vol_uuid:
self._check_clone_status(clone_id, vol_uuid, name, new_name)
self.vol_refresh_voluntary = True
luns = self._get_lun_by_args(path=clone_path)
if luns:
cloned_lun = luns[0]
Expand Down Expand Up @@ -1396,11 +1416,9 @@ def _update_volume_stats(self):
data["vendor_name"] = 'NetApp'
data["driver_version"] = self.VERSION
data["storage_protocol"] = 'iSCSI'

data['total_capacity_gb'] = 'infinite'
data['free_capacity_gb'] = 'infinite'
data['reserved_percentage'] = 0
data['QoS_support'] = False
self._get_capacity_info(data)
provide_ems(self, self.client, data, netapp_backend,
server_type="7mode")
self._stats = data
Expand All @@ -1416,3 +1434,53 @@ def _get_lun_block_count(self, path):
if major == 1 and minor < 15:
bs = bs - 1
return bs

def _get_capacity_info(self, data):
"""Calculates the capacity information for the filer."""
if (self.vol_refresh_time is None or self.vol_refresh_voluntary or
timeutils.is_newer_than(self.vol_refresh_time,
self.vol_refresh_interval)):
try:
job_set = set_safe_attr(self, 'vol_refresh_running', True)
if not job_set:
LOG.warn(
_("Volume refresh job already running. Returning..."))
return
self.vol_refresh_voluntary = False
self._refresh_capacity_info()
self.vol_refresh_time = timeutils.utcnow()
except Exception as e:
LOG.warn(_("Error refreshing vol capacity. Message: %s"), e)
finally:
set_safe_attr(self, 'vol_refresh_running', False)
data['total_capacity_gb'] = self.total_gb
data['free_capacity_gb'] = self.free_gb

def _refresh_capacity_info(self):
"""Gets the latest capacity information."""
LOG.info(_("Refreshing capacity info for %s."), self.client)
total_bytes = 0
free_bytes = 0
vols = self._get_filer_volumes()
for vol in vols:
volume = vol.get_child_content('name')
if self.volume_list and not volume in self.volume_list:
continue
state = vol.get_child_content('state')
inconsistent = vol.get_child_content('is-inconsistent')
invalid = vol.get_child_content('is-invalid')
if (state == 'online' and inconsistent == 'false'
and invalid == 'false'):
total_size = vol.get_child_content('size-total')
if total_size:
total_bytes = total_bytes + int(total_size)
avl_size = vol.get_child_content('size-available')
if avl_size:
free_bytes = free_bytes + int(avl_size)
self.total_gb = total_bytes / units.GiB
self.free_gb = free_bytes / units.GiB

def delete_volume(self, volume):
"""Driver entry point for destroying existing volumes."""
super(NetAppDirect7modeISCSIDriver, self).delete_volume(volume)
self.vol_refresh_voluntary = True

0 comments on commit 553a921

Please sign in to comment.