diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-01-03 22:31:36 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-02-21 01:03:08 -0500 |
commit | 28f703cc256fb6ae209aba1d1fe509d603de1735 (patch) | |
tree | 220fc0e14cd29a3b56fe18dc8594d7bb4fe66718 /rust-src | |
parent | da6a35689518599b381c285cd9505ab8d58f7c73 (diff) |
Rust now integrated into bcachefs binary
Rust is now required for building the bcachefs tool, and rust code is
now fully integrated with the C codebase - meaning it is possible to
call back and forth.
The mount helper is now a subcommand, 'mount.bcachefs' is now a small
shell wrapper that invokes 'bcachefs mount'.
This will make it easier to start rewriting other subcommands in rust,
and eventually the whole command line interface.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'rust-src')
-rw-r--r-- | rust-src/.gitignore (renamed from rust-src/mount/.gitignore) | 0 | ||||
-rw-r--r-- | rust-src/Cargo.lock (renamed from rust-src/mount/Cargo.lock) | 2 | ||||
-rw-r--r-- | rust-src/Cargo.toml (renamed from rust-src/mount/Cargo.toml) | 7 | ||||
-rw-r--r-- | rust-src/README.md (renamed from rust-src/mount/README.md) | 0 | ||||
-rw-r--r-- | rust-src/bch_bindgen/build.rs | 7 | ||||
-rw-r--r-- | rust-src/default.nix (renamed from rust-src/mount/default.nix) | 0 | ||||
-rw-r--r-- | rust-src/module.nix (renamed from rust-src/mount/module.nix) | 0 | ||||
-rw-r--r-- | rust-src/mount/src/main.rs | 53 | ||||
-rw-r--r-- | rust-src/rustfmt.toml (renamed from rust-src/mount/rustfmt.toml) | 0 | ||||
-rw-r--r-- | rust-src/src/cmd_mount.rs (renamed from rust-src/mount/src/lib.rs) | 110 | ||||
-rw-r--r-- | rust-src/src/filesystem.rs (renamed from rust-src/mount/src/filesystem.rs) | 0 | ||||
-rw-r--r-- | rust-src/src/key.rs (renamed from rust-src/mount/src/key.rs) | 43 | ||||
-rw-r--r-- | rust-src/src/lib.rs | 33 |
13 files changed, 116 insertions, 139 deletions
diff --git a/rust-src/mount/.gitignore b/rust-src/.gitignore index 644cd426..644cd426 100644 --- a/rust-src/mount/.gitignore +++ b/rust-src/.gitignore diff --git a/rust-src/mount/Cargo.lock b/rust-src/Cargo.lock index 0b193360..9e5fd2a5 100644 --- a/rust-src/mount/Cargo.lock +++ b/rust-src/Cargo.lock @@ -44,7 +44,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "bcachefs-mount" +name = "bcachefs-rust" version = "0.3.1" dependencies = [ "anyhow", diff --git a/rust-src/mount/Cargo.toml b/rust-src/Cargo.toml index 40113945..64b195ca 100644 --- a/rust-src/mount/Cargo.toml +++ b/rust-src/Cargo.toml @@ -1,10 +1,11 @@ [package] -name = "bcachefs-mount" +name = "bcachefs-rust" version = "0.3.1" authors = ["Yuxuan Shui <yshuiv7@gmail.com>", "Kayla Firestack <dev@kaylafire.me>"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["staticlib"] [dependencies] atty = "0.2.14" @@ -23,5 +24,5 @@ parse-display = "0.1" errno = "0.2" either = "1.5" rpassword = "4" -bch_bindgen = { path = "../bch_bindgen" } +bch_bindgen = { path = "bch_bindgen" } byteorder = "1.3" diff --git a/rust-src/mount/README.md b/rust-src/README.md index e4700f6b..e4700f6b 100644 --- a/rust-src/mount/README.md +++ b/rust-src/README.md diff --git a/rust-src/bch_bindgen/build.rs b/rust-src/bch_bindgen/build.rs index da1541b1..a2cb8957 100644 --- a/rust-src/bch_bindgen/build.rs +++ b/rust-src/bch_bindgen/build.rs @@ -7,13 +7,8 @@ fn main() { let top_dir: PathBuf = std::env::var_os("CARGO_MANIFEST_DIR") .expect("ENV Var 'CARGO_MANIFEST_DIR' Expected") .into(); - let libbcachefs_inc_dir = std::env::var("LIBBCACHEFS_INCLUDE") - .unwrap_or_else(|_| top_dir.join("libbcachefs").display().to_string()); - let libbcachefs_inc_dir = std::path::Path::new(&libbcachefs_inc_dir); - println!("{}", libbcachefs_inc_dir.display()); - println!("cargo:rustc-link-lib=dylib=bcachefs"); - println!("cargo:rustc-link-search={}", env!("LIBBCACHEFS_LIB")); + let libbcachefs_inc_dir = std::path::Path::new("../.."); let _libbcachefs_dir = top_dir.join("libbcachefs").join("libbcachefs"); let bindings = bindgen::builder() diff --git a/rust-src/mount/default.nix b/rust-src/default.nix index 7cc4b956..7cc4b956 100644 --- a/rust-src/mount/default.nix +++ b/rust-src/default.nix diff --git a/rust-src/mount/module.nix b/rust-src/module.nix index b62aa7dc..b62aa7dc 100644 --- a/rust-src/mount/module.nix +++ b/rust-src/module.nix diff --git a/rust-src/mount/src/main.rs b/rust-src/mount/src/main.rs deleted file mode 100644 index 66ec8acc..00000000 --- a/rust-src/mount/src/main.rs +++ /dev/null @@ -1,53 +0,0 @@ -use bcachefs_mount::Cli; -use bch_bindgen::{error, info}; -use clap::Parser; -use colored::Colorize; - -fn main() { - let opt = Cli::parse(); - bch_bindgen::log::set_verbose_level(opt.verbose + bch_bindgen::log::ERROR); - colored::control::set_override(opt.colorize); - if let Err(e) = crate::main_inner(opt) { - error!("Fatal error: {}", e); - } -} - -pub fn main_inner(opt: Cli) -> anyhow::Result<()> { - use bcachefs_mount::{filesystem, key}; - unsafe { - libc::setvbuf(filesystem::stdout, std::ptr::null_mut(), libc::_IONBF, 0); - // libc::fflush(filesystem::stdout); - } - - let fss = filesystem::probe_filesystems()?; - let fs = fss - .get(&opt.uuid) - .ok_or_else(|| anyhow::anyhow!("filesystem was not found"))?; - - info!("found filesystem {}", fs); - if fs.encrypted() { - let key = opt - .key_location - .0 - .ok_or_else(|| anyhow::anyhow!("no keyoption specified for locked filesystem"))?; - - key::prepare_key(&fs, key)?; - } - - let mountpoint = opt - .mountpoint - .ok_or_else(|| anyhow::anyhow!("mountpoint option was not specified"))?; - - fs.mount(&mountpoint, &opt.options)?; - - Ok(()) -} - -#[cfg(test)] -mod test { - // use insta::assert_debug_snapshot; - // #[test] - // fn snapshot_testing() { - // insta::assert_debug_snapshot!(); - // } -} diff --git a/rust-src/mount/rustfmt.toml b/rust-src/rustfmt.toml index 42f2ad7c..42f2ad7c 100644 --- a/rust-src/mount/rustfmt.toml +++ b/rust-src/rustfmt.toml diff --git a/rust-src/mount/src/lib.rs b/rust-src/src/cmd_mount.rs index 68acde03..7748b199 100644 --- a/rust-src/mount/src/lib.rs +++ b/rust-src/src/cmd_mount.rs @@ -1,66 +1,11 @@ -use anyhow::anyhow; -use atty::Stream; +use bch_bindgen::{error, info}; use clap::Parser; +use colored::Colorize; +use atty::Stream; use uuid::Uuid; - -pub mod err { - pub enum GError { - Unknown { - message: std::borrow::Cow<'static, String>, - }, - } - pub type GResult<T, E, OE> = ::core::result::Result<::core::result::Result<T, E>, OE>; - pub type Result<T, E> = GResult<T, E, GError>; -} - -#[macro_export] -macro_rules! c_str { - ($lit:expr) => { - unsafe { - std::ffi::CStr::from_ptr(concat!($lit, "\0").as_ptr() as *const std::os::raw::c_char) - .to_bytes_with_nul() - .as_ptr() as *const std::os::raw::c_char - } - }; -} - -#[derive(Debug)] -struct ErrnoError(errno::Errno); -impl std::fmt::Display for ErrnoError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - self.0.fmt(f) - } -} -impl std::error::Error for ErrnoError {} - -#[derive(Clone, Debug)] -pub enum KeyLocation { - Fail, - Wait, - Ask, -} - -#[derive(Clone, Debug)] -pub struct KeyLoc(pub Option<KeyLocation>); -impl std::ops::Deref for KeyLoc { - type Target = Option<KeyLocation>; - fn deref(&self) -> &Self::Target { - &self.0 - } -} -impl std::str::FromStr for KeyLoc { - type Err = anyhow::Error; - fn from_str(s: &str) -> anyhow::Result<Self> { - // use anyhow::anyhow; - match s { - "" => Ok(KeyLoc(None)), - "fail" => Ok(KeyLoc(Some(KeyLocation::Fail))), - "wait" => Ok(KeyLoc(Some(KeyLocation::Wait))), - "ask" => Ok(KeyLoc(Some(KeyLocation::Ask))), - _ => Err(anyhow!("invalid password option")), - } - } -} +use crate::filesystem; +use crate::key; +use crate::key::KeyLoc; fn parse_fstab_uuid(uuid_raw: &str) -> Result<Uuid, uuid::Error> { let mut uuid = String::from(uuid_raw); @@ -114,12 +59,41 @@ pub struct Cli { pub verbose: u8, } -pub mod filesystem; -pub mod key; -// pub fn mnt_in_use() +pub fn cmd_mount_inner(opt: Cli) -> anyhow::Result<()> { + unsafe { + libc::setvbuf(filesystem::stdout, std::ptr::null_mut(), libc::_IONBF, 0); + } -#[test] -fn verify_cli() { - use clap::CommandFactory; - Cli::command().debug_assert() + let fss = filesystem::probe_filesystems()?; + let fs = fss + .get(&opt.uuid) + .ok_or_else(|| anyhow::anyhow!("filesystem was not found"))?; + + info!("found filesystem {}", fs); + if fs.encrypted() { + let key = opt + .key_location + .0 + .ok_or_else(|| anyhow::anyhow!("no keyoption specified for locked filesystem"))?; + + key::prepare_key(&fs, key)?; + } + + let mountpoint = opt + .mountpoint + .ok_or_else(|| anyhow::anyhow!("mountpoint option was not specified"))?; + + fs.mount(&mountpoint, &opt.options)?; + + Ok(()) +} + +#[no_mangle] +pub extern "C" fn cmd_mount() { + let opt = Cli::parse(); + bch_bindgen::log::set_verbose_level(opt.verbose + bch_bindgen::log::ERROR); + colored::control::set_override(opt.colorize); + if let Err(e) = cmd_mount_inner(opt) { + error!("Fatal error: {}", e); + } } diff --git a/rust-src/mount/src/filesystem.rs b/rust-src/src/filesystem.rs index 28a2ab9e..28a2ab9e 100644 --- a/rust-src/mount/src/filesystem.rs +++ b/rust-src/src/filesystem.rs diff --git a/rust-src/mount/src/key.rs b/rust-src/src/key.rs index a49baa68..e2d0e4c0 100644 --- a/rust-src/mount/src/key.rs +++ b/rust-src/src/key.rs @@ -1,5 +1,36 @@ use bch_bindgen::info; use colored::Colorize; +use crate::c_str; +use anyhow::anyhow; + +#[derive(Clone, Debug)] +pub enum KeyLocation { + Fail, + Wait, + Ask, +} + +#[derive(Clone, Debug)] +pub struct KeyLoc(pub Option<KeyLocation>); +impl std::ops::Deref for KeyLoc { + type Target = Option<KeyLocation>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::str::FromStr for KeyLoc { + type Err = anyhow::Error; + fn from_str(s: &str) -> anyhow::Result<Self> { + match s { + "" => Ok(KeyLoc(None)), + "fail" => Ok(KeyLoc(Some(KeyLocation::Fail))), + "wait" => Ok(KeyLoc(Some(KeyLocation::Wait))), + "ask" => Ok(KeyLoc(Some(KeyLocation::Ask))), + _ => Err(anyhow!("invalid password option")), + } + } +} fn check_for_key(key_name: &std::ffi::CStr) -> anyhow::Result<bool> { use bch_bindgen::keyutils::{self, keyctl_search}; @@ -31,7 +62,6 @@ fn wait_for_key(uuid: &uuid::Uuid) -> anyhow::Result<()> { const BCH_KEY_MAGIC: &str = "bch**key"; use crate::filesystem::FileSystem; fn ask_for_key(fs: &FileSystem) -> anyhow::Result<()> { - use anyhow::anyhow; use bch_bindgen::bcachefs::{self, bch2_chacha_encrypt_key, bch_encrypted_key, bch_key}; use byteorder::{LittleEndian, ReadBytesExt}; use std::os::raw::c_char; @@ -84,14 +114,11 @@ fn ask_for_key(fs: &FileSystem) -> anyhow::Result<()> { } } -pub fn prepare_key(fs: &FileSystem, password: crate::KeyLocation) -> anyhow::Result<()> { - use crate::KeyLocation::*; - use anyhow::anyhow; - +pub fn prepare_key(fs: &FileSystem, password: KeyLocation) -> anyhow::Result<()> { info!("checking if key exists for filesystem {}", fs.uuid()); match password { - Fail => Err(anyhow!("no key available")), - Wait => Ok(wait_for_key(fs.uuid())?), - Ask => ask_for_key(fs), + KeyLocation::Fail => Err(anyhow!("no key available")), + KeyLocation::Wait => Ok(wait_for_key(fs.uuid())?), + KeyLocation::Ask => ask_for_key(fs), } } diff --git a/rust-src/src/lib.rs b/rust-src/src/lib.rs new file mode 100644 index 00000000..b2f0aaa7 --- /dev/null +++ b/rust-src/src/lib.rs @@ -0,0 +1,33 @@ +pub mod filesystem; +pub mod key; +pub mod cmd_mount; + +pub mod err { + pub enum GError { + Unknown { + message: std::borrow::Cow<'static, String>, + }, + } + pub type GResult<T, E, OE> = ::core::result::Result<::core::result::Result<T, E>, OE>; + pub type Result<T, E> = GResult<T, E, GError>; +} + +#[macro_export] +macro_rules! c_str { + ($lit:expr) => { + unsafe { + std::ffi::CStr::from_ptr(concat!($lit, "\0").as_ptr() as *const std::os::raw::c_char) + .to_bytes_with_nul() + .as_ptr() as *const std::os::raw::c_char + } + }; +} + +#[derive(Debug)] +struct ErrnoError(errno::Errno); +impl std::fmt::Display for ErrnoError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + self.0.fmt(f) + } +} +impl std::error::Error for ErrnoError {} |