[fxfs] Add fxfs binary
Tested: Built and ran fs_test suite.
Change-Id: Ic388322be92de8ce904b1434afa79d433b322bce
diff --git a/src/storage/fxfs/BUILD.gn b/src/storage/fxfs/BUILD.gn
index 9974071..4066ad4 100644
--- a/src/storage/fxfs/BUILD.gn
+++ b/src/storage/fxfs/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/rust/rustc_binary.gni")
import("//build/rust/rustc_library.gni")
import("//src/sys/build/components.gni")
@@ -33,6 +34,8 @@
"src/lsm_tree/simple_persistent_layer.rs",
"src/lsm_tree/skip_list_layer.rs",
"src/lsm_tree/types.rs",
+ "src/mkfs.rs",
+ "src/mount.rs",
"src/object_handle.rs",
"src/object_store.rs",
"src/object_store/allocator.rs",
@@ -108,3 +111,18 @@
":lib_test($host_toolchain)",
]
}
+
+rustc_binary("fxfs") {
+ edition = "2018"
+ deps = [
+ ":lib",
+ "//src/lib/fuchsia-async",
+ "//src/lib/fuchsia-runtime",
+ "//src/lib/storage/block_client/rust:remote-block-device",
+ "//src/lib/syslog/rust:syslog",
+ "//src/lib/zircon/rust:fuchsia-zircon",
+ "//third_party/rust_crates:anyhow",
+ "//third_party/rust_crates:argh",
+ ]
+ sources = [ "src/main.rs" ]
+}
diff --git a/src/storage/fxfs/src/lib.rs b/src/storage/fxfs/src/lib.rs
index 70ac074..ea64357 100644
--- a/src/storage/fxfs/src/lib.rs
+++ b/src/storage/fxfs/src/lib.rs
@@ -5,6 +5,10 @@
pub mod device;
pub mod errors;
pub mod lsm_tree;
+#[cfg(target_os = "fuchsia")]
+pub mod mkfs;
+#[cfg(target_os = "fuchsia")]
+pub mod mount;
pub mod object_handle;
pub mod object_store;
#[cfg(target_os = "fuchsia")]
diff --git a/src/storage/fxfs/src/main.rs b/src/storage/fxfs/src/main.rs
new file mode 100644
index 0000000..886dbef
--- /dev/null
+++ b/src/storage/fxfs/src/main.rs
@@ -0,0 +1,69 @@
+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::{device::block_device::BlockDevice, mkfs, mount, server::FxfsServer},
+ remote_block_device::RemoteBlockClient,
+ std::sync::Arc,
+};
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// fxfs
+struct TopLevel {
+ #[argh(subcommand)]
+ nested: SubCommand,
+}
+
+#[derive(FromArgs, PartialEq, Debug)]
+#[argh(subcommand)]
+enum SubCommand {
+ Format(FormatSubCommand),
+ Mount(MountSubCommand),
+}
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// Format
+#[argh(subcommand, name = "mkfs")]
+struct FormatSubCommand {}
+
+#[derive(FromArgs, PartialEq, Debug)]
+/// Mount
+#[argh(subcommand, name = "mount")]
+struct MountSubCommand {}
+
+#[fasync::run(10)]
+async fn main() -> Result<(), Error> {
+ fuchsia_syslog::init().unwrap();
+
+ let args: TopLevel = argh::from_env();
+
+ // TODO: Does this need to be boxed and do we need Cache?
+ // Open the remote block device.
+ let client = RemoteBlockClient::new_sync(zx::Channel::from(
+ fuchsia_runtime::take_startup_handle(fuchsia_runtime::HandleInfo::new(
+ HandleType::User0,
+ 1,
+ ))
+ .ok_or(format_err!("Missing device handle"))?,
+ ))?;
+ let device = Arc::new(BlockDevice::new(Box::new(client)));
+
+ match args {
+ TopLevel { nested: SubCommand::Format(_) } => {
+ mkfs::mkfs(device).await?;
+ Ok(())
+ }
+ TopLevel { nested: SubCommand::Mount(_) } => {
+ let fs = mount::mount(device).await?;
+ let mut server = FxfsServer::new(fs, "default").await?;
+ let startup_handle = fuchsia_runtime::take_startup_handle(
+ fuchsia_runtime::HandleType::DirectoryRequest.into(),
+ )
+ .ok_or(MissingStartupHandle)?;
+ server.run(zx::Channel::from(startup_handle)).await
+ }
+ }
+}
diff --git a/src/storage/fxfs/src/mkfs.rs b/src/storage/fxfs/src/mkfs.rs
new file mode 100644
index 0000000..58faf75
--- /dev/null
+++ b/src/storage/fxfs/src/mkfs.rs
@@ -0,0 +1,17 @@
+use {
+ crate::{
+ device::Device,
+ object_store::{filesystem::SyncOptions, FxFilesystem},
+ volume::volume_directory,
+ },
+ anyhow::Error,
+ std::sync::Arc,
+};
+
+pub async fn mkfs(device: Arc<dyn Device>) -> Result<Arc<FxFilesystem>, Error> {
+ let fs = FxFilesystem::new_empty(device).await?;
+ let volume_directory = volume_directory(&fs).await?;
+ volume_directory.new_volume("default").await?;
+ fs.sync(SyncOptions::default()).await?;
+ Ok(fs)
+}
diff --git a/src/storage/fxfs/src/mount.rs b/src/storage/fxfs/src/mount.rs
new file mode 100644
index 0000000..6dc444f
--- /dev/null
+++ b/src/storage/fxfs/src/mount.rs
@@ -0,0 +1,10 @@
+use {
+ crate::{device::Device, object_store::FxFilesystem},
+ anyhow::Error,
+ std::sync::Arc,
+};
+
+pub async fn mount(device: Arc<dyn Device>) -> Result<Arc<FxFilesystem>, Error> {
+ let fs = FxFilesystem::open(device).await?;
+ Ok(fs)
+}