From 0d9399ba732b0d220d781e811cfdecae88014358 Mon Sep 17 00:00:00 2001 From: Chad Austin Date: Tue, 17 Dec 2024 12:44:23 -0800 Subject: [PATCH] upgrade nix to 0.29.0 Summary: Enable more features that are disabled by default and update call sites. Reviewed By: opsound, jasonwhite Differential Revision: D66275420 fbshipit-source-id: 4969045de7751c7d16b6ed5c7411f04077eb0ddc --- detcore-model/Cargo.toml | 2 +- detcore/Cargo.toml | 2 +- .../lit/child_should_inherit_fds/main.rs | 11 ++++--- detcore/tests/lit/close_on_exec/main.rs | 10 +++--- detcore/tests/lit/dup2_existing_fd/main.rs | 8 ++--- detcore/tests/lit/no_close_on_exec/main.rs | 12 ++++--- detcore/tests/lit/openat_lowest_fd/main.rs | 2 +- .../tests/lit/openat_next_lowest_fd/main.rs | 10 +++--- .../tests/lit/pipe_creates_valid_fds/main.rs | 10 +++--- detcore/tests/lit/print_race/main.rs | 7 +++-- hermit-cli/Cargo.toml | 2 +- tests/Cargo.toml | 2 +- tests/rust/futex_timeout.rs | 5 ++- tests/rust/futex_wake_some.rs | 3 +- tests/rust/pipe_basics.rs | 9 +++--- tests/rust/poll.rs | 15 ++++----- tests/rust/poll_spin.rs | 31 ++++++++++--------- tests/rust/socketpair.rs | 6 ++-- 18 files changed, 78 insertions(+), 69 deletions(-) diff --git a/detcore-model/Cargo.toml b/detcore-model/Cargo.toml index 04aad47..5ba6aae 100644 --- a/detcore-model/Cargo.toml +++ b/detcore-model/Cargo.toml @@ -14,7 +14,7 @@ bytesize = "1.1" chrono = { version = "0.4", features = ["clock", "serde", "std"], default-features = false } clap = { version = "3.2.25", features = ["derive", "env", "regex", "unicode", "wrap_help"] } libc = "0.2.139" -nix = "0.26.4" +nix = { version = "0.29.0", features = ["dir", "event", "hostname", "inotify", "ioctl", "mman", "mount", "net", "poll", "ptrace", "reboot", "resource", "sched", "term", "time", "user", "zerocopy"] } reverie-syscalls = { version = "0.1.0", git = "https://github.com/facebookexperimental/reverie.git", branch = "main" } serde = { version = "1.0.185", features = ["derive", "rc"] } shell-words = "1.1.0" diff --git a/detcore/Cargo.toml b/detcore/Cargo.toml index ef9d11e..692dc27 100644 --- a/detcore/Cargo.toml +++ b/detcore/Cargo.toml @@ -34,7 +34,7 @@ digest = { version = "0.0.0", path = "../common/digest" } futures = { version = "0.3.30", features = ["async-await", "compat"] } lazy_static = "1.4" libc = "0.2.139" -nix = "0.26.4" +nix = { version = "0.29.0", features = ["dir", "event", "hostname", "inotify", "ioctl", "mman", "mount", "net", "poll", "ptrace", "reboot", "resource", "sched", "term", "time", "user", "zerocopy"] } pretty = "0.12.1" pretty_assertions = { version = "1.2", features = ["alloc"], default-features = false } procfs = "0.15.1" diff --git a/detcore/tests/lit/child_should_inherit_fds/main.rs b/detcore/tests/lit/child_should_inherit_fds/main.rs index 8978c87..0df18d4 100644 --- a/detcore/tests/lit/child_should_inherit_fds/main.rs +++ b/detcore/tests/lit/child_should_inherit_fds/main.rs @@ -10,9 +10,10 @@ // FIXME(T96027871): %hermit run --strict -- %me +use std::os::fd::AsRawFd; + use nix::sys::wait::waitpid; use nix::sys::wait::WaitStatus; -use nix::unistd::close; use nix::unistd::fork; use nix::unistd::pipe; use nix::unistd::read; @@ -24,19 +25,19 @@ fn main() { let msg: [u8; 8] = [0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]; match unsafe { fork().unwrap() } { ForkResult::Parent { child, .. } => { - assert!(close(fdwrite).is_ok()); + drop(fdwrite); let mut buf: [u8; 8] = [0; 8]; // XXX: The following SYS_read would timeout due to detcore issue. // add a 5 seconds timeout to abort. unsafe { libc::alarm(5) }; - assert_eq!(read(fdread, &mut buf), Ok(8)); + assert_eq!(read(fdread.as_raw_fd(), &mut buf), Ok(8)); assert_eq!(buf, msg); assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0))); unsafe { libc::syscall(libc::SYS_exit_group, 0) }; } ForkResult::Child => { - assert!(close(fdread).is_ok()); - assert_eq!(write(fdwrite, &msg), Ok(8)); + drop(fdread); + assert_eq!(write(&fdwrite, &msg), Ok(8)); unsafe { libc::syscall(libc::SYS_exit_group, 0) }; } } diff --git a/detcore/tests/lit/close_on_exec/main.rs b/detcore/tests/lit/close_on_exec/main.rs index 2a7488f..a620e06 100644 --- a/detcore/tests/lit/close_on_exec/main.rs +++ b/detcore/tests/lit/close_on_exec/main.rs @@ -13,6 +13,7 @@ // FIXME(T96027871): %hermit run --strict -- %me +use std::os::fd::AsRawFd; use std::ptr; use nix::errno::Errno; @@ -20,7 +21,6 @@ use nix::fcntl::OFlag; use nix::sys::stat::fstat; use nix::sys::wait::waitpid; use nix::sys::wait::WaitStatus; -use nix::unistd::close; use nix::unistd::fork; use nix::unistd::pipe2; use nix::unistd::read; @@ -42,24 +42,24 @@ fn main() { let (fdread, fdwrite) = pipe2(OFlag::O_CLOEXEC).unwrap(); // Allocate the string before the fork to avoid deadlocks. - let fdwrite_str = format!("{}\0", fdwrite); + let fdwrite_str = format!("{}\0", fdwrite.as_raw_fd()); match unsafe { fork().unwrap() } { ForkResult::Parent { child, .. } => { - assert!(close(fdwrite).is_ok()); + drop(fdwrite); let mut msg = [0u8; 4]; // The child never writes to this fd before calling `execve`. This // is a common pattern when spawning processes for smuggling out the // `execve` errno. - assert_eq!(read(fdread, &mut msg), Ok(0)); + assert_eq!(read(fdread.as_raw_fd(), &mut msg), Ok(0)); // Wait for the child to exit. assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0))); } ForkResult::Child => { - assert!(close(fdread).is_ok()); + drop(fdread); let proc_self = "/proc/self/exe\0".as_ptr() as *const libc::c_char; diff --git a/detcore/tests/lit/dup2_existing_fd/main.rs b/detcore/tests/lit/dup2_existing_fd/main.rs index 96b9b7d..431ec32 100644 --- a/detcore/tests/lit/dup2_existing_fd/main.rs +++ b/detcore/tests/lit/dup2_existing_fd/main.rs @@ -7,11 +7,11 @@ */ // RUN: %me +use std::os::fd::AsRawFd; use nix::sys::wait::waitpid; use nix::sys::wait::WaitStatus; use nix::unistd::alarm; -use nix::unistd::close; use nix::unistd::dup2; use nix::unistd::fork; use nix::unistd::pipe; @@ -26,12 +26,12 @@ fn main() { match unsafe { fork().unwrap() } { ForkResult::Parent { child, .. } => { - assert!(close(fdwrite).is_ok()); + drop(fdwrite); let mut buf = [0u8; 8]; // If the file descriptor newfd was previously open, // it is silently closed before being reused. - assert!(dup2(fdread, libc::STDIN_FILENO).is_ok()); + assert!(dup2(fdread.as_raw_fd(), libc::STDIN_FILENO).is_ok()); // FIXME: The following SYS_read will timeout due to detcore // scheduler issue. Abort if we're still going in 5 seconds. @@ -45,7 +45,7 @@ fn main() { assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0))); } ForkResult::Child => { - assert!(close(fdread).is_ok()); + drop(fdread); assert_eq!(write(fdwrite, &msg), Ok(msg.len())); } } diff --git a/detcore/tests/lit/no_close_on_exec/main.rs b/detcore/tests/lit/no_close_on_exec/main.rs index d46f3e1..37ad61f 100644 --- a/detcore/tests/lit/no_close_on_exec/main.rs +++ b/detcore/tests/lit/no_close_on_exec/main.rs @@ -13,12 +13,13 @@ // FIXME(T96027871): %hermit run --strict -- %me +use std::os::fd::AsRawFd; +use std::os::fd::BorrowedFd; use std::ptr; use nix::fcntl::OFlag; use nix::sys::wait::waitpid; use nix::sys::wait::WaitStatus; -use nix::unistd::close; use nix::unistd::fork; use nix::unistd::pipe2; use nix::unistd::read; @@ -32,6 +33,7 @@ fn main() { if let Some(fdwrite) = args.next() { // This fd is valid since it didn't have O_CLOEXEC specified. let fdwrite: i32 = fdwrite.parse().unwrap(); + let fdwrite = unsafe { BorrowedFd::borrow_raw(fdwrite) }; assert_eq!(write(fdwrite, b"wassup"), Ok(6)); @@ -43,22 +45,22 @@ fn main() { let (fdread, fdwrite) = pipe2(OFlag::empty()).unwrap(); // Allocate the string before the fork to avoid deadlocks. - let fdwrite_str = format!("{}\0", fdwrite); + let fdwrite_str = format!("{}\0", fdwrite.as_raw_fd()); match unsafe { fork().unwrap() } { ForkResult::Parent { child, .. } => { - assert!(close(fdwrite).is_ok()); + drop(fdwrite); let mut msg = [0u8; 6]; - assert_eq!(read(fdread, &mut msg), Ok(6)); + assert_eq!(read(fdread.as_raw_fd(), &mut msg), Ok(6)); assert_eq!(&msg, b"wassup"); // Wait for the child to exit. assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0))); } ForkResult::Child => { - assert!(close(fdread).is_ok()); + drop(fdread); let proc_self = "/proc/self/exe\0".as_ptr() as *const libc::c_char; diff --git a/detcore/tests/lit/openat_lowest_fd/main.rs b/detcore/tests/lit/openat_lowest_fd/main.rs index 1dbd3c8..af5ba77 100644 --- a/detcore/tests/lit/openat_lowest_fd/main.rs +++ b/detcore/tests/lit/openat_lowest_fd/main.rs @@ -18,7 +18,7 @@ fn main() { let _ = nix::unistd::close(0); assert_eq!( - openat(libc::AT_FDCWD, "/dev/null", OFlag::O_RDONLY, Mode::S_IRUSR), + openat(None, "/dev/null", OFlag::O_RDONLY, Mode::S_IRUSR), Ok(0) ); } diff --git a/detcore/tests/lit/openat_next_lowest_fd/main.rs b/detcore/tests/lit/openat_next_lowest_fd/main.rs index f84a554..d4b2c1a 100644 --- a/detcore/tests/lit/openat_next_lowest_fd/main.rs +++ b/detcore/tests/lit/openat_next_lowest_fd/main.rs @@ -7,6 +7,7 @@ */ // RUN: %me +use std::os::fd::AsRawFd; use nix::fcntl::openat; use nix::fcntl::OFlag; @@ -14,12 +15,13 @@ use nix::sys::stat::Mode; fn main() { let (fd3, fd4) = nix::unistd::pipe().unwrap(); - assert_eq!(fd4, fd3 + 1); + assert_eq!(fd4.as_raw_fd(), fd3.as_raw_fd() + 1); - let _ = nix::unistd::close(fd3); + let fd3_raw = fd3.as_raw_fd(); + drop(fd3); assert_eq!( - openat(libc::AT_FDCWD, "/dev/null", OFlag::O_RDONLY, Mode::S_IRUSR), - Ok(fd3) + openat(None, "/dev/null", OFlag::O_RDONLY, Mode::S_IRUSR), + Ok(fd3_raw) ); } diff --git a/detcore/tests/lit/pipe_creates_valid_fds/main.rs b/detcore/tests/lit/pipe_creates_valid_fds/main.rs index f024d40..02bf407 100644 --- a/detcore/tests/lit/pipe_creates_valid_fds/main.rs +++ b/detcore/tests/lit/pipe_creates_valid_fds/main.rs @@ -7,15 +7,15 @@ */ // RUN: %me +use std::os::fd::AsRawFd; use nix::sys::stat::fstat; -use nix::unistd::close; use nix::unistd::pipe; fn main() { let (fd_read, fd_write) = pipe().unwrap(); - assert!(fstat(fd_read).is_ok()); - assert!(fstat(fd_write).is_ok()); - assert!(close(fd_write).is_ok()); - assert!(close(fd_read).is_ok()); + assert!(fstat(fd_read.as_raw_fd()).is_ok()); + assert!(fstat(fd_write.as_raw_fd()).is_ok()); + drop(fd_write); + drop(fd_read); } diff --git a/detcore/tests/lit/print_race/main.rs b/detcore/tests/lit/print_race/main.rs index 63b4751..44db1ed 100644 --- a/detcore/tests/lit/print_race/main.rs +++ b/detcore/tests/lit/print_race/main.rs @@ -9,16 +9,17 @@ // RUN: %me | FileCheck %s // CHECK: {{([ab]+)}} // CHECK-EMPTY: +use std::os::fd::BorrowedFd; fn main() { let child = std::thread::spawn(move || { for _ in 0..200 { - nix::unistd::write(1, b"a").unwrap(); + nix::unistd::write(unsafe { BorrowedFd::borrow_raw(1) }, b"a").unwrap(); } }); for _ in 0..200 { - nix::unistd::write(1, b"b").unwrap(); + nix::unistd::write(unsafe { BorrowedFd::borrow_raw(1) }, b"b").unwrap(); } child.join().unwrap(); - nix::unistd::write(1, b"\n").unwrap(); + nix::unistd::write(unsafe { BorrowedFd::borrow_raw(1) }, b"\n").unwrap(); } diff --git a/hermit-cli/Cargo.toml b/hermit-cli/Cargo.toml index ca71c92..b0be0ff 100644 --- a/hermit-cli/Cargo.toml +++ b/hermit-cli/Cargo.toml @@ -20,7 +20,7 @@ fbinit = { version = "0.2.0", git = "https://github.com/facebookexperimental/rus goblin = "0.5.2" lazy_static = "1.4" libc = "0.2.139" -nix = "0.26.4" +nix = { version = "0.29.0", features = ["dir", "event", "hostname", "inotify", "ioctl", "mman", "mount", "net", "poll", "ptrace", "reboot", "resource", "sched", "term", "time", "user", "zerocopy"] } num_cpus = "1.16" once_cell = "1.12" pretty_assertions = { version = "1.2", features = ["alloc"], default-features = false } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index f9db83f..b7b90ea 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -163,6 +163,6 @@ path = "standalone/stacktrace_events.rs" [dependencies] detcore = { version = "0.0.0", path = "../detcore" } libc = "0.2.139" -nix = "0.26.4" +nix = { version = "0.29.0", features = ["dir", "event", "hostname", "inotify", "ioctl", "mman", "mount", "net", "poll", "ptrace", "reboot", "resource", "sched", "term", "time", "user", "zerocopy"] } regex = "1.9.2" tempfile = "3.8" diff --git a/tests/rust/futex_timeout.rs b/tests/rust/futex_timeout.rs index ef17715..6cc79b8 100644 --- a/tests/rust/futex_timeout.rs +++ b/tests/rust/futex_timeout.rs @@ -7,7 +7,6 @@ */ //! Wait on a futex with a timeout. -use nix::errno::errno; use nix::errno::Errno; fn main() { @@ -30,10 +29,10 @@ fn main() { 0, // val3 - ignored ) }; - let err = errno(); + let err = Errno::last_raw(); eprintln!( "Main thread: futex wait timed out and returned {}, errno {:?}", res, - Errno::from_i32(err) + Errno::from_raw(err) ); } diff --git a/tests/rust/futex_wake_some.rs b/tests/rust/futex_wake_some.rs index 6a7f5ea..76034d9 100644 --- a/tests/rust/futex_wake_some.rs +++ b/tests/rust/futex_wake_some.rs @@ -12,7 +12,6 @@ use std::sync::Arc; /// Multiple threads wait on a futex, some are woken but not all. use libc::c_long; -use nix::errno::errno; use nix::errno::Errno; const TOTAL: i64 = 4; @@ -50,7 +49,7 @@ fn main() { println!( "UNLIKELY: child thread {} issued wait after wake already happened, errno {}", ix, - Errno::from_i32(errno()) + Errno::from_raw(Errno::last_raw()) ); } }); diff --git a/tests/rust/pipe_basics.rs b/tests/rust/pipe_basics.rs index ad76c7f..4b3c8f9 100644 --- a/tests/rust/pipe_basics.rs +++ b/tests/rust/pipe_basics.rs @@ -6,6 +6,7 @@ * LICENSE file in the root directory of this source tree. */ +use std::os::fd::AsRawFd; use std::str; use nix::unistd; @@ -15,18 +16,18 @@ fn main() { let handle = std::thread::spawn(move || { let mut buf: [u8; 14] = [0; 14]; for _ in 10..20 { - assert_eq!(unistd::read(fdread, &mut buf), Ok(14)); + assert_eq!(unistd::read(fdread.as_raw_fd(), &mut buf), Ok(14)); println!("Child received message: {}", str::from_utf8(&buf).unwrap()); } - assert!(unistd::close(fdread).is_ok()); + drop(fdread); }); for ix in 10..20 { println!("Parent writing to pipe.."); let msg = format!("hello world {}", ix); - assert_eq!(unistd::write(fdwrite, msg.as_bytes()), Ok(14)); + assert_eq!(unistd::write(&fdwrite, msg.as_bytes()), Ok(14)); } - assert!(unistd::close(fdwrite).is_ok()); + drop(fdwrite); println!("Joining child.."); handle.join().unwrap(); diff --git a/tests/rust/poll.rs b/tests/rust/poll.rs index bf30c80..19c874f 100644 --- a/tests/rust/poll.rs +++ b/tests/rust/poll.rs @@ -24,16 +24,17 @@ */ use std::fs; use std::io::Write; -use std::os::unix::io::AsRawFd; +use std::os::fd::AsFd; use nix::poll::poll; use nix::poll::PollFd; use nix::poll::PollFlags; +use nix::poll::PollTimeout; use tempfile::tempdir; fn main() { println!("Empty poll to sleep 300ms:"); - poll(&mut [], 300).expect("poll failed"); + poll(&mut [], 300u16).expect("poll failed"); println!("Finished empty poll."); { @@ -47,16 +48,16 @@ fn main() { file2.write_all(b"text2").unwrap(); } - for timeout in &[-1, 0, 300] { + for timeout in &[PollTimeout::NONE, PollTimeout::ZERO, 300u16.into()] { let file1 = fs::File::open(&path1).unwrap(); let file2 = fs::File::open(&path2).unwrap(); - let poll1 = PollFd::new(file1.as_raw_fd(), PollFlags::all()); - let poll2 = PollFd::new(file2.as_raw_fd(), PollFlags::empty()); + let poll1 = PollFd::new(file1.as_fd(), PollFlags::all()); + let poll2 = PollFd::new(file2.as_fd(), PollFlags::empty()); let mut slice = [poll1, poll2]; println!( - "\nPoll on two created temp files, fds {:?}, timeout={}:", - slice, timeout + "\nPoll on two created temp files, fds {:?}, timeout={:?}:", + slice, timeout, ); let events = poll(&mut slice, *timeout).expect("poll failed"); println!("Done poll."); diff --git a/tests/rust/poll_spin.rs b/tests/rust/poll_spin.rs index ef608ca..d8f3bd1 100644 --- a/tests/rust/poll_spin.rs +++ b/tests/rust/poll_spin.rs @@ -8,22 +8,23 @@ /*! - Spin poll() repeatedly until it succeeds. Intentionally nondeterministic to stress determinization. +Spin poll() repeatedly until it succeeds. Intentionally nondeterministic to stress determinization. - Run with rust-script if you like: +Run with rust-script if you like: - ```cargo - [dependencies] - nix = "0.20.0" - tempfile = "3.2.0" +```cargo +[dependencies] +nix = "0.20.0" +tempfile = "3.2.0" - [build] - target = "x86_64-unknown-linux-musl" +[build] +target = "x86_64-unknown-linux-musl" - [target.x86_64-unknown-linux-musl] - ``` +[target.x86_64-unknown-linux-musl] +``` */ +use std::os::fd::AsFd; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; use std::sync::Arc; @@ -33,6 +34,7 @@ use std::time; use nix::poll::poll; use nix::poll::PollFd; use nix::poll::PollFlags; +use nix::poll::PollTimeout; use nix::unistd; fn main() { @@ -44,9 +46,9 @@ fn main() { loop { work = u64::max(2 * work, 10 ^ 9); // let poll1 = PollFd::new(fdread.as_raw_fd(), PollFlags::POLLIN); - let poll1 = PollFd::new(fdread, PollFlags::POLLIN); + let poll1 = PollFd::new(fdread.as_fd(), PollFlags::POLLIN); let mut slice = [poll1]; - let res = poll(&mut slice, 0); // 0 timeout + let res = poll(&mut slice, PollTimeout::ZERO); // 0 timeout println!( "Poll result: {:?}, (count {})", res, @@ -62,7 +64,6 @@ fn main() { break; } } - assert!(unistd::close(fdread).is_ok()); }); while count2.load(Ordering::SeqCst) == 0 { @@ -71,8 +72,8 @@ fn main() { println!("Parent writing to pipe.."); let msg = "hello world\n"; - assert_eq!(unistd::write(fdwrite, msg.as_bytes()), Ok(12)); - assert!(unistd::close(fdwrite).is_ok()); + assert_eq!(unistd::write(&fdwrite, msg.as_bytes()), Ok(12)); + drop(fdwrite); println!("Joining child.."); handle.join().unwrap(); diff --git a/tests/rust/socketpair.rs b/tests/rust/socketpair.rs index 3a04139..42089fa 100644 --- a/tests/rust/socketpair.rs +++ b/tests/rust/socketpair.rs @@ -6,6 +6,8 @@ * LICENSE file in the root directory of this source tree. */ +use std::os::fd::AsRawFd; + use nix::sys::socket::socketpair; use nix::sys::socket::AddressFamily; use nix::sys::socket::SockFlag; @@ -28,10 +30,10 @@ fn main() { // WARNING: this assumes the Linux socket behavior, which is to NOT block a write call if there // is enough buffer space. This test therefore depends on that buffer being more than 5 bytes. - nix::unistd::write(sock1, b"Hello").unwrap(); + nix::unistd::write(&sock1, b"Hello").unwrap(); let mut buf = [0; 5]; - nix::unistd::read(sock2, &mut buf).unwrap(); + nix::unistd::read(sock2.as_raw_fd(), &mut buf).unwrap(); assert_eq!(&buf[..], b"Hello"); println!("Received message. Test complete.\n"); }