-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(devinfo): use a singleton to store if kernel bug state
Signed-off-by: Niladri Halder <[email protected]>
- Loading branch information
Showing
4 changed files
with
188 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use std::io::{IoSliceMut, Read}; | ||
|
||
/// This is io::Read capable Sized type. This can wrap around a Vec<u8>. | ||
pub struct ByteBuf { | ||
inner: Vec<u8>, | ||
} | ||
|
||
impl Read for ByteBuf { | ||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { | ||
self.inner.as_slice().read(buf) | ||
} | ||
|
||
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> std::io::Result<usize> { | ||
self.inner.as_slice().read_vectored(bufs) | ||
} | ||
|
||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> { | ||
self.inner.as_slice().read_to_end(buf) | ||
} | ||
|
||
fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> { | ||
self.inner.as_slice().read_to_string(buf) | ||
} | ||
|
||
fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { | ||
self.inner.as_slice().read_exact(buf) | ||
} | ||
|
||
fn by_ref(&mut self) -> &mut Self | ||
where | ||
Self: Sized, | ||
{ | ||
self | ||
} | ||
} | ||
|
||
impl From<Vec<u8>> for ByteBuf { | ||
fn from(inner: Vec<u8>) -> Self { | ||
Self { inner } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use std::{ | ||
error::Error, | ||
ffi::OsString, | ||
fmt::{Debug, Display, Formatter}, | ||
path::PathBuf, | ||
}; | ||
|
||
pub type Result<T, E = MountInfoError> = std::result::Result<T, E>; | ||
|
||
#[derive(Debug)] | ||
pub enum MountInfoError { | ||
Io(std::io::Error), | ||
InconsistentRead { filepath: PathBuf, attempts: u32 }, | ||
Nix(nix::Error), | ||
ConvertOsStrToStr { source: OsString }, | ||
Semver(semver::Error), | ||
} | ||
|
||
impl Display for MountInfoError { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
Self::Io(ref err) => write!(f, "IO error: {err}"), | ||
Self::InconsistentRead { | ||
filepath: path, | ||
attempts, | ||
} => write!( | ||
f, | ||
"failed to get a consistent read output from file {} after {attempts} attempts", | ||
path.display() | ||
), | ||
Self::Nix(ref err) => write!(f, "{err}"), | ||
Self::ConvertOsStrToStr { source: src } => { | ||
write!(f, "failed to convert {:?} to &str", src) | ||
} | ||
Self::Semver(ref err) => write!(f, "semver error: {err}"), | ||
} | ||
} | ||
} | ||
impl Error for MountInfoError { | ||
fn source(&self) -> Option<&(dyn Error + 'static)> { | ||
match *self { | ||
Self::Io(ref err) => err.source(), | ||
Self::Nix(ref err) => err.source(), | ||
Self::Semver(ref err) => err.source(), | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
impl From<std::io::Error> for MountInfoError { | ||
fn from(io_err: std::io::Error) -> Self { | ||
Self::Io(io_err) | ||
} | ||
} | ||
|
||
impl From<nix::Error> for MountInfoError { | ||
fn from(nix_err: nix::Error) -> Self { | ||
Self::Nix(nix_err) | ||
} | ||
} | ||
|
||
impl From<semver::Error> for MountInfoError { | ||
fn from(semver_err: semver::Error) -> Self { | ||
Self::Semver(semver_err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,75 +1,27 @@ | ||
use std::{ | ||
fs::read, | ||
io::{BufRead, Read}, | ||
path::Path, | ||
}; | ||
use crate::mountinfo::error::{MountInfoError, Result}; | ||
use std::{fs::read, path::Path}; | ||
|
||
const DEFAULT_RETRY_COUNT: u32 = 2; | ||
|
||
type InconsistentReadError = String; | ||
/// This is a container which is a BufRead while carrying the entire read | ||
/// payload in a buffer. | ||
pub(crate) struct ConsistentBufReader { | ||
buf: Vec<u8>, | ||
} | ||
pub(crate) fn consistent_read<P: AsRef<Path>>( | ||
path: P, | ||
retry_count: Option<u32>, | ||
) -> Result<Vec<u8>> { | ||
let mut current_content = read(path.as_ref())?; | ||
|
||
impl Read for ConsistentBufReader { | ||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { | ||
self.buf.as_slice().read(buf) | ||
} | ||
} | ||
|
||
impl BufRead for ConsistentBufReader { | ||
fn fill_buf(&mut self) -> std::io::Result<&[u8]> { | ||
Ok(self.buf.as_slice()) | ||
} | ||
|
||
fn consume(&mut self, amt: usize) { | ||
self.buf.as_slice().consume(amt) | ||
} | ||
|
||
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> std::io::Result<usize> { | ||
self.buf.as_slice().read_until(byte, buf) | ||
} | ||
let retries = retry_count.unwrap_or(DEFAULT_RETRY_COUNT); | ||
for _ in 0 .. retries { | ||
let new_content = read(path.as_ref())?; | ||
|
||
fn read_line(&mut self, buf: &mut String) -> std::io::Result<usize> { | ||
self.buf.as_slice().read_line(buf) | ||
} | ||
} | ||
|
||
impl ConsistentBufReader { | ||
// This tries to perform a consistent read, i.e. if two consecutive reads return the same byte | ||
// sequence, then the read is consistent, and we are not missing out on any entries due to a | ||
// seq index on a /proc file. | ||
pub(crate) fn new( | ||
path: &Path, | ||
retry_count: Option<u32>, | ||
) -> Result<Self, InconsistentReadError> { | ||
let read_error = |error: std::io::Error| -> InconsistentReadError { | ||
format!( | ||
"failed to read file at {}: {}", | ||
path.to_string_lossy(), | ||
error | ||
) | ||
}; | ||
|
||
let mut current_content = read(path).map_err(read_error)?; | ||
|
||
let retries = retry_count.unwrap_or(DEFAULT_RETRY_COUNT); | ||
for _ in 0 .. retries { | ||
let new_content = read(path).map_err(read_error)?; | ||
|
||
if new_content.eq(¤t_content) { | ||
return Ok(Self { buf: new_content }); | ||
} | ||
|
||
current_content = new_content; | ||
if new_content.eq(¤t_content) { | ||
return Ok(new_content); | ||
} | ||
|
||
Err(format!( | ||
"failed to get a consistent read output from file {} after {} attempts", | ||
path.to_string_lossy(), | ||
retries | ||
)) | ||
current_content = new_content; | ||
} | ||
|
||
Err(MountInfoError::InconsistentRead { | ||
filepath: path.as_ref().to_path_buf(), | ||
attempts: retries, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters