Skip to content

Commit

Permalink
Fix: Continue iteration after recoverable errors in SdrIter
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Lu <[email protected]>
  • Loading branch information
lubinszARM committed Dec 31, 2024
1 parent 7b4404c commit 9811fd4
Showing 1 changed file with 73 additions and 39 deletions.
112 changes: 73 additions & 39 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,51 +113,85 @@ where
type Item = SdrRecord;

fn next(&mut self) -> Option<Self::Item> {
let current_id = self.next_id?;
let mut recoverable_errors = 0;
const MAX_RECOVERABLE_ERRORS: usize = 10; // Max number of recoverable errors

if current_id.is_last() {
self.next_id.take();
return None;
}

let next_record = self
.ipmi
.send_recv(sdr::GetDeviceSdr::new(None, current_id));

let (value, next_record_id) = match next_record {
Ok(record) => {
let next_record_id = record.next_entry;

(Some(record.record), next_record_id)
}
Err(IpmiError::ParsingFailed {
error: ParseResponseError::Parse((e, next_record_id)),
..
}) => {
log::warn!(
"Recoverable error while parsing SDR record 0x{:04X}: {e:?}",
current_id.value()
);
(None, next_record_id)
}
Err(e) => {
log::error!(
"Unrecoverable error while parsing SDR record 0x{:04X}: {e:?}",
current_id.value()
);
while let Some(current_id) = self.next_id {
if current_id.is_last() {
self.next_id.take();
if recoverable_errors > 0 {
log::warn!(
"Iteration completed with {} recoverable errors.",
recoverable_errors
);
}
return None;
}
};

if next_record_id == current_id {
log::error!("Got duplicate SDR record IDs! Stopping iteration.");
self.next_id.take();
return None;
} else {
self.next_id = Some(next_record_id);
let next_record = self
.ipmi
.send_recv(sdr::GetDeviceSdr::new(None, current_id));

match next_record {
Ok(record) => {
if recoverable_errors > 0 {
log::warn!(
"Skipped {} recoverable errors before processing record 0x{:04X}.",
recoverable_errors,
current_id.value()
);
}

let next_record_id = record.next_entry;

if next_record_id == current_id {
log::error!("Got duplicate SDR record IDs! Stopping iteration.");
self.next_id.take();
return None;
}

self.next_id = Some(next_record_id);
return Some(record.record);
}
Err(IpmiError::ParsingFailed {
error: ParseResponseError::Parse((e, next_record_id)),
..
}) => {
recoverable_errors += 1;
if recoverable_errors > MAX_RECOVERABLE_ERRORS {
log::error!(
"Exceeded maximum recoverable errors ({}). Stopping iteration.",
MAX_RECOVERABLE_ERRORS
);
self.next_id.take();
return None;
}

log::debug!(
"Recoverable error while parsing SDR record 0x{:04X}: {e:?}. Skipping to next.",
current_id.value()
);
self.next_id = Some(next_record_id);
continue; // skip the current one
}
Err(e) => {
log::error!(
"Unrecoverable error while parsing SDR record 0x{:04X}: {e:?}",
current_id.value()
);
self.next_id.take();
return None;
}
}
}

if recoverable_errors > 0 {
log::warn!(
"Iteration completed with {} recoverable errors.",
recoverable_errors
);
}

value
None
}
}

0 comments on commit 9811fd4

Please sign in to comment.