blob: d7ad9ba60016aade24338a31a00be5b57b329ada [file] [log] [blame]
// Copyright 2019 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.
#include <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.hardware.block.partition/cpp/wire.h>
#include <fidl/fuchsia.hardware.block.volume/cpp/wire.h>
#include <lib/driver-integration-test/fixture.h>
#include <lib/fdio/cpp/caller.h>
#include <sys/types.h>
#include <cstdint>
#include <memory>
#include <utility>
#include <fbl/string_buffer.h>
#include <zxtest/zxtest.h>
#include "src/lib/storage/fs_management/cpp/fvm.h"
#include "src/storage/fvm/format.h"
#include "src/storage/fvm/test_support.h"
namespace fvm {
namespace {
constexpr uint64_t kBlockSize = 512;
constexpr uint64_t kSliceSize = 1 << 20;
using driver_integration_test::IsolatedDevmgr;
class FvmVPartitionLoadTest : public zxtest::Test {
public:
static void SetUpTestSuite() {
IsolatedDevmgr::Args args;
args.disable_block_watcher = true;
devmgr_ = std::make_unique<IsolatedDevmgr>();
ASSERT_OK(IsolatedDevmgr::Create(&args, devmgr_.get()));
}
static void TearDownTestSuite() { devmgr_.reset(); }
protected:
static std::unique_ptr<IsolatedDevmgr> devmgr_;
};
std::unique_ptr<IsolatedDevmgr> FvmVPartitionLoadTest::devmgr_ = nullptr;
TEST_F(FvmVPartitionLoadTest, LoadPartitionWithPlaceHolderGuidIsUpdated) {
constexpr uint64_t kBlockCount = (50 * kSliceSize) / kBlockSize;
std::unique_ptr<RamdiskRef> ramdisk =
RamdiskRef::Create(devmgr_->devfs_root(), kBlockSize, kBlockCount);
ASSERT_TRUE(ramdisk);
std::unique_ptr<FvmAdapter> fvm =
FvmAdapter::Create(devmgr_->devfs_root(), kBlockSize, kBlockCount, kSliceSize, ramdisk.get());
ASSERT_TRUE(fvm);
std::unique_ptr<VPartitionAdapter> vpartition = nullptr;
ASSERT_OK(fvm->AddPartition(devmgr_->devfs_root(), "test-partition",
static_cast<fvm::Guid>(fvm::kPlaceHolderInstanceGuid.data()),
static_cast<fvm::Guid>(fvm::kPlaceHolderInstanceGuid.data()), 1,
&vpartition));
// Get the device topological path
auto topo_result =
fidl::WireCall<fuchsia_device::Controller>(vpartition->channel())->GetTopologicalPath();
ASSERT_TRUE(topo_result.ok());
ASSERT_TRUE(topo_result->is_ok());
auto partition_path = std::string(topo_result->value()->path.begin() + strlen("/dev/"),
topo_result->value()->path.end());
std::vector<uint8_t> partition_guid(kGuidSize, 0);
{
// After rebind the instance guid should not be kPlaceHolderGUID.
ASSERT_OK(fvm->Rebind({}));
fbl::unique_fd fvmfd;
device_watcher::RecursiveWaitForFile(devmgr_->devfs_root(), partition_path.c_str(), &fvmfd);
fdio_cpp::UnownedFdioCaller caller(fvmfd.get());
auto result =
fidl::WireCall<fuchsia_hardware_block_partition::Partition>(caller.channel()->borrow())
->GetInstanceGuid();
ASSERT_OK(result.status());
ASSERT_OK(result.value().status);
EXPECT_FALSE(memcmp(result.value().guid.get(), kPlaceHolderInstanceGuid.data(),
kPlaceHolderInstanceGuid.size()) == 0);
memcpy(partition_guid.data(), result.value().guid.get(), kGuidSize);
}
{
// One more time to check that the UUID persisted, so it doesn't change between 'reboot'.
ASSERT_OK(fvm->Rebind({}));
fbl::unique_fd fvmfd;
device_watcher::RecursiveWaitForFile(devmgr_->devfs_root(), partition_path.c_str(), &fvmfd);
fdio_cpp::UnownedFdioCaller caller(fvmfd.get());
auto result =
fidl::WireCall<fuchsia_hardware_block_partition::Partition>(caller.channel()->borrow())
->GetInstanceGuid();
ASSERT_OK(result.status());
ASSERT_OK(result.value().status);
EXPECT_TRUE(memcmp(result.value().guid.get(), partition_guid.data(),
kPlaceHolderInstanceGuid.size()) == 0);
}
}
} // namespace
} // namespace fvm