fsfreeze: Add tool
Add fsfreeze, a Linux-specific tool used to freeze/thaw writes to a filesystem. It's an extremely simple tool so this should have full feature-parity.
This commit is contained in:
18
src/uu/fsfreeze/Cargo.toml
Normal file
18
src/uu/fsfreeze/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "uu_fsfreeze"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
path = "src/fsfreeze.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "fsfreeze"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
linux-raw-sys = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
sysinfo = { workspace = true }
|
||||
uucore = { workspace = true }
|
7
src/uu/fsfreeze/fsfreeze.md
Normal file
7
src/uu/fsfreeze/fsfreeze.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# fsfreeze
|
||||
|
||||
```
|
||||
fsfreeze <--freeze|--unfreeze> <MOUNTPOINT>
|
||||
```
|
||||
|
||||
suspends or resumes modifications to a mounted filesystem
|
85
src/uu/fsfreeze/src/fsfreeze.rs
Normal file
85
src/uu/fsfreeze/src/fsfreeze.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
// This file is part of the uutils util-linux package.
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use clap::{crate_version, Arg, ArgAction, ArgGroup, Command};
|
||||
#[cfg(target_os = "linux")]
|
||||
use std::{fs::File, io, os::fd::AsRawFd};
|
||||
#[cfg(target_os = "linux")]
|
||||
use uucore::{error::UIoError, libc};
|
||||
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||
|
||||
const ABOUT: &str = help_about!("fsfreeze.md");
|
||||
const USAGE: &str = help_usage!("fsfreeze.md");
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||
let mountpoint = matches.get_one::<String>("mountpoint").unwrap();
|
||||
let file = File::open(mountpoint)?;
|
||||
let metadata = file.metadata()?;
|
||||
if !metadata.is_dir() {
|
||||
return Err(UIoError::new(io::ErrorKind::InvalidData, "not a directory"));
|
||||
}
|
||||
|
||||
let (op_name, op_code) = if matches.get_flag("freeze") {
|
||||
("freeze", linux_raw_sys::ioctl::FIFREEZE)
|
||||
} else {
|
||||
("unfreeze", linux_raw_sys::ioctl::FITHAW)
|
||||
};
|
||||
|
||||
if unsafe { libc::ioctl(file.as_raw_fd(), op_code.into(), 0) } < 0 {
|
||||
uucore::show_error!(
|
||||
"failed to {} the filesystem: {}",
|
||||
op_name,
|
||||
UIoError::from(io::Error::last_os_error())
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn uu_app() -> Command {
|
||||
Command::new(uucore::util_name())
|
||||
.version(crate_version!())
|
||||
.about(ABOUT)
|
||||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.arg(
|
||||
Arg::new("freeze")
|
||||
.short('f')
|
||||
.long("freeze")
|
||||
.help("freeze the filesystem")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("unfreeze")
|
||||
.short('u')
|
||||
.long("unfreeze")
|
||||
.help("unfreeze the filesystem")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("mountpoint")
|
||||
.help("mountpoint of the filesystem")
|
||||
.required(true)
|
||||
.action(ArgAction::Set),
|
||||
)
|
||||
.group(
|
||||
ArgGroup::new("action")
|
||||
.required(true)
|
||||
.args(["freeze", "unfreeze"]),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let _matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||
|
||||
Err(uucore::error::USimpleError::new(
|
||||
1,
|
||||
"`fsfreeze` is available only on Linux.",
|
||||
))
|
||||
}
|
1
src/uu/fsfreeze/src/main.rs
Normal file
1
src/uu/fsfreeze/src/main.rs
Normal file
@@ -0,0 +1 @@
|
||||
uucore::bin!(uu_fsfreeze);
|
Reference in New Issue
Block a user