Skip to content

Commit 99f7c11

Browse files
committed
LiveUpdate now needs registered callbacks for serialization, with keys to uniquely identify future partitions
1 parent f1a9676 commit 99f7c11

4 files changed

Lines changed: 36 additions & 15 deletions

File tree

lib/LiveUpdate/liveupdate.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,20 @@ struct LiveUpdate
5050
typedef delegate<void(Storage&, const buffer_t*)> storage_func;
5151
typedef delegate<void(Restore&)> resume_func;
5252

53+
// Register a function to be called when serialization phase begins
54+
static void register_serialization_callback(std::string key, storage_func);
55+
5356
// Start a live update process, storing all user-defined data
5457
// If no storage function is provided no state will be saved
55-
static void begin(buffer_t blob, storage_func = nullptr);
58+
static void begin(buffer_t blob);
5659

5760
// In the event that LiveUpdate::begin() fails,
5861
// call this function in the C++ exception handler:
5962
static void restore_environment();
6063

6164
// Only store user data, as if there was a live update process
6265
// Throws exception if process or sanity checks fail
63-
static buffer_t store(storage_func);
66+
static buffer_t store();
6467

6568
// Returns true if there is stored data from before.
6669
// It performs an extensive validation process to make sure the data is
@@ -74,7 +77,7 @@ struct LiveUpdate
7477
// Attempt to restore existing stored entries.
7578
// Returns false if there was nothing there. or if the process failed
7679
// to be sure that only failure can return false, use is_resumable first
77-
static bool resume(resume_func default_handler);
80+
static bool resume(std::string key, resume_func default_handler);
7881

7982
// When explicitly resuming from heap, heap overrun checks are disabled
8083
static bool resume_from_heap(void* location, resume_func default_handler);

lib/LiveUpdate/resume.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static bool resume_helper(void* location, LiveUpdate::resume_func func)
5555
extern bool resume_begin(storage_header&, LiveUpdate::resume_func);
5656
return resume_begin(*(storage_header*) location, func);
5757
}
58-
bool LiveUpdate::resume(resume_func func)
58+
bool LiveUpdate::resume(std::string key, resume_func func)
5959
{
6060
void* location = OS::liveupdate_storage_area();
6161
/// memory sanity check

lib/LiveUpdate/update.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,24 @@ bool LIVEUPDATE_PERFORM_SANITY_CHECKS = true;
5555

5656
using namespace liu;
5757

58-
static size_t update_store_data(void* location, LiveUpdate::storage_func, const buffer_t*);
58+
static size_t update_store_data(void* location, const buffer_t*);
59+
60+
// serialization callbacks
61+
static std::unordered_map<std::string, LiveUpdate::storage_func> storage_callbacks;
62+
63+
void LiveUpdate::register_serialization_callback(std::string key, storage_func callback)
64+
{
65+
auto it = storage_callbacks.find(key);
66+
if (it == storage_callbacks.end())
67+
{
68+
storage_callbacks.emplace(std::piecewise_construct,
69+
std::forward_as_tuple(std::move(key)),
70+
std::forward_as_tuple(std::move(callback)));
71+
}
72+
else {
73+
throw std::runtime_error("Storage key '" + key + "' already used");
74+
}
75+
}
5976

6077
template <typename Class>
6178
inline bool validate_header(const Class* hdr)
@@ -66,8 +83,7 @@ inline bool validate_header(const Class* hdr)
6683
hdr->e_ident[3] == 'F';
6784
}
6885

69-
void LiveUpdate::begin(buffer_t blob,
70-
storage_func storage_callback)
86+
void LiveUpdate::begin(buffer_t blob)
7187
{
7288
void* location = OS::liveupdate_storage_area();
7389
LPRINT("LiveUpdate::begin(%p, %p:%d, ...)\n", location, blob.data(), (int) blob.size());
@@ -172,7 +188,7 @@ void LiveUpdate::begin(buffer_t blob,
172188
LPRINT("* _start is located at %#x\n", start_offset);
173189

174190
// save ourselves if function passed
175-
update_store_data(storage_area, storage_callback, &blob);
191+
update_store_data(storage_area, &blob);
176192

177193
// 2. flush all devices with flush() interface
178194
hw::Devices::flush_all();
@@ -225,10 +241,10 @@ void LiveUpdate::restore_environment()
225241
// enable interrupts again
226242
asm volatile("sti");
227243
}
228-
buffer_t LiveUpdate::store(storage_func func)
244+
buffer_t LiveUpdate::store()
229245
{
230246
char* location = (char*) OS::liveupdate_storage_area();
231-
size_t size = update_store_data(location, func, nullptr);
247+
size_t size = update_store_data(location, nullptr);
232248
return buffer_t(location, location + size);
233249
}
234250

@@ -251,17 +267,17 @@ size_t LiveUpdate::stored_data_length(void* location)
251267
return storage->total_bytes();
252268
}
253269

254-
size_t update_store_data(void* location, LiveUpdate::storage_func func, const buffer_t* blob)
270+
size_t update_store_data(void* location, const buffer_t* blob)
255271
{
256272
// create storage header in the fixed location
257273
new (location) storage_header();
258274
auto* storage = (storage_header*) location;
259275

260276
/// callback for storing stuff, if provided
261-
if (func != nullptr)
277+
for (const auto& pair : storage_callbacks)
262278
{
263279
Storage wrapper {*storage};
264-
func(wrapper, blob);
280+
pair.second(wrapper, blob);
265281
}
266282

267283
/// finalize

lib/uplink/ws_uplink.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ namespace uplink {
4747
{
4848
OS::add_stdout({this, &WS_uplink::send_log});
4949

50+
liu::LiveUpdate::register_serialization_callback("uplink", {this, &WS_uplink::store});
51+
5052
read_config();
5153
CHECK(config_.reboot, "Reboot on panic");
5254

@@ -72,7 +74,7 @@ namespace uplink {
7274
if(liu::LiveUpdate::is_resumable())
7375
{
7476
MYINFO("Found resumable state, try restoring...");
75-
auto success = liu::LiveUpdate::resume({this, &WS_uplink::restore});
77+
auto success = liu::LiveUpdate::resume("uplink", {this, &WS_uplink::restore});
7678
CHECK(success, "Success");
7779
}
7880

@@ -254,7 +256,7 @@ namespace uplink {
254256
ws_->close();
255257
// do the update
256258
Timers::oneshot(std::chrono::milliseconds(10), [this, buffer] (auto) {
257-
liu::LiveUpdate::begin(buffer, {this, &WS_uplink::store});
259+
liu::LiveUpdate::begin(buffer);
258260
});
259261
}
260262

0 commit comments

Comments
 (0)