mirror of
https://github.com/xcat2/confluent.git
synced 2026-08-27 00:56:45 +00:00
Merge pull request #277 from Obihoernchen/fix/ipmi-completion-code-checks
Act on the ipmi completion codes again
This commit is contained in:
@@ -453,9 +453,11 @@ class Command(object):
|
||||
retry=True, timeout=None, rslun=0):
|
||||
"""Send raw ipmi command to BMC, raising exception on error
|
||||
|
||||
This is identical to raw_command, except it raises exceptions
|
||||
This is identical to oldraw_command, except it raises exceptions
|
||||
on IPMI errors and returns data as a buffer. This is the recommend
|
||||
function to use. The response['data'] being a buffer allows
|
||||
function to use, and a caller that has to act on a particular
|
||||
completion code reads it from the exception's ipmicode. The
|
||||
response['data'] being a buffer allows
|
||||
traditional indexed access as well as works nicely with
|
||||
struct.unpack_from when certain data is coming back.
|
||||
|
||||
@@ -1089,13 +1091,14 @@ class Command(object):
|
||||
await self.init_sdr()
|
||||
for sensor in self._sdr.get_sensor_numbers():
|
||||
currsensor = self._sdr.sensors[sensor]
|
||||
rsp = await self.raw_command(command=0x2d, netfn=4,
|
||||
rslun=currsensor.sensor_lun,
|
||||
data=(currsensor.sensor_number,))
|
||||
if 'error' in rsp:
|
||||
if rsp['code'] == 203: # Sensor does not exist, optional dev
|
||||
try:
|
||||
rsp = await self.raw_command(command=0x2d, netfn=4,
|
||||
rslun=currsensor.sensor_lun,
|
||||
data=(currsensor.sensor_number,))
|
||||
except exc.IpmiException as ie:
|
||||
if ie.ipmicode == 203: # Sensor does not exist, optional dev
|
||||
continue
|
||||
raise exc.IpmiException(rsp['error'], code=rsp['code'])
|
||||
raise
|
||||
yield await self._sdr.sensors[sensor].\
|
||||
decode_sensor_reading(self, rsp['data'])
|
||||
await self.oem_init()
|
||||
@@ -1304,9 +1307,18 @@ class Command(object):
|
||||
# handler of commands
|
||||
lanchan = await self.get_network_channel()
|
||||
if self._ipv6support is None:
|
||||
rsp = await self.raw_command(netfn=0xc, command=0x2, data=(2, lanchan,
|
||||
0x32, 0, 0))
|
||||
self._ipv6support = rsp['code'] == 0
|
||||
try:
|
||||
await self.raw_command(netfn=0xc, command=0x2,
|
||||
data=(2, lanchan, 0x32, 0, 0))
|
||||
self._ipv6support = True
|
||||
except exc.IpmiException as ie:
|
||||
# A platform without the standard parameter says so in the
|
||||
# completion code, which is the answer. Anything else, a
|
||||
# timeout or a lost session, is not, and must not be remembered
|
||||
# as the platform's answer for the rest of the session.
|
||||
if not 0 < ie.ipmicode <= 0xff:
|
||||
raise
|
||||
self._ipv6support = False
|
||||
return self._ipv6support
|
||||
|
||||
async def set_alert_destination(self, ip=None, acknowledge_required=None,
|
||||
|
||||
@@ -150,8 +150,6 @@ class FRU(object):
|
||||
async def fetch_fru(self, fruid):
|
||||
response = await self.ipmicmd.raw_command(
|
||||
netfn=0xa, command=0x10, data=[fruid])
|
||||
if 'error' in response:
|
||||
raise iexc.IpmiException(response['error'], code=response['code'])
|
||||
frusize = response['data'][0] | (response['data'][1] << 8)
|
||||
# In our case, we don't need to think too hard about whether
|
||||
# the FRU is word or byte, we just process what we get back in the
|
||||
@@ -165,20 +163,21 @@ class FRU(object):
|
||||
offset = 0
|
||||
self.rawfru = bytearray([])
|
||||
while chunksize:
|
||||
response = await self.ipmicmd.raw_command(
|
||||
netfn=0xa, command=0x11, data=[fruid, offset & 0xff,
|
||||
offset >> 8, chunksize])
|
||||
if response['code'] in (201, 202):
|
||||
try:
|
||||
response = await self.ipmicmd.raw_command(
|
||||
netfn=0xa, command=0x11, data=[fruid, offset & 0xff,
|
||||
offset >> 8, chunksize])
|
||||
except iexc.IpmiException as ie:
|
||||
# if it was too big, back off and try smaller
|
||||
# Try just over half to mitigate the chance of
|
||||
# one request becoming three rather than just two
|
||||
if chunksize == 3:
|
||||
raise iexc.IpmiException(response['error'])
|
||||
chunksize //= 2
|
||||
chunksize += 2
|
||||
smaller = chunksize // 2 + 2
|
||||
if ie.ipmicode not in (201, 202) or smaller >= chunksize:
|
||||
# Nothing left to give up, and asking again unchanged would
|
||||
# never end
|
||||
raise
|
||||
chunksize = smaller
|
||||
continue
|
||||
elif 'error' in response:
|
||||
raise iexc.IpmiException(response['error'], response['code'])
|
||||
offset += response['data'][0]
|
||||
if response['data'][0] == 0:
|
||||
break
|
||||
|
||||
@@ -769,24 +769,35 @@ class SDR(object):
|
||||
rqdata = [rsvid & 0xff, rsvid >> 8,
|
||||
recid & 0xff, recid >> 8,
|
||||
offset, size]
|
||||
sdrrec = await self.ipmicmd.raw_command(netfn=0x0a, command=0x23,
|
||||
data=rqdata)
|
||||
if sdrrec['code'] == 0xca:
|
||||
if size == 0xff: # get just 5 to get header to know length
|
||||
size = 5
|
||||
elif size > 5:
|
||||
size //= 2
|
||||
try:
|
||||
sdrrec = await self.ipmicmd.raw_command(
|
||||
netfn=0x0a, command=0x23, data=rqdata)
|
||||
except exc.IpmiException as ie:
|
||||
# The two codes this loop negotiates with, rather than
|
||||
# failures: more asked for than the bmc will return at once,
|
||||
# and a reservation that has gone stale
|
||||
if ie.ipmicode == 0xca:
|
||||
if size == 0xff: # get just 5 to get header to know length
|
||||
size = 5
|
||||
continue
|
||||
# push things over such that it's less
|
||||
# likely to be just 1 short of a read
|
||||
# and incur a whole new request
|
||||
size += 2
|
||||
chunksize = size
|
||||
continue
|
||||
if sdrrec['code'] == 0xc5: # need a new reservation id
|
||||
rsvid = 0
|
||||
continue
|
||||
if sdrrec['code'] != 0:
|
||||
raise exc.IpmiException(sdrrec['error'])
|
||||
smaller = size // 2 + 2
|
||||
if smaller >= size or (currlen == 0 and smaller < 5):
|
||||
# Nothing left to give up, and asking again
|
||||
# unchanged would never end. A header read has to
|
||||
# be 5 bytes to carry the record length, so a
|
||||
# smaller one could not be parsed either
|
||||
raise
|
||||
size = chunksize = smaller
|
||||
continue
|
||||
if ie.ipmicode == 0xc5: # need a new reservation id
|
||||
# Take one here rather than leaving it to the top of
|
||||
# the loop, which only reserves for a partial read
|
||||
rsvid = await self.get_sdr_reservation()
|
||||
continue
|
||||
raise
|
||||
if newrecid == 0:
|
||||
newrecid = (sdrrec['data'][1] << 8) + sdrrec['data'][0]
|
||||
if currlen == 0:
|
||||
|
||||
Reference in New Issue
Block a user