11// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
33
4- use std::fs::File;
5- use std::os::unix::fs::MetadataExt;
6-
74use vm_memory::{GuestAddress, GuestMemory, ReadVolatile, VolatileMemoryError};
85
96use crate::arch::initrd_load_addr;
10- use crate::utils::u64_to_usize;
11- use crate::vmm_config::boot_source::BootConfig;
127use crate::vstate::memory::GuestMemoryMmap;
138
149/// Errors associated with initrd loading.
@@ -20,8 +15,6 @@ pub enum InitrdError {
2015 Load,
2116 /// Cannot image metadata: {0}
2217 Metadata(std::io::Error),
23- /// Cannot copy initrd file fd: {0}
24- CloneFd(std::io::Error),
2518 /// Cannot load initrd due to an invalid image: {0}
2619 Read(VolatileMemoryError),
2720}
@@ -36,31 +29,20 @@ pub struct InitrdConfig {
3629}
3730
3831impl InitrdConfig {
39- /// Load initrd into guest memory based on the boot config.
40- pub fn from_config(
41- boot_cfg: &BootConfig,
42- vm_memory: &GuestMemoryMmap,
43- ) -> Result<Option<Self>, InitrdError> {
44- Ok(match &boot_cfg.initrd_file {
45- Some(f) => {
46- let f = f.try_clone().map_err(InitrdError::CloneFd)?;
47- Some(Self::from_file(vm_memory, f)?)
48- }
49- None => None,
50- })
51- }
52-
5332 /// Loads the initrd from a file into guest memory.
54- pub fn from_file(vm_memory: &GuestMemoryMmap, mut file: File) -> Result<Self, InitrdError> {
55- let size = file.metadata().map_err(InitrdError::Metadata)?.size();
56- let size = u64_to_usize(size);
33+ pub fn from_reader<R: ReadVolatile>(
34+ vm_memory: &GuestMemoryMmap,
35+ mut reader: R,
36+ size: usize,
37+ ) -> Result<Self, InitrdError> {
5738 let Some(address) = initrd_load_addr(vm_memory, size) else {
5839 return Err(InitrdError::Address);
5940 };
6041 let mut slice = vm_memory
6142 .get_slice(GuestAddress(address), size)
6243 .map_err(|_| InitrdError::Load)?;
63- file.read_exact_volatile(&mut slice)
44+ reader
45+ .read_exact_volatile(&mut slice)
6446 .map_err(InitrdError::Read)?;
6547
6648 Ok(InitrdConfig {
@@ -105,7 +87,7 @@ mod tests {
10587
10688 // Need to reset the cursor to read initrd properly.
10789 tempfile.seek(SeekFrom::Start(0)).unwrap();
108- let initrd = InitrdConfig::from_file (&gm, tempfile).unwrap();
90+ let initrd = InitrdConfig::from_reader (&gm, tempfile, image.len() ).unwrap();
10991 assert!(gm.address_in_range(initrd.address));
11092 assert_eq!(initrd.size, image.len());
11193 }
@@ -120,7 +102,7 @@ mod tests {
120102
121103 // Need to reset the cursor to read initrd properly.
122104 tempfile.seek(SeekFrom::Start(0)).unwrap();
123- let res = InitrdConfig::from_file (&gm, tempfile);
105+ let res = InitrdConfig::from_reader (&gm, tempfile, image.len() );
124106 assert!(matches!(res, Err(InitrdError::Address)), "{:?}", res);
125107 }
126108
@@ -134,7 +116,7 @@ mod tests {
134116
135117 // Need to reset the cursor to read initrd properly.
136118 tempfile.seek(SeekFrom::Start(0)).unwrap();
137- let res = InitrdConfig::from_file (&gm, tempfile);
119+ let res = InitrdConfig::from_reader (&gm, tempfile, image.len() );
138120 assert!(matches!(res, Err(InitrdError::Address)), "{:?}", res);
139121 }
140122}
0 commit comments