Gracefully handle ENOTSUP for memfd_create (#6230)

* Gracefully handle ENOTSUP for `memfd_create`

Looks like in #6229 older kernels may not support memfd in which case we
can fall back to manual memory initialization gracefully.

Closes #6229

* Fix tests
This commit is contained in:
Alex Crichton
2023-04-18 11:50:48 -05:00
committed by GitHub
parent 387db16d28
commit 299131ae2d

View File

@@ -157,7 +157,10 @@ impl MemoryImage {
use std::io::Write; use std::io::Write;
let memfd = create_memfd()?; let memfd = match create_memfd()? {
Some(memfd) => memfd,
None => return Ok(None),
};
memfd.as_file().write_all(data)?; memfd.as_file().write_all(data)?;
// Seal the memfd's data and length. // Seal the memfd's data and length.
@@ -237,14 +240,23 @@ impl MemoryImage {
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn create_memfd() -> Result<memfd::Memfd> { fn create_memfd() -> Result<Option<memfd::Memfd>> {
use std::io::ErrorKind;
// Create the memfd. It needs a name, but the // Create the memfd. It needs a name, but the
// documentation for `memfd_create()` says that names can // documentation for `memfd_create()` says that names can
// be duplicated with no issues. // be duplicated with no issues.
memfd::MemfdOptions::new() match memfd::MemfdOptions::new()
.allow_sealing(true) .allow_sealing(true)
.create("wasm-memory-image") .create("wasm-memory-image")
.map_err(|e| e.into()) {
Ok(memfd) => Ok(Some(memfd)),
// If this kernel is old enough to not support memfd then attempt to
// gracefully handle that and fall back to skipping the memfd
// optimization.
Err(memfd::Error::Create(err)) if err.kind() == ErrorKind::Unsupported => Ok(None),
Err(e) => Err(e.into()),
}
} }
impl ModuleMemoryImages { impl ModuleMemoryImages {
@@ -830,12 +842,16 @@ impl Drop for MemoryImageSlot {
mod test { mod test {
use std::sync::Arc; use std::sync::Arc;
use super::{create_memfd, FdSource, MemoryImage, MemoryImageSlot, MemoryPlan, MemoryStyle}; use super::{FdSource, MemoryImage, MemoryImageSlot, MemoryPlan, MemoryStyle};
use crate::mmap::Mmap; use crate::mmap::Mmap;
use anyhow::Result; use anyhow::Result;
use std::io::Write; use std::io::Write;
use wasmtime_environ::Memory; use wasmtime_environ::Memory;
fn create_memfd() -> Result<memfd::Memfd> {
Ok(super::create_memfd()?.expect("kernel doesn't support memfd"))
}
fn create_memfd_with_data(offset: usize, data: &[u8]) -> Result<MemoryImage> { fn create_memfd_with_data(offset: usize, data: &[u8]) -> Result<MemoryImage> {
// Offset must be page-aligned. // Offset must be page-aligned.
let page_size = crate::page_size(); let page_size = crate::page_size();