123 lines
2.5 KiB
C++
123 lines
2.5 KiB
C++
// (C) 2018-2024 by Folkert van Heusden
|
|
// Released under MIT license
|
|
|
|
#include <cassert>
|
|
|
|
#include "disk_backend.h"
|
|
#include "gen.h"
|
|
#include "utils.h"
|
|
#if IS_POSIX
|
|
#include "disk_backend_file.h"
|
|
#else
|
|
#include "disk_backend_esp32.h"
|
|
#endif
|
|
#include "disk_backend_nbd.h"
|
|
|
|
|
|
disk_backend::disk_backend()
|
|
{
|
|
}
|
|
|
|
disk_backend::~disk_backend()
|
|
{
|
|
}
|
|
|
|
void disk_backend::store_object_in_overlay(const off_t id, const std::vector<uint8_t> & data)
|
|
{
|
|
overlay.insert_or_assign(id, data);
|
|
}
|
|
|
|
std::optional<std::vector<uint8_t> > disk_backend::get_object_from_overlay(const off_t id)
|
|
{
|
|
auto it = overlay.find(id);
|
|
if (it != overlay.end())
|
|
return it->second;
|
|
|
|
return { };
|
|
}
|
|
|
|
std::optional<std::vector<uint8_t> > disk_backend::get_from_overlay(const off_t offset, const size_t sector_size)
|
|
{
|
|
assert((offset % sector_size) == 0);
|
|
|
|
if (use_overlay)
|
|
return get_object_from_overlay(offset / sector_size);
|
|
|
|
return { };
|
|
}
|
|
|
|
bool disk_backend::store_mem_range_in_overlay(const off_t offset, const size_t n, const uint8_t *const from, const size_t sector_size)
|
|
{
|
|
assert((offset % sector_size) == 0);
|
|
assert((n % sector_size) == 0);
|
|
|
|
if (use_overlay) {
|
|
for(size_t o=0; o<n; o += sector_size)
|
|
store_object_in_overlay((offset + o) / sector_size, std::vector<uint8_t>(from + o, from + o + sector_size));
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
JsonDocument disk_backend::serialize_overlay() const
|
|
{
|
|
JsonDocument out;
|
|
|
|
for(auto & id: overlay) {
|
|
JsonDocument j_data;
|
|
JsonArray j_data_work = j_data.to<JsonArray>();
|
|
|
|
for(size_t i=0; i<id.second.size(); i++)
|
|
j_data_work.add(id.second.at(i));
|
|
|
|
out[format("%lu", id.first)] = j_data;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
void disk_backend::deserialize_overlay(const JsonVariantConst j)
|
|
{
|
|
if (j.containsKey("overlay") == false)
|
|
return; // we can have state-dumps without overlay
|
|
|
|
for(auto kv : j.as<JsonObjectConst>()) {
|
|
uint32_t id = std::atoi(kv.key().c_str());
|
|
|
|
std::vector<uint8_t> data;
|
|
for(auto v: kv.value().as<JsonArrayConst>())
|
|
data.push_back(v);
|
|
|
|
store_object_in_overlay(id, data);
|
|
}
|
|
}
|
|
|
|
disk_backend *disk_backend::deserialize(const JsonVariantConst j)
|
|
{
|
|
std::string type = j["disk-backend-type"];
|
|
|
|
disk_backend *d = nullptr;
|
|
|
|
if (type == "nbd")
|
|
d = disk_backend_nbd::deserialize(j);
|
|
|
|
#if IS_POSIX
|
|
else if (type == "file")
|
|
d = disk_backend_file::deserialize(j);
|
|
#else
|
|
else if (type == "esp32")
|
|
d = disk_backend_esp32::deserialize(j);
|
|
#endif
|
|
|
|
// should not be triggered
|
|
assert(d);
|
|
|
|
d->deserialize_overlay(j);
|
|
|
|
// assume we want snapshots (again?)
|
|
d->begin(true);
|
|
|
|
return d;
|
|
}
|