-
Notifications
You must be signed in to change notification settings - Fork 115
Another iteration of supporting file backed memory regions #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| pub fn new(mapping: MmapRegion, guest_base: GuestAddress) -> result::Result<Self, Error> { | ||
| if guest_base.0.checked_add(mapping.len() as u64).is_none() { | ||
| return Err(Error::InvalidGuestRegion); | ||
| } |
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.
Should we also check that the offset and len are page aligned? Or just let the mmap syscall to check them?
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 guess it's better to check it ourselves since we cannot assume that both Linux and Windows mmap syscall will check for that, right?
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 don't think we should do the checks at this point; this method expects to be passed a valid MmapRegion. For Linux mmap already checks that offset is aligned (like Sebastien pointed out a while ago), and the length of the mapping doesn't need to be page aligned. I don't know what Windows does, but if the equivalent of mmap doesn't check alignment when necessary, our code should do it when creating the Windows MmapRegion.
| let file = tempfile::tempfile().unwrap(); | ||
| let start = 1234; | ||
| let file_offset = FileOffset::new(file, start); | ||
| assert_eq!(file_offset.start(), start); |
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 adding a test case for non-page-aligned offset?
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 wanted to keep FileOffset as lightweight as possible. If a FileOffset object is invalid for some reason, this will be caught when actually trying to map the memory. I'll add an offset alignment test for MmapRegion if there isn't one already.
|
@sboeuf What's your thoughts on this? |
I'm planning to review this today :) |
sboeuf
left a comment
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.
@alexandruag From a design perspective, the PR looks perfect to me! You can definitely move forward and complete it, unless @jiangliu or @bonzini have some objections.
Thanks!
alexandruag
left a comment
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.
Hi everyone,
Just finished answering comments and rebasing the PR with the following changes:
- Added the
arc(&self)method toFileOffsetso nowfile(&self)returns an actual&File. - Renamed
fd_overlapstofds_overlap. - Added tests for
mmap::buildandmmap::fds_overlap. - Added the test changes from Sebastien's original to the last commit.
There's still the question of what to do on the Windows side. Unfortunately, I didn't have the time to pursue that as well. Will try to reach out to @tkreuzer and see how we can proceed.
| let file = tempfile::tempfile().unwrap(); | ||
| let start = 1234; | ||
| let file_offset = FileOffset::new(file, start); | ||
| assert_eq!(file_offset.start(), start); |
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 wanted to keep FileOffset as lightweight as possible. If a FileOffset object is invalid for some reason, this will be caught when actually trying to map the memory. I'll add an offset alignment test for MmapRegion if there isn't one already.
| pub fn new(mapping: MmapRegion, guest_base: GuestAddress) -> result::Result<Self, Error> { | ||
| if guest_base.0.checked_add(mapping.len() as u64).is_none() { | ||
| return Err(Error::InvalidGuestRegion); | ||
| } |
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 don't think we should do the checks at this point; this method expects to be passed a valid MmapRegion. For Linux mmap already checks that offset is aligned (like Sebastien pointed out a while ago), and the length of the mapping doesn't need to be page aligned. I don't know what Windows does, but if the equivalent of mmap doesn't check alignment when necessary, our code should do it when creating the Windows MmapRegion.
19657f7 to
de979be
Compare
sboeuf
left a comment
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.
Looks good, the only thing missing is to adapt the Windows code too. It looks like it should be pretty easy since it's mostly about renaming functions, or am I missing something?
| } | ||
|
|
||
| /// Creates a new mapping based on the provided arguments. | ||
| pub fn build( |
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 think that half of this function should be generic to unix and windows, therefore should be defined in mmap.rs. The file offset processing is the part that should be common.
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.
Make sense, I refactored this by adding the check_file_offset function to mmap.rs in the same commit.
| fd.as_raw_fd(), | ||
| offset, | ||
| ) | ||
| pub fn from_file(file_offset: FileOffset, size: usize) -> Result<Self> { |
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 modify the same way the function from_fd in mmap_windows.rs. This should be pretty straightforward.
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 pulled in the commit where you did this, thanks!
Added a struct which keeps track of the file and offset associated with a guest memory region backed by a memory mapped file. Signed-off-by: Alexandru Agache <aagch@amazon.com>
alexandruag
left a comment
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 a bit of refactoring (as mentioned in one of the responses), and cherry-picked a commit from Sebastien which makes the Windows tests succeed. We still need more Windows testing, but the CI should be happy at least.
| fd.as_raw_fd(), | ||
| offset, | ||
| ) | ||
| pub fn from_file(file_offset: FileOffset, size: usize) -> Result<Self> { |
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 pulled in the commit where you did this, thanks!
| } | ||
|
|
||
| /// Creates a new mapping based on the provided arguments. | ||
| pub fn build( |
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.
Make sense, I refactored this by adding the check_file_offset function to mmap.rs in the same commit.
de979be to
c5e6d2a
Compare
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com> Signed-off-by: Alexandru Agache <aagch@amazon.com>
Also, refactored some names and the way we resolve paths to use different `Error` and `Result` definitions. Signed-off-by: Alexandru Agache <aagch@amazon.com>
The GuestRegionMmap constructor now checks that adding the guest base address to the length of the mapped region does not overflow. Signed-off-by: Alexandru Agache <aagch@amazon.com>
The new method simplifies the creation of a GuestMemoryMmap object that contains file backed regions (potentially alongside anonymous memory regions). Also, updated the GuestMemoryRegion trait with the `file_offset` method, and implemented it for GuestRegionMmap. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com> Signed-off-by: Alexandru Agache <aagch@amazon.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
c5e6d2a to
e6e235e
Compare
| if metadata.len() < end { | ||
| return Err(MmapRegionError::MappingPastEof); | ||
| } | ||
| } |
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.
Do we need to handle the case when file.metadata() 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.
We could create a special Error case for it.
Once @alexandruag updates it, we need to re-approve the PR.
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 could merge the big PR first and submit another bugfix PR for this issue.
Review a small bugfix PR is much easier:)
|
The green button is very tempting :) |
This PR is based on code from Sebastien's original proposal (#20) and the subsequent comments and conversations.
As per Paolo's suggestion, the offset is now represented as an
u64. I didn't name the new structFileRange, because it should've also kept alengthfield, and that information is already available via thelen()method of theGuestMemoryRegion. Instead I've called itFileOffset(will rename on demand), and it only keeps theArc<File>andoffset.The Linux code is clearly ahead of the Windows one right now, and some harmonization is in order. I've just created a Windows VM on my machine, but didn't get the chance to install Rust and test things yet. It would be good to know if ppl are ok with the proposed way of implementing this functionality on Linux, and then we can bring the Windows implementation up to date as well (and add some more tests to this PR).