QEMU-Nyx-fork/nyx/snapshot/block/nyx_block_snapshot.c
Sergej Schumilo 8a88edc2a1 auto-apply clang-format
- including vl.c & kvm-all.c
2022-10-16 23:51:13 +02:00

167 lines
4.4 KiB
C

#include "qemu/osdep.h"
#include "block/qapi.h"
#include "migration/vmstate.h"
#include "qemu/main-loop.h"
#include "sysemu/block-backend.h"
#include "sysemu/runstate.h"
#include "sysemu/sysemu.h"
#include "nyx/debug.h"
#include "nyx/snapshot/block/nyx_block_snapshot.h"
#include "nyx/state/state.h"
typedef struct fast_reload_cow_entry_s {
uint32_t id;
char idstr[256];
} fast_reload_cow_entry_t;
nyx_block_t *nyx_block_snapshot_init_from_file(const char *folder, bool pre_snapshot)
{
nyx_block_t *self = malloc(sizeof(nyx_block_t));
memset(self, 0, sizeof(nyx_block_t));
BlockBackend *blk;
fast_reload_cow_entry_t entry;
char *tmp1;
char *tmp2;
assert(asprintf(&tmp1, "%s/fs_cache.meta", folder) != -1);
assert(asprintf(&tmp2, "%s/fs_drv", folder) != -1);
self->cow_cache_array_size = 0;
FILE *f = fopen(tmp1, "r");
assert(f != NULL);
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
if (blk && blk->cow_cache) {
nyx_debug("%p %s\n", blk->cow_cache, blk->cow_cache->filename);
self->cow_cache_array_size++;
}
}
uint32_t temp_cow_cache_array_size;
assert(fread(&temp_cow_cache_array_size, sizeof(uint32_t), 1, f) == 1);
nyx_debug("%d vs %x\n", temp_cow_cache_array_size, self->cow_cache_array_size);
assert(self->cow_cache_array_size == temp_cow_cache_array_size);
self->cow_cache_array =
(cow_cache_t **)malloc(sizeof(cow_cache_t *) * self->cow_cache_array_size);
uint32_t i = 0;
uint32_t id = 0;
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
if (blk && blk->cow_cache) {
self->cow_cache_array[i++] = blk->cow_cache;
assert(fread(&entry, sizeof(fast_reload_cow_entry_t), 1, f) == 1);
assert(!strcmp(entry.idstr, blk->cow_cache->filename));
assert(entry.id == id);
}
id++;
}
fclose(f);
for (i = 0; i < self->cow_cache_array_size; i++) {
read_primary_buffer(self->cow_cache_array[i], tmp2, !pre_snapshot);
}
free(tmp1);
free(tmp2);
return self;
}
nyx_block_t *nyx_block_snapshot_init(void)
{
nyx_block_t *self = malloc(sizeof(nyx_block_t));
memset(self, 0, sizeof(nyx_block_t));
BlockBackend *blk;
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
if (blk && blk->cow_cache) {
nyx_debug("%p %s\n", blk->cow_cache, blk->cow_cache->filename);
self->cow_cache_array_size++;
}
}
self->cow_cache_array =
(cow_cache_t **)malloc(sizeof(cow_cache_t *) * self->cow_cache_array_size);
uint32_t i = 0;
for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
if (blk && blk->cow_cache) {
self->cow_cache_array[i++] = blk->cow_cache;
}
}
for (i = 0; i < self->cow_cache_array_size; i++) {
switch_to_fuzz_mode(self->cow_cache_array[i]);
}
return self;
}
void nyx_block_snapshot_flush(nyx_block_t *self)
{
GET_GLOBAL_STATE()->cow_cache_full = false;
}
void nyx_block_snapshot_switch_incremental(nyx_block_t *self)
{
for (uint32_t i = 0; i < self->cow_cache_array_size; i++) {
cow_cache_enable_tmp_mode(self->cow_cache_array[i]);
}
nyx_block_snapshot_flush(self);
}
void nyx_block_snapshot_disable_incremental(nyx_block_t *self)
{
for (uint32_t i = 0; i < self->cow_cache_array_size; i++) {
cow_cache_disable_tmp_mode(self->cow_cache_array[i]);
}
}
void nyx_block_snapshot_reset(nyx_block_t *self)
{
for (uint32_t i = 0; i < self->cow_cache_array_size; i++) {
cow_cache_reset(self->cow_cache_array[i]);
}
}
void nyx_block_snapshot_serialize(nyx_block_t *self, const char *snapshot_folder)
{
fast_reload_cow_entry_t entry;
char *tmp1;
char *tmp2;
assert(asprintf(&tmp1, "%s/fs_cache.meta", snapshot_folder) != -1);
assert(asprintf(&tmp2, "%s/fs_drv", snapshot_folder) != -1);
FILE *f = fopen(tmp1, "w");
fwrite(&(self->cow_cache_array_size), sizeof(uint32_t), 1, f);
for (uint32_t i = 0; i < self->cow_cache_array_size; i++) {
entry.id = i;
strncpy((char *)&entry.idstr,
(const char *)self->cow_cache_array[i]->filename, 255);
fwrite(&entry, sizeof(fast_reload_cow_entry_t), 1, f);
dump_primary_buffer(self->cow_cache_array[i], tmp2);
}
fclose(f);
free(tmp1);
free(tmp2);
}