Skip to content

Commit

Permalink
Add error logs for Huawei driver
Browse files Browse the repository at this point in the history
Log some errors to avoid losing the exception messages.
HVS driver do repeated judgements for JSON results, here add error
logs and replace these judgement codes with a assertion function.

fixes bug 1229877
Change-Id: Icd1e859566e07c0f02aa0b2d5c136a2048524527
  • Loading branch information
zhangchao010 committed Sep 26, 2013
1 parent 180513d commit 59cb2be
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 49 deletions.
4 changes: 2 additions & 2 deletions cinder/tests/test_huawei_t_dorado.py
Expand Up @@ -1044,7 +1044,7 @@ def test_conf_invalid(self):
tmp_configuration = mox.MockObject(conf.Configuration)
tmp_configuration.cinder_huawei_conf_file = tmp_fonf_file
tmp_configuration.append_config_values(mox.IgnoreArg())
self.assertRaises(exception.ConfigNotFound,
self.assertRaises(IOError,
HuaweiVolumeDriver,
configuration=tmp_configuration)
# Test Product and Protocol invalid
Expand Down Expand Up @@ -1635,7 +1635,7 @@ def test_reach_max_connection_limit(self):

def test_socket_timeout(self):
self.stubs.Set(FakeChannel, 'recv', self._fake_recv2)
self.assertRaises(exception.CinderException,
self.assertRaises(socket.timeout,
self.driver.create_volume, FAKE_VOLUME)

def _fake_recv1(self, nbytes):
Expand Down
2 changes: 1 addition & 1 deletion cinder/volume/drivers/huawei/__init__.py
Expand Up @@ -18,7 +18,7 @@
"""
Provide a unified driver class for users.
The product type and the protocol should be specified in confige file before.
The product type and the protocol should be specified in config file before.
"""

from oslo.config import cfg
Expand Down
90 changes: 48 additions & 42 deletions cinder/volume/drivers/huawei/rest_common.py
Expand Up @@ -78,8 +78,9 @@ def call(self, url=False, data=None, method=None):

try:
res_json = json.loads(res)
except Exception:
raise exception.CinderException(_('JSON transfer Error'))
except Exception as err:
LOG.error(_('JSON transfer error'))
raise err

return res_json

Expand All @@ -99,6 +100,7 @@ def login(self):
if (result['error']['code'] != 0) or ("data" not in result):
time.sleep(30)
msg = _("Login error, reason is %s") % result
LOG.error(msg)
raise exception.CinderException(msg)

deviceid = result['data']['deviceid']
Expand Down Expand Up @@ -166,17 +168,22 @@ def _assert_rest_result(self, result, err_str):
LOG.error(msg)
raise exception.CinderException(msg)

def _assert_data_in_result(self, result, msg):
if "data" not in result:
msg = _('%s "data" was not in result.') % msg
LOG.error(msg)
raise exception.CinderException(msg)

def _create_volume(self, lun_param):
url = self.url + "/lun"
data = json.dumps(lun_param)
result = self.call(url, data)
self._assert_rest_result(result, 'create volume error')

if "data" in result:
return result['data']['ID']
else:
msg = _('create volume error: %(err)s') % {'err': result}
raise exception.CinderException(msg)
msg = 'Create volume error.'
self._assert_rest_result(result, msg)
self._assert_data_in_result(result, msg)

return result['data']['ID']

def create_volume(self, volume):
volume_name = self._encode_name(volume['id'])
Expand Down Expand Up @@ -267,7 +274,7 @@ def _read_xml(self):
root = tree.getroot()
except Exception as err:
LOG.error(_('_read_xml:%s') % err)
raise exception.VolumeBackendAPIException(data=err)
raise err
return root

def _encode_name(self, name):
Expand All @@ -282,6 +289,7 @@ def _find_pool_info(self):
pool_name = root.findtext('LUN/StoragePool')
if not pool_name:
err_msg = _("Invalid resource pool: %s") % pool_name
LOG.error(err_msg)
raise exception.InvalidInput(err_msg)

url = self.url + "/storagepool"
Expand All @@ -299,6 +307,7 @@ def _find_pool_info(self):

if not poolinfo:
msg = (_('Get pool info error, pool name is:%s') % pool_name)
LOG.error(msg)
raise exception.CinderException(msg)

return poolinfo
Expand Down Expand Up @@ -338,10 +347,10 @@ def _create_snapshot(self, snapshot):
"PARENTTYPE": "11",
"PARENTID": lun_id})
result = self.call(url, data)
self._assert_rest_result(result, 'Create snapshot error.')

