Skip to main content

vm_ch/
storage.rs

1use crate::error::{Result, VzError};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum DiskImageCachingMode {
5    Automatic,
6    Cached,
7    Uncached,
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum DiskImageSynchronizationMode {
12    Full,
13    Fsync,
14    None,
15}
16
17// ---------------------------------------------------------------------------
18// Attachment types – store config consumed later by the VM builder
19// ---------------------------------------------------------------------------
20
21pub trait StorageAttachment {
22    fn disk_path(&self) -> Option<&str>;
23    fn nbd_uri(&self) -> Option<&str>;
24    fn is_read_only(&self) -> bool;
25}
26
27pub struct DiskImageAttachment {
28    pub(crate) path: String,
29    pub(crate) read_only: bool,
30}
31
32impl DiskImageAttachment {
33    pub fn new(path: &str, read_only: bool) -> Result<Self> {
34        Ok(DiskImageAttachment {
35            path: path.to_string(),
36            read_only,
37        })
38    }
39
40    pub fn new_with_options(
41        path: &str,
42        read_only: bool,
43        _caching_mode: DiskImageCachingMode,
44        _sync_mode: DiskImageSynchronizationMode,
45    ) -> Result<Self> {
46        Self::new(path, read_only)
47    }
48}
49
50impl StorageAttachment for DiskImageAttachment {
51    fn disk_path(&self) -> Option<&str> {
52        Some(&self.path)
53    }
54    fn nbd_uri(&self) -> Option<&str> {
55        None
56    }
57    fn is_read_only(&self) -> bool {
58        self.read_only
59    }
60}
61
62pub struct NbdAttachment {
63    pub(crate) uri: String,
64    pub(crate) read_only: bool,
65}
66
67impl NbdAttachment {
68    pub fn new(uri: &str, _timeout_secs: f64, _read_only: bool) -> Result<Self> {
69        // TODO: implement userspace NBD client for Linux.
70        // For now fall back to HANZO_VM_STORAGE=direct.
71        Err(VzError::new(format!(
72            "NBD storage ({}) not yet supported on Linux. Set HANZO_VM_STORAGE=direct",
73            uri
74        )))
75    }
76}
77
78impl StorageAttachment for NbdAttachment {
79    fn disk_path(&self) -> Option<&str> {
80        None
81    }
82    fn nbd_uri(&self) -> Option<&str> {
83        Some(&self.uri)
84    }
85    fn is_read_only(&self) -> bool {
86        self.read_only
87    }
88}
89
90// ---------------------------------------------------------------------------
91// Block device config
92// ---------------------------------------------------------------------------
93
94pub trait StorageDevice {
95    fn get_disk_path(&self) -> Option<&str>;
96    fn get_read_only(&self) -> bool;
97}
98
99pub struct VirtioBlockDevice {
100    pub(crate) path: Option<String>,
101    pub(crate) read_only: bool,
102}
103
104impl VirtioBlockDevice {
105    pub fn new(attachment: &dyn StorageAttachment) -> Self {
106        VirtioBlockDevice {
107            path: attachment.disk_path().map(|s| s.to_string()),
108            read_only: attachment.is_read_only(),
109        }
110    }
111}
112
113impl StorageDevice for VirtioBlockDevice {
114    fn get_disk_path(&self) -> Option<&str> {
115        self.path.as_deref()
116    }
117    fn get_read_only(&self) -> bool {
118        self.read_only
119    }
120}