1use std::path::Path;
7use vm_resource::Resource;
8use vm_resource::kind::DiskHandleKind;
9
10pub fn open_disk_type(path: &Path, read_only: bool) -> anyhow::Result<Resource<DiskHandleKind>> {
16 Ok(match path.extension().and_then(|s| s.to_str()) {
17 Some("vhd") => {
18 let file = std::fs::OpenOptions::new()
19 .read(true)
20 .write(!read_only)
21 .open(path)?;
22
23 match disk_vhd1::Vhd1Disk::open_fixed(file, read_only) {
24 Ok(vhd) => Resource::new(disk_backend_resources::FixedVhd1DiskHandle(
25 vhd.into_inner(),
26 )),
27 Err(disk_vhd1::OpenError::NotFixed) => {
28 #[cfg(windows)]
29 {
30 Resource::new(disk_vhdmp::OpenVhdmpDiskConfig(
31 disk_vhdmp::VhdmpDisk::open_vhd(path, read_only)?,
32 ))
33 }
34 #[cfg(not(windows))]
35 anyhow::bail!("non-fixed VHD not supported on Linux");
36 }
37 Err(err) => return Err(err.into()),
38 }
39 }
40 Some("vhdx") => {
41 #[cfg(windows)]
42 {
43 Resource::new(disk_vhdmp::OpenVhdmpDiskConfig(
44 disk_vhdmp::VhdmpDisk::open_vhd(path, read_only)?,
45 ))
46 }
47 #[cfg(not(windows))]
48 anyhow::bail!("VHDX not supported on Linux");
49 }
50 Some("iso") if !read_only => {
51 anyhow::bail!("iso file cannot be opened as read/write")
52 }
53 Some("vmgs") => {
54 let file = std::fs::OpenOptions::new()
57 .read(true)
58 .write(!read_only)
59 .open(path)?;
60
61 Resource::new(disk_backend_resources::FixedVhd1DiskHandle(file))
62 }
63 _ => {
64 let file = std::fs::OpenOptions::new()
65 .read(true)
66 .write(!read_only)
67 .open(path)?;
68
69 Resource::new(disk_backend_resources::FileDiskHandle(file))
70 }
71 })
72}
73
74pub fn create_disk_type(path: &Path, size: u64) -> anyhow::Result<Resource<DiskHandleKind>> {
76 Ok(match path.extension().and_then(|s| s.to_str()) {
77 Some("vhd") | Some("vmgs") => {
78 let file = std::fs::OpenOptions::new()
79 .create(true)
80 .truncate(true)
81 .read(true)
82 .write(true)
83 .open(path)?;
84
85 file.set_len(size)?;
86 disk_vhd1::Vhd1Disk::make_fixed(&file)?;
87 Resource::new(disk_backend_resources::FixedVhd1DiskHandle(file))
88 }
89 Some("vhdx") => {
90 anyhow::bail!("creating vhdx not supported")
91 }
92 Some("iso") => {
93 anyhow::bail!("creating iso not supported")
94 }
95 _ => {
96 let file = std::fs::OpenOptions::new()
97 .create(true)
98 .truncate(true)
99 .read(true)
100 .write(true)
101 .open(path)?;
102
103 file.set_len(size)?;
104 Resource::new(disk_backend_resources::FileDiskHandle(file))
105 }
106 })
107}