Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/CI.yaml → .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Docker Image
run: make docker-build
- name: Compile
run: ./dev cargo build
run: cargo build
- name: Test
run: ./dev cargo test
run: cargo test
18 changes: 0 additions & 18 deletions Dockerfile

This file was deleted.

1 change: 0 additions & 1 deletion dev

This file was deleted.

6 changes: 0 additions & 6 deletions docker-compose.yml

This file was deleted.

3 changes: 2 additions & 1 deletion writeboost-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ edition = "2024"
anyhow = "1"
byteorder = "1"
clap = { version = "4", features = ["derive"] }
crc = "3"
crc = "3"
thiserror = "2.0.17"
Empty file.
102 changes: 75 additions & 27 deletions writeboost-cli/src/sub/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,26 @@ fn checksum(data: &[u8]) -> u32 {
CASTAGNOLI.checksum(data)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_checksum() {
let buf = vec![0; 4096 - 512];
assert_eq!(checksum(&buf), 143703573);
}
}

#[derive(Args)]
#[command(about = "Check if the segment is broken")]
pub struct CommandArgs {
#[arg(help = "Path to the cache device")]
cachedev: String,
#[arg(help = "Segment id")]
segid: i32,
#[derive(thiserror::Error, Debug)]
enum CheckError {
#[error("segment is not initialized")]
NotInitialized,
#[error(
"segment {seg_id} is broken. checksum: computed={computed_checksum}, expected={expected_checksum}"
)]
CacheBlockBroken {
seg_id: i32,
computed_checksum: u32,
expected_checksum: u32,
},
}

pub fn run(args: CommandArgs) {
let devname: String = args.cachedev;
let id = args.segid;
fn do_check(devname: &str, seg_id: i32) -> Result<(), CheckError> {
let cache_dev = CacheDevice::new(devname.to_owned());

let mut f = File::open(&devname).expect(&format!("Device {} not found", &devname));

let start_byte: u64 = (cache_dev.calc_segment_start(id) as u64) << 9;
let start_byte: u64 = (cache_dev.calc_segment_start(seg_id) as u64) << 9;
f.seek(SeekFrom::Start(start_byte)).unwrap();

let header = {
Expand All @@ -48,7 +40,7 @@ pub fn run(args: CommandArgs) {
};

if header.uninitialized() {
std::process::exit(0);
return Err(CheckError::NotInitialized);
}

let computed = {
Expand All @@ -59,9 +51,65 @@ pub fn run(args: CommandArgs) {
};

if computed != header.checksum {
panic!(
"Checksum is broken. computed={}, expected={}",
computed, header.checksum
);
return Err(CheckError::CacheBlockBroken {
seg_id,
computed_checksum: computed,
expected_checksum: header.checksum,
});
}

Ok(())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_checksum() {
let buf = vec![0; 4096 - 512];
assert_eq!(checksum(&buf), 143703573);
}

#[test]
fn test_check() {
let devname = "data/sample.cache.226";
let seg_id = 1;
let res = do_check(&devname, seg_id);
assert!(res.is_ok());
}

#[test]
fn test_uninitialized() {
let devname = "data/sample.cache.uninit";
let seg_id = 0;
let res = do_check(&devname, seg_id);
assert!(matches!(res, Err(CheckError::NotInitialized)));
}
}

#[derive(Args)]
#[command(about = "Check if the segment is broken")]
pub struct CommandArgs {
#[arg(help = "Path to the cache device")]
cachedev: String,
#[arg(help = "Segment id")]
segid: i32,
}

pub fn run(args: CommandArgs) {
let devname: String = args.cachedev;
let id = args.segid;

match do_check(&devname, id) {
Ok(()) => {}
Err(CheckError::NotInitialized) => {
// Since segments are zero-ed out at formatting,
// if the segment is all zeros, it is considered still unused.
eprintln!("segment is not initialized");
}
Err(e) => {
panic!("{e}")
}
}
}