Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
416 changes: 398 additions & 18 deletions Cargo.lock

Large diffs are not rendered by default.

28 changes: 25 additions & 3 deletions src/devices/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,40 @@ virgl_resource_map2 = []
bitflags = "1.2.0"
crossbeam-channel = ">=0.5.15"
env_logger = "0.9.0"
libc = ">=0.2.39"
libc = ">=0.2.173"
libloading = "0.8"
log = "0.4.0"
nix = { version = "0.24.1", features = ["poll"] }
nix = { version = "0.24.1", features = ["poll", "event"] }
pw = { package = "pipewire", version = "0.8.0", optional = true }
rand = "0.8.5"
thiserror = { version = "1.0", optional = true }
virtio-bindings = "0.2.0"
vm-memory = { version = ">=0.13", features = ["backend-mmap"] }
zerocopy = { version = "0.6.3", optional = true }
zerocopy-derive = { version = "0.6.3", optional = true }
bytes = "1"
mio = { version = "1.0.4", features = ["net", "os-ext", "os-poll"] }
socket2 = { version = "0.5.10", features = ["all"] }
pnet = "0.35.0"
tracing = { version = "0.1.41" } # , features = ["release_max_level_debug"]
rustix = { version = "1", features = ["fs"] }
smoltcp = { version = "0.12", features = [
"std",
"log",
"medium-ip",
"proto-ipv4",
"proto-ipv6",
"socket-udp",
"socket-tcp",
] }

arch = { path = "../arch" }
utils = { path = "../utils" }
polly = { path = "../polly" }
rutabaga_gfx = { path = "../rutabaga_gfx", features = ["virgl_renderer", "virgl_renderer_next"], optional = true }
rutabaga_gfx = { path = "../rutabaga_gfx", features = [
"virgl_renderer",
"virgl_renderer_next",
], optional = true }
imago = { version = "0.1.4", features = ["sync-wrappers", "vm-memory"] }

[target.'cfg(target_os = "macos")'.dependencies]
Expand All @@ -48,3 +66,7 @@ kvm-ioctls = ">=0.21"

[target.'cfg(target_arch = "aarch64")'.dependencies]
vm-fdt = ">= 0.2.0"

