mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-22 00:00:03 +03:00
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>
This commit is contained in:
parent
da6a356895
commit
28f703cc25
4
.gitignore
vendored
4
.gitignore
vendored
@ -6,8 +6,6 @@ bcachefs.5
|
|||||||
*.so
|
*.so
|
||||||
*.d
|
*.d
|
||||||
*.a
|
*.a
|
||||||
/rust-src/mount/result
|
|
||||||
/rust-src/bch_bindgen/result
|
|
||||||
tags
|
tags
|
||||||
TAGS
|
TAGS
|
||||||
cscope*
|
cscope*
|
||||||
@ -21,6 +19,4 @@ tests/__pycache__/
|
|||||||
!.travis.yml
|
!.travis.yml
|
||||||
!.editorconfig
|
!.editorconfig
|
||||||
|
|
||||||
mount/target
|
|
||||||
mount.bcachefs
|
|
||||||
bcachefs-principles-of-operation.*
|
bcachefs-principles-of-operation.*
|
||||||
|
43
Makefile
43
Makefile
@ -90,10 +90,11 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: bcachefs lib
|
all: bcachefs
|
||||||
|
|
||||||
.PHONY: lib
|
.PHONY: debug
|
||||||
lib: libbcachefs.so
|
debug: CFLAGS+=-Werror -DCONFIG_BCACHEFS_DEBUG=y -DCONFIG_VALGRIND=y
|
||||||
|
debug: bcachefs
|
||||||
|
|
||||||
.PHONY: tests
|
.PHONY: tests
|
||||||
tests: tests/test_helper
|
tests: tests/test_helper
|
||||||
@ -123,30 +124,17 @@ OBJS=$(SRCS:.c=.o)
|
|||||||
@echo " [CC] $@"
|
@echo " [CC] $@"
|
||||||
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
bcachefs: $(filter-out ./tests/%.o, $(OBJS))
|
bcachefs: libbcachefs.a rust-src/target/release/libbcachefs_rust.a
|
||||||
@echo " [LD] $@"
|
@echo " [LD] $@"
|
||||||
$(Q)$(CC) $(LDFLAGS) $+ $(LOADLIBES) $(LDLIBS) -o $@
|
$(Q)$(CC) $(LDFLAGS) -Wl,--whole-archive $+ $(LOADLIBES) -Wl,--no-whole-archive $(LDLIBS) -o $@
|
||||||
|
|
||||||
|
libbcachefs.a: $(filter-out ./tests/%.o, $(OBJS))
|
||||||
|
@echo " [AR] $@"
|
||||||
|
$(Q)ar -rc $@ $+
|
||||||
|
|
||||||
RUST_SRCS=$(shell find rust-src/ -type f -iname '*.rs')
|
RUST_SRCS=$(shell find rust-src/ -type f -iname '*.rs')
|
||||||
MOUNT_SRCS=$(filter %mount, $(RUST_SRCS))
|
rust-src/target/release/libbcachefs_rust.a: libbcachefs.a $(RUST_SRCS)
|
||||||
|
$(CARGO_BUILD) --manifest-path rust-src/Cargo.toml
|
||||||
debug: CFLAGS+=-Werror -DCONFIG_BCACHEFS_DEBUG=y -DCONFIG_VALGRIND=y
|
|
||||||
debug: bcachefs
|
|
||||||
|
|
||||||
MOUNT_OBJ=$(filter-out ./bcachefs.o ./tests/%.o ./cmd_%.o , $(OBJS))
|
|
||||||
libbcachefs.so: LDFLAGS+=-shared
|
|
||||||
libbcachefs.so: $(MOUNT_OBJ)
|
|
||||||
@echo " [CC] $@"
|
|
||||||
$(Q)$(CC) $(LDFLAGS) $+ -o $@ $(LDLIBS)
|
|
||||||
|
|
||||||
MOUNT_TOML=rust-src/mount/Cargo.toml
|
|
||||||
mount.bcachefs: lib $(MOUNT_SRCS)
|
|
||||||
LIBBCACHEFS_LIB=$(CURDIR) \
|
|
||||||
LIBBCACHEFS_INCLUDE=$(CURDIR) \
|
|
||||||
$(CARGO_BUILD) --manifest-path $(MOUNT_TOML)
|
|
||||||
|
|
||||||
ln -f rust-src/mount/target/$(CARGO_PROFILE)/bcachefs-mount $@
|
|
||||||
|
|
||||||
|
|
||||||
tests/test_helper: $(filter ./tests/%.o, $(OBJS))
|
tests/test_helper: $(filter ./tests/%.o, $(OBJS))
|
||||||
@echo " [LD] $@"
|
@echo " [LD] $@"
|
||||||
@ -166,15 +154,14 @@ cmd_version.o : .version
|
|||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: INITRAMFS_HOOK=$(INITRAMFS_DIR)/hooks/bcachefs
|
install: INITRAMFS_HOOK=$(INITRAMFS_DIR)/hooks/bcachefs
|
||||||
install: INITRAMFS_SCRIPT=$(INITRAMFS_DIR)/scripts/local-premount/bcachefs
|
install: INITRAMFS_SCRIPT=$(INITRAMFS_DIR)/scripts/local-premount/bcachefs
|
||||||
install: bcachefs lib
|
install: bcachefs
|
||||||
$(INSTALL) -m0755 -D bcachefs -t $(DESTDIR)$(ROOT_SBINDIR)
|
$(INSTALL) -m0755 -D bcachefs -t $(DESTDIR)$(ROOT_SBINDIR)
|
||||||
$(INSTALL) -m0755 fsck.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
|
$(INSTALL) -m0755 fsck.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
|
||||||
$(INSTALL) -m0755 mkfs.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
|
$(INSTALL) -m0755 mkfs.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
|
||||||
|
$(INSTALL) -m0755 mount.bcachefs $(DESTDIR)$(ROOT_SBINDIR)
|
||||||
$(INSTALL) -m0644 -D bcachefs.8 -t $(DESTDIR)$(PREFIX)/share/man/man8/
|
$(INSTALL) -m0644 -D bcachefs.8 -t $(DESTDIR)$(PREFIX)/share/man/man8/
|
||||||
$(INSTALL) -m0755 -D initramfs/script $(DESTDIR)$(INITRAMFS_SCRIPT)
|
$(INSTALL) -m0755 -D initramfs/script $(DESTDIR)$(INITRAMFS_SCRIPT)
|
||||||
$(INSTALL) -m0755 -D initramfs/hook $(DESTDIR)$(INITRAMFS_HOOK)
|
$(INSTALL) -m0755 -D initramfs/hook $(DESTDIR)$(INITRAMFS_HOOK)
|
||||||
$(INSTALL) -m0755 -D mount.bcachefs.sh $(DESTDIR)$(ROOT_SBINDIR)
|
|
||||||
$(INSTALL) -m0755 -D libbcachefs.so -t $(DESTDIR)$(PREFIX)/lib/
|
|
||||||
|
|
||||||
sed -i '/^# Note: make install replaces/,$$d' $(DESTDIR)$(INITRAMFS_HOOK)
|
sed -i '/^# Note: make install replaces/,$$d' $(DESTDIR)$(INITRAMFS_HOOK)
|
||||||
echo "copy_exec $(ROOT_SBINDIR)/bcachefs /sbin/bcachefs" >> $(DESTDIR)$(INITRAMFS_HOOK)
|
echo "copy_exec $(ROOT_SBINDIR)/bcachefs /sbin/bcachefs" >> $(DESTDIR)$(INITRAMFS_HOOK)
|
||||||
@ -182,7 +169,7 @@ install: bcachefs lib
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@echo "Cleaning all"
|
@echo "Cleaning all"
|
||||||
$(Q)$(RM) bcachefs mount.bcachefs libbcachefs.so libbcachefs_mount.a tests/test_helper .version *.tar.xz $(OBJS) $(DEPS) $(DOCGENERATED)
|
$(Q)$(RM) bcachefs libbcachefs.a tests/test_helper .version *.tar.xz $(OBJS) $(DEPS) $(DOCGENERATED)
|
||||||
$(Q)$(RM) -rf rust-src/*/target
|
$(Q)$(RM) -rf rust-src/*/target
|
||||||
|
|
||||||
.PHONY: deb
|
.PHONY: deb
|
||||||
|
17
bcachefs.c
17
bcachefs.c
@ -177,8 +177,21 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
char *cmd = pop_cmd(&argc, argv);
|
if (argc < 2) {
|
||||||
if (argc < 1) {
|
puts("missing command\n");
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rust commands first - rust can't handle us mutating argv */
|
||||||
|
char *cmd = argv[1];
|
||||||
|
|
||||||
|
if (!strcmp(cmd, "mount")) {
|
||||||
|
cmd_mount();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = pop_cmd(&argc, argv);
|
||||||
|
if (!cmd) {
|
||||||
puts("missing command\n");
|
puts("missing command\n");
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
|
1
cmds.h
1
cmds.h
@ -61,5 +61,6 @@ int cmd_subvolume_delete(int argc, char *argv[]);
|
|||||||
int cmd_subvolume_snapshot(int argc, char *argv[]);
|
int cmd_subvolume_snapshot(int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_fusemount(int argc, char *argv[]);
|
int cmd_fusemount(int argc, char *argv[]);
|
||||||
|
void cmd_mount(void);
|
||||||
|
|
||||||
#endif /* _CMDS_H */
|
#endif /* _CMDS_H */
|
||||||
|
4
mount.bcachefs
Executable file
4
mount.bcachefs
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SDIR="$(readlink -f "$0")"
|
||||||
|
exec "${SDIR%/*}/bcachefs" mount "$@"
|
2
rust-src/mount/Cargo.lock → rust-src/Cargo.lock
generated
2
rust-src/mount/Cargo.lock → rust-src/Cargo.lock
generated
@ -44,7 +44,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bcachefs-mount"
|
name = "bcachefs-rust"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
@ -1,10 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bcachefs-mount"
|
name = "bcachefs-rust"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
authors = ["Yuxuan Shui <yshuiv7@gmail.com>", "Kayla Firestack <dev@kaylafire.me>"]
|
authors = ["Yuxuan Shui <yshuiv7@gmail.com>", "Kayla Firestack <dev@kaylafire.me>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[lib]
|
||||||
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
@ -23,5 +24,5 @@ parse-display = "0.1"
|
|||||||
errno = "0.2"
|
errno = "0.2"
|
||||||
either = "1.5"
|
either = "1.5"
|
||||||
rpassword = "4"
|
rpassword = "4"
|
||||||
bch_bindgen = { path = "../bch_bindgen" }
|
bch_bindgen = { path = "bch_bindgen" }
|
||||||
byteorder = "1.3"
|
byteorder = "1.3"
|
@ -7,13 +7,8 @@ fn main() {
|
|||||||
let top_dir: PathBuf = std::env::var_os("CARGO_MANIFEST_DIR")
|
let top_dir: PathBuf = std::env::var_os("CARGO_MANIFEST_DIR")
|
||||||
.expect("ENV Var 'CARGO_MANIFEST_DIR' Expected")
|
.expect("ENV Var 'CARGO_MANIFEST_DIR' Expected")
|
||||||
.into();
|
.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");
|
let libbcachefs_inc_dir = std::path::Path::new("../..");
|
||||||
println!("cargo:rustc-link-search={}", env!("LIBBCACHEFS_LIB"));
|
|
||||||
|
|
||||||
let _libbcachefs_dir = top_dir.join("libbcachefs").join("libbcachefs");
|
let _libbcachefs_dir = top_dir.join("libbcachefs").join("libbcachefs");
|
||||||
let bindings = bindgen::builder()
|
let bindings = bindgen::builder()
|
||||||
|
@ -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!();
|
|
||||||
// }
|
|
||||||
}
|
|
@ -1,66 +1,11 @@
|
|||||||
use anyhow::anyhow;
|
use bch_bindgen::{error, info};
|
||||||
use atty::Stream;
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use colored::Colorize;
|
||||||
|
use atty::Stream;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
use crate::filesystem;
|
||||||
pub mod err {
|
use crate::key;
|
||||||
pub enum GError {
|
use crate::key::KeyLoc;
|
||||||
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")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_fstab_uuid(uuid_raw: &str) -> Result<Uuid, uuid::Error> {
|
fn parse_fstab_uuid(uuid_raw: &str) -> Result<Uuid, uuid::Error> {
|
||||||
let mut uuid = String::from(uuid_raw);
|
let mut uuid = String::from(uuid_raw);
|
||||||
@ -114,12 +59,41 @@ pub struct Cli {
|
|||||||
pub verbose: u8,
|
pub verbose: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod filesystem;
|
pub fn cmd_mount_inner(opt: Cli) -> anyhow::Result<()> {
|
||||||
pub mod key;
|
unsafe {
|
||||||
// pub fn mnt_in_use()
|
libc::setvbuf(filesystem::stdout, std::ptr::null_mut(), libc::_IONBF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
let fss = filesystem::probe_filesystems()?;
|
||||||
fn verify_cli() {
|
let fs = fss
|
||||||
use clap::CommandFactory;
|
.get(&opt.uuid)
|
||||||
Cli::command().debug_assert()
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,36 @@
|
|||||||
use bch_bindgen::info;
|
use bch_bindgen::info;
|
||||||
use colored::Colorize;
|
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> {
|
fn check_for_key(key_name: &std::ffi::CStr) -> anyhow::Result<bool> {
|
||||||
use bch_bindgen::keyutils::{self, keyctl_search};
|
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";
|
const BCH_KEY_MAGIC: &str = "bch**key";
|
||||||
use crate::filesystem::FileSystem;
|
use crate::filesystem::FileSystem;
|
||||||
fn ask_for_key(fs: &FileSystem) -> anyhow::Result<()> {
|
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 bch_bindgen::bcachefs::{self, bch2_chacha_encrypt_key, bch_encrypted_key, bch_key};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use std::os::raw::c_char;
|
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<()> {
|
pub fn prepare_key(fs: &FileSystem, password: KeyLocation) -> anyhow::Result<()> {
|
||||||
use crate::KeyLocation::*;
|
|
||||||
use anyhow::anyhow;
|
|
||||||
|
|
||||||
info!("checking if key exists for filesystem {}", fs.uuid());
|
info!("checking if key exists for filesystem {}", fs.uuid());
|
||||||
match password {
|
match password {
|
||||||
Fail => Err(anyhow!("no key available")),
|
KeyLocation::Fail => Err(anyhow!("no key available")),
|
||||||
Wait => Ok(wait_for_key(fs.uuid())?),
|
KeyLocation::Wait => Ok(wait_for_key(fs.uuid())?),
|
||||||
Ask => ask_for_key(fs),
|
KeyLocation::Ask => ask_for_key(fs),
|
||||||
}
|
}
|
||||||
}
|
}
|
33
rust-src/src/lib.rs
Normal file
33
rust-src/src/lib.rs
Normal file
@ -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 {}
|
Loading…
Reference in New Issue
Block a user