Skip to content
This repository has been archived by the owner on Jun 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #29 from darrenldl/dev
Browse files Browse the repository at this point in the history
A lot of improvements, closing a lot of issues
  • Loading branch information
darrenldl committed Mar 19, 2018
2 parents 44835c5 + fab5daa commit 3b4464e
Show file tree
Hide file tree
Showing 22 changed files with 689 additions and 175 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.9.2
- Made decode mode output file path determination more robust
- Only the file part of the SNM field is used rather than the entire path when computing the final output path
- Added `--info-only` flag to encode mode
- Using the flag shows various calculation results and statistical information

## 0.9.1
- Fixed encode mode output file determination logic
- Prior to this version, encode mode would append the entire input path to the output path if output path is a directory, instead of just appending only the file name part
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rsbx"
version = "0.9.1"
version = "0.9.2"
authors = ["Darren Ldl <darrenldldev@gmail.com>"]
build = "build.rs"
exclude = [
Expand Down Expand Up @@ -32,7 +32,7 @@ license = "MIT"
reed-solomon-erasure = "3.0"
ring = "0.12.1"
hex-slice = "0.1.2"
blake2_c = "0.2.0"
blake2_c = "0.3"
rand = "0.4"
smallvec = "0.6"
nom = "3.2"
Expand All @@ -41,7 +41,7 @@ enum-map = "0.2"
pond = "0.2"
futures = "0.1"
clap = "2.30.0"
ctrlc = "3.1.0"
ctrlc = "3.1"

[dev-dependencies]
quickcheck = "0.6"
46 changes: 19 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# rust-SeqBox
[![Build Status](https://travis-ci.org/darrenldl/rust-SeqBox.svg?branch=master)](https://travis-ci.org/darrenldl/rust-SeqBox)
[![Build status](https://ci.appveyor.com/api/projects/status/ho6v99qysi9l8p6d?svg=true)](https://ci.appveyor.com/project/darrenldl/rust-seqbox)
[![Crates](https://img.shields.io/crates/v/rsbx.svg)](https://crates.io/crates/rsbx)
[![dependency status](https://deps.rs/repo/github/darrenldl/rsbx/status.svg)](https://deps.rs/repo/github/darrenldl/rsbx)

[Documentation](https://github.com/darrenldl/rust-SeqBox/wiki)

Enhanced implementation of SeqBox in Rust

SeqBox is a single-file archive format designed by [Marco Pontello](https://github.com/MarcoPon) that facilitates sector level data recovery for when file system metadata is corrupted/missing, while the archive itself still exists as a normal file on file system.
Expand All @@ -19,33 +26,18 @@ Rsbx is overall based around [osbx](https://github.com/darrenldl/ocaml-SeqBox),
## Goals
As rsbx is to be used largely as a backup utility, security/robustness of the code will be prioritised over apparent performance.

Modularity and ease of maintenance will be of high priority during development as well for easy maintenance in future.

## Progress
- [x] encoder
- [x] base SBX versions(1, 2, 3)
- [x] error recovery enabled SBX versions(17, 18, 19)
- [x] burst error resistance arrangement
- [x] decoder
- [x] all SBX versions(1, 2, 3, 17, 18, 19)
- [x] rescuer
- [x] all SBX versions(1, 2, 3, 17, 18, 19)
- [x] shower
- [x] all SBX versions(1, 2, 3, 17, 18, 19)
- [x] repairer
- [x] error recovery enabled SBX versions(17, 18, 19)
- [x] repairing code with burst error resistant pattern awareness
- [x] sorter
- [x] basic sequential sorting for base SBX versions(1, 2, 3)
- [x] burst error resistance aware sorting for versions(17, 18, 19)
- [x] code refactoring and polishing
- largely complete - a lot of massive rewrites have been made
- but small code refactoring is still ongoing
- [x] UI/UX polishing
- [x] setup basic test suite
- [ ] setup fuzzing suite

## Notes
## Getting started
#### Installation
rsbx is available via Cargo
```
cargo install rsbx
```

#### Usage guides & screencasts & other resources
The [wiki](https://github.com/darrenldl/rust-SeqBox/wiki) contains comprehensive guides and resources.

## Changelog
[Changelog](CHANGELOG.md)

## Specification
[Sbx format](SBX_FORMAT.md)
Expand Down
6 changes: 4 additions & 2 deletions SBX_FORMAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,17 @@ The maximum number of such errors tolerable is same as the parity shard count.

Assuming arrangement of **M** data shards, **N** parity shards, **B** burst error resistance.

Then the SBX container can tolerate up to **N** burst errors, and each individual error may be up to **B** SBX blocks.
Then the SBX container can tolerate up to **N** burst errors in every **(M + N) * B** consecutive blocks, and each individual error may be up to **B** SBX blocks.

#### Diagrams

**M** data shards, **N** parity shards, **B** burst error resistance

**Sequential arrangement**

| 00 | 00 | ... | 00 | 01 | 02 | 03 | 04 | ... |
| 0 | 1 | ... | N | N + 1 | N + 2 | N + 3 | N + 4 | ... |
|--- |--- | --- |--- | --- | --- | --- | --- | --- |
| 00 | 00 | ... | 00 | 01 | 02 | 03 | 04 | ... |

**1 + N** metadata blocks at the front

Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ build: false
test_script:
- cargo build --verbose --all
- cargo test --verbose --all
- bash tests/dev_tests.sh

branches:
only:
Expand Down
157 changes: 157 additions & 0 deletions src/cli_calc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
use sbx_specs::{Version,
ver_to_usize,
ver_to_block_size,
ver_to_data_size,
ver_uses_rs};

use std::str::FromStr;

use file_utils;

use clap::*;
use cli_utils::*;
pub fn sub_command<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("calc")
.about("Compute and display detailed information given a configuration")
.arg(Arg::with_name("in_file_size")
.value_name("INFILE-SIZE")
.required(true)
.index(1)
.help("Input file size"))
.arg(sbx_version_arg())
.arg(Arg::with_name("no_meta")
.long("no-meta")
.help("Skip metadata block in the calculations. Metadata block is
never skipped for version 17, 18, 19.
This means this option has no effect for version 17, 18, 19."))
.arg(rs_data_arg())
.arg(rs_parity_arg())
.arg(burst_arg())
}

pub fn calc<'a>(matches : &ArgMatches<'a>) -> i32 {
let version = get_version!(matches);

let in_file_size =
match u64::from_str(matches.value_of("in_file_size").unwrap()) {
Ok(x) => x,
Err(_) => exit_with_msg!(usr => "Invalid file size")
};

let data_par_burst =
if ver_uses_rs(version) {
// deal with RS related options
let data_shards = get_data_shards!(matches, version);
let parity_shards = get_parity_shards!(matches, version);

check_data_parity_shards!(data_shards, parity_shards);

let burst = get_burst_or_zero!(matches);

Some((data_shards, parity_shards, burst))
} else {
None
};

let out_file_size =
file_utils::from_orig_file_size::calc_container_size(version,
data_par_burst,
in_file_size);

let total_block_count =
file_utils::from_orig_file_size::calc_total_block_count_exc_burst_gaps(version,
data_par_burst,
in_file_size);

let (data_only_block_count, parity_block_count) =
file_utils::from_orig_file_size::calc_data_only_and_parity_block_count_exc_burst_gaps(version,
data_par_burst,
in_file_size);

println!( "SBX container general info");
println!( "========================================");
if ver_uses_rs(version) {
println!(" SBX container version : {} (0x{:X})",
ver_to_usize(version),
ver_to_usize(version));
} else {
println!(" SBX container version : {}", ver_to_usize(version));
}
println!( " SBX container block size : {}", ver_to_block_size(version));
println!( " SBX container data size : {}", ver_to_data_size(version));

println!();

println!( "SBX block distribution");
println!( "========================================");
if ver_uses_rs(version) {
println!(" Metadata block count : {}", 1 + data_par_burst.unwrap().1);
println!(" Data only block count : {}", data_only_block_count);
println!(" Data parity block count : {}", parity_block_count);
println!(" Total block count : {}", total_block_count);
} else {
println!(" Metadata block count : {}", 1);
println!(" Data block count : {}", data_only_block_count);
println!(" Total block count : {}", total_block_count);
}

println!();

println!( "Error correction info");
println!( "========================================");
if ver_uses_rs(version) {
println!(" RS data shard count : {}", data_par_burst.unwrap().0);
println!(" RS parity shard count : {}", data_par_burst.unwrap().1);
println!(" Burst error resistance level : {}", data_par_burst.unwrap().2);
} else {
println!(" RS data shard count : {}", "version does not use RS");
println!(" RS parity shard count : {}", "version does not use RS");
println!(" Burst error resistance level : {}", "version does not support burst error resistance");
}

println!();

if ver_uses_rs(version) {
let (data, par, burst) = data_par_burst.unwrap();

let block_size = ver_to_block_size(version);

println!("Error correction parameters interpretation");
println!("========================================");
if burst == 0 {
println!(" The container can tolerate corruption of {} SBX blocks(totalling {} bytes) in
every set of {} consecutive blocks({} bytes).",
par,
par * block_size,
data + par,
(data + par) * block_size);
} else {
println!(" The container can tolerate {} burst SBX block corruptions in
every set of {} consecutive blocks({} bytes).
Each burst error may be up to {} blocks({} bytes) in size.
In total, {} bytes(aligned at block boundary) may be corrupted in
any set of {} consecutive blocks({} bytes).",
par,
(data + par) * burst,
(data + par) * burst * block_size,
burst,
burst * block_size,
par * burst * block_size,
(data + par) * burst,
(data + par) * burst * block_size);
println!();
println!(" Note that the actual tolerance depends on the behaviour of the file system.");
}

println!();
}

println!( "File and container size");
println!( "========================================");
println!( " File size : {}", in_file_size);
println!( " SBX container size : {}", out_file_size);

exit_with_msg!(ok => "")
}

0 comments on commit 3b4464e

Please sign in to comment.