From feada739335807a9432a1a7e36f5aa32a346c73b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 19 Jun 2024 20:37:27 -0400 Subject: [PATCH] Port to rustix, drop nix We already have rustix as a dependency; now that we don't use IPC anymore it's trivial to port to rustix. I prefer its API and maintainer. Signed-off-by: Colin Walters --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- src/cli/bootupctl.rs | 2 +- src/efi.rs | 18 +++++++++++------- src/filesystem.rs | 5 +++-- src/filetree.rs | 22 ++++++---------------- src/util.rs | 5 ++--- 7 files changed, 27 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7af52d84..d35ba323 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,11 +83,11 @@ dependencies = [ "libc", "libsystemd", "log", - "nix 0.23.2", "openat", "openat-ext", "openssl", "os-release", + "rustix", "serde", "serde_json", "tempfile", @@ -699,9 +699,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.4.1", "errno", diff --git a/Cargo.toml b/Cargo.toml index 4f1d4c09..47f9eb08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,11 +30,11 @@ hex = "0.4.3" libc = "^0.2" libsystemd = ">= 0.3, < 0.8" log = "^0.4" -nix = ">= 0.22.1, < 0.24.0" openat = "0.1.20" openat-ext = ">= 0.2.2, < 0.3.0" openssl = "^0.10" os-release = "0.1.0" +rustix = { version = "0.38.34", features = ["process", "fs"] } serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tempfile = "^3.10" diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index e8150b1e..123d42bd 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -142,7 +142,7 @@ fn running_in_systemd() -> bool { /// Require root permission fn require_root_permission() -> Result<()> { - if !nix::unistd::Uid::effective().is_root() { + if !rustix::process::getuid().is_root() { anyhow::bail!("This command requires root privileges") } Ok(()) diff --git a/src/efi.rs b/src/efi.rs index e89fb05b..060eedd9 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -13,6 +13,7 @@ use anyhow::{bail, Context, Result}; use fn_error_context::context; use openat_ext::OpenatDirExt; use os_release::OsRelease; +use rustix::fd::BorrowedFd; use walkdir::WalkDir; use widestring::U16CString; @@ -82,9 +83,9 @@ impl Efi { if !mnt.exists() { continue; } - let st = nix::sys::statfs::statfs(&mnt) - .with_context(|| format!("statfs failed for {mnt:?}"))?; - if st.filesystem_type() != nix::sys::statfs::MSDOS_SUPER_MAGIC { + let st = + rustix::fs::statfs(&mnt).with_context(|| format!("statfs failed for {mnt:?}"))?; + if st.f_type != libc::MSDOS_SUPER_MAGIC { continue; } log::debug!("Reusing existing {mnt:?}"); @@ -454,10 +455,13 @@ impl Drop for Efi { } fn validate_esp(dir: &openat::Dir) -> Result<()> { - let stat = nix::sys::statfs::fstatfs(dir)?; - let fstype = stat.filesystem_type(); - if fstype != nix::sys::statfs::MSDOS_SUPER_MAGIC { - bail!("EFI mount is not a msdos filesystem, but is {:?}", fstype); + let dir = unsafe { BorrowedFd::borrow_raw(dir.as_raw_fd()) }; + let stat = rustix::fs::fstatfs(&dir)?; + if stat.f_type != libc::MSDOS_SUPER_MAGIC { + bail!( + "EFI mount is not a msdos filesystem, but is {:?}", + stat.f_type + ); }; Ok(()) } diff --git a/src/filesystem.rs b/src/filesystem.rs index c9060a70..80b942b3 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -5,6 +5,7 @@ use std::process::Command; use anyhow::{Context, Result}; use fn_error_context::context; +use rustix::fd::BorrowedFd; use serde::Deserialize; #[derive(Deserialize, Debug)] @@ -24,12 +25,12 @@ pub(crate) struct Findmnt { #[context("Inspecting filesystem {path:?}")] pub(crate) fn inspect_filesystem(root: &openat::Dir, path: &str) -> Result { - let rootfd = root.as_raw_fd(); + let rootfd = unsafe { BorrowedFd::borrow_raw(root.as_raw_fd()) }; // SAFETY: This is unsafe just for the pre_exec, when we port to cap-std we can use cap-std-ext let o = unsafe { Command::new("findmnt") .args(["-J", "-v", "--output=SOURCE,FSTYPE,OPTIONS,UUID", path]) - .pre_exec(move || nix::unistd::fchdir(rootfd).map_err(Into::into)) + .pre_exec(move || rustix::process::fchdir(rootfd).map_err(Into::into)) .output()? }; let st = o.status; diff --git a/src/filetree.rs b/src/filetree.rs index c1e58a88..1fff67ae 100644 --- a/src/filetree.rs +++ b/src/filetree.rs @@ -17,8 +17,6 @@ use std::fmt::Display; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::os::unix::io::AsRawFd; #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] -use std::os::unix::process::CommandExt; -#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] use std::path::Path; /// The prefix we apply to our temporary files. @@ -274,20 +272,12 @@ pub(crate) struct ApplyUpdateOptions { // Let's just fork off a helper process for now. #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] pub(crate) fn syncfs(d: &openat::Dir) -> Result<()> { - let d = d.sub_dir(".").expect("subdir"); - let mut c = std::process::Command::new("sync"); - let c = c.args(["-f", "."]); - unsafe { - c.pre_exec(move || { - nix::unistd::fchdir(d.as_raw_fd()).expect("fchdir"); - Ok(()) - }) - }; - let r = c.status().context("syncfs failed")?; - if !r.success() { - bail!("syncfs failed"); - } - Ok(()) + use rustix::fd::BorrowedFd; + use rustix::fs::{Mode, OFlags}; + let d = unsafe { BorrowedFd::borrow_raw(d.as_raw_fd()) }; + let oflags = OFlags::RDONLY | OFlags::CLOEXEC | OFlags::DIRECTORY; + let d = rustix::fs::openat(d, ".", oflags, Mode::empty())?; + rustix::fs::syncfs(d).map_err(Into::into) } #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] diff --git a/src/util.rs b/src/util.rs index c88d173e..d52a745e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -67,10 +67,9 @@ pub(crate) fn filenames(dir: &openat::Dir) -> Result> { } pub(crate) fn ensure_writable_mount>(p: P) -> Result<()> { - use nix::sys::statvfs; let p = p.as_ref(); - let stat = statvfs::statvfs(p)?; - if !stat.flags().contains(statvfs::FsFlags::ST_RDONLY) { + let stat = rustix::fs::statvfs(p)?; + if !stat.f_flag.contains(rustix::fs::StatVfsMountFlags::RDONLY) { return Ok(()); } let status = std::process::Command::new("mount")