Skip to main content

fuchsia_storage_benchmarks/
testing.rs

1// Copyright 2024 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 async_trait::async_trait;
6use fidl::endpoints::DiscoverableProtocolMarker as _;
7use fidl_fuchsia_io as fio;
8use fidl_fuchsia_storage_block::BlockMarker;
9use fs_management::Fvm;
10use fs_management::filesystem::{
11    BlockConnector, DirBasedBlockConnector, ServingMultiVolumeFilesystem,
12};
13use fuchsia_async as fasync;
14use fuchsia_component::client::connect_to_protocol_at_dir_root;
15use ramdevice_client::RamdiskClient;
16use storage_benchmarks::block_device::BlockDevice;
17use storage_benchmarks::{BlockDeviceConfig, BlockDeviceFactory};
18use storage_isolated_driver_manager::create_random_guid;
19
20use crate::block_devices::create_fvm_volume;
21
22pub const RAMDISK_FVM_SLICE_SIZE: u64 = 1024 * 1024;
23
24/// Creates block devices on ramdisks.
25pub struct RamdiskFactory {
26    block_size: u64,
27    block_count: u64,
28}
29
30impl RamdiskFactory {
31    #[allow(dead_code)]
32    pub fn new(block_size: u64, block_count: u64) -> Self {
33        Self { block_size, block_count }
34    }
35}
36
37#[async_trait]
38impl BlockDeviceFactory for RamdiskFactory {
39    async fn create_block_device(&self, config: &BlockDeviceConfig) -> Box<dyn BlockDevice> {
40        Box::new(Ramdisk::new(self.block_size, self.block_count, config).await)
41    }
42}
43
44/// A ramdisk backed block device.
45pub struct Ramdisk {
46    _ramdisk: RamdiskClient,
47    _fvm: ServingMultiVolumeFilesystem,
48    volume_dir: fio::DirectoryProxy,
49    _crypt_task: Option<fasync::Task<()>>,
50}
51
52impl Ramdisk {
53    async fn new(block_size: u64, block_count: u64, config: &BlockDeviceConfig) -> Self {
54        let ramdisk = RamdiskClient::builder(block_size, block_count)
55            .build()
56            .await
57            .expect("Failed to create RamdiskClient");
58
59        let mut fs = fs_management::filesystem::Filesystem::from_boxed_config(
60            ramdisk.connector().unwrap(),
61            Box::new(Fvm { slice_size: RAMDISK_FVM_SLICE_SIZE, ..Fvm::default() }),
62        );
63        fs.format().await.expect("Failed to format FVM");
64        let fvm = fs.serve_multi_volume().await.expect("Failed to serve FVM");
65        let volumes = connect_to_protocol_at_dir_root::<fidl_fuchsia_fs_startup::VolumesMarker>(
66            fvm.exposed_dir(),
67        )
68        .unwrap();
69        let (volume_dir, crypt_task) =
70            create_fvm_volume(&volumes, create_random_guid(), config).await;
71
72        Self { _ramdisk: ramdisk, _fvm: fvm, volume_dir, _crypt_task: crypt_task }
73    }
74}
75
76impl BlockDevice for Ramdisk {
77    fn connector(&self) -> Box<dyn BlockConnector> {
78        let volume_dir = fuchsia_fs::directory::clone(&self.volume_dir).unwrap();
79        Box::new(DirBasedBlockConnector::new(
80            volume_dir,
81            format!("svc/{}", BlockMarker::PROTOCOL_NAME),
82        ))
83    }
84}