mirror of
https://github.com/xcat2/confluent.git
synced 2026-10-20 14:45:45 +00:00
Read a lan parameter the bmc does not have without crashing
A bmc that does not implement a lan configuration parameter says so in the completion code and answers with no data at all. The helper reached straight into the payload, so such a parameter raised IndexError, and with it went the whole of nodeconfig over ipmi: the bmc group, the plain, the detailed, the extended and the advanced reads all ended in "bytearray index out of range". It also took the attribute enumeration with it, so the client then rejected names it should have accepted. The guard that was there caught an exception carrying the completion code, but oldraw_command reports the code in its response rather than raising on it, so nothing was ever caught. Read the code from the response instead: parameter not supported and parameter out of range mean the platform does not have it, and anything else is a real failure that should say what it was rather than be mistaken for absence. The address configuration method was looked up in a table with no regard for whether it had been read at all, so a bmc that does not report it would have traded the IndexError for a KeyError. Answer None when it is absent, as the address above it already does, and name the value when it is present but unfamiliar.
This commit is contained in:
@@ -825,14 +825,19 @@ class Command(object):
|
||||
one byte, return the int value
|
||||
"""
|
||||
fetchcmd = bytearray((channel, param, 0, 0))
|
||||
try:
|
||||
fetched = await self.oldraw_command(0xc, 2, data=fetchcmd)
|
||||
except exc.IpmiException as ie:
|
||||
if ie.ipmicode == 0x80:
|
||||
return None
|
||||
raise
|
||||
fetched = await self.oldraw_command(0xc, 2, data=fetchcmd)
|
||||
# A bmc without the parameter says so in the completion code and sends
|
||||
# no data at all, so the code has to be read before the payload is.
|
||||
# oldraw_command reports the code rather than raising on it, which is
|
||||
# why this cannot be done by catching something.
|
||||
if fetched['code'] in (0x80, 0xc9):
|
||||
# parameter not supported, and parameter out of range
|
||||
return None
|
||||
if fetched['code']:
|
||||
raise exc.IpmiException(util.get_ipmi_error(fetched),
|
||||
fetched['code'])
|
||||
fetchdata = fetched['data']
|
||||
if bytearray(fetchdata)[0] != 17:
|
||||
if not fetchdata or bytearray(fetchdata)[0] != 17:
|
||||
return None
|
||||
if param == 0x14:
|
||||
vlaninfo = struct.unpack('<H', fetchdata[1:])[0]
|
||||
@@ -1066,8 +1071,12 @@ class Command(object):
|
||||
3: 'BIOS',
|
||||
4: 'Other',
|
||||
}
|
||||
retdata['ipv4_configuration'] = v4cfgmethods[await self._fetch_lancfg_param(
|
||||
channel, 4)]
|
||||
v4cfgmethod = await self._fetch_lancfg_param(channel, 4)
|
||||
if v4cfgmethod is None:
|
||||
retdata['ipv4_configuration'] = None
|
||||
else:
|
||||
retdata['ipv4_configuration'] = v4cfgmethods.get(
|
||||
v4cfgmethod, 'Unknown ({0})'.format(v4cfgmethod))
|
||||
retdata['mac_address'] = await self._fetch_lancfg_param(channel, 5)
|
||||
retdata['ipv4_gateway'] = await self._fetch_lancfg_param(channel, 12)
|
||||
retdata['ipv4_backup_gateway'] = await self._fetch_lancfg_param(channel, 14)
|
||||
|
||||
Reference in New Issue
Block a user