blob: 60f328ad7d34e7bd9fc892089149f49c3c03d643 [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.
#ifndef LIB_INSPECT_VMO_SNAPSHOT_H_
#define LIB_INSPECT_VMO_SNAPSHOT_H_
#include <fbl/array.h>
#include <fbl/function.h>
#include <lib/inspect-vmo/block.h>
#include <lib/zx/vmo.h>
#include <unistd.h>
#include <zircon/types.h>
namespace inspect {
namespace vmo {
// |Snapshot| parses an incoming VMO buffer and produces a snapshot of
// the VMO contents. |Snapshot::Options| determines the behavior of
// snapshotting if a concurrent write potentially occurred.
//
// Example:
// fbl::unique_ptr<Snapshot> snapshot;
// zx_status_t status = Snapshot::Create(std::move(vmo),
// {.read_attempts = 1024, .skip_consistency_check = false},
// &snapshot);
//
// Test Example:
// zx_status_t status = Snapshot::Create(std::move(vmo),
// {.read_attempts = 1024, .skip_consistency_check = false},
// std::make_unique<TestCallback>(),
// &snapshot);
class Snapshot final {
public:
struct Options {
// The number of attempts to read a consistent snapshot.
// Reading fails if the number of attempts exceeds this number.
int read_attempts;
// If true, skip checking the buffer for consistency.
bool skip_consistency_check;
};
// Type for observing reads on the VMO.
using ReadObserver = fbl::Function<void(uint8_t* buffer, size_t buffer_size)>;
// By default, ensure consistency of the incoming Inspect VMO and retry up to
// 1024 times.
static constexpr Options kDefaultOptions = {.read_attempts = 1024,
.skip_consistency_check = false};
// Create a new snapshot of the given VMO and default options.
static zx_status_t Create(const zx::vmo& vmo, Snapshot* out_snapshot);
// Create a new snapshot of the given VMO and given options.
static zx_status_t Create(const zx::vmo& vmo, Options options, Snapshot* out_snapshot);
// Create a new snapshot of the given VMO, given options, and the given read observer
// for observing snapshot operations.
static zx_status_t Create(const zx::vmo& vmo, Options options, ReadObserver read_observer,
Snapshot* out_snapshot);
Snapshot() = default;
~Snapshot() = default;
Snapshot(Snapshot&&) = default;
Snapshot& operator=(Snapshot&&) = default;
operator bool() const { return buffer_.size() > 0; }
// Returns the start of the snapshot data, if valid.
const uint8_t* data() const { return buffer_.begin(); }
// Returns the size of the snapshot, if valid.
size_t size() const { return buffer_.size(); }
// Get a pointer to a block in the buffer by index.
// Returns nullptr if the index is out of bounds.
internal::Block* GetBlock(internal::BlockIndex index) const;
private:
// Read from the VMO into a buffer.
static zx_status_t Read(const zx::vmo& vmo, size_t size, uint8_t* buffer);
// Parse the header from a buffer and obtain the generation count.
static zx_status_t ParseHeader(uint8_t* buffer, uint64_t* out_generation_count);
// Take a new snapshot of the VMO with default options.
// If reading fails, the boolean value of the constructed |Snapshot| will be false.
explicit Snapshot(fbl::Array<uint8_t> buffer);
// The buffer storing the snapshot.
fbl::Array<uint8_t> buffer_;
};
} // namespace vmo
} // namespace inspect
#endif // LIB_INSPECT_VMO_SNAPSHOT_H_