[thin_repair/thin_dump (rust)] Support rebuilding superblock
This commit is contained in:
parent
213442bffd
commit
8a822cebec
@ -10,6 +10,7 @@ use std::sync::Arc;
|
|||||||
use thinp::file_utils;
|
use thinp::file_utils;
|
||||||
use thinp::report::*;
|
use thinp::report::*;
|
||||||
use thinp::thin::dump::{dump, ThinDumpOptions};
|
use thinp::thin::dump::{dump, ThinDumpOptions};
|
||||||
|
use thinp::thin::metadata_repair::SuperblockOverrides;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let parser = App::new("thin_dump")
|
let parser = App::new("thin_dump")
|
||||||
@ -40,6 +41,12 @@ fn main() {
|
|||||||
.long("skip-mappings"),
|
.long("skip-mappings"),
|
||||||
)
|
)
|
||||||
// options
|
// options
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("DATA_BLOCK_SIZE")
|
||||||
|
.help("Provide the data block size for repairing")
|
||||||
|
.long("data-block-size")
|
||||||
|
.value_name("SECTORS"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("METADATA_SNAPSHOT")
|
Arg::with_name("METADATA_SNAPSHOT")
|
||||||
.help("Access the metadata snapshot on a live pool")
|
.help("Access the metadata snapshot on a live pool")
|
||||||
@ -47,6 +54,12 @@ fn main() {
|
|||||||
.long("metadata-snapshot")
|
.long("metadata-snapshot")
|
||||||
.value_name("METADATA_SNAPSHOT"),
|
.value_name("METADATA_SNAPSHOT"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("NR_DATA_BLOCKS")
|
||||||
|
.help("Override the number of data blocks if needed")
|
||||||
|
.long("nr-data-blocks")
|
||||||
|
.value_name("NUM"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("OUTPUT")
|
Arg::with_name("OUTPUT")
|
||||||
.help("Specify the output file rather than stdout")
|
.help("Specify the output file rather than stdout")
|
||||||
@ -54,6 +67,12 @@ fn main() {
|
|||||||
.long("output")
|
.long("output")
|
||||||
.value_name("FILE"),
|
.value_name("FILE"),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("TRANSACTION_ID")
|
||||||
|
.help("Override the transaction id if needed")
|
||||||
|
.long("transaction-id")
|
||||||
|
.value_name("NUM"),
|
||||||
|
)
|
||||||
// arguments
|
// arguments
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("INPUT")
|
Arg::with_name("INPUT")
|
||||||
@ -75,6 +94,27 @@ fn main() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let transaction_id = matches.value_of("TRANSACTION_ID").map(|s| {
|
||||||
|
s.parse::<u64>().unwrap_or_else(|_| {
|
||||||
|
eprintln!("Couldn't parse transaction_id");
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let data_block_size = matches.value_of("DATA_BLOCK_SIZE").map(|s| {
|
||||||
|
s.parse::<u32>().unwrap_or_else(|_| {
|
||||||
|
eprintln!("Couldn't parse data_block_size");
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let nr_data_blocks = matches.value_of("NR_DATA_BLOCKS").map(|s| {
|
||||||
|
s.parse::<u64>().unwrap_or_else(|_| {
|
||||||
|
eprintln!("Couldn't parse nr_data_blocks");
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let report;
|
let report;
|
||||||
|
|
||||||
if matches.is_present("QUIET") {
|
if matches.is_present("QUIET") {
|
||||||
@ -90,6 +130,12 @@ fn main() {
|
|||||||
output: output_file,
|
output: output_file,
|
||||||
async_io: matches.is_present("ASYNC_IO"),
|
async_io: matches.is_present("ASYNC_IO"),
|
||||||
report,
|
report,
|
||||||
|
repair: matches.is_present("REPAIR"),
|
||||||
|
overrides: SuperblockOverrides {
|
||||||
|
transaction_id,
|
||||||
|
data_block_size,
|
||||||
|
nr_data_blocks,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(reason) = dump(opts) {
|
if let Err(reason) = dump(opts) {
|
||||||
|
@ -9,6 +9,7 @@ use std::process::exit;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use thinp::file_utils;
|
use thinp::file_utils;
|
||||||
use thinp::report::*;
|
use thinp::report::*;
|
||||||
|
use thinp::thin::metadata_repair::SuperblockOverrides;
|
||||||
use thinp::thin::repair::{repair, ThinRepairOptions};
|
use thinp::thin::repair::{repair, ThinRepairOptions};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -29,6 +30,12 @@ fn main() {
|
|||||||
.long("quiet"),
|
.long("quiet"),
|
||||||
)
|
)
|
||||||
// options
|
// options
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("DATA_BLOCK_SIZE")
|
||||||
|
.help("Provide the data block size for repairing")
|
||||||
|
.long("data-block-size")
|
||||||
|
.value_name("SECTORS"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("INPUT")
|
Arg::with_name("INPUT")
|
||||||
.help("Specify the input device")
|
.help("Specify the input device")
|
||||||
@ -37,6 +44,12 @@ fn main() {
|
|||||||
.value_name("FILE")
|
.value_name("FILE")
|
||||||
.required(true),
|
.required(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("NR_DATA_BLOCKS")
|
||||||
|
.help("Override the number of data blocks if needed")
|
||||||
|
.long("nr-data-blocks")
|
||||||
|
.value_name("NUM"),
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("OUTPUT")
|
Arg::with_name("OUTPUT")
|
||||||
.help("Specify the output device")
|
.help("Specify the output device")
|
||||||
@ -46,11 +59,10 @@ fn main() {
|
|||||||
.required(true),
|
.required(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("OVERRIDE_MAPPING_ROOT")
|
Arg::with_name("TRANSACTION_ID")
|
||||||
.help("Specify a mapping root to use")
|
.help("Override the transaction id if needed")
|
||||||
.long("override-mapping-root")
|
.long("transaction-id")
|
||||||
.value_name("OVERRIDE_MAPPING_ROOT")
|
.value_name("NUM"),
|
||||||
.takes_value(true),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let matches = parser.get_matches();
|
let matches = parser.get_matches();
|
||||||
@ -62,6 +74,27 @@ fn main() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let transaction_id = matches.value_of("TRANSACTION_ID").map(|s| {
|
||||||
|
s.parse::<u64>().unwrap_or_else(|_| {
|
||||||
|
eprintln!("Couldn't parse transaction_id");
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let data_block_size = matches.value_of("DATA_BLOCK_SIZE").map(|s| {
|
||||||
|
s.parse::<u32>().unwrap_or_else(|_| {
|
||||||
|
eprintln!("Couldn't parse data_block_size");
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let nr_data_blocks = matches.value_of("NR_DATA_BLOCKS").map(|s| {
|
||||||
|
s.parse::<u64>().unwrap_or_else(|_| {
|
||||||
|
eprintln!("Couldn't parse nr_data_blocks");
|
||||||
|
exit(1);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let report;
|
let report;
|
||||||
|
|
||||||
if matches.is_present("QUIET") {
|
if matches.is_present("QUIET") {
|
||||||
@ -77,6 +110,11 @@ fn main() {
|
|||||||
output: &output_file,
|
output: &output_file,
|
||||||
async_io: matches.is_present("ASYNC_IO"),
|
async_io: matches.is_present("ASYNC_IO"),
|
||||||
report,
|
report,
|
||||||
|
overrides: SuperblockOverrides {
|
||||||
|
transaction_id,
|
||||||
|
data_block_size,
|
||||||
|
nr_data_blocks,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(reason) = repair(opts) {
|
if let Err(reason) = repair(opts) {
|
||||||
|
@ -15,6 +15,7 @@ use crate::report::*;
|
|||||||
use crate::thin::block_time::*;
|
use crate::thin::block_time::*;
|
||||||
use crate::thin::ir::{self, MetadataVisitor};
|
use crate::thin::ir::{self, MetadataVisitor};
|
||||||
use crate::thin::metadata::*;
|
use crate::thin::metadata::*;
|
||||||
|
use crate::thin::metadata_repair::*;
|
||||||
use crate::thin::superblock::*;
|
use crate::thin::superblock::*;
|
||||||
use crate::thin::xml;
|
use crate::thin::xml;
|
||||||
|
|
||||||
@ -147,6 +148,8 @@ pub struct ThinDumpOptions<'a> {
|
|||||||
pub output: Option<&'a Path>,
|
pub output: Option<&'a Path>,
|
||||||
pub async_io: bool,
|
pub async_io: bool,
|
||||||
pub report: Arc<Report>,
|
pub report: Arc<Report>,
|
||||||
|
pub repair: bool,
|
||||||
|
pub overrides: SuperblockOverrides,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
@ -311,7 +314,12 @@ pub fn dump_metadata(
|
|||||||
|
|
||||||
pub fn dump(opts: ThinDumpOptions) -> Result<()> {
|
pub fn dump(opts: ThinDumpOptions) -> Result<()> {
|
||||||
let ctx = mk_context(&opts)?;
|
let ctx = mk_context(&opts)?;
|
||||||
let sb = read_superblock(ctx.engine.as_ref(), SUPERBLOCK_LOCATION)?;
|
let sb;
|
||||||
|
if opts.repair {
|
||||||
|
sb = read_or_rebuild_superblock(ctx.engine.clone(), SUPERBLOCK_LOCATION, &opts.overrides)?;
|
||||||
|
} else {
|
||||||
|
sb = read_superblock(ctx.engine.as_ref(), SUPERBLOCK_LOCATION)?;
|
||||||
|
}
|
||||||
let md = build_metadata(ctx.engine.clone(), &sb)?;
|
let md = build_metadata(ctx.engine.clone(), &sb)?;
|
||||||
|
|
||||||
ctx.report
|
ctx.report
|
||||||
|
@ -7,6 +7,7 @@ use crate::pdata::space_map_metadata::*;
|
|||||||
use crate::report::*;
|
use crate::report::*;
|
||||||
use crate::thin::dump::*;
|
use crate::thin::dump::*;
|
||||||
use crate::thin::metadata::*;
|
use crate::thin::metadata::*;
|
||||||
|
use crate::thin::metadata_repair::*;
|
||||||
use crate::thin::restore::*;
|
use crate::thin::restore::*;
|
||||||
use crate::thin::superblock::*;
|
use crate::thin::superblock::*;
|
||||||
use crate::write_batcher::*;
|
use crate::write_batcher::*;
|
||||||
@ -18,6 +19,7 @@ pub struct ThinRepairOptions<'a> {
|
|||||||
pub output: &'a Path,
|
pub output: &'a Path,
|
||||||
pub async_io: bool,
|
pub async_io: bool,
|
||||||
pub report: Arc<Report>,
|
pub report: Arc<Report>,
|
||||||
|
pub overrides: SuperblockOverrides,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
@ -53,7 +55,8 @@ fn new_context(opts: &ThinRepairOptions) -> Result<Context> {
|
|||||||
pub fn repair(opts: ThinRepairOptions) -> Result<()> {
|
pub fn repair(opts: ThinRepairOptions) -> Result<()> {
|
||||||
let ctx = new_context(&opts)?;
|
let ctx = new_context(&opts)?;
|
||||||
|
|
||||||
let sb = read_superblock(ctx.engine_in.as_ref(), SUPERBLOCK_LOCATION)?;
|
let sb =
|
||||||
|
read_or_rebuild_superblock(ctx.engine_in.clone(), SUPERBLOCK_LOCATION, &opts.overrides)?;
|
||||||
let md = build_metadata(ctx.engine_in.clone(), &sb)?;
|
let md = build_metadata(ctx.engine_in.clone(), &sb)?;
|
||||||
let md = optimise_metadata(md)?;
|
let md = optimise_metadata(md)?;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user