blob: c2b28000e7e8c92426f259bb71ab0254493dae8e [file] [log] [blame]
// Copyright 2023 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 "src/storage/lib/paver/violet.h"
#include <lib/stdcompat/span.h>
#include <algorithm>
#include <iterator>
#include <gpt/gpt.h>
#include "src/lib/uuid/uuid.h"
#include "src/storage/lib/paver/pave-logging.h"
#include "src/storage/lib/paver/utils.h"
namespace paver {
namespace {
using uuid::Uuid;
} // namespace
zx::result<std::unique_ptr<DevicePartitioner>> VioletPartitioner::Initialize(
fbl::unique_fd devfs_root, fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root,
fidl::ClientEnd<fuchsia_device::Controller> block_device) {
auto status = IsBoard(devfs_root, "violet");
if (status.is_error()) {
return status.take_error();
}
auto status_or_gpt =
GptDevicePartitioner::InitializeGpt(std::move(devfs_root), svc_root, std::move(block_device));
if (status_or_gpt.is_error()) {
return status_or_gpt.take_error();
}
auto partitioner = WrapUnique(new VioletPartitioner(std::move(status_or_gpt->gpt)));
LOG("Successfully initialized VioletPartitioner Device Partitioner\n");
return zx::ok(std::move(partitioner));
}
bool VioletPartitioner::SupportsPartition(const PartitionSpec& spec) const {
const PartitionSpec supported_specs[] = {PartitionSpec(paver::Partition::kZirconA)};
return std::any_of(std::cbegin(supported_specs), std::cend(supported_specs),
[&](const PartitionSpec& supported) { return SpecMatches(spec, supported); });
}
zx::result<std::unique_ptr<PartitionClient>> VioletPartitioner::AddPartition(
const PartitionSpec& spec) const {
ERROR("Cannot add partitions to a violet device\n");
return zx::error(ZX_ERR_NOT_SUPPORTED);
}
zx::result<std::unique_ptr<PartitionClient>> VioletPartitioner::FindPartition(
const PartitionSpec& spec) const {
if (!SupportsPartition(spec)) {
ERROR("Unsupported partition %s\n", spec.ToString().c_str());
return zx::error(ZX_ERR_NOT_SUPPORTED);
}
std::variant<std::string_view, Uuid> part_info;
switch (spec.partition) {
case Partition::kZirconA:
part_info = "boot";
break;
default:
ERROR("Partition type is invalid\n");
return zx::error(ZX_ERR_INVALID_ARGS);
}
const auto filter_by_name = [&part_info](const gpt_partition_t& part) {
char cstring_name[GPT_NAME_LEN] = {};
utf16_to_cstring(cstring_name, part.name, GPT_NAME_LEN);
return std::get<std::string_view>(part_info) == std::string_view(cstring_name);
};
if (std::holds_alternative<Uuid>(part_info)) {
auto partition =
OpenBlockPartition(gpt_->devfs_root(), std::nullopt, std::get<Uuid>(part_info), ZX_SEC(5));
if (partition.is_error()) {
return partition.take_error();
}
return zx::ok(new BlockPartitionClient(std::move(partition.value())));
}
auto status = gpt_->FindPartition(std::move(filter_by_name));
if (status.is_error()) {
return status.take_error();
}
return zx::ok(std::move(status->partition));
}
zx::result<> VioletPartitioner::WipeFvm() const { return gpt_->WipeFvm(); }
zx::result<> VioletPartitioner::InitPartitionTables() const {
return zx::error(ZX_ERR_NOT_SUPPORTED);
}
zx::result<> VioletPartitioner::WipePartitionTables() const {
return zx::error(ZX_ERR_NOT_SUPPORTED);
}
zx::result<> VioletPartitioner::ValidatePayload(const PartitionSpec& spec,
cpp20::span<const uint8_t> data) const {
if (!SupportsPartition(spec)) {
ERROR("Unsupported partition %s\n", spec.ToString().c_str());
return zx::error(ZX_ERR_NOT_SUPPORTED);
}
return zx::ok();
}
zx::result<std::unique_ptr<DevicePartitioner>> VioletPartitionerFactory::New(
fbl::unique_fd devfs_root, fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root, Arch arch,
std::shared_ptr<Context> context, fidl::ClientEnd<fuchsia_device::Controller> block_device) {
return VioletPartitioner::Initialize(std::move(devfs_root), svc_root, std::move(block_device));
}
zx::result<std::unique_ptr<abr::Client>> VioletAbrClientFactory::New(
fbl::unique_fd devfs_root, fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root,
std::shared_ptr<paver::Context> context) {
return zx::error(ZX_ERR_NOT_SUPPORTED);
}
} // namespace paver