blob: 56e082ac52f9507b17f6f4921a788a9981a636c0 [file] [log] [blame]
// Copyright 2021 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/iwlwifi/platform/driver-inspector.h"
#include <lib/inspect/cpp/reader.h>
#include <zircon/errors.h>
#include <algorithm>
namespace wlan::iwlwifi {
DriverInspector::DriverInspector(DriverInspectorOptions options)
: inspector_(std::make_unique<::inspect::Inspector>(
::inspect::InspectSettings{.maximum_size = options.vmo_size})),
core_dump_capacity_(options.core_dump_capacity) {
auto& inspector_root = inspector_->GetRoot();
if (inspector_root) {
root_node_ = inspector_root.CreateChild(options.root_name);
}
}
DriverInspector::~DriverInspector() = default;
zx_status_t DriverInspector::PublishCoreDump(const char* core_dump_name,
cpp20::span<const char> core_dump) {
zx_status_t status = ZX_OK;
if (core_dump.size() > core_dump_capacity_) {
return ZX_ERR_INVALID_ARGS;
}
std::lock_guard lock(core_dump_mutex_);
// Drop the oldest core dumps until enough space is available.
size_t total_size = 0;
for (auto riter = core_dumps_.rbegin(); riter != core_dumps_.rend(); ++riter) {
total_size += riter->dump_size_;
if (core_dump.size() + total_size > core_dump_capacity_) {
core_dumps_.erase(core_dumps_.begin(), riter.base());
break;
}
}
::inspect::ByteVectorProperty property = GetRoot().CreateByteVector(
core_dump_name, {reinterpret_cast<const uint8_t*>(core_dump.data()), core_dump.size()});
if (!property) {
return ZX_ERR_NO_SPACE;
}
core_dumps_.emplace_back(CoreDumpEntry{std::move(property), core_dump.size()});
return status;
}
::inspect::Node& DriverInspector::GetRoot() {
// ::inspect::Node is thread-safe.
return root_node_;
}
const ::inspect::Node& DriverInspector::GetRoot() const {
// ::inspect::Node is thread-safe.
return root_node_;
}
::zx::vmo DriverInspector::DuplicateVmo() const { return inspector_->DuplicateVmo(); }
} // namespace wlan::iwlwifi