Skip to content
Merged
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
20 changes: 20 additions & 0 deletions include/libkrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,26 @@ int32_t krun_add_virtiofs2(uint32_t ctx_id,
const char *c_path,
uint64_t shm_size);

/**
* Adds an independent virtio-fs device pointing to a host's directory with a tag. This
* variant allows specifying the size of the DAX window and a read-only flag.
*
* Arguments:
* "ctx_id" - the configuration context ID.
* "c_tag" - tag to identify the filesystem in the guest.
* "c_path" - full path to the directory in the host to be exposed to the guest.
* "shm_size" - size of the DAX SHM window in bytes.
* "read_only" - if true, the filesystem will be exposed as read-only to the guest.
*
* Returns:
* Zero on success or a negative error number on failure.
*/
int32_t krun_add_virtiofs3(uint32_t ctx_id,
const char *c_tag,
const char *c_path,
uint64_t shm_size,
bool read_only);

/* Send the VFKIT magic after establishing the connection,
as required by gvproxy in vfkit mode. */
#define NET_FLAG_VFKIT 1 << 0
Expand Down
13 changes: 11 additions & 2 deletions src/devices/src/virtio/fs/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use virtio_bindings::{virtio_config::VIRTIO_F_VERSION_1, virtio_ring::VIRTIO_RIN
use vm_memory::{ByteValued, GuestMemoryMmap};

use super::super::{
ActivateResult, DeviceQueue, DeviceState, FsError, QueueConfig, VirtioDevice, VirtioShmRegion,
ActivateError, ActivateResult, DeviceQueue, DeviceState, FsError, QueueConfig, VirtioDevice,
VirtioShmRegion,
};
use super::passthrough;
use super::worker::FsWorker;
Expand Down Expand Up @@ -46,6 +47,7 @@ pub struct Fs {
config: VirtioFsConfig,
shm_region: Option<VirtioShmRegion>,
passthrough_cfg: passthrough::Config,
read_only: bool,
worker_thread: Option<JoinHandle<()>>,
worker_stopfd: EventFd,
exit_code: Arc<AtomicI32>,
Expand All @@ -59,6 +61,7 @@ impl Fs {
shared_dir: String,
exit_code: Arc<AtomicI32>,
allow_root_dir_delete: bool,
read_only: bool,
) -> super::Result<Fs> {
let avail_features = (1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_RING_F_EVENT_IDX);

Expand All @@ -80,6 +83,7 @@ impl Fs {
config,
shm_region: None,
passthrough_cfg: fs_cfg,
read_only,
worker_thread: None,
worker_stopfd: EventFd::new(EFD_NONBLOCK).map_err(FsError::EventFd)?,
exit_code,
Expand Down Expand Up @@ -183,11 +187,16 @@ impl VirtioDevice for Fs {
mem.clone(),
self.shm_region.clone(),
self.passthrough_cfg.clone(),
self.read_only,
self.worker_stopfd.try_clone().unwrap(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since you are already refactoring this block to return an ActivateError instead of panicking when worker creation fails, you should also handle the potential error from try_clone() on the worker_stopfd. Using unwrap() here still leaves a panic point during device activation.

Suggested change
self.worker_stopfd.try_clone().unwrap(),
self.worker_stopfd.try_clone().map_err(|e| {
error!("virtio_fs: failed to clone stop_fd: {}", e);
ActivateError::BadActivate
})?,

self.exit_code.clone(),
#[cfg(target_os = "macos")]
self.map_sender.clone(),
);
)
.map_err(|e| {
error!("virtio_fs: failed to create worker: {}", e);
ActivateError::BadActivate
})?;
self.worker_thread = Some(worker.run());

self.device_state = DeviceState::Activated(mem, interrupt);
Expand Down
13 changes: 8 additions & 5 deletions src/devices/src/virtio/fs/macos/passthrough.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2313,6 +2313,12 @@ impl FileSystem for PassthroughFs {
return Err(linux_error(io::Error::from_raw_os_error(libc::ENOSYS)));
}

let open_flags = if (flags & fuse::SetupmappingFlags::WRITE.bits()) != 0 {
libc::O_RDWR
} else {
libc::O_RDONLY
};

let prot_flags = if (flags & fuse::SetupmappingFlags::WRITE.bits()) != 0 {
libc::PROT_READ | libc::PROT_WRITE
} else {
Expand All @@ -2327,7 +2333,7 @@ impl FileSystem for PassthroughFs {

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

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

let host_addr = unsafe {
Expand All @@ -2344,10 +2350,7 @@ impl FileSystem for PassthroughFs {
return Err(linux_error(io::Error::last_os_error()));
}

let ret = unsafe { libc::close(fd) };
if ret == -1 {
return Err(linux_error(io::Error::last_os_error()));
}
drop(file);

// We've checked that map_sender is something above.
let sender = map_sender.as_ref().unwrap();
Expand Down
1 change: 1 addition & 0 deletions src/devices/src/virtio/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod filesystem;
pub mod fuse;
#[allow(dead_code)]
mod multikey;
mod read_only;
mod server;
mod worker;

Expand Down
Loading
Loading