disk_blockdevice/
resolver.rs1use super::BlockDevice;
7use super::NewDeviceError;
8use async_trait::async_trait;
9use disk_backend::resolve::ResolveDiskParameters;
10use disk_backend::resolve::ResolvedDisk;
11use disk_backend_resources::BlockDeviceDiskHandle;
12use scsi_buffers::BounceBufferTracker;
13use std::fmt::Debug;
14use std::sync::Arc;
15use thiserror::Error;
16use uevent::UeventListener;
17use vm_resource::AsyncResolveResource;
18use vm_resource::ResourceResolver;
19use vm_resource::declare_static_async_resolver;
20use vm_resource::kind::DiskHandleKind;
21
22pub struct BlockDeviceResolver {
23 uevent_listener: Option<Arc<UeventListener>>,
24 bounce_buffer_tracker: Arc<BounceBufferTracker>,
25 always_bounce: bool,
26}
27
28impl BlockDeviceResolver {
29 pub fn new(
30 uevent_listener: Option<Arc<UeventListener>>,
31 bounce_buffer_tracker: Arc<BounceBufferTracker>,
32 always_bounce: bool,
33 ) -> Self {
34 Self {
35 uevent_listener,
36 bounce_buffer_tracker,
37 always_bounce,
38 }
39 }
40}
41
42#[derive(Debug, Error)]
43pub enum ResolveDiskError {
44 #[error("failed to create new device")]
45 NewDevice(#[source] NewDeviceError),
46 #[error("invalid disk")]
47 InvalidDisk(#[source] disk_backend::InvalidDisk),
48}
49
50#[async_trait]
51impl AsyncResolveResource<DiskHandleKind, BlockDeviceDiskHandle> for BlockDeviceResolver {
52 type Output = ResolvedDisk;
53 type Error = ResolveDiskError;
54
55 async fn resolve(
56 &self,
57 _resolver: &ResourceResolver,
58 rsrc: BlockDeviceDiskHandle,
59 input: ResolveDiskParameters<'_>,
60 ) -> Result<Self::Output, Self::Error> {
61 let disk = BlockDevice::new(
62 rsrc.file,
63 input.read_only,
64 input.driver_source.current(),
65 self.uevent_listener.as_deref(),
66 Some(self.bounce_buffer_tracker.clone()),
67 self.always_bounce,
68 )
69 .await
70 .map_err(ResolveDiskError::NewDevice)?;
71 ResolvedDisk::new(disk).map_err(ResolveDiskError::InvalidDisk)
72 }
73}
74
75pub struct StaticBlockDeviceResolver;
79
80declare_static_async_resolver!(
81 StaticBlockDeviceResolver,
82 (DiskHandleKind, BlockDeviceDiskHandle),
83);
84
85#[async_trait]
86impl AsyncResolveResource<DiskHandleKind, BlockDeviceDiskHandle> for StaticBlockDeviceResolver {
87 type Output = ResolvedDisk;
88 type Error = ResolveDiskError;
89
90 async fn resolve(
91 &self,
92 _resolver: &ResourceResolver,
93 rsrc: BlockDeviceDiskHandle,
94 input: ResolveDiskParameters<'_>,
95 ) -> Result<Self::Output, Self::Error> {
96 let disk = BlockDevice::new(
97 rsrc.file,
98 input.read_only,
99 input.driver_source.current(),
100 None,
101 None,
102 false,
103 )
104 .await
105 .map_err(ResolveDiskError::NewDevice)?;
106 ResolvedDisk::new(disk).map_err(ResolveDiskError::InvalidDisk)
107 }
108}