blob: a5d4d13b0bf6c36b6b984645cb6ca42962301a9c [file] [log] [blame]
// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_STORAGE_FVM_FVM_TEST_INSTANCE_H_
#define SRC_STORAGE_FVM_FVM_TEST_INSTANCE_H_
#include <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.hardware.block.volume/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/driver_test_realm/realm_builder/cpp/lib.h>
#include <lib/zx/result.h>
#include <memory>
#include <fbl/unique_fd.h>
#include <ramdevice-client/ramdisk.h>
#include "src/storage/lib/fs_management/cpp/fvm.h"
namespace fvm {
enum class FvmImplementation : uint8_t { kDriver, kComponent };
constexpr char kFvmDriverLib[] = "fvm.cm";
constexpr uuid::Uuid kTestUniqueGuid1 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
constexpr uuid::Uuid kTestUniqueGuid2 = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
constexpr std::string_view kTestPartDataName = "data";
constexpr uuid::Uuid kTestPartDataGuid = {
0xAA, 0xFF, 0xBB, 0x00, 0x33, 0x44, 0x88, 0x99, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
};
constexpr std::string_view kTestPartBlobName = "blob";
constexpr uuid::Uuid kTestPartBlobGuid = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xAA, 0xFF, 0xBB, 0x00, 0x33, 0x44, 0x88, 0x99,
};
constexpr std::string_view kTestPartSystemName = "system";
constexpr uuid::Uuid kTestPartSystemGuid = {
0xEE, 0xFF, 0xBB, 0x00, 0x33, 0x44, 0x88, 0x99, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
};
class BlockConnector {
public:
virtual ~BlockConnector() = default;
virtual fidl::ClientEnd<fuchsia_hardware_block::Block> connect_block() const = 0;
virtual fidl::UnownedClientEnd<fuchsia_hardware_block::Block> as_block() const = 0;
virtual fidl::UnownedClientEnd<fuchsia_hardware_block_volume::Volume> as_volume() const = 0;
};
struct AllocatePartitionRequest {
size_t slice_count = 1;
const uuid::Uuid& type;
const uuid::Uuid& guid;
const std::string_view& name;
uint32_t flags = 0;
};
class FvmInstance {
public:
virtual void SetUp() = 0;
virtual void TearDown() = 0;
virtual ~FvmInstance() = default;
// Creates a ramdisk, destroying and recreating it if it already exists.
virtual void CreateRamdisk(uint64_t block_size, uint64_t block_count) = 0;
// Creates a ramdisk and formats it with fvm.
virtual void CreateFvm(uint64_t block_size, uint64_t block_count, uint64_t slice_size) = 0;
virtual void StartFvm() = 0;
// Rebinds or restarts the FVM instance.
virtual void RestartFvm() = 0;
// Create a new ramdisk with a new total size. The block size must be the same as the existing
// block size. This will start the disk and the fvm after recreating the disk.
virtual void RestartFvmWithNewDiskSize(uint64_t block_size, uint64_t block_count) = 0;
// Get general info about fvm.
virtual fuchsia_hardware_block_volume::wire::VolumeManagerInfo GetFvmInfo() const = 0;
// Allocates a new partition.
virtual zx::result<std::unique_ptr<BlockConnector>> AllocatePartition(
const AllocatePartitionRequest& request) const = 0;
// Opens an existing partition. This will wait for it to appear if it doesn't already exist.
virtual zx::result<std::unique_ptr<BlockConnector>> OpenPartition(
std::string_view label) const = 0;
// Destroys the named partition, removing it from this fvm instance.
virtual void DestroyPartition(std::string_view label) const = 0;
// Returns the block interface of the underlying ramdisk.
virtual fidl::UnownedClientEnd<fuchsia_hardware_block::Block> GetRamdiskPartition() const = 0;
};
class DriverFvmInstance : public FvmInstance {
public:
void SetUp() override;
void TearDown() override;
void CreateRamdisk(uint64_t block_size, uint64_t block_count) override;
void CreateFvm(uint64_t block_size, uint64_t block_count, uint64_t slice_size) override;
void StartFvm() override;
void RestartFvm() override;
void RestartFvmWithNewDiskSize(uint64_t block_size, uint64_t block_count) override;
fuchsia_hardware_block_volume::wire::VolumeManagerInfo GetFvmInfo() const override;
zx::result<std::unique_ptr<BlockConnector>> AllocatePartition(
const AllocatePartitionRequest& request) const override;
zx::result<std::unique_ptr<BlockConnector>> OpenPartition(std::string_view label) const override;
void DestroyPartition(std::string_view label) const override;
fidl::UnownedClientEnd<fuchsia_hardware_block::Block> GetRamdiskPartition() const override;
fidl::UnownedClientEnd<fuchsia_device::Controller> GetRamdiskControllerInterface() const;
const fbl::unique_fd& devfs_root() const { return devfs_root_; }
zx::result<fidl::ClientEnd<fuchsia_hardware_block_volume::VolumeManager>> GetVolumeManager()
const;
zx::result<std::unique_ptr<BlockConnector>> OpenPartitionNoWait(std::string_view label) const;
std::string GetFvmPath() const;
private:
std::unique_ptr<async::Loop> loop_;
std::unique_ptr<component_testing::RealmRoot> realm_;
fbl::unique_fd devfs_root_;
ramdisk_client_t* ramdisk_ = nullptr;
zx::vmo vmo_;
};
std::unique_ptr<FvmInstance> CreateFvmInstance(FvmImplementation impl);
} // namespace fvm
#endif // SRC_STORAGE_FVM_FVM_TEST_INSTANCE_H_