1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-06-08 15:56:16 +02:00

Merge pull request #2369 from anti-entropy123/main

update nix to 0.27.1 🎉
This commit is contained in:
Yashodhan 2023-10-09 20:46:13 +05:30 committed by GitHub
commit b968ac5f96
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 118 additions and 66 deletions

26
Cargo.lock generated
View File

@ -1736,7 +1736,7 @@ dependencies = [
"flate2", "flate2",
"libcgroups", "libcgroups",
"libcontainer", "libcontainer",
"nix", "nix 0.27.1",
"num_cpus", "num_cpus",
"oci-spec", "oci-spec",
"once_cell", "once_cell",
@ -1895,7 +1895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75adb4021282a72ca63ebbc0e4247750ad74ede68ff062d247691072d709ad8b" checksum = "75adb4021282a72ca63ebbc0e4247750ad74ede68ff062d247691072d709ad8b"
dependencies = [ dependencies = [
"cc", "cc",
"nix", "nix 0.26.2",
"num_cpus", "num_cpus",
"pkg-config", "pkg-config",
] ]
@ -1918,7 +1918,7 @@ dependencies = [
"libbpf-sys", "libbpf-sys",
"libc", "libc",
"mockall", "mockall",
"nix", "nix 0.27.1",
"oci-spec", "oci-spec",
"procfs", "procfs",
"quickcheck", "quickcheck",
@ -1944,7 +1944,7 @@ dependencies = [
"libc", "libc",
"libcgroups", "libcgroups",
"libseccomp", "libseccomp",
"nix", "nix 0.27.1",
"oci-spec", "oci-spec",
"once_cell", "once_cell",
"prctl", "prctl",
@ -2227,6 +2227,18 @@ dependencies = [
"static_assertions", "static_assertions",
] ]
[[package]]
name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
"bitflags 2.4.0",
"cfg-if",
"libc",
"memoffset 0.9.0",
]
[[package]] [[package]]
name = "no-std-net" name = "no-std-net"
version = "0.6.0" version = "0.6.0"
@ -2602,7 +2614,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "059a34f111a9dee2ce1ac2826a68b24601c4298cfeb1a587c3cb493d5ab46f52" checksum = "059a34f111a9dee2ce1ac2826a68b24601c4298cfeb1a587c3cb493d5ab46f52"
dependencies = [ dependencies = [
"libc", "libc",
"nix", "nix 0.26.2",
] ]
[[package]] [[package]]
@ -3105,7 +3117,7 @@ name = "runtimetest"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"nix", "nix 0.27.1",
"oci-spec", "oci-spec",
] ]
@ -5726,7 +5738,7 @@ dependencies = [
"libcgroups", "libcgroups",
"libcontainer", "libcontainer",
"liboci-cli", "liboci-cli",
"nix", "nix 0.27.1",
"once_cell", "once_cell",
"pentacle", "pentacle",
"procfs", "procfs",

View File

@ -16,21 +16,21 @@ keywords = ["youki", "container", "cgroups"]
default = ["v1", "v2", "systemd"] default = ["v1", "v2", "systemd"]
v1 = [] v1 = []
v2 = [] v2 = []
systemd = ["v2"] systemd = ["v2", "nix/socket", "nix/uio"]
cgroupsv2_devices = ["rbpf", "libbpf-sys", "errno", "libc"] cgroupsv2_devices = ["rbpf", "libbpf-sys", "errno", "libc", "nix/dir"]
[dependencies] [dependencies]
nix = "0.26.2" nix = { version = "0.27.1", features = ["signal", "user", "fs"] }
procfs = "0.15.1" procfs = "0.15.1"
oci-spec = { version = "~0.6.2", features = ["runtime"] } oci-spec = { version = "~0.6.2", features = ["runtime"] }
fixedbitset = "0.4.2" fixedbitset = "0.4.2"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
rbpf = {version = "0.2.0", optional = true } rbpf = { version = "0.2.0", optional = true }
libbpf-sys = { version = "1.2.1", optional = true } libbpf-sys = { version = "1.2.1", optional = true }
errno = { version = "0.3.5", optional = true } errno = { version = "0.3.5", optional = true }
libc = { version = "0.2.149", optional = true } libc = { version = "0.2.149", optional = true }
thiserror = "1.0.49" thiserror = "1.0.49"
tracing = { version = "0.1.37", features = ["attributes"]} tracing = { version = "0.1.37", features = ["attributes"] }
[dev-dependencies] [dev-dependencies]
anyhow = "1.0" anyhow = "1.0"

View File

@ -7,6 +7,7 @@ use super::utils::{DbusError, Result, SystemdClientError};
use nix::sys::socket; use nix::sys::socket;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{IoSlice, IoSliceMut}; use std::io::{IoSlice, IoSliceMut};
use std::os::fd::AsRawFd;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::atomic::{AtomicU32, Ordering};
@ -121,17 +122,18 @@ impl DbusConnection {
/// Open a new dbus connection to given address /// Open a new dbus connection to given address
/// authenticating as user with given uid /// authenticating as user with given uid
pub fn new(addr: &str, uid: u32, system: bool) -> Result<Self> { pub fn new(addr: &str, uid: u32, system: bool) -> Result<Self> {
let socket = socket::socket( // Use ManuallyDrop to keep the socket open.
let socket = std::mem::ManuallyDrop::new(socket::socket(
socket::AddressFamily::Unix, socket::AddressFamily::Unix,
socket::SockType::Stream, socket::SockType::Stream,
socket::SockFlag::empty(), socket::SockFlag::empty(),
None, None,
)?; )?);
let addr = socket::UnixAddr::new(addr)?; let addr = socket::UnixAddr::new(addr)?;
socket::connect(socket, &addr)?; socket::connect(socket.as_raw_fd(), &addr)?;
let mut dbus = Self { let mut dbus = Self {
socket, socket: socket.as_raw_fd(),
msg_ctr: AtomicU32::new(0), msg_ctr: AtomicU32::new(0),
id: None, id: None,
system, system,
@ -237,11 +239,11 @@ impl DbusConnection {
let mut ret = Vec::with_capacity(512); let mut ret = Vec::with_capacity(512);
loop { loop {
let mut reply: [u8; REPLY_BUF_SIZE] = [0_u8; REPLY_BUF_SIZE]; let mut reply: [u8; REPLY_BUF_SIZE] = [0_u8; REPLY_BUF_SIZE];
let reply_buffer = IoSliceMut::new(&mut reply[0..]); let mut reply_buffer = [IoSliceMut::new(&mut reply[0..])];
let reply_rcvd = socket::recvmsg::<()>( let reply_rcvd = socket::recvmsg::<()>(
self.socket, self.socket,
&mut [reply_buffer], &mut reply_buffer,
None, None,
socket::MsgFlags::empty(), socket::MsgFlags::empty(),
)?; )?;

View File

@ -22,23 +22,35 @@ cgroupsv2_devices = ["libcgroups/cgroupsv2_devices"]
[dependencies] [dependencies]
bitflags = "2.4.0" bitflags = "2.4.0"
caps = "0.5.5" caps = "0.5.5"
chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] } chrono = { version = "0.4", default-features = false, features = [
"clock",
"serde",
] }
fastrand = "^2.0.1" fastrand = "^2.0.1"
futures = { version = "0.3", features = ["thread-pool"] } futures = { version = "0.3", features = ["thread-pool"] }
libc = "0.2.149" libc = "0.2.149"
nix = "0.26.2" nix = { version = "0.27.1", features = [
"socket",
"sched",
"mount",
"mman",
"resource",
"dir",
"term",
"hostname",
] }
oci-spec = { version = "~0.6.2", features = ["runtime"] } oci-spec = { version = "~0.6.2", features = ["runtime"] }
once_cell = "1.18.0" once_cell = "1.18.0"
procfs = "0.15.1" procfs = "0.15.1"
prctl = "1.0.0" prctl = "1.0.0"
libcgroups = { version = "0.2.0", path = "../libcgroups", default-features = false } libcgroups = { version = "0.2.0", path = "../libcgroups", default-features = false }
libseccomp = { version = "0.3.0", optional=true } libseccomp = { version = "0.3.0", optional = true }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
rust-criu = "0.4.0" rust-criu = "0.4.0"
regex = "1.9.6" regex = "1.9.6"
thiserror = "1.0.49" thiserror = "1.0.49"
tracing = { version = "0.1.37", features = ["attributes"]} tracing = { version = "0.1.37", features = ["attributes"] }
safe-path = "0.1.0" safe-path = "0.1.0"
[dev-dependencies] [dev-dependencies]

View File

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use std::{ use std::{
io::{IoSlice, IoSliceMut}, io::{IoSlice, IoSliceMut},
marker::PhantomData, marker::PhantomData,
os::unix::prelude::RawFd, os::{fd::AsRawFd, unix::prelude::RawFd},
}; };
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -210,10 +210,16 @@ where
// Use socketpair as the underlying pipe. // Use socketpair as the underlying pipe.
fn unix_channel() -> Result<(RawFd, RawFd), ChannelError> { fn unix_channel() -> Result<(RawFd, RawFd), ChannelError> {
Ok(socket::socketpair( let (f1, f2) = socket::socketpair(
socket::AddressFamily::Unix, socket::AddressFamily::Unix,
socket::SockType::SeqPacket, socket::SockType::SeqPacket,
None, None,
socket::SockFlag::SOCK_CLOEXEC, socket::SockFlag::SOCK_CLOEXEC,
)?) )?;
// It is not straightforward to share the OwnedFd across forks, so we
// treat them as i32. We use ManuallyDrop to keep the connection open.
let f1 = std::mem::ManuallyDrop::new(f1);
let f2 = std::mem::ManuallyDrop::new(f2);
Ok((f1.as_raw_fd(), f2.as_raw_fd()))
} }

View File

@ -1,4 +1,4 @@
use std::{ffi::c_int, num::NonZeroUsize}; use std::{ffi::c_int, fs::File, num::NonZeroUsize};
use libc::SIGCHLD; use libc::SIGCHLD;
use nix::{ use nix::{
@ -164,12 +164,14 @@ fn clone(cb: CloneCb, flags: u64, exit_signal: Option<u64>) -> Result<Pid, Clone
// do not use MAP_GROWSDOWN since it is not well supported. // do not use MAP_GROWSDOWN since it is not well supported.
// Ref: https://man7.org/linux/man-pages/man2/mmap.2.html // Ref: https://man7.org/linux/man-pages/man2/mmap.2.html
let child_stack = unsafe { let child_stack = unsafe {
mman::mmap( // Since nix = "0.27.1", `mmap()` requires a generic type `F: AsFd`.
// `::<File>` doesn't have any meaning because we won't use it.
mman::mmap::<File>(
None, None,
NonZeroUsize::new(default_stack_size).ok_or(CloneError::ZeroStackSize)?, NonZeroUsize::new(default_stack_size).ok_or(CloneError::ZeroStackSize)?,
mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE, mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE,
mman::MapFlags::MAP_PRIVATE | mman::MapFlags::MAP_ANONYMOUS | mman::MapFlags::MAP_STACK, mman::MapFlags::MAP_PRIVATE | mman::MapFlags::MAP_ANONYMOUS | mman::MapFlags::MAP_STACK,
-1, None,
0, 0,
) )
.map_err(CloneError::StackAllocation)? .map_err(CloneError::StackAllocation)?

View File

@ -5,7 +5,7 @@ use nix::{
unistd, unistd,
}; };
use oci_spec::runtime; use oci_spec::runtime;
use std::{io::IoSlice, path::Path}; use std::{io::IoSlice, os::fd::AsRawFd, path::Path};
use super::channel; use super::channel;
@ -76,7 +76,7 @@ fn sync_seccomp_send_msg(listener_path: &Path, msg: &[u8], fd: i32) -> Result<()
); );
SeccompListenerError::UnixOther(err) SeccompListenerError::UnixOther(err)
})?; })?;
socket::connect(socket, &unix_addr).map_err(|err| { socket::connect(socket.as_raw_fd(), &unix_addr).map_err(|err| {
tracing::error!( tracing::error!(
?err, ?err,
?listener_path, ?listener_path,
@ -91,15 +91,19 @@ fn sync_seccomp_send_msg(listener_path: &Path, msg: &[u8], fd: i32) -> Result<()
let iov = [IoSlice::new(msg)]; let iov = [IoSlice::new(msg)];
let fds = [fd]; let fds = [fd];
let cmsgs = socket::ControlMessage::ScmRights(&fds); let cmsgs = socket::ControlMessage::ScmRights(&fds);
socket::sendmsg::<UnixAddr>(socket, &iov, &[cmsgs], socket::MsgFlags::empty(), None).map_err( socket::sendmsg::<UnixAddr>(
|err| { socket.as_raw_fd(),
tracing::error!(?err, "failed to write container state to seccomp listener"); &iov,
SeccompListenerError::UnixOther(err) &[cmsgs],
}, socket::MsgFlags::empty(),
)?; None,
)
.map_err(|err| {
tracing::error!(?err, "failed to write container state to seccomp listener");
SeccompListenerError::UnixOther(err)
})?;
// The spec requires the listener socket to be closed immediately after sending. // The spec requires the listener socket to be closed immediately after sending.
let _ = unistd::close(socket); drop(socket);
Ok(()) Ok(())
} }

View File

@ -13,6 +13,7 @@ use nix::{
use oci_spec::runtime::LinuxRlimit; use oci_spec::runtime::LinuxRlimit;
use std::ffi::{CStr, CString, OsStr}; use std::ffi::{CStr, CString, OsStr};
use std::fs; use std::fs;
use std::os::fd::BorrowedFd;
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
use std::os::unix::fs::symlink; use std::os::unix::fs::symlink;
use std::os::unix::io::RawFd; use std::os::unix::io::RawFd;
@ -305,7 +306,8 @@ impl Syscall for LinuxSyscall {
/// Set namespace for process /// Set namespace for process
fn set_ns(&self, rawfd: i32, nstype: CloneFlags) -> Result<()> { fn set_ns(&self, rawfd: i32, nstype: CloneFlags) -> Result<()> {
nix::sched::setns(rawfd, nstype)?; let fd = unsafe { BorrowedFd::borrow_raw(rawfd) };
nix::sched::setns(fd, nstype)?;
Ok(()) Ok(())
} }

View File

@ -81,16 +81,18 @@ pub fn setup_console_socket(
linked: linked.to_path_buf().into(), linked: linked.to_path_buf().into(),
console_socket_path: console_socket_path.to_path_buf().into(), console_socket_path: console_socket_path.to_path_buf().into(),
})?; })?;
// Using ManuallyDrop to keep the socket open.
let mut csocketfd = socket::socket( let csocketfd = std::mem::ManuallyDrop::new(
socket::AddressFamily::Unix, socket::socket(
socket::SockType::Stream, socket::AddressFamily::Unix,
socket::SockFlag::empty(), socket::SockType::Stream,
None, socket::SockFlag::empty(),
) None,
.map_err(|err| TTYError::CreateConsoleSocketFd { source: err })?; )
csocketfd = match socket::connect( .map_err(|err| TTYError::CreateConsoleSocketFd { source: err })?,
csocketfd, );
let csocketfd = match socket::connect(
csocketfd.as_raw_fd(),
&socket::UnixAddr::new(socket_name).map_err(|err| TTYError::InvalidSocketName { &socket::UnixAddr::new(socket_name).map_err(|err| TTYError::InvalidSocketName {
source: err, source: err,
socket_name: socket_name.to_string(), socket_name: socket_name.to_string(),
@ -101,7 +103,7 @@ pub fn setup_console_socket(
source: errno, source: errno,
socket_name: socket_name.to_string(), socket_name: socket_name.to_string(),
})?, })?,
Ok(()) => csocketfd, Ok(()) => csocketfd.as_raw_fd(),
}; };
Ok(csocketfd) Ok(csocketfd)
} }
@ -113,7 +115,13 @@ pub fn setup_console(console_fd: &RawFd) -> Result<()> {
.map_err(|err| TTYError::CreatePseudoTerminal { source: err })?; .map_err(|err| TTYError::CreatePseudoTerminal { source: err })?;
let pty_name: &[u8] = b"/dev/ptmx"; let pty_name: &[u8] = b"/dev/ptmx";
let iov = [IoSlice::new(pty_name)]; let iov = [IoSlice::new(pty_name)];
let fds = [openpty_result.master];
let [master, slave] = [openpty_result.master, openpty_result.slave];
// Use ManuallyDrop to keep FDs open.
let master = std::mem::ManuallyDrop::new(master);
let slave = std::mem::ManuallyDrop::new(slave);
let fds = [master.as_raw_fd()];
let cmsg = socket::ControlMessage::ScmRights(&fds); let cmsg = socket::ControlMessage::ScmRights(&fds);
socket::sendmsg::<UnixAddr>( socket::sendmsg::<UnixAddr>(
console_fd.as_raw_fd(), console_fd.as_raw_fd(),
@ -124,10 +132,10 @@ pub fn setup_console(console_fd: &RawFd) -> Result<()> {
) )
.map_err(|err| TTYError::SendPtyMaster { source: err })?; .map_err(|err| TTYError::SendPtyMaster { source: err })?;
if unsafe { libc::ioctl(openpty_result.slave, libc::TIOCSCTTY) } < 0 { if unsafe { libc::ioctl(slave.as_raw_fd(), libc::TIOCSCTTY) } < 0 {
tracing::warn!("could not TIOCSCTTY"); tracing::warn!("could not TIOCSCTTY");
}; };
let slave = openpty_result.slave; let slave = slave.as_raw_fd();
connect_stdio(&slave, &slave, &slave)?; connect_stdio(&slave, &slave, &slave)?;
close(console_fd.as_raw_fd()).map_err(|err| TTYError::CloseConsoleSocket { source: err })?; close(console_fd.as_raw_fd()).map_err(|err| TTYError::CloseConsoleSocket { source: err })?;

View File

@ -4,7 +4,6 @@ use std::collections::HashMap;
use std::fs::{self, DirBuilder, File}; use std::fs::{self, DirBuilder, File};
use std::os::linux::fs::MetadataExt; use std::os::linux::fs::MetadataExt;
use std::os::unix::fs::DirBuilderExt; use std::os::unix::fs::DirBuilderExt;
use std::os::unix::prelude::AsRawFd;
use std::path::{Component, Path, PathBuf}; use std::path::{Component, Path, PathBuf};
use nix::sys::stat::Mode; use nix::sys::stat::Mode;
@ -249,7 +248,7 @@ pub fn ensure_procfs(path: &Path) -> Result<(), EnsureProcfsError> {
tracing::error!(?err, ?path, "failed to open procfs file"); tracing::error!(?err, ?path, "failed to open procfs file");
err err
})?; })?;
let fstat_info = statfs::fstatfs(&procfs_fd.as_raw_fd()).map_err(|err| { let fstat_info = statfs::fstatfs(&procfs_fd).map_err(|err| {
tracing::error!(?err, ?path, "failed to fstatfs the procfs"); tracing::error!(?err, ?path, "failed to fstatfs the procfs");
err err
})?; })?;

View File

@ -31,7 +31,7 @@ chrono = { version = "0.4", default-features = false, features = ["clock", "serd
libcgroups = { version = "0.2.0", path = "../libcgroups", default-features = false } libcgroups = { version = "0.2.0", path = "../libcgroups", default-features = false }
libcontainer = { version = "0.2.0", path = "../libcontainer", default-features = false } libcontainer = { version = "0.2.0", path = "../libcontainer", default-features = false }
liboci-cli = { version = "0.2.0", path = "../liboci-cli" } liboci-cli = { version = "0.2.0", path = "../liboci-cli" }
nix = "0.26.2" nix = "0.27.1"
once_cell = "1.18.0" once_cell = "1.18.0"
pentacle = "1.0.0" pentacle = "1.0.0"
procfs = "0.15.1" procfs = "0.15.1"

View File

@ -9,7 +9,7 @@ chrono = { version = "0.4", default-features = false, features = ["clock"] }
flate2 = "1.0" flate2 = "1.0"
libcgroups = { path = "../../../crates/libcgroups" } libcgroups = { path = "../../../crates/libcgroups" }
libcontainer = { path = "../../../crates/libcontainer" } libcontainer = { path = "../../../crates/libcontainer" }
nix = "0.26.2" nix = "0.27.1"
num_cpus = "1.16" num_cpus = "1.16"
oci-spec = { version = "0.6.1", features = ["runtime"] } oci-spec = { version = "0.6.1", features = ["runtime"] }
once_cell = "1.18.0" once_cell = "1.18.0"

View File

@ -4,7 +4,14 @@ use nix::{
sys::socket::{self, UnixAddr}, sys::socket::{self, UnixAddr},
unistd, unistd,
}; };
use std::{io::IoSliceMut, os::unix::prelude::RawFd, path::Path}; use std::{
io::IoSliceMut,
os::{
fd::{AsFd, AsRawFd},
unix::prelude::RawFd,
},
path::Path,
};
const DEFAULT_BUFFER_SIZE: usize = 4096; const DEFAULT_BUFFER_SIZE: usize = 4096;
@ -24,14 +31,14 @@ pub fn recv_seccomp_listener(seccomp_listener: &Path) -> SeccompAgentResult {
None, None,
) )
.context("failed to create seccomp listener socket")?; .context("failed to create seccomp listener socket")?;
socket::bind(socket, &addr).context("failed to bind to seccomp listener socket")?;
socket::bind(socket.as_raw_fd(), &addr).context("failed to bind to seccomp listener socket")?;
// Force the backlog to be 1 so in the case of an error, only one connection // Force the backlog to be 1 so in the case of an error, only one connection
// from clients will be waiting. // from clients will be waiting.
socket::listen(socket, 1).context("failed to listen on seccomp listener")?; socket::listen(&socket.as_fd(), 1).context("failed to listen on seccomp listener")?;
let conn = match socket::accept(socket) { let conn = match socket::accept(socket.as_raw_fd()) {
Ok(conn) => conn, Ok(conn) => conn,
Err(e) => { Err(e) => {
let _ = unistd::close(socket);
bail!("failed to accept connection: {}", e); bail!("failed to accept connection: {}", e);
} }
}; };
@ -47,15 +54,13 @@ pub fn recv_seccomp_listener(seccomp_listener: &Path) -> SeccompAgentResult {
Ok(msg) => msg, Ok(msg) => msg,
Err(e) => { Err(e) => {
let _ = unistd::close(conn); let _ = unistd::close(conn);
let _ = unistd::close(socket);
bail!("failed to receive message: {}", e); bail!("failed to receive message: {}", e);
} }
}; };
// We received the message correctly here, so we can now safely close the socket and connection. // We received the message correctly here, so we can now safely close the socket and connection.
let _ = unistd::close(conn); let _ = unistd::close(conn);
let _ = unistd::close(socket); drop(socket);
// We are expecting 1 SCM_RIGHTS message with 1 fd. // We are expecting 1 SCM_RIGHTS message with 1 fd.
let cmsg = msg let cmsg = msg
.cmsgs() .cmsgs()

View File

@ -5,6 +5,6 @@ edition = "2021"
[dependencies] [dependencies]
oci-spec = { version = "0.6.1", features = ["runtime"] } oci-spec = { version = "0.6.1", features = ["runtime"] }
nix = "0.26.2" nix = "0.27.1"
anyhow = "1.0" anyhow = "1.0"