mirror of
https://github.com/xcat2/confluent.git
synced 2026-09-02 07:26:04 +00:00
Back off a fru read the bmc will not serve in one piece
Completion codes 201 and 202 mean the chunk asked for was too big, and the check for them sat after a call that raises, so a bmc that cannot serve 224 bytes at once failed the fru read rather than being asked for less. The retry could not terminate either: chunksize // 2 + 2 is 4 for a chunksize of 4, so the chunksize == 3 guard was unreachable and a bmc that kept refusing would have been asked for 4 bytes for ever.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user