disk_crypt/
resolver.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Resource resolver for the encrypted disk device.
5
6use crate::CryptDisk;
7use async_trait::async_trait;
8use disk_backend::resolve::ResolveDiskParameters;
9use disk_backend::resolve::ResolvedDisk;
10use disk_crypt_resources::DiskCryptHandle;
11use thiserror::Error;
12use vm_resource::AsyncResolveResource;
13use vm_resource::ResolveError;
14use vm_resource::ResourceResolver;
15use vm_resource::declare_static_async_resolver;
16use vm_resource::kind::DiskHandleKind;
17
18declare_static_async_resolver! {
19    DiskCryptResolver,
20    (DiskHandleKind, DiskCryptHandle),
21}
22
23/// The resolver for [`DiskCryptHandle`].
24pub struct DiskCryptResolver;
25
26/// An error that occurred while resolving a [`DiskCryptHandle`].
27#[derive(Debug, Error)]
28pub enum DiskResolveError {
29    /// Failed to resolve the inner disk.
30    #[error("failed to resolve inner disk")]
31    ResolveInner(#[source] ResolveError),
32    /// Failed to create the disk.
33    #[error("failed to create disk")]
34    NewDisk(#[source] crate::NewDiskError),
35    /// The disk is invalid.
36    #[error("invalid disk")]
37    InvalidDisk(#[source] disk_backend::InvalidDisk),
38}
39
40#[async_trait]
41impl AsyncResolveResource<DiskHandleKind, DiskCryptHandle> for DiskCryptResolver {
42    type Output = ResolvedDisk;
43    type Error = DiskResolveError;
44
45    async fn resolve(
46        &self,
47        resolver: &ResourceResolver,
48        resource: DiskCryptHandle,
49        input: ResolveDiskParameters<'_>,
50    ) -> Result<Self::Output, Self::Error> {
51        let inner = resolver
52            .resolve(
53                resource.disk,
54                ResolveDiskParameters {
55                    read_only: input.read_only,
56                    _async_trait_workaround: &(),
57                },
58            )
59            .await
60            .map_err(DiskResolveError::ResolveInner)?;
61
62        let disk = CryptDisk::new(resource.cipher, &resource.key, inner.0)
63            .map_err(DiskResolveError::NewDisk)?;
64        ResolvedDisk::new(disk).map_err(DiskResolveError::InvalidDisk)
65    }
66}