-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdisk_backend.cpp
123 lines (91 loc) · 2.49 KB
/
disk_backend.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// (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;
}