Skip to content

Commit

Permalink
feat(sdr): make SDR parsing failure recoverable
Browse files Browse the repository at this point in the history
  • Loading branch information
datdenkikniet committed May 12, 2024
1 parent 58880be commit 0dfaec6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
50 changes: 39 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,49 @@ where
type Item = SdrRecord;

fn next(&mut self) -> Option<Self::Item> {
let next_id = self.next_id?;
let current_id = self.next_id?;
let next_record = self
.ipmi
.send_recv(sdr::GetDeviceSdr::new(None, next_id))
.map_err(|e| {
log::error!("Error occured while iterating SDR records: {e:?}");
})
.ok()?;

if !next_record.next_entry.is_last() {
self.next_id = Some(next_record.next_entry);
} else {
.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_id)),
..
}) => {
log::warn!(
"Recoverable error while parsing SDR record 0x{:04X}: {e:?}",
current_id.value()
);
(None, next_id)
}
Err(e) => {
log::error!(
"Unrecoverable error while parsing SDR record 0x{:04X}: {e:?}",
current_id.value()
);
self.next_id.take();
return None;
}
};

if current_id.is_last() {
self.next_id.take();
} else {
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);
}
}

Some(next_record.record)
value
}
}
6 changes: 4 additions & 2 deletions src/storage/sdr/get_sdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl From<GetDeviceSdr> for Message {
impl IpmiCommand for GetDeviceSdr {
type Output = RecordInfo;

type Error = RecordParseError;
type Error = (RecordParseError, RecordId);

fn parse_response(
completion_code: crate::connection::CompletionCode,
Expand All @@ -68,7 +68,9 @@ impl IpmiCommand for GetDeviceSdr {
return Err(ParseResponseError::NotEnoughData);
}

let res = RecordInfo::parse(data)?;
let next_id = RecordId::new_raw(u16::from_le_bytes([data[0], data[1]]));

let res = RecordInfo::parse(data).map_err(|e| (e, next_id))?;

Ok(res)
}
Expand Down

0 comments on commit 0dfaec6

Please sign in to comment.