openvmm_helpers/
shared_memory.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Helpers for file-backed shared guest memory.
5
6use anyhow::Context;
7use openvmm_defs::worker::SharedMemoryFd;
8
9/// Open (or create) a file to back guest RAM, and return the appropriate
10/// fd/handle for use as shared memory.
11///
12/// If the file is newly created (size 0), it is extended to `size` bytes.
13/// If it already exists with a different size, an error is returned.
14pub fn open_memory_backing_file(
15    path: &std::path::Path,
16    size: u64,
17) -> anyhow::Result<SharedMemoryFd> {
18    let file = fs_err::OpenOptions::new()
19        .read(true)
20        .write(true)
21        .create(true)
22        .truncate(false)
23        .open(path)?;
24
25    let existing_len = file.metadata()?.len();
26    if existing_len == 0 {
27        file.set_len(size)
28            .context("failed to set memory backing file size")?;
29    } else if existing_len != size {
30        anyhow::bail!(
31            "memory backing file {} has size {} bytes, expected {} bytes",
32            path.display(),
33            existing_len,
34            size,
35        );
36    }
37
38    file_to_shared_memory_fd(file.into())
39}
40
41/// Convert a `std::fs::File` to the platform-appropriate shared memory handle.
42pub fn file_to_shared_memory_fd(file: std::fs::File) -> anyhow::Result<SharedMemoryFd> {
43    #[cfg(unix)]
44    {
45        use std::os::unix::io::OwnedFd;
46        Ok(OwnedFd::from(file))
47    }
48    #[cfg(windows)]
49    {
50        // On Windows, MapViewOfFile needs a section handle, not a raw file
51        // handle. sparse_mmap has a helper that calls CreateFileMappingW.
52        Ok(sparse_mmap::new_mappable_from_file(&file, true, false)?)
53    }
54}