From 2becb424fcfec249965152779e130b9981b7c29d Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Sat, 15 Aug 2026 04:44:43 +0200 Subject: [PATCH] End the device sdr retries a bmc will not satisfy _read_device_sdr_lun negotiates the read size down when the bmc answers 0xCA, but the size > 5 guard leaves a size of 5 alone, so a bmc that will not serve 5 bytes at once was asked the same question for ever. Give up once the request cannot get any smaller, and once a header read would go under the 5 bytes the record length sits in, by falling through to the raise already there. 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, so the very first request repeated unchanged. Take one where the code is handled. --- confluent_server/aiohmi/ipmi/sdr.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/confluent_server/aiohmi/ipmi/sdr.py b/confluent_server/aiohmi/ipmi/sdr.py index 01314fca..e32c60b4 100644 --- a/confluent_server/aiohmi/ipmi/sdr.py +++ b/confluent_server/aiohmi/ipmi/sdr.py @@ -832,16 +832,21 @@ class SDR(object): if sdrrec['code'] == 0xca: if size == 0xff: # get just 5 to get header to know length size = 5 - elif size > 5: - size //= 2 - # 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 + continue + # push things over such that it's less + # likely to be just 1 short of a read + # and incur a whole new request + smaller = size // 2 + 2 + # Asking again unchanged would never end, and a header read + # under 5 bytes could not carry the record length, so fall + # through to the raise below rather than retry either + if smaller < size and (currlen != 0 or smaller >= 5): + size = chunksize = smaller + continue if sdrrec['code'] == 0xc5: # need a new reservation id - rsvid = 0 + # Take one here rather than leaving it to the top of the + # loop, which only reserves for a partial read + rsvid = await self.get_device_sdr_reservation() continue if sdrrec['code'] != 0: raise exc.IpmiException(sdrrec['error'])