blob: 60bf59c32c79dcc27d2ad17424b9861f6e6c2111 [file] [log] [blame]
// Copyright 2021 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::{format_err, Error},
argh::FromArgs,
fuchsia_async as fasync,
fuchsia_component::server::MissingStartupHandle,
fuchsia_runtime::HandleType,
fuchsia_syslog, fuchsia_zircon as zx,
fxfs::{mkfs, mount, object_store::fsck::fsck, server::FxfsServer},
remote_block_device::RemoteBlockClient,
storage_device::{block_device::BlockDevice, DeviceHolder},
};
#[derive(FromArgs, PartialEq, Debug)]
/// fxfs
struct TopLevel {
#[argh(subcommand)]
nested: SubCommand,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
enum SubCommand {
Format(FormatSubCommand),
Mount(MountSubCommand),
Fsck(FsckSubCommand),
}
#[derive(FromArgs, PartialEq, Debug)]
/// Format
#[argh(subcommand, name = "mkfs")]
struct FormatSubCommand {}
#[derive(FromArgs, PartialEq, Debug)]
/// Mount
#[argh(subcommand, name = "mount")]
struct MountSubCommand {}
#[derive(FromArgs, PartialEq, Debug)]
/// Fsck
#[argh(subcommand, name = "fsck")]
struct FsckSubCommand {}
#[fasync::run(10)]
async fn main() -> Result<(), Error> {
fuchsia_syslog::init().unwrap();
fuchsia_trace_provider::trace_provider_create_with_fdio();
let args: TopLevel = argh::from_env();
let client = RemoteBlockClient::new(zx::Channel::from(
fuchsia_runtime::take_startup_handle(fuchsia_runtime::HandleInfo::new(
HandleType::User0,
1,
))
.ok_or(format_err!("Missing device handle"))?,
))
.await?;
match args {
TopLevel { nested: SubCommand::Format(_) } => {
mkfs::mkfs(DeviceHolder::new(BlockDevice::new(Box::new(client), false).await?)).await?;
Ok(())
}
TopLevel { nested: SubCommand::Mount(_) } => {
let fs =
mount::mount(DeviceHolder::new(BlockDevice::new(Box::new(client), false).await?))
.await?;
let server = FxfsServer::new(fs, "default").await?;
let startup_handle =
fuchsia_runtime::take_startup_handle(HandleType::DirectoryRequest.into())
.ok_or(MissingStartupHandle)?;
server.run(zx::Channel::from(startup_handle)).await
}
TopLevel { nested: SubCommand::Fsck(_) } => {
let fs = mount::mount_read_only(DeviceHolder::new(
BlockDevice::new(Box::new(client), true).await?,
))
.await?;
fsck(fs.as_ref()).await
}
}
}