Merge pull request #179 from dezgeg/fsfreeze
fsfreeze: add tool (+ linux-raw-sys dependency)
This commit is contained in:
18
Cargo.lock
generated
18
Cargo.lock
generated
@ -393,6 +393,12 @@ version = "0.4.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.22"
|
version = "0.4.22"
|
||||||
@ -1016,6 +1022,7 @@ dependencies = [
|
|||||||
"textwrap",
|
"textwrap",
|
||||||
"uu_ctrlaltdel",
|
"uu_ctrlaltdel",
|
||||||
"uu_dmesg",
|
"uu_dmesg",
|
||||||
|
"uu_fsfreeze",
|
||||||
"uu_last",
|
"uu_last",
|
||||||
"uu_lscpu",
|
"uu_lscpu",
|
||||||
"uu_lsmem",
|
"uu_lsmem",
|
||||||
@ -1047,6 +1054,17 @@ dependencies = [
|
|||||||
"uucore",
|
"uucore",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uu_fsfreeze"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"linux-raw-sys 0.6.5",
|
||||||
|
"regex",
|
||||||
|
"sysinfo",
|
||||||
|
"uucore",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uu_last"
|
name = "uu_last"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
@ -26,6 +26,7 @@ default = ["feat_common_core"]
|
|||||||
uudoc = []
|
uudoc = []
|
||||||
|
|
||||||
feat_common_core = [
|
feat_common_core = [
|
||||||
|
"fsfreeze",
|
||||||
"mountpoint",
|
"mountpoint",
|
||||||
"lscpu",
|
"lscpu",
|
||||||
"lsmem",
|
"lsmem",
|
||||||
@ -55,6 +56,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
serde_json = "1.0.122"
|
serde_json = "1.0.122"
|
||||||
tabled = "0.17.0"
|
tabled = "0.17.0"
|
||||||
dns-lookup = "2.0.4"
|
dns-lookup = "2.0.4"
|
||||||
|
linux-raw-sys = { version = "0.6.5", features = ["ioctl"] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
@ -66,6 +68,7 @@ textwrap = { workspace = true }
|
|||||||
dns-lookup = { workspace = true }
|
dns-lookup = { workspace = true }
|
||||||
|
|
||||||
#
|
#
|
||||||
|
fsfreeze = { optional = true, version = "0.0.1", package = "uu_fsfreeze", path = "src/uu/fsfreeze" }
|
||||||
lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" }
|
lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" }
|
||||||
lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/uu/lsmem" }
|
lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/uu/lsmem" }
|
||||||
mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" }
|
mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" }
|
||||||
|
@ -35,6 +35,7 @@ First, reimplement the most important tools from util-linux:
|
|||||||
Started
|
Started
|
||||||
- `fsck`: Checks and repairs filesystems.
|
- `fsck`: Checks and repairs filesystems.
|
||||||
- `fsfreeze`: Freezes/unfreezes filesystems.
|
- `fsfreeze`: Freezes/unfreezes filesystems.
|
||||||
|
Done
|
||||||
- `fstrim`: Discards unused blocks on filesystems.
|
- `fstrim`: Discards unused blocks on filesystems.
|
||||||
- `wipefs`: Wipes filesystem signatures.
|
- `wipefs`: Wipes filesystem signatures.
|
||||||
|
|
||||||
|
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);
|
62
tests/by-util/test_fsfreeze.rs
Normal file
62
tests/by-util/test_fsfreeze.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// 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 crate::common::util::TestScenario;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_arg() {
|
||||||
|
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_operations_mutually_exclusive() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("--freeze")
|
||||||
|
.arg("--unfreeze")
|
||||||
|
.arg("/foo")
|
||||||
|
.fails()
|
||||||
|
.code_is(1)
|
||||||
|
.stderr_contains("the argument '--freeze' cannot be used with '--unfreeze'");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod linux {
|
||||||
|
use crate::common::util::TestScenario;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fails_on_non_existing_path() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("--unfreeze")
|
||||||
|
.arg("/non/existing")
|
||||||
|
.fails()
|
||||||
|
.code_is(1)
|
||||||
|
.stderr_contains("No such file or directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fails_on_non_directory() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("--unfreeze")
|
||||||
|
.arg("/dev/null")
|
||||||
|
.fails()
|
||||||
|
.code_is(1)
|
||||||
|
.stderr_contains("not a directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
mod non_linux {
|
||||||
|
use crate::common::util::TestScenario;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fails_on_unsupported_platforms() {
|
||||||
|
new_ucmd!()
|
||||||
|
.arg("--unfreeze")
|
||||||
|
.arg("/non/existing")
|
||||||
|
.fails()
|
||||||
|
.code_is(1)
|
||||||
|
.stderr_is("fsfreeze: `fsfreeze` is available only on Linux.\n");
|
||||||
|
}
|
||||||
|
}
|
@ -36,3 +36,7 @@ mod test_last;
|
|||||||
#[cfg(feature = "dmesg")]
|
#[cfg(feature = "dmesg")]
|
||||||
#[path = "by-util/test_dmesg.rs"]
|
#[path = "by-util/test_dmesg.rs"]
|
||||||
mod test_dmesg;
|
mod test_dmesg;
|
||||||
|
|
||||||
|
#[cfg(feature = "fsfreeze")]
|
||||||
|
#[path = "by-util/test_fsfreeze.rs"]
|
||||||
|
mod test_fsfreeze;
|
||||||
|
Reference in New Issue
Block a user