[dev-dependencies]
tempfile = "3.0"
tokio = { version = "1.0", features = ["full"] }
10 changes: 5 additions & 5 deletions src/devices/src/legacy/hvfgicv3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ impl HvfGicV3 {
let mut dist_size: usize = 0;
let ret = unsafe { (bindings.hv_gic_get_distributor_size)(&mut dist_size) };
if ret != HV_SUCCESS {
return Err(Error::VmCreate);
return Err(Error::VmCreate(ret));
}
let dist_size = dist_size as u64;

let mut redist_size: usize = 0;
let ret = unsafe { (bindings.hv_gic_get_redistributor_size)(&mut redist_size) };
if ret != HV_SUCCESS {
return Err(Error::VmCreate);
return Err(Error::VmCreate(ret));
}

let redists_size = redist_size as u64 * vcpu_count;
Expand All @@ -92,7 +92,7 @@ impl HvfGicV3 {
let gic_config = unsafe { (bindings.hv_gic_config_create)() };
let ret = unsafe { (bindings.hv_gic_config_set_distributor_base)(gic_config, dist_addr) };
if ret != HV_SUCCESS {
return Err(Error::VmCreate);
return Err(Error::VmCreate(ret));
}

let ret = unsafe {
Expand All @@ -102,12 +102,12 @@ impl HvfGicV3 {
)
};
if ret != HV_SUCCESS {
return Err(Error::VmCreate);
return Err(Error::VmCreate(ret));
}

let ret = unsafe { (bindings.hv_gic_create)(gic_config) };
if ret != HV_SUCCESS {
return Err(Error::VmCreate);
return Err(Error::VmCreate(ret));
}

Ok(Self {
Expand Down
4 changes: 3 additions & 1 deletion src/devices/src/virtio/console/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ pub(crate) fn get_win_size() -> (u16, u16) {
let ret = unsafe { tiocgwinsz(0, &mut ws) };

if let Err(err) = ret {
error!("Couldn't get terminal dimensions: {}", err);
if err != nix::errno::Errno::ENODEV {
error!("Couldn't get terminal dimensions: {}", err);
}
(0, 0)
} else {
(ws.cols, ws.rows)
Expand Down
6 changes: 4 additions & 2 deletions src/devices/src/virtio/console/port_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ impl PortOutputLog {
}

fn force_flush(&mut self) {
log::log!(target: PortOutputLog::LOG_TARGET, Level::Error, "[missing newline]{}", String::from_utf8_lossy(&self.buf));
println!("[missing newline]{}", String::from_utf8_lossy(&self.buf));
// log::log!(target: PortOutputLog::LOG_TARGET, Level::Error, "[missing newline]{}", String::from_utf8_lossy(&self.buf));
self.buf.clear();
}
}
Expand All @@ -178,7 +179,8 @@ impl PortOutput for PortOutputLog {
let mut start = 0;
for (i, ch) in self.buf.iter().cloned().enumerate() {
if ch == b'\n' {
log::log!(target: PortOutputLog::LOG_TARGET, Level::Error, "{}", String::from_utf8_lossy(&self.buf[start..i]));
println!("{}", String::from_utf8_lossy(&self.buf[start..i]));
// log::log!(target: PortOutputLog::LOG_TARGET, Level::Error, "{}", String::from_utf8_lossy(&self.buf[start..i]));
start = i + 1;
}
}
Expand Down
81 changes: 7 additions & 74 deletions src/devices/src/virtio/fs/linux/passthrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ const EMPTY_CSTR: &[u8] = b"\0";
const PROC_CSTR: &[u8] = b"/proc/self/fd\0";
const INIT_CSTR: &[u8] = b"init.krun\0";

static INIT_BINARY: &[u8] = include_bytes!("../../../../../../init/init");

type Inode = u64;
type Handle = u64;

Expand Down Expand Up @@ -147,26 +145,20 @@ fn stat(f: &File) -> io::Result<libc::stat64> {
}

fn statx(f: &File) -> io::Result<(libc::stat64, u64)> {
let mut stx = MaybeUninit::<libc::statx>::zeroed();

// Safe because this is a constant value and a valid C string.
let pathname = unsafe { CStr::from_bytes_with_nul_unchecked(EMPTY_CSTR) };

// Safe because the kernel will only write data in `st` and we check the return
// value.
let res = unsafe {
libc::statx(
f.as_raw_fd(),
pathname.as_ptr(),
libc::AT_EMPTY_PATH | libc::AT_SYMLINK_NOFOLLOW,
libc::STATX_BASIC_STATS | libc::STATX_MNT_ID,
stx.as_mut_ptr(),
rustix::fs::statx(
f,
pathname,
rustix::fs::AtFlags::EMPTY_PATH | rustix::fs::AtFlags::SYMLINK_NOFOLLOW,
rustix::fs::StatxFlags::BASIC_STATS | rustix::fs::StatxFlags::MNT_ID,
)
};
if res >= 0 {
// Safe because the kernel guarantees that the struct is now fully initialized.
let stx = unsafe { stx.assume_init() };

if let Ok(stx) = res {
// Unfortunately, we cannot use an initializer to create the stat64 object,
// because it may contain padding and reserved fields (depending on the
// architecture), and it does not implement the Default trait.
Expand Down Expand Up @@ -940,25 +932,7 @@ impl FileSystem for PassthroughFs {

fn lookup(&self, _ctx: Context, parent: Inode, name: &CStr) -> io::Result<Entry> {
debug!("do_lookup: {:?}", name);
let init_name = unsafe { CStr::from_bytes_with_nul_unchecked(INIT_CSTR) };

if self.init_inode != 0 && name == init_name {
let mut st: libc::stat64 = unsafe { mem::zeroed() };
st.st_size = INIT_BINARY.len() as i64;
st.st_ino = self.init_inode;
st.st_mode = 0o100_755;

Ok(Entry {
inode: self.init_inode,
generation: 0,
attr: st,
attr_flags: 0,
attr_timeout: self.cfg.attr_timeout,
entry_timeout: self.cfg.entry_timeout,
})
} else {
self.do_lookup(parent, name)
}
self.do_lookup(parent, name)
}

fn forget(&self, _ctx: Context, inode: Inode, count: u64) {
Expand Down Expand Up @@ -1174,17 +1148,6 @@ impl FileSystem for PassthroughFs {
_flags: u32,
) -> io::Result<usize> {
debug!("read: {:?}", inode);
if inode == self.init_inode {
let off: usize = offset
.try_into()
.map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;
let len = if off + (size as usize) < INIT_BINARY.len() {
size as usize
} else {
INIT_BINARY.len() - off
};
return w.write(&INIT_BINARY[off..(off + len)]);
}

let data = self
.handles
Expand Down Expand Up @@ -2019,36 +1982,6 @@ impl FileSystem for PassthroughFs {

debug!("setupmapping: ino {:?} addr={:x} len={}", inode, addr, len);

if inode == self.init_inode {
let ret = unsafe {
libc::mmap(
addr as *mut libc::c_void,
len as usize,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_FIXED,
-1,
0,
)
};
if std::ptr::eq(ret, libc::MAP_FAILED) {
return Err(io::Error::last_os_error());
}

let to_copy = if len as usize > INIT_BINARY.len() {
INIT_BINARY.len()
} else {
len as usize
};
unsafe {
libc::memcpy(
addr as *mut libc::c_void,
INIT_BINARY.as_ptr() as *const _,
to_copy,
)
};
return Ok(());
}

let file = self.open_inode(inode, open_flags)?;
let fd = file.as_raw_fd();

Expand Down
36 changes: 0 additions & 36 deletions src/devices/src/virtio/fs/macos/passthrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ const XATTR_KEY: &[u8] = b"user.containers.override_stat\0";

const UID_MAX: u32 = u32::MAX - 1;

#[cfg(not(feature = "efi"))]
static INIT_BINARY: &[u8] = include_bytes!("../../../../../../init/init");

type Inode = u64;
type Handle = u64;

Expand Down Expand Up @@ -974,27 +971,6 @@ impl FileSystem for PassthroughFs {

fn lookup(&self, _ctx: Context, parent: Inode, name: &CStr) -> io::Result<Entry> {
debug!("lookup: {:?}", name);
let _init_name = unsafe { CStr::from_bytes_with_nul_unchecked(INIT_CSTR) };

#[cfg(not(feature = "efi"))]
if self.init_inode != 0 && name == _init_name {
let mut st: bindings::stat64 = unsafe { mem::zeroed() };
st.st_size = INIT_BINARY.len() as i64;
st.st_ino = self.init_inode;
st.st_mode = 0o100_755;

Ok(Entry {
inode: self.init_inode,
generation: 0,
attr: st,
attr_flags: 0,
attr_timeout: self.cfg.attr_timeout,
entry_timeout: self.cfg.entry_timeout,
})
} else {
self.do_lookup(parent, name)
}
#[cfg(feature = "efi")]
self.do_lookup(parent, name)
}

Expand Down Expand Up @@ -1236,18 +1212,6 @@ impl FileSystem for PassthroughFs {
_flags: u32,
) -> io::Result<usize> {
debug!("read: {:?}", inode);
#[cfg(not(feature = "efi"))]
if inode == self.init_inode {
let off: usize = offset
.try_into()
.map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;
let len = if off + (size as usize) < INIT_BINARY.len() {
size as usize
} else {
INIT_BINARY.len() - off
};
return w.write(&INIT_BINARY[off..(off + len)]);
}

let data = self
.handles
Expand Down
5 changes: 5 additions & 0 deletions src/devices/src/virtio/net/backend.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::os::fd::RawFd;

use utils::epoll::EpollEvent;

#[allow(dead_code)]
#[derive(Debug)]
pub enum ConnectError {
Expand Down Expand Up @@ -37,4 +39,7 @@ pub trait NetBackend {
fn has_unfinished_write(&self) -> bool;
fn try_finish_write(&mut self, hdr_len: usize, buf: &[u8]) -> Result<(), WriteError>;
fn raw_socket_fd(&self) -> RawFd;
fn handle_event(&self, _event: &EpollEvent) {
// noop by default
}
}
Loading