-
Notifications
You must be signed in to change notification settings - Fork 16
Inflight I/O: Implement missing traits #20
base: main
Are you sure you want to change the base?
Conversation
9b9ee56
to
347357a
Compare
fd1e8e5
to
0e0c52e
Compare
@sboeuf I changed the nix calls to libc calls. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to think about a way to share the inflight file with the consumer of the vhost_user_backend
crate so that it can fill the inflight region.
I think the point is to handle as much as we can from this crate (which means receiving the fd and creating the mapping), and let the consumers deal with the content of what they wanna write into this region.
src/lib.rs
Outdated
libc::MFD_CLOEXEC, | ||
) | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you use vu_get_inflight_fd()
from https://github.com/qemu/qemu/blob/master/subprojects/libvhost-user/libvhost-user.c#L1654 as a reference?
From what I see, you forgot to call into fcntl(*fd, F_ADD_SEALS, flags)
in order to add F_SEAL_GROW
, F_SEAL_SHRINK
and F_SEAL_SEAL
to setup the proper seals, and you didn't mmap()
the fd into the vhost-user
process address space.
src/lib.rs
Outdated
_inflight: &VhostUserInflight, | ||
file: File, | ||
) -> VhostUserResult<()> { | ||
self.inflight_file = Some(file); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, please use https://github.com/qemu/qemu/blob/master/subprojects/libvhost-user/libvhost-user.c#L1706 as a reference, and make sure to update the file after you called into mmap()
.
The previous inflight_file
will be closed automatically by Rust since you're replacing it with the new file you just received, so we're good there. But you must also unmap
what has been previously mapped through get_inflight_fd()
. That's why you need to store something like inflight_mapping_addr: Option<GuestAddress>
to be able to know if a previous mapping happened.
ab2297c
to
b99b485
Compare
@sboeuf I have reimplemented the get and set functionalities. The current error handling in functions like "memfd_alloc" compares return values and converts it into the corresponding pointer. Would it be better to create a new error variant in vhost_user::Error, to handle each such case? |
What do you think? |
Great, we should do that:) |
@harshanavkis Could you please help to rebase this MR so we could include it into v0.2.0? |
@jiangliu sure, will get this done. |
b99b485
to
b33b3bd
Compare
6a3e7ce
to
2ccceca
Compare
I have created a pull request here: rust-vmm/vhost#84, to add the error enums for handling errors during get_inflight_fd. |
2ccceca
to
6393439
Compare
7d84393
to
8faef7d
Compare
473e7e6
to
9509c15
Compare
src/handler.rs
Outdated
return Err(VhostUserError::MemFdCreateError); | ||
} | ||
|
||
inflight_file = ret_val; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inflight_file is a RawFd, so it need to be manually closed on error handling path. Otherwise it will get leaked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inflight_file is actually a RawFd, and it's error prone to deal with RawFd.
So it would be better to convert the infight_file from RawFd into a File object, which eases the error handling cases.
src/handler.rs
Outdated
// map the inflight_file into memory. | ||
// unsafe as extern mmap is called | ||
Ok(( | ||
unsafe { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to handle the case that mmap fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, makes sense. Perhaps we should add a new error enum into vhost_user::Error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be solved/refined by refactor the code. The suggestion is to avoid RawFd if possible, because it doesn't solve the file descriptor ownership. The way to avoid RawFd is to convert it into File as soon as possible. And it's safe and easy to get RawFd from File object by file.as_raw_fd().
src/handler.rs
Outdated
} | ||
|
||
fn set_desc_num_split(&mut self, inflight_region: u64, num_queues: u16, queue_size: u16) { | ||
let raw_ptr = inflight_region as *mut QueueRegionSplit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this for code readability:
let mut regions = unsafe { slice::from_raw_parts_mut(inflight_region as *mut QueueRegionSplit, num_queues as usize) };
regions.iter_mut().map(|v| v.desc_num = queue_size);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rust complains about unsused Map because of lazy iterators so I changed it slightly, let me know what you think.
src/handler.rs
Outdated
self.get_inflight_queue_size(inflight.queue_size) * inflight.num_queues as usize; | ||
|
||
// Create a memfd region to hold the queues for inflight I/O tracking | ||
let (mmap_ptr, inflight_fd, dup_inflight_fd) = self.memfd_alloc(total_mmap_size)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems it will get simpler if moves following "sef.inflight_state.set_inflight_state()" into memfd_alloc()
1654d61
to
25c1f0c
Compare
This commit implements the get and set inflight fd members of the VhostUserSlaveReqHandlerMut trait, which is used to pass inflight I/O queue tracking regions as memfds. Fixes rust-vmm#14. Signed-off-by: Harshavardhan Unnibhavi <[email protected]>
Signed-off-by: Harshavardhan Unnibhavi <[email protected]>
25c1f0c
to
89e3492
Compare
This commit implements the get and set inflight fd members of the
VhostUserSlaveReqHandlerMut trait, which is used to pass inflight
I/O queue tracking regions as memfds.
Fixes #14.
Signed-off-by: Harshavardhan Unnibhavi [email protected]