deb-bootupd/src/freezethaw.rs
robojerk aaf662d5b1
Some checks failed
Cross build / Build on ppc64le (push) Failing after 1m8s
Cross build / Build on s390x (push) Failing after 2s
Restructure project layout for better CI/CD integration
- Flattened nested bootupd/bootupd/ structure to root level
- Moved all core project files to root directory
- Added proper Debian packaging structure (debian/ directory)
- Created build scripts and CI configuration
- Improved project organization for CI/CD tools
- All Rust source, tests, and configuration now at root level
- Added GitHub Actions workflow for automated testing
- Maintained all original functionality while improving structure
2025-08-09 23:11:42 -07:00

50 lines
1.5 KiB
Rust
Executable file

use rustix::fd::AsFd;
use rustix::ffi as c;
use rustix::io::Errno;
use rustix::ioctl::opcode;
use rustix::{io, ioctl};
use crate::util::SignalTerminationGuard;
fn ioctl_fifreeze<Fd: AsFd>(fd: Fd) -> io::Result<()> {
// SAFETY: `FIFREEZE` is a no-argument opcode.
// `FIFREEZE` is defined as `_IOWR('X', 119, int)`.
unsafe {
let ctl = ioctl::NoArg::<{ opcode::read_write::<c::c_int>(b'X', 119) }>::new();
ioctl::ioctl(fd, ctl)
}
}
fn ioctl_fithaw<Fd: AsFd>(fd: Fd) -> io::Result<()> {
// SAFETY: `FITHAW` is a no-argument opcode.
// `FITHAW` is defined as `_IOWR('X', 120, int)`.
unsafe {
let ctl = ioctl::NoArg::<{ opcode::read_write::<c::c_int>(b'X', 120) }>::new();
ioctl::ioctl(fd, ctl)
}
}
/// syncfs() doesn't flush the journal on XFS,
/// and since GRUB2 can't read the XFS journal, the system
/// could fail to boot.
///
/// http://marc.info/?l=linux-fsdevel&m=149520244919284&w=2
/// https://github.com/ostreedev/ostree/pull/1049
///
/// This function always call syncfs() first, then calls
/// `ioctl(FIFREEZE)` and `ioctl(FITHAW)`, ignoring `EOPNOTSUPP` and `EPERM`
pub(crate) fn fsfreeze_thaw_cycle<Fd: AsFd>(fd: Fd) -> anyhow::Result<()> {
rustix::fs::syncfs(&fd)?;
let _guard = SignalTerminationGuard::new()?;
let freeze = ioctl_fifreeze(&fd);
match freeze {
// Ignore permissions errors (tests)
Err(Errno::PERM) => Ok(()),
// Ignore unsupported FS
Err(Errno::NOTSUP) => Ok(()),
Ok(()) => Ok(ioctl_fithaw(fd)?),
_ => Ok(freeze?),
}
}