Merge "Improve Hitachi HNAS volume drivers log messages"
This commit is contained in:
commit
dbebca66b0
@ -254,10 +254,20 @@ class HNASiSCSIDriverTest(test.TestCase):
|
||||
'172.17.39.133': {'evs_number': 2},
|
||||
'172.17.39.134': {'evs_number': 3}}
|
||||
|
||||
version_info = {
|
||||
'mac': '83-68-96-AA-DA-5D',
|
||||
'model': 'HNAS 4040',
|
||||
'version': '12.4.3924.11',
|
||||
'hardware': 'NAS Platform',
|
||||
'serial': 'B1339109',
|
||||
}
|
||||
|
||||
self.mock_object(HNASSSHBackend, 'get_fs_info',
|
||||
mock.Mock(return_value=True))
|
||||
self.mock_object(HNASSSHBackend, 'get_evs_info',
|
||||
mock.Mock(return_value=evs_info))
|
||||
self.mock_object(HNASSSHBackend, 'get_version',
|
||||
mock.Mock(return_value=version_info))
|
||||
|
||||
self.driver.do_setup(None)
|
||||
|
||||
@ -269,10 +279,20 @@ class HNASiSCSIDriverTest(test.TestCase):
|
||||
'172.17.39.133': {'evs_number': 2},
|
||||
'172.17.39.134': {'evs_number': 3}}
|
||||
|
||||
version_info = {
|
||||
'mac': '83-68-96-AA-DA-5D',
|
||||
'model': 'HNAS 4040',
|
||||
'version': '12.4.3924.11',
|
||||
'hardware': 'NAS Platform',
|
||||
'serial': 'B1339109',
|
||||
}
|
||||
|
||||
self.mock_object(HNASSSHBackend, 'get_fs_info',
|
||||
mock.Mock(return_value=True))
|
||||
self.mock_object(HNASSSHBackend, 'get_evs_info',
|
||||
mock.Mock(return_value=evs_info))
|
||||
self.mock_object(HNASSSHBackend, 'get_version',
|
||||
mock.Mock(return_value=version_info))
|
||||
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.driver.do_setup, None)
|
||||
|
@ -82,12 +82,12 @@ class HNASSSHBackend(object):
|
||||
return out, err
|
||||
except putils.ProcessExecutionError as e:
|
||||
if 'Failed to establish SSC connection' in e.stderr:
|
||||
LOG.debug("SSC connection error!")
|
||||
msg = _("Failed to establish SSC connection.")
|
||||
msg = _("Failed to establish SSC connection!")
|
||||
LOG.exception(msg)
|
||||
raise exception.HNASConnError(msg)
|
||||
elif 'Connection reset' in e.stderr:
|
||||
LOG.debug("HNAS connection reset!")
|
||||
msg = _("HNAS has disconnected SSC")
|
||||
msg = _("HNAS connection reset!")
|
||||
LOG.exception(msg)
|
||||
raise exception.HNASConnError(msg)
|
||||
else:
|
||||
raise
|
||||
@ -124,6 +124,7 @@ class HNASSSHBackend(object):
|
||||
|
||||
self.storage_version = version_info
|
||||
|
||||
LOG.debug("version_info: %(info)s", {'info': self.storage_version})
|
||||
return self.storage_version
|
||||
|
||||
def get_evs_info(self):
|
||||
@ -236,7 +237,10 @@ class HNASSSHBackend(object):
|
||||
# When the FS is found in the list of known FS, returns the EVS ID
|
||||
for key in self.fslist:
|
||||
if fs_label == self.fslist[key]['label']:
|
||||
LOG.debug("EVS ID for fs %(fs)s: %(id)s.",
|
||||
{'fs': fs_label, 'id': self.fslist[key]['evsid']})
|
||||
return self.fslist[key]['evsid']
|
||||
LOG.debug("Can't find EVS ID for fs %(fs)s.", {'fs': fs_label})
|
||||
|
||||
def _get_targets(self, evs_id, tgt_alias=None, refresh=False):
|
||||
"""Gets the target list of an EVS.
|
||||
@ -365,11 +369,13 @@ class HNASSSHBackend(object):
|
||||
if not fs:
|
||||
LOG.error(_LE("Can't find file %(file)s in FS %(label)s"),
|
||||
{'file': src, 'label': fs_label})
|
||||
msg = _('FS label: %s') % fs_label
|
||||
msg = _('FS label: %(fs_label)s') % {'fs_label': fs_label}
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
self._run_cmd("console-context", "--evs", fs['evsid'],
|
||||
'file-clone-create', '-f', fs_label, src, name)
|
||||
LOG.debug('file_clone: fs:%(fs_label)s %(src)s/src: -> %(name)s/dst',
|
||||
{'fs_label': fs_label, 'src': src, 'name': name})
|
||||
|
||||
def extend_lu(self, fs_label, new_size, lu_name):
|
||||
"""Extends an iSCSI volume.
|
||||
@ -433,6 +439,7 @@ class HNASSSHBackend(object):
|
||||
|
||||
LOG.debug('add_iscsi_conn: LU %(lu)s added to %(tgt)s.',
|
||||
{'lu': lu_name, 'tgt': tgt_alias})
|
||||
LOG.debug('conn_info: %(conn_info)s', {'conn_info': conn_info})
|
||||
|
||||
return conn_info
|
||||
|
||||
@ -487,7 +494,10 @@ class HNASSSHBackend(object):
|
||||
for line in lines:
|
||||
if 'Globally unique name' in line:
|
||||
full_iqn = line.split()[3]
|
||||
LOG.debug('get_target_iqn: %(iqn)s', {'iqn': full_iqn})
|
||||
return full_iqn
|
||||
LOG.debug("Could not find iqn for alias %(alias)s on fs %(fs_label)s",
|
||||
{'alias': tgt_alias, 'fs_label': fs_label})
|
||||
|
||||
def set_target_secret(self, targetalias, fs_label, secret):
|
||||
"""Sets the chap secret for the specified target.
|
||||
@ -598,7 +608,8 @@ class HNASSSHBackend(object):
|
||||
lu_info['id'] = 0
|
||||
lu_info['tgt'] = None
|
||||
|
||||
LOG.debug("LU %(lu)s not attached.", {'lu': vol_name})
|
||||
LOG.debug("LU %(lu)s not attached. lu_info: %(lu_info)s",
|
||||
{'lu': vol_name, 'lu_info': lu_info})
|
||||
|
||||
return lu_info
|
||||
|
||||
@ -769,6 +780,7 @@ class HNASSSHBackend(object):
|
||||
|
||||
export_list.append(export_info)
|
||||
|
||||
LOG.debug("get_export_list: %(exp_list)s", {'exp_list': export_list})
|
||||
return export_list
|
||||
|
||||
def create_cloned_lu(self, src_lu, fs_label, clone_name):
|
||||
@ -799,3 +811,5 @@ class HNASSSHBackend(object):
|
||||
'iscsi-target', 'add', tgt_alias, secret)
|
||||
|
||||
self._get_targets(_evs_id, refresh=True)
|
||||
LOG.debug("create_target: alias: %(alias)s fs_label: %(fs_label)s",
|
||||
{'alias': tgt_alias, 'fs_label': fs_label})
|
||||
|
@ -140,15 +140,15 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
configuration is found.
|
||||
:raises: ParameterNotFound
|
||||
"""
|
||||
LOG.debug("Available services: %(svc)s.",
|
||||
{'svc': self.config['services'].keys()})
|
||||
label = utils.extract_host(volume.host, level='pool')
|
||||
LOG.info(_LI("Using service label: %(lbl)s."), {'lbl': label})
|
||||
|
||||
if label in self.config['services'].keys():
|
||||
svc = self.config['services'][label]
|
||||
LOG.info(_LI("Using service label: %(lbl)s."), {'lbl': label})
|
||||
return svc['hdp']
|
||||
else:
|
||||
LOG.info(_LI("Available services: %(svc)s."),
|
||||
{'svc': self.config['services'].keys()})
|
||||
LOG.error(_LE("No configuration found for service: %(lbl)s."),
|
||||
{'lbl': label})
|
||||
raise exception.ParameterNotFound(param=label)
|
||||
@ -176,6 +176,10 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
service = (
|
||||
svc['iscsi_ip'], svc['iscsi_port'], svc['evs'], svc['port'],
|
||||
fs_label, lu_info['tgt']['alias'], lu_info['tgt']['secret'])
|
||||
LOG.info(_LI("Volume %(vol_name)s already mapped on target "
|
||||
"%(tgt)s to LUN %(lunid)s."),
|
||||
{'vol_name': volume.name, 'tgt': lu_info['tgt']['alias'],
|
||||
'lunid': lu_info['id']})
|
||||
return service
|
||||
|
||||
# Each EVS can have up to 32 targets. Each target can have up to 32
|
||||
@ -291,11 +295,11 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
hnas_stat['pools'] = self.pools
|
||||
|
||||
LOG.info(_LI("stats: %(stat)s."), {'stat': hnas_stat})
|
||||
LOG.debug("stats: %(stat)s.", {'stat': hnas_stat})
|
||||
return hnas_stat
|
||||
|
||||
def _check_fs_list(self):
|
||||
"""Verifies the FSs in HNAS array.
|
||||
"""Verifies the FSs list in HNAS.
|
||||
|
||||
Verify that all FSs specified in the configuration files actually
|
||||
exists on the storage.
|
||||
@ -304,9 +308,8 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
for fs in fs_list:
|
||||
if not self.backend.get_fs_info(fs):
|
||||
msg = (
|
||||
_("File system not found or not mounted: %(fs)s") %
|
||||
{'fs': fs})
|
||||
msg = (_("File system not found or not mounted: %(fs)s") %
|
||||
{'fs': fs})
|
||||
LOG.error(msg)
|
||||
raise exception.ParameterNotFound(param=msg)
|
||||
|
||||
@ -324,22 +327,22 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
pool_from_vol_type = hnas_utils.get_pool(self.config, volume)
|
||||
|
||||
pool_from_host = utils.extract_host(volume.host, level='pool')
|
||||
|
||||
if self.config['services'][pool_from_vol_type]['hdp'] != fs_label:
|
||||
msg = (_("Failed to manage existing volume because the pool of "
|
||||
"the volume type chosen does not match the file system "
|
||||
"passed in the volume reference."),
|
||||
{'File System passed': fs_label,
|
||||
'File System for volume type':
|
||||
self.config['services'][pool_from_vol_type]['hdp']})
|
||||
pool = self.config['services'][pool_from_vol_type]['hdp']
|
||||
if pool != fs_label:
|
||||
msg = (_("Failed to manage existing volume because the "
|
||||
"pool %(pool)s of the volume type chosen does not "
|
||||
"match the file system %(fs_label)s passed in the "
|
||||
"volume reference.")
|
||||
% {'pool': pool, 'fs_label': fs_label})
|
||||
LOG.error(msg)
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
if pool_from_host != pool_from_vol_type:
|
||||
msg = (_("Failed to manage existing volume because the pool of "
|
||||
"the volume type chosen does not match the pool of "
|
||||
"the host."),
|
||||
{'Pool of the volume type': pool_from_vol_type,
|
||||
'Pool of the host': pool_from_host})
|
||||
msg = (_("Failed to manage existing volume because the pool "
|
||||
"%(pool)s of the volume type chosen does not match the "
|
||||
"pool %(pool_host)s of the host.") %
|
||||
{'pool': pool_from_vol_type, 'pool_host': pool_from_host})
|
||||
LOG.error(msg)
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
def _get_info_from_vol_ref(self, vol_ref):
|
||||
@ -360,9 +363,10 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
return fs_label, vol_name
|
||||
else:
|
||||
msg = (_("The reference to the volume in the backend should have "
|
||||
"the format file_system/volume_name (volume_name cannot "
|
||||
"contain '/')"))
|
||||
msg = _("The reference to the volume in the backend should have "
|
||||
"the format file_system/volume_name (volume_name cannot "
|
||||
"contain '/')")
|
||||
LOG.error(msg)
|
||||
raise exception.ManageExistingInvalidReference(
|
||||
existing_ref=vol_ref, reason=msg)
|
||||
|
||||
@ -374,6 +378,14 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
self.context = context
|
||||
self._check_fs_list()
|
||||
|
||||
version_info = self.backend.get_version()
|
||||
LOG.info(_LI("HNAS iSCSI driver."))
|
||||
LOG.info(_LI("HNAS model: %(mdl)s"), {'mdl': version_info['model']})
|
||||
LOG.info(_LI("HNAS version: %(version)s"),
|
||||
{'version': version_info['version']})
|
||||
LOG.info(_LI("HNAS hardware: %(hw)s"),
|
||||
{'hw': version_info['hardware']})
|
||||
LOG.info(_LI("HNAS S/N: %(sn)s"), {'sn': version_info['serial']})
|
||||
service_list = self.config['services'].keys()
|
||||
for svc in service_list:
|
||||
svc = self.config['services'][svc]
|
||||
@ -384,7 +396,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
self.pools.append(pool)
|
||||
|
||||
LOG.info(_LI("Configured pools: %(pool)s"), {'pool': self.pools})
|
||||
LOG.debug("Configured pools: %(pool)s", {'pool': self.pools})
|
||||
|
||||
evs_info = self.backend.get_evs_info()
|
||||
LOG.info(_LI("Configured EVSs: %(evs)s"), {'evs': evs_info})
|
||||
@ -392,7 +404,8 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
for svc in self.config['services'].keys():
|
||||
svc_ip = self.config['services'][svc]['iscsi_ip']
|
||||
if svc_ip in evs_info.keys():
|
||||
LOG.info(_LI("iSCSI portal found for service: %s"), svc_ip)
|
||||
LOG.info(_LI("iSCSI portal found for service: %(svc_ip)s"),
|
||||
{'svc_ip': svc_ip})
|
||||
self.config['services'][svc]['evs'] = (
|
||||
evs_info[svc_ip]['evs_number'])
|
||||
self.config['services'][svc]['iscsi_port'] = '3260'
|
||||
@ -401,6 +414,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
LOG.error(_LE("iSCSI portal not found "
|
||||
"for service: %(svc)s"), {'svc': svc_ip})
|
||||
raise exception.InvalidParameterValue(err=svc_ip)
|
||||
LOG.info(_LI("HNAS iSCSI Driver loaded successfully."))
|
||||
|
||||
def ensure_export(self, context, volume):
|
||||
pass
|
||||
@ -411,6 +425,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
def remove_export(self, context, volume):
|
||||
pass
|
||||
|
||||
@cinder_utils.trace
|
||||
def create_volume(self, volume):
|
||||
"""Creates a LU on HNAS.
|
||||
|
||||
@ -422,11 +437,9 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
self.backend.create_lu(fs, size, volume.name)
|
||||
|
||||
LOG.info(_LI("LU %(lu)s of size %(sz)s GB is created."),
|
||||
{'lu': volume.name, 'sz': volume.size})
|
||||
|
||||
return {'provider_location': self._get_provider_location(volume)}
|
||||
|
||||
@cinder_utils.trace
|
||||
def create_cloned_volume(self, dst, src):
|
||||
"""Creates a clone of a volume.
|
||||
|
||||
@ -439,14 +452,14 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
self.backend.create_cloned_lu(src.name, fs_label, dst.name)
|
||||
|
||||
if src.size < dst.size:
|
||||
size = dst.size
|
||||
self.extend_volume(dst, size)
|
||||
|
||||
LOG.debug("LU %(lu)s of size %(size)d GB is cloned.",
|
||||
{'lu': src.name, 'size': src.size})
|
||||
LOG.debug("Increasing dest size from %(old_size)s to "
|
||||
"%(new_size)s",
|
||||
{'old_size': src.size, 'new_size': dst.size})
|
||||
self.extend_volume(dst, dst.size)
|
||||
|
||||
return {'provider_location': self._get_provider_location(dst)}
|
||||
|
||||
@cinder_utils.trace
|
||||
def extend_volume(self, volume, new_size):
|
||||
"""Extends an existing volume.
|
||||
|
||||
@ -456,9 +469,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
fs = self._get_service(volume)
|
||||
self.backend.extend_lu(fs, new_size, volume.name)
|
||||
|
||||
LOG.info(_LI("LU %(lu)s extended to %(size)s GB."),
|
||||
{'lu': volume.name, 'size': new_size})
|
||||
|
||||
@cinder_utils.trace
|
||||
def delete_volume(self, volume):
|
||||
"""Deletes the volume on HNAS.
|
||||
|
||||
@ -467,9 +478,8 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
fs = self._get_service(volume)
|
||||
self.backend.delete_lu(fs, volume.name)
|
||||
|
||||
LOG.debug("Delete LU %(lu)s", {'lu': volume.name})
|
||||
|
||||
@cinder_utils.synchronized('volume_mapping')
|
||||
@cinder_utils.trace
|
||||
def initialize_connection(self, volume, connector):
|
||||
"""Maps the created volume to connector['initiator'].
|
||||
|
||||
@ -478,9 +488,6 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
:returns: The connection information
|
||||
:raises: ISCSITargetAttachFailed
|
||||
"""
|
||||
LOG.info(_LI("initialize volume %(vol)s connector %(conn)s"),
|
||||
{'vol': volume, 'conn': connector})
|
||||
|
||||
service_info = self._get_service_target(volume)
|
||||
(ip, ipp, evs, port, _fs, tgtalias, secret) = service_info
|
||||
|
||||
@ -492,7 +499,8 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
except processutils.ProcessExecutionError:
|
||||
msg = (_("Error attaching volume %(vol)s. "
|
||||
"Target limit might be reached!") % {'vol': volume.id})
|
||||
raise exception.ISCSITargetAttachFailed(message=msg)
|
||||
LOG.error(msg)
|
||||
raise exception.ISCSITargetAttachFailed(volume_id=volume.id)
|
||||
|
||||
hnas_portal = ip + ':' + ipp
|
||||
lu_id = six.text_type(conn['lu_id'])
|
||||
@ -501,7 +509,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
volume.provider_location + ',' + evs + ',' +
|
||||
port + ',' + lu_id)
|
||||
|
||||
LOG.info(_LI("initiate: connection %s"), tgt)
|
||||
LOG.info(_LI("initiate: connection %(tgt)s"), {'tgt': tgt})
|
||||
|
||||
properties = {}
|
||||
properties['provider_location'] = tgt
|
||||
@ -517,12 +525,11 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
properties['auth_password'] = secret
|
||||
|
||||
conn_info = {'driver_volume_type': 'iscsi', 'data': properties}
|
||||
LOG.debug("initialize_connection: conn_info: %(conn)s.",
|
||||
{'conn': conn_info})
|
||||
|
||||
return conn_info
|
||||
|
||||
@cinder_utils.synchronized('volume_mapping')
|
||||
@cinder_utils.trace
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
"""Terminate a connection to a volume.
|
||||
|
||||
@ -535,9 +542,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
self.backend.del_iscsi_conn(evs, tgtalias, lu_info['id'])
|
||||
|
||||
LOG.info(_LI("terminate_connection: %(vol)s"),
|
||||
{'vol': volume.provider_location})
|
||||
|
||||
@cinder_utils.trace
|
||||
def create_volume_from_snapshot(self, volume, snapshot):
|
||||
"""Creates a volume from a snapshot.
|
||||
|
||||
@ -549,11 +554,9 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
self.backend.create_cloned_lu(snapshot.name, fs, volume.name)
|
||||
|
||||
LOG.info(_LI("LU %(lu)s of size %(sz)d MB is created."),
|
||||
{'lu': snapshot.name, 'sz': snapshot.volume_size})
|
||||
|
||||
return {'provider_location': self._get_provider_location(snapshot)}
|
||||
|
||||
@cinder_utils.trace
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Creates a snapshot.
|
||||
|
||||
@ -564,11 +567,9 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
self.backend.create_cloned_lu(snapshot.volume_name, fs, snapshot.name)
|
||||
|
||||
LOG.debug("LU %(lu)s of size %(size)d GB is created.",
|
||||
{'lu': snapshot.name, 'size': snapshot.volume_size})
|
||||
|
||||
return {'provider_location': self._get_provider_location(snapshot)}
|
||||
|
||||
@cinder_utils.trace
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot.
|
||||
|
||||
@ -577,8 +578,6 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
fs = self._get_service(snapshot.volume)
|
||||
self.backend.delete_lu(fs, snapshot.name)
|
||||
|
||||
LOG.debug("Delete lu %(lu)s", {'lu': snapshot.name})
|
||||
|
||||
def get_volume_stats(self, refresh=False):
|
||||
"""Gets the volume driver stats.
|
||||
|
||||
@ -590,6 +589,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
return self.driver_stats
|
||||
|
||||
@cinder_utils.trace
|
||||
def manage_existing_get_size(self, volume, existing_vol_ref):
|
||||
"""Gets the size to manage_existing.
|
||||
|
||||
@ -627,6 +627,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
'If your volume name contains "/", please rename it '
|
||||
'and try to manage again.'))
|
||||
|
||||
@cinder_utils.trace
|
||||
def manage_existing(self, volume, existing_vol_ref):
|
||||
"""Manages an existing volume.
|
||||
|
||||
@ -641,13 +642,13 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
volume
|
||||
:returns: the provider location of the volume managed
|
||||
"""
|
||||
LOG.info(_LI("Asked to manage ISCSI volume %(vol)s, with vol "
|
||||
"ref %(ref)s."), {'vol': volume.id,
|
||||
'ref': existing_vol_ref['source-name']})
|
||||
|
||||
fs_label, vol_name = (
|
||||
self._get_info_from_vol_ref(existing_vol_ref['source-name']))
|
||||
|
||||
LOG.debug("Asked to manage ISCSI volume %(vol)s, with vol "
|
||||
"ref %(ref)s.", {'vol': volume.id,
|
||||
'ref': existing_vol_ref['source-name']})
|
||||
|
||||
if volume.volume_type is not None:
|
||||
self._check_pool_and_fs(volume, fs_label)
|
||||
|
||||
@ -658,6 +659,7 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
return {'provider_location': self._get_provider_location(volume)}
|
||||
|
||||
@cinder_utils.trace
|
||||
def unmanage(self, volume):
|
||||
"""Unmanages a volume from cinder.
|
||||
|
||||
@ -674,9 +676,10 @@ class HNASISCSIDriver(driver.ISCSIDriver):
|
||||
|
||||
self.backend.rename_existing_lu(fslabel, volume.name, new_name)
|
||||
|
||||
LOG.info(_LI("Cinder ISCSI volume with current path %(path)s is "
|
||||
"no longer being managed. The new name is %(unm)s."),
|
||||
{'path': vol_path, 'unm': new_name})
|
||||
LOG.info(_LI("The volume with path %(old)s is no longer being managed "
|
||||
"by Cinder. However, it was not deleted and can be found "
|
||||
"with the new name %(cr)s on backend."),
|
||||
{'old': vol_path, 'cr': new_name})
|
||||
|
||||
def _get_provider_location(self, volume):
|
||||
"""Gets the provider location of a given volume
|
||||
|
@ -130,8 +130,8 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
|
||||
if label in self.config['services'].keys():
|
||||
svc = self.config['services'][label]
|
||||
LOG.info(_LI("_get_service: %(lbl)s->%(svc)s"),
|
||||
{'lbl': label, 'svc': svc['export']['fs']})
|
||||
LOG.debug("_get_service: %(lbl)s->%(svc)s",
|
||||
{'lbl': label, 'svc': svc['export']['fs']})
|
||||
service = (svc['hdp'], svc['export']['path'], svc['export']['fs'])
|
||||
else:
|
||||
LOG.info(_LI("Available services: %(svc)s"),
|
||||
@ -142,6 +142,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
|
||||
return service
|
||||
|
||||
@cutils.trace
|
||||
def extend_volume(self, volume, new_size):
|
||||
"""Extend an existing volume.
|
||||
|
||||
@ -153,7 +154,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
path = self._get_volume_path(nfs_mount, volume.name)
|
||||
|
||||
# Resize the image file on share to new size.
|
||||
LOG.debug("Checking file for resize")
|
||||
LOG.info(_LI("Checking file for resize."))
|
||||
|
||||
if not self._is_file_size_equal(path, new_size):
|
||||
LOG.info(_LI("Resizing file to %(sz)sG"), {'sz': new_size})
|
||||
@ -163,7 +164,9 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
LOG.info(_LI("LUN %(id)s extended to %(size)s GB."),
|
||||
{'id': volume.id, 'size': new_size})
|
||||
else:
|
||||
raise exception.InvalidResults(_("Resizing image file failed."))
|
||||
msg = _("Resizing image file failed.")
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidResults(msg)
|
||||
|
||||
def _is_file_size_equal(self, path, size):
|
||||
"""Checks if file size at path is equal to size."""
|
||||
@ -175,6 +178,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
else:
|
||||
return False
|
||||
|
||||
@cutils.trace
|
||||
def create_volume_from_snapshot(self, volume, snapshot):
|
||||
"""Creates a volume from a snapshot.
|
||||
|
||||
@ -182,13 +186,12 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
:param snapshot: source snapshot
|
||||
:returns: the provider_location of the volume created
|
||||
"""
|
||||
LOG.debug("create_volume_from %(vol)s", {'vol': volume})
|
||||
|
||||
self._clone_volume(snapshot.volume, volume.name, snapshot.name)
|
||||
share = snapshot.volume.provider_location
|
||||
|
||||
return {'provider_location': share}
|
||||
|
||||
@cutils.trace
|
||||
def create_snapshot(self, snapshot):
|
||||
"""Create a snapshot.
|
||||
|
||||
@ -203,12 +206,12 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
# returns the mount point (not path)
|
||||
return {'provider_location': share}
|
||||
|
||||
@cutils.trace
|
||||
def delete_snapshot(self, snapshot):
|
||||
"""Deletes a snapshot.
|
||||
|
||||
:param snapshot: dictionary snapshot reference
|
||||
"""
|
||||
|
||||
nfs_mount = snapshot.volume.provider_location
|
||||
|
||||
if self._volume_not_present(nfs_mount, snapshot.name):
|
||||
@ -244,6 +247,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
return os.path.join(self._get_mount_point_for_share(nfs_share),
|
||||
volume_name)
|
||||
|
||||
@cutils.trace
|
||||
def create_cloned_volume(self, volume, src_vref):
|
||||
"""Creates a clone of the specified volume.
|
||||
|
||||
@ -277,6 +281,8 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
'reserved_percentage': percentage of size reserved
|
||||
}
|
||||
"""
|
||||
LOG.info(_LI("Getting volume stats"))
|
||||
|
||||
_stats = super(HNASNFSDriver, self).get_volume_stats(refresh)
|
||||
_stats["vendor_name"] = 'Hitachi'
|
||||
_stats["driver_version"] = HNAS_NFS_VERSION
|
||||
@ -292,18 +298,20 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
|
||||
_stats['pools'] = self.pools
|
||||
|
||||
LOG.info(_LI('Driver stats: %(stat)s'), {'stat': _stats})
|
||||
LOG.debug('Driver stats: %(stat)s', {'stat': _stats})
|
||||
|
||||
return _stats
|
||||
|
||||
def do_setup(self, context):
|
||||
"""Perform internal driver setup."""
|
||||
version_info = self.backend.get_version()
|
||||
LOG.info(_LI("HNAS Array NFS driver"))
|
||||
LOG.info(_LI("HNAS model: %s"), version_info['model'])
|
||||
LOG.info(_LI("HNAS version: %s"), version_info['version'])
|
||||
LOG.info(_LI("HNAS hardware: %s"), version_info['hardware'])
|
||||
LOG.info(_LI("HNAS S/N: %s"), version_info['serial'])
|
||||
LOG.info(_LI("HNAS NFS driver."))
|
||||
LOG.info(_LI("HNAS model: %(mdl)s"), {'mdl': version_info['model']})
|
||||
LOG.info(_LI("HNAS version: %(ver)s"),
|
||||
{'ver': version_info['version']})
|
||||
LOG.info(_LI("HNAS hardware: %(hw)s"),
|
||||
{'hw': version_info['hardware']})
|
||||
LOG.info(_LI("HNAS S/N: %(sn)s"), {'sn': version_info['serial']})
|
||||
|
||||
self.context = context
|
||||
self._load_shares_config(
|
||||
@ -328,8 +336,8 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
try:
|
||||
out, err = self._execute('showmount', '-e', server_ip)
|
||||
except processutils.ProcessExecutionError:
|
||||
LOG.error(_LE("NFS server %(srv)s not reachable!"),
|
||||
{'srv': server_ip})
|
||||
LOG.exception(_LE("NFS server %(srv)s not reachable!"),
|
||||
{'srv': server_ip})
|
||||
raise
|
||||
|
||||
export_list = out.split('\n')[1:]
|
||||
@ -342,7 +350,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
LOG.error(_LE("Configured share %(share)s is not present"
|
||||
"in %(srv)s."),
|
||||
{'share': mountpoint, 'srv': server_ip})
|
||||
msg = _('Section: %s') % svc_name
|
||||
msg = _('Section: %(svc_name)s') % {'svc_name': svc_name}
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
LOG.debug("Loading services: %(svc)s", {
|
||||
@ -358,7 +366,8 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
|
||||
self.pools.append(pool)
|
||||
|
||||
LOG.info(_LI("Configured pools: %(pool)s"), {'pool': self.pools})
|
||||
LOG.debug("Configured pools: %(pool)s", {'pool': self.pools})
|
||||
LOG.info(_LI("HNAS NFS Driver loaded successfully."))
|
||||
|
||||
def _clone_volume(self, src_vol, clone_name, src_name=None):
|
||||
"""Clones mounted volume using the HNAS file_clone.
|
||||
@ -387,6 +396,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
|
||||
self.backend.file_clone(fs_label, source_path, target_path)
|
||||
|
||||
@cutils.trace
|
||||
def create_volume(self, volume):
|
||||
"""Creates a volume.
|
||||
|
||||
@ -424,8 +434,8 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
try:
|
||||
vol_ref_share_ip = cutils.resolve_hostname(share_split[0])
|
||||
except socket.gaierror as e:
|
||||
LOG.error(_LE('Invalid hostname %(host)s'),
|
||||
{'host': share_split[0]})
|
||||
LOG.exception(_LE('Invalid hostname %(host)s'),
|
||||
{'host': share_split[0]})
|
||||
LOG.debug('error: %(err)s', {'err': e.strerror})
|
||||
raise
|
||||
|
||||
@ -468,8 +478,8 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
file_path) = vol_ref_share.partition(cfg_share)
|
||||
if work_share == cfg_share:
|
||||
file_path = file_path[1:] # strip off leading path divider
|
||||
LOG.debug("Found possible share %s; checking mount.",
|
||||
work_share)
|
||||
LOG.debug("Found possible share %(shr)s; checking mount.",
|
||||
{'shr': work_share})
|
||||
nfs_mount = self._get_mount_point_for_share(nfs_share)
|
||||
vol_full_path = os.path.join(nfs_mount, file_path)
|
||||
if os.path.isfile(vol_full_path):
|
||||
@ -486,6 +496,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
existing_ref=vol_ref,
|
||||
reason=_('Volume not found on configured storage backend.'))
|
||||
|
||||
@cutils.trace
|
||||
def manage_existing(self, volume, existing_vol_ref):
|
||||
"""Manages an existing volume.
|
||||
|
||||
@ -507,9 +518,10 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
(nfs_share, nfs_mount, vol_name
|
||||
) = self._get_share_mount_and_vol_from_vol_ref(existing_vol_ref)
|
||||
|
||||
LOG.debug("Asked to manage NFS volume %(vol)s, with vol ref %(ref)s.",
|
||||
{'vol': volume.id,
|
||||
'ref': existing_vol_ref['source-name']})
|
||||
LOG.info(_LI("Asked to manage NFS volume %(vol)s, "
|
||||
"with vol ref %(ref)s."),
|
||||
{'vol': volume.id,
|
||||
'ref': existing_vol_ref['source-name']})
|
||||
|
||||
self._check_pool_and_share(volume, nfs_share)
|
||||
|
||||
@ -526,12 +538,13 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
"to %(vol)s.", {'vol': volume.name})
|
||||
self._set_rw_permissions_for_all(dst_vol)
|
||||
except (OSError, processutils.ProcessExecutionError) as err:
|
||||
exception_msg = (_("Failed to manage existing volume "
|
||||
"%(name)s, because rename operation "
|
||||
"failed: Error msg: %(msg)s."),
|
||||
{'name': existing_vol_ref['source-name'],
|
||||
'msg': six.text_type(err)})
|
||||
raise exception.VolumeBackendAPIException(data=exception_msg)
|
||||
msg = (_("Failed to manage existing volume "
|
||||
"%(name)s, because rename operation "
|
||||
"failed: Error msg: %(msg)s.") %
|
||||
{'name': existing_vol_ref['source-name'],
|
||||
'msg': six.text_type(err)})
|
||||
LOG.error(msg)
|
||||
raise exception.VolumeBackendAPIException(data=msg)
|
||||
return {'provider_location': nfs_share}
|
||||
|
||||
def _check_pool_and_share(self, volume, nfs_share):
|
||||
@ -548,23 +561,25 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
pool_from_vol_type = hnas_utils.get_pool(self.config, volume)
|
||||
|
||||
pool_from_host = utils.extract_host(volume.host, level='pool')
|
||||
|
||||
if self.config['services'][pool_from_vol_type]['hdp'] != nfs_share:
|
||||
pool = self.config['services'][pool_from_vol_type]['hdp']
|
||||
if pool != nfs_share:
|
||||
msg = (_("Failed to manage existing volume because the pool of "
|
||||
"the volume type chosen does not match the NFS share "
|
||||
"passed in the volume reference."),
|
||||
{'Share passed': nfs_share, 'Share for volume type':
|
||||
self.config['services'][pool_from_vol_type]['hdp']})
|
||||
"the volume type chosen (%(pool)s) does not match the "
|
||||
"NFS share passed in the volume reference (%(share)s).")
|
||||
% {'share': nfs_share, 'pool': pool})
|
||||
LOG.error(msg)
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
if pool_from_host != pool_from_vol_type:
|
||||
msg = (_("Failed to manage existing volume because the pool of "
|
||||
"the volume type chosen does not match the pool of "
|
||||
"the host."),
|
||||
{'Pool of the volume type': pool_from_vol_type,
|
||||
'Pool of the host': pool_from_host})
|
||||
"the volume type chosen (%(pool)s) does not match the "
|
||||
"pool of the host %(pool_host)s") %
|
||||
{'pool': pool_from_vol_type,
|
||||
'pool_host': pool_from_host})
|
||||
LOG.error(msg)
|
||||
raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
|
||||
|
||||
@cutils.trace
|
||||
def manage_existing_get_size(self, volume, existing_vol_ref):
|
||||
"""Returns the size of volume to be managed by manage_existing.
|
||||
|
||||
@ -595,6 +610,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
"%(name)s, because of error in getting "
|
||||
"volume size."),
|
||||
{'name': existing_vol_ref['source-name']})
|
||||
LOG.exception(exception_message)
|
||||
raise exception.VolumeBackendAPIException(data=exception_message)
|
||||
|
||||
LOG.debug("Reporting size of NFS volume ref %(ref)s as %(size)d GB.",
|
||||
@ -602,6 +618,7 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
|
||||
return vol_size
|
||||
|
||||
@cutils.trace
|
||||
def unmanage(self, volume):
|
||||
"""Removes the specified volume from Cinder management.
|
||||
|
||||
@ -623,9 +640,11 @@ class HNASNFSDriver(nfs.NfsDriver):
|
||||
self._try_execute("mv", vol_path, new_path,
|
||||
run_as_root=False, check_exit_code=True)
|
||||
|
||||
LOG.info(_LI("Cinder NFS volume with current path %(cr)s is "
|
||||
"no longer being managed."), {'cr': new_path})
|
||||
LOG.info(_LI("The volume with path %(old)s is no longer being "
|
||||
"managed by Cinder. However, it was not deleted "
|
||||
"and can be found in the new path %(cr)s."),
|
||||
{'old': vol_path, 'cr': new_path})
|
||||
|
||||
except (OSError, ValueError):
|
||||
LOG.error(_LE("The NFS Volume %(cr)s does not exist."),
|
||||
{'cr': new_path})
|
||||
LOG.exception(_LE("The NFS Volume %(cr)s does not exist."),
|
||||
{'cr': vol_path})
|
||||
|
@ -26,8 +26,7 @@ import six
|
||||
from xml.etree import ElementTree as ETree
|
||||
|
||||
from cinder import exception
|
||||
|
||||
from cinder.i18n import _, _LW
|
||||
from cinder.i18n import _, _LW, _LE
|
||||
from cinder.volume import volume_types
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -45,7 +44,7 @@ drivers_common_opts = [
|
||||
'the SMU IP.'),
|
||||
cfg.StrOpt('hnas_ssc_cmd',
|
||||
default='ssc',
|
||||
help='Command to communicate to HNAS array.'),
|
||||
help='Command to communicate to HNAS.'),
|
||||
cfg.StrOpt('hnas_username',
|
||||
help='HNAS username.'),
|
||||
cfg.StrOpt('hnas_password',
|
||||
@ -96,6 +95,7 @@ def _check_conf_params(config, vol_type, dv_type, idx):
|
||||
if config['username'] is None:
|
||||
msg = (_("The config parameter hnas_username "
|
||||
"is not set in the cinder.conf."))
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
if (config['password'] is None and
|
||||
@ -104,11 +104,13 @@ def _check_conf_params(config, vol_type, dv_type, idx):
|
||||
"missing: you need to set hnas_password "
|
||||
"or hnas_ssh_private_key "
|
||||
"in the cinder.conf."))
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
if config['mgmt_ip0'] is None:
|
||||
msg = (_("The config parameter hnas_mgmt_ip0 "
|
||||
"is not set in the cinder.conf."))
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
if config['services'][vol_type]['hdp'] is None:
|
||||
@ -116,6 +118,7 @@ def _check_conf_params(config, vol_type, dv_type, idx):
|
||||
"not set in the cinder.conf. Note that you need to "
|
||||
"have at least one pool configured.") %
|
||||
{'idx': idx})
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
if config['services'][vol_type]['volume_type'] is None:
|
||||
@ -124,6 +127,7 @@ def _check_conf_params(config, vol_type, dv_type, idx):
|
||||
"in the cinder.conf. Note that you need to "
|
||||
"have at least one pool configured.") %
|
||||
{'idx': idx})
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
if (dv_type == 'iscsi' and
|
||||
@ -132,6 +136,7 @@ def _check_conf_params(config, vol_type, dv_type, idx):
|
||||
"hnas_svc%(idx)s_iscsi_ip is not set "
|
||||
"in the cinder.conf. Note that you need to "
|
||||
"have at least one pool configured.") % {'idx': idx})
|
||||
LOG.error(msg)
|
||||
raise exception.InvalidParameterValue(err=msg)
|
||||
|
||||
|
||||
@ -147,6 +152,7 @@ def _xml_read(root, element, check=None):
|
||||
|
||||
# mandatory parameter not found
|
||||
if val is None and check:
|
||||
LOG.error(_LE("Mandatory parameter not found: %(p)s"), {'p': element})
|
||||
raise exception.ParameterNotFound(param=element)
|
||||
|
||||
# tag not found
|
||||
@ -158,6 +164,7 @@ def _xml_read(root, element, check=None):
|
||||
if not val.strip():
|
||||
if svc_tag_pattern.search(element):
|
||||
return ""
|
||||
LOG.error(_LE("Parameter not found: %(param)s"), {'param': element})
|
||||
raise exception.ParameterNotFound(param=element)
|
||||
|
||||
LOG.debug("%(element)s: %(val)s",
|
||||
@ -180,6 +187,7 @@ def read_xml_config(xml_config_file, svc_params, optional_params):
|
||||
if not os.access(xml_config_file, os.R_OK):
|
||||
msg = (_("Can't find HNAS configurations on cinder.conf neither "
|
||||
"on the path %(xml)s.") % {'xml': xml_config_file})
|
||||
LOG.error(msg)
|
||||
raise exception.ConfigNotFound(message=msg)
|
||||
else:
|
||||
LOG.warning(_LW("This XML configuration file %(xml)s is deprecated. "
|
||||
@ -191,7 +199,9 @@ def read_xml_config(xml_config_file, svc_params, optional_params):
|
||||
try:
|
||||
root = ETree.parse(xml_config_file).getroot()
|
||||
except ETree.ParseError:
|
||||
msg = (_("Error parsing config file: %s") % xml_config_file)
|
||||
msg = (_("Error parsing config file: %(xml_config_file)s") %
|
||||
{'xml_config_file': xml_config_file})
|
||||
LOG.error(msg)
|
||||
raise exception.ConfigNotFound(message=msg)
|
||||
|
||||
# mandatory parameters for NFS and iSCSI
|
||||
@ -210,7 +220,8 @@ def read_xml_config(xml_config_file, svc_params, optional_params):
|
||||
config['password'] = _xml_read(root, 'password')
|
||||
|
||||
if config['ssh_private_key'] is None and config['password'] is None:
|
||||
msg = (_("Missing authentication option (passw or private key file)."))
|
||||
msg = _("Missing authentication option (passw or private key file).")
|
||||
LOG.error(msg)
|
||||
raise exception.ConfigNotFound(message=msg)
|
||||
|
||||
if _xml_read(root, 'ssh_port') is not None:
|
||||
@ -235,8 +246,8 @@ def read_xml_config(xml_config_file, svc_params, optional_params):
|
||||
|
||||
# at least one service required!
|
||||
if not config['services'].keys():
|
||||
msg = (_("svc_0"))
|
||||
raise exception.ParameterNotFound(param=msg)
|
||||
LOG.error(_LE("No service found in xml config file"))
|
||||
raise exception.ParameterNotFound(param="svc_0")
|
||||
|
||||
return config
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user