fuchsia_storage_benchmarks/filesystems/
fxblob.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::filesystems::{BlobFilesystem, DeliveryBlob, FsManagementFilesystemInstance};
6use async_trait::async_trait;
7use blob_writer::BlobWriter;
8use fidl_fuchsia_fxfs::{BlobCreatorMarker, BlobCreatorProxy, BlobReaderMarker, BlobReaderProxy};
9use fidl_fuchsia_io as fio;
10use fuchsia_component::client::connect_to_protocol_at_dir_svc;
11use std::path::Path;
12use storage_benchmarks::{
13    BlockDeviceConfig, BlockDeviceFactory, CacheClearableFilesystem, Filesystem, FilesystemConfig,
14};
15
16/// Config object for starting Fxblob instances.
17#[derive(Clone)]
18pub struct Fxblob;
19
20#[async_trait]
21impl FilesystemConfig for Fxblob {
22    type Filesystem = FxblobInstance;
23
24    async fn start_filesystem(
25        &self,
26        block_device_factory: &dyn BlockDeviceFactory,
27    ) -> FxblobInstance {
28        let block_device = block_device_factory
29            .create_block_device(&BlockDeviceConfig {
30                requires_fvm: false,
31                use_zxcrypt: false,
32                volume_size: Some(104 * 1024 * 1024),
33            })
34            .await;
35        let fxblob = FsManagementFilesystemInstance::new(
36            fs_management::Fxfs::default(),
37            block_device,
38            None,
39            /*as_blob=*/ true,
40        )
41        .await;
42        let blob_creator =
43            connect_to_protocol_at_dir_svc::<BlobCreatorMarker>(fxblob.exposed_dir())
44                .expect("failed to connect to the BlobCreator service");
45        let blob_reader = connect_to_protocol_at_dir_svc::<BlobReaderMarker>(fxblob.exposed_dir())
46            .expect("failed to connect to the BlobReader service");
47        FxblobInstance { blob_creator, blob_reader, fxblob }
48    }
49
50    fn name(&self) -> String {
51        "fxblob".to_owned()
52    }
53}
54
55pub struct FxblobInstance {
56    blob_creator: BlobCreatorProxy,
57    blob_reader: BlobReaderProxy,
58    fxblob: FsManagementFilesystemInstance,
59}
60
61#[async_trait]
62impl Filesystem for FxblobInstance {
63    async fn shutdown(self) {
64        self.fxblob.shutdown().await
65    }
66
67    fn benchmark_dir(&self) -> &Path {
68        self.fxblob.benchmark_dir()
69    }
70}
71
72#[async_trait]
73impl CacheClearableFilesystem for FxblobInstance {
74    async fn clear_cache(&mut self) {
75        let () = self.fxblob.clear_cache().await;
76        self.blob_reader =
77            connect_to_protocol_at_dir_svc::<BlobReaderMarker>(self.fxblob.exposed_dir())
78                .expect("failed to connect to the BlobCreator service");
79    }
80}
81
82#[async_trait]
83impl BlobFilesystem for FxblobInstance {
84    async fn get_vmo(&self, blob: &DeliveryBlob) -> zx::Vmo {
85        self.blob_reader
86            .get_vmo(&blob.name.into())
87            .await
88            .expect("transport error on BlobReader.GetVmo")
89            .expect("failed to get vmo")
90    }
91
92    async fn write_blob(&self, blob: &DeliveryBlob) {
93        let writer_client_end = self
94            .blob_creator
95            .create(&blob.name.into(), false)
96            .await
97            .expect("transport error on BlobCreator.Create")
98            .expect("failed to create blob");
99        let writer = writer_client_end.into_proxy();
100        let mut blob_writer = BlobWriter::create(writer, blob.data.len() as u64)
101            .await
102            .expect("failed to create BlobWriter");
103        blob_writer.write(&blob.data).await.unwrap();
104    }
105
106    fn exposed_dir(&self) -> &fio::DirectoryProxy {
107        self.fxblob.exposed_dir()
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::Fxblob;
114    use crate::filesystems::testing::check_blob_filesystem;
115
116    #[fuchsia::test]
117    async fn start_fxblob_new() {
118        check_blob_filesystem(Fxblob).await;
119    }
120}