mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +03:00
create common entry point for Rust commands
The bcachefs sub-commands that are implemented in Rust (completions, list, and mount) had separate entrypoints and thus had some differences in behavior. This introduces a common entry point for the Rust sub-commands. This reduces duplicate boilerplate code like parsing argv and setting up logging, and will facilitate converting more sub-commands to Rust in the future. An immediate benefit is that this fixes an issue with `bcachefs list` not reporting errors: before: $ bcachefs list /dev/typo $ echo $? 0 after: $ bcachefs list /dev/typo ERROR - bcachefs_rust::cmd_list: Fatal error: "No such file or directory" $ echo $? 1 Signed-off-by: Thomas Bertschinger <tahbertschinger@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
b90031efaa
commit
9a9af6e9e6
14
bcachefs.c
14
bcachefs.c
@ -207,7 +207,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifndef BCACHEFS_NO_RUST
|
#ifndef BCACHEFS_NO_RUST
|
||||||
if (strstr(full_cmd, "mount"))
|
if (strstr(full_cmd, "mount"))
|
||||||
return cmd_mount(argc, argv);
|
return rust_main(argc, argv, "mount");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
@ -265,10 +265,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (!strcmp(cmd, "dump"))
|
if (!strcmp(cmd, "dump"))
|
||||||
return cmd_dump(argc, argv);
|
return cmd_dump(argc, argv);
|
||||||
#ifndef BCACHEFS_NO_RUST
|
|
||||||
if (!strcmp(cmd, "list"))
|
|
||||||
return cmd_list(argc, argv);
|
|
||||||
#endif
|
|
||||||
if (!strcmp(cmd, "list_journal"))
|
if (!strcmp(cmd, "list_journal"))
|
||||||
return cmd_list_journal(argc, argv);
|
return cmd_list_journal(argc, argv);
|
||||||
if (!strcmp(cmd, "kill_btree_node"))
|
if (!strcmp(cmd, "kill_btree_node"))
|
||||||
@ -277,10 +273,10 @@ int main(int argc, char *argv[])
|
|||||||
if (!strcmp(cmd, "setattr"))
|
if (!strcmp(cmd, "setattr"))
|
||||||
return cmd_setattr(argc, argv);
|
return cmd_setattr(argc, argv);
|
||||||
#ifndef BCACHEFS_NO_RUST
|
#ifndef BCACHEFS_NO_RUST
|
||||||
if (!strcmp(cmd, "mount"))
|
if (!strcmp(cmd, "list") ||
|
||||||
return cmd_mount(argc, argv);
|
!strcmp(cmd, "mount") ||
|
||||||
if (strstr(cmd, "completions"))
|
!strcmp(cmd, "completions"))
|
||||||
return cmd_completions(argc, argv);
|
return rust_main(argc, argv, cmd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BCACHEFS_FUSE
|
#ifdef BCACHEFS_FUSE
|
||||||
|
5
cmds.h
5
cmds.h
@ -37,7 +37,6 @@ int cmd_remove_passphrase(int argc, char *argv[]);
|
|||||||
int cmd_fsck(int argc, char *argv[]);
|
int cmd_fsck(int argc, char *argv[]);
|
||||||
|
|
||||||
int cmd_dump(int argc, char *argv[]);
|
int cmd_dump(int argc, char *argv[]);
|
||||||
int cmd_list(int argc, char *argv[]);
|
|
||||||
int cmd_list_journal(int argc, char *argv[]);
|
int cmd_list_journal(int argc, char *argv[]);
|
||||||
int cmd_kill_btree_node(int argc, char *argv[]);
|
int cmd_kill_btree_node(int argc, char *argv[]);
|
||||||
|
|
||||||
@ -54,7 +53,7 @@ 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[]);
|
||||||
int cmd_mount(int argc, char *argv[]);
|
|
||||||
int cmd_completions(int argc, char *argv[]);
|
int rust_main(int argc, char *argv[], char *cmd);
|
||||||
|
|
||||||
#endif /* _CMDS_H */
|
#endif /* _CMDS_H */
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::transform_c_args;
|
|
||||||
use clap::{Command, CommandFactory, Parser};
|
use clap::{Command, CommandFactory, Parser};
|
||||||
use clap_complete::{generate, Generator, Shell};
|
use clap_complete::{generate, Generator, Shell};
|
||||||
use std::ffi::{c_char, c_int};
|
use std::ffi::{c_int, OsStr};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
/// Generate shell completions
|
/// Generate shell completions
|
||||||
@ -14,10 +13,7 @@ fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
|
|||||||
generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
|
generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
pub fn cmd_completions(argv: Vec<&OsStr>) -> c_int {
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
|
||||||
pub extern "C" fn cmd_completions(argc: c_int, argv: *const *const c_char) -> c_int {
|
|
||||||
transform_c_args!(argv, argc, argv);
|
|
||||||
let cli = Cli::parse_from(argv);
|
let cli = Cli::parse_from(argv);
|
||||||
print_completions(cli.shell, &mut super::Cli::command());
|
print_completions(cli.shell, &mut super::Cli::command());
|
||||||
0
|
0
|
||||||
|
@ -9,8 +9,7 @@ use bch_bindgen::btree::BtreeIter;
|
|||||||
use bch_bindgen::btree::BtreeNodeIter;
|
use bch_bindgen::btree::BtreeNodeIter;
|
||||||
use bch_bindgen::btree::BtreeIterFlags;
|
use bch_bindgen::btree::BtreeIterFlags;
|
||||||
use clap::{Parser};
|
use clap::{Parser};
|
||||||
use std::ffi::{c_int, c_char};
|
use std::ffi::{c_int, OsStr};
|
||||||
use crate::transform_c_args;
|
|
||||||
|
|
||||||
fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
|
fn list_keys(fs: &Fs, opt: Cli) -> anyhow::Result<()> {
|
||||||
let trans = BtreeTrans::new(fs);
|
let trans = BtreeTrans::new(fs);
|
||||||
@ -158,13 +157,13 @@ fn cmd_list_inner(opt: Cli) -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
pub fn cmd_list(argv: Vec<&OsStr>) -> c_int {
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
|
||||||
pub extern "C" fn cmd_list(argc: c_int, argv: *const *const c_char) {
|
|
||||||
transform_c_args!(argv, argc, argv);
|
|
||||||
let opt = Cli::parse_from(argv);
|
let opt = Cli::parse_from(argv);
|
||||||
colored::control::set_override(opt.colorize);
|
colored::control::set_override(opt.colorize);
|
||||||
if let Err(e) = cmd_list_inner(opt) {
|
if let Err(e) = cmd_list_inner(opt) {
|
||||||
error!("Fatal error: {}", e);
|
error!("Fatal error: {}", e);
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
rust-src/src/cmd_main.rs
Normal file
34
rust-src/src/cmd_main.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use log::{error, LevelFilter};
|
||||||
|
use std::ffi::{CStr, c_int, c_char};
|
||||||
|
use crate::transform_c_args;
|
||||||
|
use crate::logger::SimpleLogger;
|
||||||
|
use crate::cmd_completions::cmd_completions;
|
||||||
|
use crate::cmd_list::cmd_list;
|
||||||
|
use crate::cmd_mount::cmd_mount;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rust_main(argc: c_int, argv: *const *const c_char, cmd: *const c_char) -> c_int {
|
||||||
|
transform_c_args!(argv, argc, argv);
|
||||||
|
|
||||||
|
log::set_boxed_logger(Box::new(SimpleLogger)).unwrap();
|
||||||
|
log::set_max_level(LevelFilter::Warn);
|
||||||
|
|
||||||
|
let cmd: &CStr = unsafe { CStr::from_ptr(cmd) };
|
||||||
|
let cmd = match cmd.to_str() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(e) => {
|
||||||
|
error!("could not parse command: {}", e);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match cmd {
|
||||||
|
"completions" => cmd_completions(argv),
|
||||||
|
"list" => cmd_list(argv),
|
||||||
|
"mount" => cmd_mount(argv),
|
||||||
|
_ => {
|
||||||
|
error!("unknown command: {}", cmd);
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,10 +4,9 @@ use log::{info, debug, error, LevelFilter};
|
|||||||
use clap::{Parser};
|
use clap::{Parser};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use crate::{key, transform_c_args};
|
use crate::key;
|
||||||
use crate::key::KeyLocation;
|
use crate::key::KeyLocation;
|
||||||
use crate::logger::SimpleLogger;
|
use std::ffi::{CString, c_int, c_char, c_void, OsStr};
|
||||||
use std::ffi::{CString, c_int, c_char, c_void};
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
fn mount_inner(
|
fn mount_inner(
|
||||||
@ -222,14 +221,9 @@ fn cmd_mount_inner(opt: Cli) -> anyhow::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
pub fn cmd_mount(argv: Vec<&OsStr>) -> c_int {
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
|
||||||
pub extern "C" fn cmd_mount(argc: c_int, argv: *const *const c_char) -> c_int {
|
|
||||||
transform_c_args!(argv, argc, argv);
|
|
||||||
let opt = Cli::parse_from(argv);
|
let opt = Cli::parse_from(argv);
|
||||||
|
|
||||||
log::set_boxed_logger(Box::new(SimpleLogger)).unwrap();
|
|
||||||
|
|
||||||
// @TODO : more granular log levels via mount option
|
// @TODO : more granular log levels via mount option
|
||||||
log::set_max_level(match opt.verbose {
|
log::set_max_level(match opt.verbose {
|
||||||
0 => LevelFilter::Warn,
|
0 => LevelFilter::Warn,
|
||||||
|
@ -2,6 +2,7 @@ use clap::Subcommand;
|
|||||||
|
|
||||||
pub mod key;
|
pub mod key;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
|
pub mod cmd_main;
|
||||||
pub mod cmd_mount;
|
pub mod cmd_mount;
|
||||||
pub mod cmd_list;
|
pub mod cmd_list;
|
||||||
pub mod cmd_completions;
|
pub mod cmd_completions;
|
||||||
|
Loading…
Reference in New Issue
Block a user