Skip to content
This repository has been archived by the owner on Oct 24, 2022. It is now read-only.

Inflight I/O: Implement missing traits #20

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

harshanavkis
Copy link

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]

@harshanavkis harshanavkis force-pushed the inflight-traits branch 2 times, most recently from 9b9ee56 to 347357a Compare July 21, 2021 12:03
@harshanavkis harshanavkis marked this pull request as ready for review July 21, 2021 12:25
Cargo.toml Outdated Show resolved Hide resolved
@harshanavkis harshanavkis force-pushed the inflight-traits branch 3 times, most recently from fd1e8e5 to 0e0c52e Compare July 21, 2021 15:33
@harshanavkis
Copy link
Author

@sboeuf I changed the nix calls to libc calls.

Copy link

@sboeuf sboeuf left a 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,
)
};

Copy link

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);
Copy link

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.

@harshanavkis harshanavkis force-pushed the inflight-traits branch 5 times, most recently from ab2297c to b99b485 Compare July 26, 2021 13:55
@harshanavkis
Copy link
Author

@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?

@sboeuf
Copy link

sboeuf commented Jul 26, 2021

@jiangliu

Would it be better to create a new error variant in vhost_user::Error, to handle each such case?

What do you think?

@jiangliu
Copy link
Member

jiangliu commented Sep 9, 2021

@jiangliu

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:)

@jiangliu
Copy link
Member

jiangliu commented Sep 9, 2021

@harshanavkis Could you please help to rebase this MR so we could include it into v0.2.0?

@harshanavkis
Copy link
Author

@jiangliu sure, will get this done.

@harshanavkis
Copy link
Author

I have created a pull request here: rust-vmm/vhost#84, to add the error enums for handling errors during get_inflight_fd.

Cargo.toml Outdated Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
@harshanavkis harshanavkis force-pushed the inflight-traits branch 10 times, most recently from 7d84393 to 8faef7d Compare December 22, 2021 11:54
src/handler.rs Outdated Show resolved Hide resolved
src/handler.rs Outdated Show resolved Hide resolved
src/handler.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/handler.rs Outdated Show resolved Hide resolved
src/handler.rs Outdated
return Err(VhostUserError::MemFdCreateError);
}

inflight_file = ret_val;
Copy link
Member

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.

Copy link
Member

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 {
Copy link
Member

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.

Copy link
Author

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?

Copy link
Member

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;
Copy link
Member

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);

Copy link
Author

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)?;
Copy link
Member

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()

@harshanavkis harshanavkis force-pushed the inflight-traits branch 3 times, most recently from 1654d61 to 25c1f0c Compare December 22, 2021 18:09
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]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing trait items
5 participants