blob: acd7abdd86e20feaa119c4194694e8220cac32b2 [file] [log] [blame] [edit]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
anyhow::{Context as _, Error},
blackout_target::{
static_tree::{DirectoryEntry, EntryDistribution},
CommonCommand, CommonOpts,
},
fs_management::{Filesystem, Minfs},
rand::{rngs::StdRng, Rng, SeedableRng},
structopt::StructOpt,
};
#[derive(Debug, StructOpt)]
#[structopt(rename_all = "kebab-case")]
struct Opts {
#[structopt(flatten)]
common: CommonOpts,
/// A particular step of the test to perform.
#[structopt(subcommand)]
commands: CommonCommand,
}
fn setup(mut minfs: Filesystem<Minfs>) -> Result<(), Error> {
println!("formatting block device with minfs");
minfs.format().context("failed to format minfs")?;
Ok(())
}
fn test(mut minfs: Filesystem<Minfs>, seed: u64) -> Result<(), Error> {
let root = format!("/test-fs-root-{}", seed);
println!("mounting minfs into default namespace at {}", root);
minfs.mount(&root).context("failed to mount minfs")?;
println!("generating load");
let mut rng = StdRng::seed_from_u64(seed);
loop {
println!("generating tree");
let dist = EntryDistribution::new(6);
let tree: DirectoryEntry = rng.sample(&dist);
println!("generated tree: {:?}", tree);
let tree_name = tree.get_name();
let tree_path = format!("{}/{}", root, tree_name);
println!("writing tree");
tree.write_tree_at(&root).context("failed to write directory tree")?;
// now try renaming the tree root
let tree_path2 = format!("{}/{}-renamed", root, tree_name);
println!("moving tree");
std::fs::rename(&tree_path, &tree_path2).context("failed to move directory tree")?;
// then try deleting the entire thing.
println!("deleting tree");
std::fs::remove_dir_all(&tree_path2).context("failed to delete directory tree")?;
}
}
fn verify(mut minfs: Filesystem<Minfs>) -> Result<(), Error> {
println!("verifying disk with fsck");
minfs.fsck().context("failed to run fsck")?;
println!("verification successful");
Ok(())
}
fn main() -> Result<(), Error> {
let opts = Opts::from_args();
println!("minfs block device: {}", opts.common.block_device);
let minfs = Minfs::new(&opts.common.block_device)?;
match opts.commands {
CommonCommand::Setup => setup(minfs),
CommonCommand::Test => test(minfs, opts.common.seed),
CommonCommand::Verify => verify(minfs),
}
}