[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::report::*;
|
||||
use thinp::thin::dump::{dump, ThinDumpOptions};
|
||||
use thinp::thin::metadata_repair::SuperblockOverrides;
|
||||
|
||||
fn main() {
|
||||
let parser = App::new("thin_dump")
|
||||
@ -40,6 +41,12 @@ fn main() {
|
||||
.long("skip-mappings"),
|
||||
)
|
||||
// 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::with_name("METADATA_SNAPSHOT")
|
||||
.help("Access the metadata snapshot on a live pool")
|
||||
@ -47,6 +54,12 @@ fn main() {
|
||||
.long("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::with_name("OUTPUT")
|
||||
.help("Specify the output file rather than stdout")
|
||||
@ -54,6 +67,12 @@ fn main() {
|
||||
.long("output")
|
||||
.value_name("FILE"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("TRANSACTION_ID")
|
||||
.help("Override the transaction id if needed")
|
||||
.long("transaction-id")
|
||||
.value_name("NUM"),
|
||||
)
|
||||
// arguments
|
||||
.arg(
|
||||
Arg::with_name("INPUT")
|
||||
@ -75,6 +94,27 @@ fn main() {
|
||||
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;
|
||||
|
||||
if matches.is_present("QUIET") {
|
||||
@ -90,6 +130,12 @@ fn main() {
|
||||
output: output_file,
|
||||
async_io: matches.is_present("ASYNC_IO"),
|
||||
report,
|
||||
repair: matches.is_present("REPAIR"),
|
||||
overrides: SuperblockOverrides {
|
||||
transaction_id,
|
||||
data_block_size,
|
||||
nr_data_blocks,
|
||||
},
|
||||
};
|
||||
|
||||
if let Err(reason) = dump(opts) {
|
||||
|
@ -9,6 +9,7 @@ use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use thinp::file_utils;
|
||||
use thinp::report::*;
|
||||
use thinp::thin::metadata_repair::SuperblockOverrides;
|
||||
use thinp::thin::repair::{repair, ThinRepairOptions};
|
||||
|
||||
fn main() {
|
||||
@ -29,6 +30,12 @@ fn main() {
|
||||
.long("quiet"),
|
||||
)
|
||||
// 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::with_name("INPUT")
|
||||
.help("Specify the input device")
|
||||
@ -37,6 +44,12 @@ fn main() {
|
||||
.value_name("FILE")
|
||||
.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::with_name("OUTPUT")
|
||||
.help("Specify the output device")
|
||||
@ -46,11 +59,10 @@ fn main() {
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("OVERRIDE_MAPPING_ROOT")
|
||||
.help("Specify a mapping root to use")
|
||||
.long("override-mapping-root")
|
||||
.value_name("OVERRIDE_MAPPING_ROOT")
|
||||
.takes_value(true),
|
||||
Arg::with_name("TRANSACTION_ID")
|
||||
.help("Override the transaction id if needed")
|
||||
.long("transaction-id")
|
||||
.value_name("NUM"),
|
||||
);
|
||||
|
||||
let matches = parser.get_matches();
|
||||
@ -62,6 +74,27 @@ fn main() {
|
||||
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;
|
||||
|
||||
if matches.is_present("QUIET") {
|
||||
@ -77,6 +110,11 @@ fn main() {
|
||||
output: &output_file,
|
||||
async_io: matches.is_present("ASYNC_IO"),
|
||||
report,
|
||||
overrides: SuperblockOverrides {
|
||||
transaction_id,
|
||||
data_block_size,
|
||||
nr_data_blocks,
|
||||
},
|
||||
};
|
||||
|
||||
if let Err(reason) = repair(opts) {
|
||||
|
@ -15,6 +15,7 @@ use crate::report::*;
|
||||
use crate::thin::block_time::*;
|
||||
use crate::thin::ir::{self, MetadataVisitor};
|
||||
use crate::thin::metadata::*;
|
||||
use crate::thin::metadata_repair::*;
|
||||
use crate::thin::superblock::*;
|
||||
use crate::thin::xml;
|
||||
|
||||
@ -147,6 +148,8 @@ pub struct ThinDumpOptions<'a> {
|
||||
pub output: Option<&'a Path>,
|
||||
pub async_io: bool,
|
||||
pub report: Arc<Report>,
|
||||
pub repair: bool,
|
||||
pub overrides: SuperblockOverrides,
|
||||
}
|
||||
|
||||
struct Context {
|
||||
@ -311,7 +314,12 @@ pub fn dump_metadata(
|
||||
|
||||
pub fn dump(opts: ThinDumpOptions) -> Result<()> {
|
||||
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)?;
|
||||
|
||||
ctx.report
|
||||
|
@ -7,6 +7,7 @@ use crate::pdata::space_map_metadata::*;
|
||||
use crate::report::*;
|
||||
use crate::thin::dump::*;
|
||||
use crate::thin::metadata::*;
|
||||
use crate::thin::metadata_repair::*;
|
||||
use crate::thin::restore::*;
|
||||
use crate::thin::superblock::*;
|
||||
use crate::write_batcher::*;
|
||||
@ -18,6 +19,7 @@ pub struct ThinRepairOptions<'a> {
|
||||
pub output: &'a Path,
|
||||
pub async_io: bool,
|
||||
pub report: Arc<Report>,
|
||||
pub overrides: SuperblockOverrides,
|
||||
}
|
||||
|
||||
struct Context {
|
||||
@ -53,7 +55,8 @@ fn new_context(opts: &ThinRepairOptions) -> Result<Context> {
|
||||
pub fn repair(opts: ThinRepairOptions) -> Result<()> {
|
||||
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 = optimise_metadata(md)?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user