#ifndef _BHYVE_SNAPSHOT_
#define _BHYVE_SNAPSHOT_
#include <machine/vmm_snapshot.h>
#include <libxo/xo.h>
#include <ucl.h>
#define BHYVE_RUN_DIR "/var/run/bhyve/"
#define MAX_SNAPSHOT_FILENAME PATH_MAX
struct vmctx;
struct restore_state {
int kdata_fd;
int vmmem_fd;
void *kdata_map;
size_t kdata_len;
size_t vmmem_len;
struct ucl_parser *meta_parser;
ucl_object_t *meta_root_obj;
};
struct checkpoint_thread_info {
struct vmctx *ctx;
int socket_fd;
};
typedef int (*vm_snapshot_dev_cb)(struct vm_snapshot_meta *);
typedef int (*vm_pause_dev_cb) (const char *);
typedef int (*vm_resume_dev_cb) (const char *);
struct vm_snapshot_dev_info {
const char *dev_name;
vm_snapshot_dev_cb snapshot_cb;
vm_pause_dev_cb pause_cb;
vm_resume_dev_cb resume_cb;
};
struct vm_snapshot_kern_info {
const char *struct_name;
enum snapshot_req req;
};
void destroy_restore_state(struct restore_state *rstate);
const char *lookup_vmname(struct restore_state *rstate);
int lookup_memflags(struct restore_state *rstate);
size_t lookup_memsize(struct restore_state *rstate);
int lookup_guest_ncpus(struct restore_state *rstate);
void checkpoint_cpu_add(int vcpu);
void checkpoint_cpu_resume(int vcpu);
void checkpoint_cpu_suspend(int vcpu);
int restore_vm_mem(struct vmctx *ctx, struct restore_state *rstate);
int vm_restore_kern_structs(struct vmctx *ctx, struct restore_state *rstate);
int vm_restore_devices(struct restore_state *rstate);
int vm_pause_devices(void);
int vm_resume_devices(void);
int get_checkpoint_msg(int conn_fd, struct vmctx *ctx);
void *checkpoint_thread(void *param);
int init_checkpoint_thread(struct vmctx *ctx);
int load_restore_file(const char *filename, struct restore_state *rstate);
int vm_snapshot_guest2host_addr(struct vmctx *ctx, void **addrp, size_t len,
bool restore_null, struct vm_snapshot_meta *meta);
#define SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(CTX, ADDR, LEN, RNULL, META, RES, LABEL) \
do { \
(RES) = vm_snapshot_guest2host_addr((CTX), (void **)&(ADDR), (LEN), \
(RNULL), (META)); \
if ((RES) != 0) { \
if ((RES) == EFAULT) \
EPRINTLN("%s: invalid address: %s", __func__, #ADDR); \
goto LABEL; \
} \
} while (0)
#endif