scsidisk_resources/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resources for emulated SCSI disks.
5
6#![forbid(unsafe_code)]
7
8use inspect::Inspect;
9use mesh::MeshPayload;
10use mesh::payload::Protobuf;
11use mesh::rpc::FailableRpc;
12use storage_string::AsciiString;
13use vm_resource::Resource;
14use vm_resource::ResourceId;
15use vm_resource::kind::DiskHandleKind;
16use vm_resource::kind::ScsiDeviceHandleKind;
17
18/// Resource handle for an emulated SCSI disk.
19#[derive(MeshPayload)]
20pub struct SimpleScsiDiskHandle {
21    /// The backing disk handle.
22    pub disk: Resource<DiskHandleKind>,
23    /// Whether the disk is read only.
24    pub read_only: bool,
25    /// Parameters controlling how the SCSI emulation behaves.
26    pub parameters: DiskParameters,
27}
28
29impl ResourceId<ScsiDeviceHandleKind> for SimpleScsiDiskHandle {
30    const ID: &'static str = "emulated_disk";
31}
32
33/// Parameters controlling SCSI disk behavior.
34///
35/// These parameters are all optional. If not provided, a default will be chosen
36/// based on the backing disk's capabilities.
37#[derive(Debug, Default, Clone, Protobuf)]
38pub struct DiskParameters {
39    /// The disk ID, used in T10 identification.
40    pub disk_id: Option<[u8; 16]>,
41    /// Vendor/model disk information.
42    pub identity: Option<DiskIdentity>,
43    /// The disk's serial number.
44    pub serial_number: Vec<u8>,
45    /// The SCSI medium rotation rate.
46    pub medium_rotation_rate: Option<u16>,
47    /// The physical sector size.
48    pub physical_sector_size: Option<u32>,
49    /// Whether FUA is supported.
50    pub fua: Option<bool>,
51    /// Whether a write cache is present.
52    pub write_cache: Option<bool>,
53    /// The disk size to present.
54    pub scsi_disk_size_in_bytes: Option<u64>,
55    /// Whether ODX (copy offload) is supported.
56    ///
57    /// TODO: remove this, our emulator doesn't support ODX.
58    pub odx: Option<bool>,
59    /// Whether unmap is supported.
60    pub unmap: Option<bool>,
61    /// The maximum transfer length for IOs (TODO: or is it for write same?)
62    pub max_transfer_length: Option<usize>,
63    /// The minimum optimal number of sectors to unmap in a request.
64    pub optimal_unmap_sectors: Option<u32>,
65    /// Report LBA status to the guest.
66    ///
67    /// Note that this will always report fully mapped LBAs, since the
68    /// underlying disk implementation has no mechanism to report unmapped LBAs.
69    pub get_lba_status: bool,
70}
71
72/// The disk identity.
73#[derive(Debug, Clone, Inspect, Protobuf)]
74pub struct DiskIdentity {
75    /// The vendor ID.
76    pub vendor_id: AsciiString<8>,
77    /// The product ID.
78    pub product_id: AsciiString<16>,
79    /// The product revision level.
80    pub product_revision_level: AsciiString<4>,
81    /// The model number.
82    pub model_number: Vec<u8>, // BUGBUG: this is never used.
83}
84
85impl DiskIdentity {
86    /// Returns the default disk identity, which reports a "Msft Virtual Disk
87    /// 1.0".
88    pub fn msft() -> Self {
89        Self {
90            vendor_id: (*b"Msft    ").into(),
91            product_id: (*b"Virtual Disk    ").into(),
92            product_revision_level: (*b"1.0 ").into(),
93            model_number: Vec::new(),
94        }
95    }
96}
97
98/// Resource handle for an emulated SCSI DVD drive.
99#[derive(MeshPayload)]
100pub struct SimpleScsiDvdHandle {
101    /// The backing media, or `None` for an empty DVD drive.
102    pub media: Option<Resource<DiskHandleKind>>,
103    /// Request channel used to update the contents of the drive.
104    pub requests: Option<mesh::Receiver<SimpleScsiDvdRequest>>,
105}
106
107/// An emulated DVD drive request.
108#[derive(MeshPayload)]
109pub enum SimpleScsiDvdRequest {
110    /// Change the media to the new backing disk.
111    ChangeMedia(FailableRpc<Option<Resource<DiskHandleKind>>, ()>),
112}
113
114impl ResourceId<ScsiDeviceHandleKind> for SimpleScsiDvdHandle {
115    const ID: &'static str = "emulated_dvd";
116}