mirror of
https://github.com/xcat2/confluent.git
synced 2026-10-20 14:45:45 +00:00
Read the sdr partial read codes from the exception
raw_command raises on any nonzero completion code, so the 0xCA and 0xC5 checks in get_sdr could not run: a bmc that will not return a whole record in one go, or whose reservation went stale, failed the sensor load outright instead of being retried. Read the code from the exception, which carries it. The back off also had a fixed point, size // 2 + 2 being 3 for a size of 3, so a bmc that kept refusing would have been asked the same question for ever. Give up when the request cannot get any smaller. A header read cannot go under 5 bytes either, since that is where the record length sits, so give up there rather than parse a reply too short to index. The stale reservation retry could not end on its own either: it cleared the id and left taking a new one to the top of the loop, which only reserves for a partial read. Take one where the code is handled.
This commit is contained in:
@@ -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