hvlite_helpers/disk.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//! Guest disk helpers.
use std::path::Path;
use vm_resource::Resource;
use vm_resource::kind::DiskHandleKind;
/// Opens the resources needed for using a disk from a file at `path`.
///
/// If the file ends with .vhd and is a fixed VHD1, it will be opened using
/// the user-mode VHD parser. Otherwise, if the file ends with .vhd or
/// .vhdx, the file will be opened using the kernel-mode VHD parser.
pub fn open_disk_type(path: &Path, read_only: bool) -> anyhow::Result<Resource<DiskHandleKind>> {
Ok(match path.extension().and_then(|s| s.to_str()) {
Some("vhd") => {
let file = std::fs::OpenOptions::new()
.read(true)
.write(!read_only)
.open(path)?;
match disk_vhd1::Vhd1Disk::open_fixed(file, read_only) {
Ok(vhd) => Resource::new(disk_backend_resources::FixedVhd1DiskHandle(
vhd.into_inner(),
)),
Err(disk_vhd1::OpenError::NotFixed) => {
#[cfg(windows)]
{
Resource::new(disk_vhdmp::OpenVhdmpDiskConfig(
disk_vhdmp::VhdmpDisk::open_vhd(path, read_only)?,
))
}
#[cfg(not(windows))]
anyhow::bail!("non-fixed VHD not supported on Linux");
}
Err(err) => return Err(err.into()),
}
}
Some("vhdx") => {
#[cfg(windows)]
{
Resource::new(disk_vhdmp::OpenVhdmpDiskConfig(
disk_vhdmp::VhdmpDisk::open_vhd(path, read_only)?,
))
}
#[cfg(not(windows))]
anyhow::bail!("VHDX not supported on Linux");
}
Some("iso") if !read_only => {
anyhow::bail!("iso file cannot be opened as read/write")
}
Some("vmgs") => {
// VMGS files are fixed VHD1s. Don't bother to validate the footer
// here; let the resource resolver do that later.
let file = std::fs::OpenOptions::new()
.read(true)
.write(!read_only)
.open(path)?;
Resource::new(disk_backend_resources::FixedVhd1DiskHandle(file))
}
_ => {
let file = std::fs::OpenOptions::new()
.read(true)
.write(!read_only)
.open(path)?;
Resource::new(disk_backend_resources::FileDiskHandle(file))
}
})
}