blob: 3cea14a20a76aba898601e85b3b4331a78e24c17 [file] [log] [blame]
// Copyright 2020 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 "sysconfig-fidl.h"
#include <lib/fidl/epitaph.h>
#include <fbl/string.h>
#include "device-partitioner.h"
#include "lib/async/dispatcher.h"
#include "src/storage/lib/paver/pave-logging.h"
namespace paver {
void Sysconfig::Bind(async_dispatcher_t* dispatcher, fbl::unique_fd devfs_root,
fidl::ClientEnd<fuchsia_io::Directory> svc_root,
std::shared_ptr<Context> context,
fidl::ServerEnd<fuchsia_paver::Sysconfig> server) {
zx::result device_partitioner = DevicePartitionerFactory::Create(
devfs_root.duplicate(), svc_root, GetCurrentArch(), std::move(context));
if (device_partitioner.is_error()) {
ERROR("Unable to initialize a partitioner: %s.\n", device_partitioner.status_string());
fidl_epitaph_write(server.channel().get(), ZX_ERR_BAD_STATE);
return;
}
zx::result res = device_partitioner.value()->FindPartition(PartitionSpec(Partition::kSysconfig));
if (res.is_error()) {
ERROR("Unable to find sysconfig-data partition. %s\n", res.status_string());
fidl_epitaph_write(server.channel().get(), ZX_ERR_NOT_SUPPORTED);
return;
}
std::unique_ptr sysconfig = std::make_unique<Sysconfig>(std::move(res.value()));
fidl::BindServer(dispatcher, std::move(server), std::move(sysconfig));
}
void Sysconfig::Read(ReadCompleter::Sync& completer) {
LOG("Reading sysconfig-data partition.\n");
auto status_get_partition_size = partitioner_->GetPartitionSize();
if (status_get_partition_size.is_error()) {
completer.ReplyError(status_get_partition_size.error_value());
return;
}
const uint64_t partition_size = status_get_partition_size.value();
zx::vmo vmo;
if (auto status = zx::make_result(zx::vmo::create(partition_size, 0, &vmo)); status.is_error()) {
ERROR("Error creating vmo for sysconfig partition read: %s\n", status.status_string());
completer.ReplyError(status.error_value());
return;
}
if (auto status = partitioner_->Read(vmo, static_cast<size_t>(partition_size));
status.is_error()) {
ERROR("Error writing partition data for sysconfig: %s\n", status.status_string());
completer.ReplyError(status.error_value());
return;
}
completer.ReplySuccess(fuchsia_mem::wire::Buffer{std::move(vmo), partition_size});
LOG("Completed successfully\n");
}
void Sysconfig::Write(WriteRequestView request, WriteCompleter::Sync& completer) {
LOG("Writing sysconfig-data partition.\n");
if (auto status = partitioner_->Write(request->payload.vmo, request->payload.size);
status.is_error()) {
ERROR("Error writing to sysconfig partition. %s, %lu, \n", status.status_string(),
request->payload.size);
completer.Reply(status.error_value());
}
completer.Reply(ZX_OK);
LOG("Completed successfully\n");
}
void Sysconfig::GetPartitionSize(GetPartitionSizeCompleter::Sync& completer) {
LOG("Getting sysconfig-data partition size.\n");
auto status_get_partition_size = partitioner_->GetPartitionSize();
if (status_get_partition_size.is_error()) {
ERROR("Error getting partition size\n");
completer.ReplyError(status_get_partition_size.error_value());
return;
}
const uint64_t partition_size = status_get_partition_size.value();
completer.ReplySuccess(partition_size);
LOG("Completed successfully\n");
}
void Sysconfig::Flush(FlushCompleter::Sync& completer) {
LOG("Flushing sysconfig-data partition\n")
if (auto status = partitioner_->Flush(); status.is_error()) {
ERROR("Error flushing sysconfig-data partition. %s\n", status.status_string());
completer.Reply(status.error_value());
}
completer.Reply(ZX_OK);
LOG("Completed successfully\n");
}
void Sysconfig::Wipe(WipeCompleter::Sync& completer) {
LOG("Wiping sysconfig-data partition\n")
auto get_ptn_size_status = partitioner_->GetPartitionSize();
if (get_ptn_size_status.is_error()) {
ERROR("Failed to get partition size: %s\n", get_ptn_size_status.status_string());
completer.Reply(get_ptn_size_status.error_value());
return;
}
auto ptn_size = get_ptn_size_status.value();
zx::vmo zeros;
// Assuem all bytes are 0 when intialized
if (auto status = zx::vmo::create(ptn_size, 0, &zeros); status != ZX_OK) {
ERROR("Failed to create VMO: %s\n", zx_status_get_string(status));
completer.Reply(status);
return;
}
if (auto status = partitioner_->Write(zeros, ptn_size); status.is_error()) {
ERROR("Failed to write to partition. %s\n", status.status_string());
completer.Reply(status.error_value());
return;
}
completer.Reply(ZX_OK);
LOG("Completed successfully\n");
}
} // namespace paver