if 'data' not in result:
raise exception.CinderException(_('Create snapshot error.'))
msg = 'Create snapshot error.'
self._assert_rest_result(result, msg)
self._assert_data_in_result(result, msg)

return result['data']['ID']

Expand Down Expand Up @@ -439,10 +448,10 @@ def _create_luncopy(self, luncopyname, srclunid, tgtlunid):
"TARGETLUN": ("INVALID;%s;INVALID;INVALID;INVALID"
% tgtlunid)})
result = self.call(url, data)
self._assert_rest_result(result, 'Create lun copy error.')

if "data" not in result:
raise exception.CinderException(_('Create luncopy error.'))
msg = 'Create lun copy error.'
self._assert_rest_result(result, msg)
self._assert_data_in_result(result, msg)

return result['data']['ID']

Expand Down Expand Up @@ -578,11 +587,10 @@ def initialize_connection_fc(self, volume, connector):
def _get_iscsi_tgt_port(self):
url = self.url + "/iscsidevicename"
result = self.call(url, None)

msg = 'Get iSCSI target port error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

return result['data'][0]['CMO_ISCSI_DEVICE_NAME']

Expand Down Expand Up @@ -618,11 +626,10 @@ def _create_hostgroup(self, hostgroupname):
url = self.url + "/hostgroup"
data = json.dumps({"TYPE": "14", "NAME": hostgroupname})
result = self.call(url, data)

msg = 'Create host group error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

return result['data']['ID']

Expand All @@ -631,11 +638,10 @@ def _create_lungroup(self, lungroupname):
data = json.dumps({"DESCRIPTION": lungroupname,
"NAME": lungroupname})
result = self.call(url, data)

msg = 'Create lun group error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

return result['data']['ID']

Expand Down Expand Up @@ -686,9 +692,10 @@ def _find_host_lun_id(self, hostid, lunid):
hostassoinfo = json.loads(associate_data)
host_lun_id = hostassoinfo['HostLUNID']
break
except Exception:
msg = _("_find_host_lun_id transfer data error! ")
raise exception.CinderException(msg)
except Exception as err:
msg = _("JSON transfer data error. %s") % err
LOG.error(msg)
raise err
return host_lun_id

def _find_host(self, hostname):
Expand Down Expand Up @@ -800,11 +807,10 @@ def _find_mapping_view(self, name):
url = self.url + "/mappingview"
data = json.dumps({"TYPE": "245"})
result = self.call(url, data, "GET")

msg = 'Find map view error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

viewid = None
for item in result['data']:
Expand Down Expand Up @@ -937,6 +943,7 @@ def _get_lun_conf_params(self):
err_msg = (_('Config file is wrong. LUNType must be "Thin"'
' or "Thick". LUNType:%(fetchtype)s')
% {'fetchtype': luntype})
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)

