linuxutils_system/
fsfreeze.rs1use linuxutils_common::man::ManContent;
2
3pub const MAN: ManContent = ManContent::empty();
4
5use clap::Parser;
6use std::{fs::File, io, os::unix::io::AsRawFd, process::ExitCode};
7
8const FIFREEZE: libc::c_ulong = 0xc0045877;
9const FITHAW: libc::c_ulong = 0xc0045878;
10
11#[derive(Parser)]
12#[command(
13 name = "fsfreeze",
14 about = "Suspend or resume access to a filesystem"
15)]
16pub struct Args {
17 #[arg(short = 'f', long, conflicts_with = "unfreeze")]
19 freeze: bool,
20
21 #[arg(short = 'u', long, conflicts_with = "freeze")]
23 unfreeze: bool,
24
25 mountpoint: String,
27}
28
29fn fsfreeze_ioctl(path: &str, ioctl_nr: libc::c_ulong) -> io::Result<()> {
30 let f = File::open(path)?;
31 let arg: libc::c_int = 0;
32 let ret = unsafe { libc::ioctl(f.as_raw_fd(), ioctl_nr, &arg) };
33 if ret < 0 {
34 Err(io::Error::last_os_error())
35 } else {
36 Ok(())
37 }
38}
39
40pub fn run(args: Args) -> ExitCode {
41 if !args.freeze && !args.unfreeze {
42 eprintln!("fsfreeze: one of --freeze or --unfreeze must be specified");
43 return ExitCode::FAILURE;
44 }
45
46 let (ioctl_nr, action) = if args.freeze {
47 (FIFREEZE, "freeze")
48 } else {
49 (FITHAW, "unfreeze")
50 };
51
52 if let Err(e) = fsfreeze_ioctl(&args.mountpoint, ioctl_nr) {
53 eprintln!("fsfreeze: failed to {action} {}: {e}", args.mountpoint);
54 return ExitCode::FAILURE;
55 }
56
57 ExitCode::SUCCESS
58}