2
0
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:
Markus Hilger
2026-08-14 23:48:19 +02:00
parent e9e5fc2516
commit a513bfc04f
+26 -15
View File
@@ -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: