scsidisk_resources/lib.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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//! Resources for emulated SCSI disks.
#![forbid(unsafe_code)]
use inspect::Inspect;
use mesh::MeshPayload;
use mesh::payload::Protobuf;
use mesh::rpc::FailableRpc;
use storage_string::AsciiString;
use vm_resource::Resource;
use vm_resource::ResourceId;
use vm_resource::kind::DiskHandleKind;
use vm_resource::kind::ScsiDeviceHandleKind;
/// Resource handle for an emulated SCSI disk.
#[derive(MeshPayload)]
pub struct SimpleScsiDiskHandle {
/// The backing disk handle.
pub disk: Resource<DiskHandleKind>,
/// Whether the disk is read only.
pub read_only: bool,
/// Parameters controlling how the SCSI emulation behaves.
pub parameters: DiskParameters,
}
impl ResourceId<ScsiDeviceHandleKind> for SimpleScsiDiskHandle {
const ID: &'static str = "emulated_disk";
}
/// Parameters controlling SCSI disk behavior.
///
/// These parameters are all optional. If not provided, a default will be chosen
/// based on the backing disk's capabilities.
#[derive(Debug, Default, Clone, Protobuf)]
pub struct DiskParameters {
/// The disk ID, used in T10 identification.
pub disk_id: Option<[u8; 16]>,
/// Vendor/model disk information.
pub identity: Option<DiskIdentity>,
/// The disk's serial number.
pub serial_number: Vec<u8>,
/// The SCSI medium rotation rate.
pub medium_rotation_rate: Option<u16>,
/// The physical sector size.
pub physical_sector_size: Option<u32>,
/// Whether FUA is supported.
pub fua: Option<bool>,
/// Whether a write cache is present.
pub write_cache: Option<bool>,
/// The disk size to present.
pub scsi_disk_size_in_bytes: Option<u64>,
/// Whether ODX (copy offload) is supported.
///
/// TODO: remove this, our emulator doesn't support ODX.
pub odx: Option<bool>,
/// Whether unmap is supported.
pub unmap: Option<bool>,
/// The maximum transfer length for IOs (TODO: or is it for write same?)
pub max_transfer_length: Option<usize>,
/// The minimum optimal number of sectors to unmap in a request.
pub optimal_unmap_sectors: Option<u32>,
/// Report LBA status to the guest.
///
/// Note that this will always report fully mapped LBAs, since the
/// underlying disk implementation has no mechanism to report unmapped LBAs.
pub get_lba_status: bool,
}
/// The disk identity.
#[derive(Debug, Clone, Inspect, Protobuf)]
pub struct DiskIdentity {
/// The vendor ID.
pub vendor_id: AsciiString<8>,
/// The product ID.
pub product_id: AsciiString<16>,
/// The product revision level.
pub product_revision_level: AsciiString<4>,
/// The model number.
pub model_number: Vec<u8>, // BUGBUG: this is never used.
}
impl DiskIdentity {
/// Returns the default disk identity, which reports a "Msft Virtual Disk
/// 1.0".
pub fn msft() -> Self {
Self {
vendor_id: (*b"Msft ").into(),
product_id: (*b"Virtual Disk ").into(),
product_revision_level: (*b"1.0 ").into(),
model_number: Vec::new(),
}
}
}
/// Resource handle for an emulated SCSI DVD drive.
#[derive(MeshPayload)]
pub struct SimpleScsiDvdHandle {
/// The backing media, or `None` for an empty DVD drive.
pub media: Option<Resource<DiskHandleKind>>,
/// Request channel used to update the contents of the drive.
pub requests: Option<mesh::Receiver<SimpleScsiDvdRequest>>,
}
/// An emulated DVD drive request.
#[derive(MeshPayload)]
pub enum SimpleScsiDvdRequest {
/// Change the media to the new backing disk.
ChangeMedia(FailableRpc<Option<Resource<DiskHandleKind>>, ()>),
}
impl ResourceId<ScsiDeviceHandleKind> for SimpleScsiDvdHandle {
const ID: &'static str = "emulated_dvd";
}