stripunitsize = root.findtext('LUN/StripUnitSize')
Expand All @@ -963,6 +970,7 @@ def _get_lun_conf_params(self):
err_msg = (_('PrefetchType config is wrong. PrefetchType'
' must in 1,2,3,4. fetchtype is:%(fetchtype)s')
% {'fetchtype': fetchtype})
LOG.error(err_msg)
raise exception.CinderException(err_msg)
else:
LOG.debug(_('Use default prefetch fetchtype. '
Expand All @@ -980,6 +988,7 @@ def _wait_for_luncopy(self, luncopyid):
err_msg = (_('_wait_for_luncopy:LUNcopy status is not normal.'
'LUNcopy name: %(luncopyname)s')
% {'luncopyname': luncopyid})
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)
time.sleep(10)

Expand Down Expand Up @@ -1014,11 +1023,10 @@ def _get_connected_free_wwns(self):
"""
url = self.url + "/fc_initiator?ISFREE=true&range=[0-1000]"
result = self.call(url, None, "GET")

msg = 'Get connected free FC wwn error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

wwns = []
for item in result['data']:
Expand All @@ -1039,11 +1047,10 @@ def _get_iscsi_port_info(self, ip):
"""Get iscsi port info in order to build the iscsi target iqn."""
url = self.url + "/eth_port"
result = self.call(url, None, "GET")

msg = 'Get iSCSI port information error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

iscsi_port_info = None
for item in result['data']:
Expand Down Expand Up @@ -1102,11 +1109,10 @@ def _get_fc_target_wwpns(self, wwn):
url = (self.url +
"/host_link?INITIATOR_TYPE=223&INITIATOR_PORT_WWN=" + wwn)
result = self.call(url, None, "GET")

msg = 'Get FC target wwpn error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

fc_wwpns = None
for item in result['data']:
Expand Down Expand Up @@ -1174,11 +1180,10 @@ def update_volume_stats(self, refresh=False):
def _find_qos_policy_info(self, policy_name):
url = self.url + "/ioclass"
result = self.call(url, None, "GET")

msg = 'Get qos policy error.'
self._assert_rest_result(result, msg)

if "data" not in result:
raise exception.CinderException(_('%s') % msg)
self._assert_data_in_result(result, msg)

qos_info = {}
for item in result['data']:
Expand Down Expand Up @@ -1245,6 +1250,7 @@ def _check_conf_file(self):
if not pool_node:
err_msg = (_('_check_conf_file: Config file invalid. '
'StoragePool must be set.'))
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)

def _get_iscsi_params(self, connector):
Expand Down
16 changes: 12 additions & 4 deletions cinder/volume/drivers/huawei/ssh_common.py
Expand Up @@ -52,7 +52,7 @@ def parse_xml_file(filepath):
return root
except IOError as err:
LOG.error(_('parse_xml_file: %s') % err)
raise exception.ConfigNotFound(path=err)
raise err


def ssh_read(user, channel, cmd, timeout):
Expand All @@ -62,9 +62,10 @@ def ssh_read(user, channel, cmd, timeout):
while True:
try:
result = result + channel.recv(8192)
except socket.timeout:
raise exception.CinderException(_('ssh_read: Read '
'SSH timeout.'))
except socket.timeout as err:
msg = _('ssh_read: Read SSH timeout. %s') % err
LOG.error(msg)
raise err
else:
# CLI returns welcome information when first log in. So need to
# deal differently.
Expand All @@ -79,6 +80,7 @@ def ssh_read(user, channel, cmd, timeout):
# Reach maximum limit of SSH connection.
elif re.search('No response message', result):
msg = _('No response message. Please check system status.')
LOG.error(msg)
raise exception.CinderException(msg)
elif (re.search(user + ':/>' + cmd, result) and
result.endswith(user + ':/>')):
Expand Down Expand Up @@ -362,6 +364,7 @@ def _parse_conf_lun_params(self):
else:
err_msg = (_('LUNType must be "Thin" or "Thick". '
'LUNType:%(type)s') % {'type': luntype})
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)

stripunitsize = root.findtext('LUN/StripUnitSize')
Expand Down Expand Up @@ -411,6 +414,7 @@ def _get_maximum_capacity_pool_id(self, pools_conf, pools_dev, luntype):
'id. Please check config file and make sure '
'the StoragePool %s is created in storage '
'array.') % pools_conf)
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)

def _execute_cli(self, cmd):
Expand Down Expand Up @@ -486,6 +490,7 @@ def _execute_cli(self, cmd):
else:
if ssh_client:
self.ssh_pool.remove(ssh_client)
LOG.error(_('_execute_cli: %s') % err)
raise err

def _reset_transport_timeout(self, ssh, time):
Expand Down Expand Up @@ -839,6 +844,7 @@ def _assert_cli_out(self, condition, func, msg, cmd, cliout):
'msg': msg,
'cmd': cmd,
'out': cliout})
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)

def _assert_cli_operate_out(self, func, msg, cmd, cliout):
Expand All @@ -850,6 +856,7 @@ def map_volume(self, host_id, volume_id):
"""Map a volume to a host."""
# Map a LUN to a host if not mapped.
if not self._check_volume_created(volume_id):
LOG.error(_('map_volume: Volume %s was not found.') % volume_id)
raise exception.VolumeNotFound(volume_id=volume_id)

hostlun_id = None
Expand Down Expand Up @@ -1318,6 +1325,7 @@ def _parse_conf_lun_params(self):
else:
err_msg = (_('LUNType must be "Thin" or "Thick". '
'LUNType:%(type)s') % {'type': luntype})
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)

# Here we do not judge whether the parameters are set correct.
Expand Down

0 comments on commit 59cb2be

Please sign in to comment.