Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/LiveUpdate/liveupdate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct LiveUpdate
// Register a function to be called when serialization phase begins
// Internally it will be stored as its own partition and can be restored using
// the same @key value during the resume process
static void register_serialization_callback(std::string key, storage_func);
static void register_partition(std::string key, storage_func);

// Start a live update process, storing all user-defined data
// If no storage functions are registered no state will be saved
Expand All @@ -76,7 +76,9 @@ struct LiveUpdate
static bool is_resumable(void* location);

// Restore existing state for a partition named @key.
static void resume(std::string key, resume_func handler);
// Returns false if there was no such partition
// Can throw lots of standard exceptions
static bool resume(std::string key, resume_func handler);

// When explicitly resuming from heap, heap overrun checks are disabled
static void resume_from_heap(void* location, std::string key, resume_func);
Expand Down
2 changes: 1 addition & 1 deletion lib/LiveUpdate/partition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ int storage_header::find_partition(const char* key)
throw std::runtime_error("Invalid CRC in partition '" + std::string(key) + "'");
}
}
throw std::out_of_range("Could not find partition named " + std::string(key));
return -1;
}
void storage_header::finish_partition(int p)
{
Expand Down
16 changes: 9 additions & 7 deletions lib/LiveUpdate/resume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extern char* heap_end;

namespace liu
{
static void resume_begin(storage_header&, std::string, LiveUpdate::resume_func);
static bool resume_begin(storage_header&, std::string, LiveUpdate::resume_func);

bool LiveUpdate::is_resumable()
{
Expand All @@ -45,17 +45,17 @@ bool LiveUpdate::is_resumable(void* location)
return ((storage_header*) location)->validate();
}

static void resume_helper(void* location, std::string key, LiveUpdate::resume_func func)
static bool resume_helper(void* location, std::string key, LiveUpdate::resume_func func)
{
// check if an update has occurred
if (!LiveUpdate::is_resumable(location))
throw std::runtime_error("Trying to resume from invalid storage area");
return false;

LPRINT("* Restoring data...\n");
// restore connections etc.
resume_begin(*(storage_header*) location, key.c_str(), func);
return resume_begin(*(storage_header*) location, key.c_str(), func);
}
void LiveUpdate::resume(std::string key, resume_func func)
bool LiveUpdate::resume(std::string key, resume_func func)
{
void* location = OS::liveupdate_storage_area();
/// memory sanity check
Expand All @@ -65,19 +65,20 @@ void LiveUpdate::resume(std::string key, resume_func func)
(long int) (heap_end - (char*) location));
throw std::runtime_error("LiveUpdate storage area inside heap");
}
resume_helper(location, std::move(key), func);
return resume_helper(location, std::move(key), func);
}
void LiveUpdate::resume_from_heap(void* location, std::string key, LiveUpdate::resume_func func)
{
resume_helper(location, std::move(key), func);
}

void resume_begin(storage_header& storage, std::string key, LiveUpdate::resume_func func)
bool resume_begin(storage_header& storage, std::string key, LiveUpdate::resume_func func)
{
if (key.empty())
throw std::length_error("LiveUpdate partition key cannot be an empty string");

int p = storage.find_partition(key.c_str());
if (p == -1) return false;
LPRINT("* Resuming from partition %d at %p from %p\n",
p, storage.begin(p), &storage);

Expand All @@ -92,6 +93,7 @@ void resume_begin(storage_header& storage, std::string key, LiveUpdate::resume_f
storage.zero_partition(p);
// if there are no more partitions, clear everything
storage.try_zero();
return true;
}

/// struct Restore
Expand Down
9 changes: 4 additions & 5 deletions lib/LiveUpdate/update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@

static const int SECT_SIZE = 512;
static const int ELF_MINIMUM = 164;

extern "C"
void solo5_exec(const char*, size_t);
// hotswapping functions
extern "C" void solo5_exec(const char*, size_t);
static void* HOTSWAP_AREA = (void*) 0x8000;
extern "C" void hotswap(const char*, int, char*, uintptr_t, void*);
extern "C" char __hotswap_length;
Expand All @@ -61,7 +60,7 @@ static size_t update_store_data(void* location, const buffer_t*);
// serialization callbacks
static std::unordered_map<std::string, LiveUpdate::storage_func> storage_callbacks;

void LiveUpdate::register_serialization_callback(std::string key, storage_func callback)
void LiveUpdate::register_partition(std::string key, storage_func callback)
{
auto it = storage_callbacks.find(key);
if (it == storage_callbacks.end())
Expand All @@ -86,7 +85,7 @@ inline bool validate_header(const Class* hdr)

void LiveUpdate::exec(const buffer_t& blob, std::string key, storage_func func)
{
if (func != nullptr) register_serialization_callback(key, func);
if (func != nullptr) LiveUpdate::register_partition(key, func);
LiveUpdate::exec(blob);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/uplink/ws_uplink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace uplink {
{
OS::add_stdout({this, &WS_uplink::send_log});

liu::LiveUpdate::register_serialization_callback("uplink", {this, &WS_uplink::store});
liu::LiveUpdate::register_partition("uplink", {this, &WS_uplink::store});

read_config();
CHECK(config_.reboot, "Reboot on panic");
Expand Down
2 changes: 2 additions & 0 deletions test/kernel/integration/LiveUpdate/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ void Service::start()
{
auto& inet = net::Super_stack::get<net::IP4>(0);
setup_liveupdate_server(inet, 666, func);
// signal test.py that the server is up
printf("Ready to receive binary blob\n");
}
}
2 changes: 1 addition & 1 deletion test/kernel/integration/LiveUpdate/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import socket

includeos_src = os.environ.get('INCLUDEOS_SRC',
os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))).split('/test')[0])
os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))).split('/test')[0])
sys.path.insert(0,includeos_src)

from vmrunner import vmrunner
Expand Down
11 changes: 3 additions & 8 deletions test/kernel/integration/LiveUpdate/test_boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,15 @@ static void boot_resume_all(Restore& thing)

LiveUpdate::storage_func begin_test_boot()
{
try {
LiveUpdate::resume("test", boot_resume_all);
// if we are here,
// resume() must have succeeded
if (LiveUpdate::resume("test", boot_resume_all))
{
if (timestamps.size() >= 30)
{
// calculate median by sorting
std::sort(timestamps.begin(), timestamps.end());
auto median = timestamps[timestamps.size()/2];
// show information
printf("Median boot time over %lu samples: %llu micros\n",
printf("Median boot time over %lu samples: %ld micros\n",
timestamps.size(), median);
/*
for (auto& stamp : timestamps) {
Expand All @@ -53,9 +51,6 @@ LiveUpdate::storage_func begin_test_boot()
LiveUpdate::exec(bloberino, "test", boot_save);
}
}
catch (std::exception& e) {
printf("Ready to receive binary blob\n");
}
// wait for update
return boot_save;
}