[LibOS] Refactor checkpointing code

This commit still leaves checkpointing macros as-is; this will be
fixed in a folow-up commit.
This commit is contained in:
Dmitrii Kuvaiskii
2020-06-19 00:28:03 +00:00
parent 08311935b5
commit 14b9edbbf5
18 changed files with 555 additions and 707 deletions
+89 -103
View File
@@ -2,47 +2,39 @@
/* Copyright (C) 2014 Stony Brook University */
/*
* shim_checkpoints.c
* shim_checkpoint.h
*
* This file contains definitions and macros for checkpointing method.
* This file contains definitions and macros for checkpointing.
*/
#ifndef _SHIM_CHECKPOINT_H_
#define _SHIM_CHECKPOINT_H_
#include <stdarg.h>
#include <stdint.h>
#include <pal.h>
#include <shim_defs.h>
#include <shim_ipc.h>
#include "pal.h"
#ifdef __i386__
#error "x86-32 support is heavily broken."
#endif
typedef uint64_t ptr_t;
#include "shim_defs.h"
#include "shim_ipc.h"
#define __attribute_migratable __attribute__((section(".migratable")))
extern char __migratable;
extern char __migratable_end;
/* FIXME: Checkpointing must be de-macroed and simplified */
/* TSAI 7/11/2012:
The checkpoint scheme we are expecting is to support an easy syntax to
implement migration procedure. A migration procedure can be written
in the following syntax:
BEGIN_CP_DEFINITION(exec)
{
BEGIN_CP_DEFINITION(exec) {
DEFINE_CP(thread, ...);
DEFINE_CP(handle_map, ...);
}
void * checkpoint = DO_CHECKPOINT(exec);
The structure of checkpoint data will be a counting-down stack-like
memory segment, with enough space reserved below for 1. in case the
dry run miscalculate the checkpoint size or 2. stack use for the new
thread.
void* checkpoint = DO_CHECKPOINT(exec);
Below is the figure for our checkpoint structure:
@@ -55,16 +47,11 @@ extern char __migratable_end;
...
checkpoint_entry[n] CP_NULL
High Bytes ------------------------------------------------
*/
struct shim_cp_entry {
ptr_t cp_type; /* entry type */
union {
ptr_t cp_val; /* integer value */
/* originally there is a pointer, now we don't need them */
} cp_un;
uintptr_t cp_type;
uintptr_t cp_val;
};
struct shim_mem_entry {
@@ -72,8 +59,8 @@ struct shim_mem_entry {
void* addr;
size_t size;
void** paddr;
int prot; /*< Combination of PAL_PROT_* flags */
void* data;
int prot; /* combination of PAL_PROT_* flags */
};
struct shim_palhdl_entry {
@@ -88,25 +75,27 @@ struct shim_cp_store {
void* cp_map;
struct shim_handle* cp_file;
/* allocation method for check point area */
void* (*alloc)(struct shim_cp_store*, void*, size_t);
/* allocation method for checkpoint area */
void* (*alloc)(void*, size_t);
/* check point area */
ptr_t base, offset, bound;
/* checkpoint area */
uintptr_t base;
size_t offset;
size_t bound;
/* entries of out-of-band data */
/* VMA entries */
struct shim_mem_entry* last_mem_entry;
int mem_nentries;
size_t mem_entries_cnt;
size_t mem_size;
/* entries of pal handles to send */
/* PAL-handle entries */
struct shim_palhdl_entry* last_palhdl_entry;
int palhdl_nentries;
size_t palhdl_entries_cnt;
};
#define CP_FUNC_ARGS struct shim_cp_store* store, void* obj, size_t size, void** objp
#define RS_FUNC_ARGS struct shim_cp_entry* entry, ptr_t base, ptr_t* offset, long rebase
#define RS_FUNC_ARGS struct shim_cp_entry* entry, uintptr_t base, size_t* offset, size_t rebase
#define DEFINE_CP_FUNC(name) int cp_##name(CP_FUNC_ARGS)
#define DEFINE_RS_FUNC(name) int rs_##name(RS_FUNC_ARGS)
@@ -120,7 +109,6 @@ extern const rs_func __rs_func;
enum {
CP_NULL = 0,
CP_IGNORE,
CP_OOB,
CP_ADDR,
CP_SIZE,
@@ -138,15 +126,15 @@ enum {
#define __ADD_CP_OFFSET(size) \
({ \
ptr_t _off = store->offset; \
size_t _off = store->offset; \
if (store->offset + (size) > store->bound) { \
ptr_t new_bound = store->bound * 2; \
size_t new_bound = store->bound * 2; \
\
while (store->offset + (size) > new_bound) \
new_bound *= 2; \
\
void* buf = \
store->alloc(store, (void*)store->base + store->bound, new_bound - store->bound); \
store->alloc((void*)store->base + store->bound, new_bound - store->bound); \
if (!buf) \
return -ENOMEM; \
\
@@ -160,9 +148,7 @@ enum {
({ \
struct shim_cp_entry* tmp = (void*)base + __ADD_CP_OFFSET(sizeof(struct shim_cp_entry)); \
tmp->cp_type = CP_##type; \
tmp->cp_un.cp_val = (ptr_t)(value); \
if (DEBUG_CHECKPOINT) \
debug("ADD CP_" #type "(0x%08lx) >%ld\n", tmp->cp_un.cp_val, store->offset); \
tmp->cp_val = (uintptr_t)(value); \
tmp; \
})
@@ -171,10 +157,8 @@ enum {
size_t _size = ALIGN_UP(size, sizeof(void*)); \
struct shim_cp_entry* oob = (void*)base + __ADD_CP_OFFSET(sizeof(struct shim_cp_entry)); \
oob->cp_type = CP_OOB; \
oob->cp_un.cp_val = (ptr_t)_size; \
ptr_t _off = (ptr_t)__ADD_CP_OFFSET(_size); \
if (DEBUG_CHECKPOINT) \
debug("ADD OFFSET(%lu) >%ld\n", size, store->offset); \
oob->cp_val = (uintptr_t)_size; \
size_t _off = __ADD_CP_OFFSET(_size); \
_off; \
})
@@ -182,9 +166,7 @@ enum {
({ \
struct shim_cp_entry* tmp = (void*)base + __ADD_CP_OFFSET(sizeof(struct shim_cp_entry)); \
tmp->cp_type = CP_FUNC_TYPE; \
tmp->cp_un.cp_val = (ptr_t)(value); \
if (DEBUG_CHECKPOINT) \
debug("ADD %s(0x%08lx) >%ld\n", CP_FUNC_NAME, value, store->offset); \
tmp->cp_val = (uintptr_t)(value); \
tmp; \
})
@@ -199,28 +181,24 @@ enum {
} \
*offset += sizeof(struct shim_cp_entry); \
if (tmp->cp_type == CP_OOB) \
*offset += tmp->cp_un.cp_val; \
*offset += tmp->cp_val; \
else \
break; \
} \
tmp; \
})
#define GET_CP_ENTRY(type) \
({ \
struct shim_cp_entry* tmp = NEXT_CP_ENTRY(); \
\
while (tmp->cp_type != CP_##type) \
tmp = NEXT_CP_ENTRY(); \
\
/* debug("GET CP_" #type "(%p)\n",tmp->cp_un.cp_val); */ \
tmp->cp_un.cp_val; \
#define GET_CP_ENTRY(type) \
({ \
struct shim_cp_entry* tmp = NEXT_CP_ENTRY(); \
while (tmp->cp_type != CP_##type) \
tmp = NEXT_CP_ENTRY(); \
tmp->cp_val; \
})
#define GET_CP_FUNC_ENTRY() \
({ \
/* debug("GET CP_FUNC_%s(%p) :%d\n", CP_FUNC_NAME, entry->cp_un.cp_val); */ \
entry->cp_un.cp_val; \
#define GET_CP_FUNC_ENTRY() \
({ \
entry->cp_val; \
})
#define BEGIN_CP_FUNC(name) \
@@ -233,10 +211,10 @@ enum {
DEFINE_CP_FUNC(name) { \
int CP_FUNC_TYPE __attribute__((unused)) = CP_FUNC(name); \
const char* CP_FUNC_NAME __attribute__((unused)) = #name; \
ptr_t base __attribute__((unused)) = store->base;
size_t base __attribute__((unused)) = store->base;
#define END_CP_FUNC(name) \
return 0; \
#define END_CP_FUNC(name) \
return 0; \
}
#define END_CP_FUNC_NO_RS(name) \
@@ -254,8 +232,8 @@ enum {
int CP_FUNC_TYPE __attribute__((unused)) = CP_FUNC(name); \
const char* CP_FUNC_NAME __attribute__((unused)) = #name;
#define END_RS_FUNC(name) \
return 0; \
#define END_RS_FUNC(name) \
return 0; \
}
#define CP_REBASE(obj) \
@@ -282,12 +260,11 @@ enum {
struct shim_cp_map_entry {
void* addr;
ptr_t off;
size_t off;
};
void* create_cp_map(void);
void destroy_cp_map(void* map);
struct shim_cp_map_entry* get_cp_map_entry(void* map, void* addr, bool create);
#define GET_FROM_CP_MAP(obj) \
@@ -304,8 +281,8 @@ struct shim_cp_map_entry* get_cp_map_entry(void* map, void* addr, bool create);
#define BEGIN_MIGRATION_DEF(name, ...) \
int migrate_cp_##name(struct shim_cp_store* store, ##__VA_ARGS__) { \
int ret = 0; \
ptr_t base = store->base;
int ret = 0; \
size_t base = store->base;
#define END_MIGRATION_DEF(name) \
ADD_CP_ENTRY(NULL, 0); \
@@ -319,12 +296,11 @@ struct shim_cp_map_entry* get_cp_map_entry(void* map, void* addr, bool create);
return ret; \
} while (0)
#define DEBUG_RESUME 0
#define DEBUG_CHECKPOINT 0
#define DEBUG_RESUME 0
#if DEBUG_RESUME == 1
#define DEBUG_RS(fmt, ...) \
debug("GET %s(0x%08lx): " fmt "\n", CP_FUNC_NAME, entry->cp_un.cp_val, ##__VA_ARGS__)
debug("GET %s(0x%08lx): " fmt "\n", CP_FUNC_NAME, entry->cp_val, ##__VA_ARGS__)
#else
#define DEBUG_RS(...) do {} while (0)
#endif
@@ -348,37 +324,47 @@ struct shim_cp_map_entry* get_cp_map_entry(void* map, void* addr, bool create);
ret; \
})
struct newproc_cp_header {
struct cp_header {
unsigned long size;
void* addr;
unsigned long offset;
} hdr;
struct mem_header {
unsigned long entoffset;
int nentries;
} mem;
struct palhdl_header {
unsigned long entoffset;
int nentries;
} palhdl;
struct checkpoint_hdr {
void* addr;
size_t size;
size_t offset;
size_t mem_offset;
size_t mem_entries_cnt;
size_t palhdl_offset;
size_t palhdl_entries_cnt;
};
struct newproc_header {
struct newproc_cp_header checkpoint;
int failure;
};
typedef int (*migrate_func_t)(struct shim_cp_store*, struct shim_thread*, struct shim_process*,
va_list);
struct newproc_response {
IDTYPE child_vmid;
int failure;
};
/*!
* \brief Create child process and migrate current-process state to it.
*
* Called in parent process during fork/clone/execve.
*
* \param migrate_func Migration function defined by the caller.
* \param exec Executable to load in the child process.
* \param argv Arguments passed to the child process.
* \param thread Main-thread handle to be migrated to the child process.
*
* The remaining arguments are passed into the migration function.
*
* \return 0 on success, negative POSIX error code on failure.
*/
int create_process_and_send_checkpoint(migrate_func_t migrate_func, struct shim_handle* exec,
const char** argv, struct shim_thread* thread, ...);
int do_migration(struct newproc_cp_header* hdr, void** cpptr);
int restore_checkpoint(struct cp_header* cphdr, struct mem_header* memhdr, ptr_t base, ptr_t type);
int do_migrate_process(int (*migrate)(struct shim_cp_store*, struct shim_thread*,
struct shim_process*, va_list),
struct shim_handle* exec, const char** argv, struct shim_thread* thread,
...);
/*!
* \brief Receive a checkpoint from parent process and restore state based on it.
*
* Called in child process during initialization.
*
* \param[in] hdr Checkpoint header already received from the parent.
*
* \return 0 on success, negative POSIX error code on failure.
*/
int receive_checkpoint_and_restore(struct checkpoint_hdr* hdr);
#endif /* _SHIM_CHECKPOINT_H_ */
-8
View File
@@ -1,14 +1,6 @@
#ifndef _SHIM_DEFS_H_
#define _SHIM_DEFS_H_
/*
* If enable CPSTORE_DERANDOMIZATION, the library OS will try to load the checkpoint (from the
* parent) at the exact address it was created. Currently this option is disabled to prevent
* internal fragmentation of virtual memory space.
*/
#define CPSTORE_DERANDOMIZATION 1
#define DEFAULT_HEAP_MIN_SIZE (256 * 1024 * 1024) /* 256MB */
#define DEFAULT_MEM_MAX_NPAGES (1024 * 1024) /* 4GB */
#define DEFAULT_BRK_MAX_SIZE (256 * 1024) /* 256KB */
+12
View File
@@ -18,6 +18,18 @@ struct shim_handle;
void sysparser_printf(const char* fmt, ...);
/* quick hash function based on Robert Jenkins' hash algorithm */
static inline uint64_t hash64(uint64_t key) {
key = (~key) + (key << 21);
key = key ^ (key >> 24);
key = (key + (key << 3)) + (key << 8);
key = key ^ (key >> 14);
key = (key + (key << 2)) + (key << 4);
key = key ^ (key >> 28);
key = key + (key << 31);
return key;
}
/* string object */
struct shim_str* get_str_obj(void);
int free_str_obj(struct shim_str* str);
+3 -3
View File
@@ -703,7 +703,7 @@ BEGIN_CP_FUNC(handle) {
struct shim_handle* hdl = (struct shim_handle*)obj;
struct shim_handle* new_hdl = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_handle));
@@ -806,7 +806,7 @@ BEGIN_CP_FUNC(fd_handle) {
struct shim_fd_handle* fdhdl = (struct shim_fd_handle*)obj;
struct shim_fd_handle* new_fdhdl = NULL;
ptr_t off = ADD_CP_OFFSET(sizeof(struct shim_fd_handle));
size_t off = ADD_CP_OFFSET(sizeof(struct shim_fd_handle));
new_fdhdl = (struct shim_fd_handle*)(base + off);
memcpy(new_fdhdl, fdhdl, sizeof(struct shim_fd_handle));
DO_CP(handle, fdhdl->handle, &new_fdhdl->handle);
@@ -831,7 +831,7 @@ BEGIN_CP_FUNC(handle_map) {
size = sizeof(struct shim_handle_map) + (sizeof(struct shim_fd_handle*) * fd_size);
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(size);
+4 -4
View File
@@ -529,7 +529,7 @@ BEGIN_CP_FUNC(signal_handles)
struct shim_signal_handles* handles = (struct shim_signal_handles*)obj;
struct shim_signal_handles* new_handles = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_signal_handles));
@@ -576,7 +576,7 @@ BEGIN_CP_FUNC(thread)
struct shim_thread * thread = (struct shim_thread *) obj;
struct shim_thread * new_thread = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_thread));
@@ -671,10 +671,10 @@ BEGIN_CP_FUNC(running_thread)
struct shim_thread * new_thread = NULL;
DO_CP(thread, thread, &new_thread);
ADD_CP_FUNC_ENTRY((ptr_t) new_thread - base);
ADD_CP_FUNC_ENTRY((uintptr_t)new_thread - base);
if (thread->shim_tcb) {
ptr_t toff = ADD_CP_OFFSET(sizeof(shim_tcb_t));
size_t toff = ADD_CP_OFFSET(sizeof(shim_tcb_t));
new_thread->shim_tcb = (void *)(base + toff);
struct shim_tcb* new_tcb = new_thread->shim_tcb;
memcpy(new_tcb, thread->shim_tcb, sizeof(*new_tcb));
+1 -1
View File
@@ -1137,7 +1137,7 @@ BEGIN_CP_FUNC(vma)
struct shim_vma_info* vma = (struct shim_vma_info*) obj;
struct shim_vma_info* new_vma = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(*vma));
+2 -2
View File
@@ -1605,7 +1605,7 @@ BEGIN_CP_FUNC(library) {
struct link_map* map = (struct link_map*)obj;
struct link_map* new_map;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct link_map));
@@ -1708,7 +1708,7 @@ BEGIN_CP_FUNC(loaded_libraries) {
map = map->l_next;
}
ADD_CP_FUNC_ENTRY((ptr_t)new_interp_map);
ADD_CP_FUNC_ENTRY((uintptr_t)new_interp_map);
}
END_CP_FUNC(loaded_libraries)
+1 -1
View File
@@ -328,7 +328,7 @@ BEGIN_CP_FUNC(dentry) {
struct shim_dentry* dent = (struct shim_dentry*)obj;
struct shim_dentry* new_dent = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_dentry));
+1 -1
View File
@@ -542,7 +542,7 @@ BEGIN_CP_FUNC(mount) {
struct shim_mount* mount = (struct shim_mount*)obj;
struct shim_mount* new_mount = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_mount));
+2 -2
View File
@@ -443,7 +443,7 @@ BEGIN_CP_FUNC(ipc_info) {
struct shim_ipc_info* info = (struct shim_ipc_info*)obj;
struct shim_ipc_info* new_info = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_ipc_info));
@@ -483,7 +483,7 @@ BEGIN_CP_FUNC(process) {
struct shim_process* process = (struct shim_process*)obj;
struct shim_process* new_process = NULL;
ptr_t off = GET_FROM_CP_MAP(obj);
size_t off = GET_FROM_CP_MAP(obj);
if (!off) {
off = ADD_CP_OFFSET(sizeof(struct shim_process));
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -125,8 +125,8 @@ BEGIN_CP_FUNC(gdb_map) {
struct gdb_link_map* newm = NULL;
while (m) {
ptr_t off = ADD_CP_OFFSET(sizeof(struct gdb_link_map));
newm = (struct gdb_link_map*)(base + off);
size_t off = ADD_CP_OFFSET(sizeof(struct gdb_link_map));
newm = (struct gdb_link_map*)(base + off);
memcpy(newm, m, sizeof(struct gdb_link_map));
newm->l_prev = newm->l_next = NULL;
+14 -29
View File
@@ -477,17 +477,6 @@ fail:
(auxp) = _tmp + sizeof(char *); \
} while (0)
static int init_newproc (struct newproc_header * hdr)
{
PAL_NUM bytes = DkStreamRead(PAL_CB(parent_process), 0,
sizeof(struct newproc_header), hdr,
NULL, 0);
if (bytes == PAL_STREAM_ERROR)
return -PAL_ERRNO();
return hdr->failure;
}
#define CALL_INIT(func, args ...) func(args)
#define RUN_INIT(func, ...) \
@@ -535,8 +524,6 @@ noreturn void* shim_init(int argc, void* args)
/* call to figure out where the arguments are */
FIND_ARG_COMPONENTS(args, argc, argv, envp, auxp);
struct newproc_header hdr;
void * cpaddr = NULL;
RUN_INIT(init_vma);
RUN_INIT(init_slab);
@@ -550,17 +537,17 @@ noreturn void* shim_init(int argc, void* args)
debug("shim loaded at %p, ready to initialize\n", &__load_address);
if (!cpaddr && PAL_CB(parent_process)) {
RUN_INIT(init_newproc, &hdr);
if (hdr.checkpoint.hdr.size)
RUN_INIT(do_migration, &hdr.checkpoint, &cpaddr);
}
if (PAL_CB(parent_process)) {
struct checkpoint_hdr hdr;
PAL_NUM ret = DkStreamRead(PAL_CB(parent_process), 0, sizeof(hdr), &hdr, NULL, 0);
if (ret == PAL_STREAM_ERROR || ret != sizeof(hdr))
shim_do_exit(-PAL_ERRNO());
if (cpaddr) {
thread_start_event = DkNotificationEventCreate(PAL_FALSE);
RUN_INIT(restore_checkpoint,
&hdr.checkpoint.hdr, &hdr.checkpoint.mem,
(ptr_t) cpaddr, 0);
assert(hdr.size);
RUN_INIT(receive_checkpoint_and_restore, &hdr);
}
if (PAL_CB(manifest_handle))
@@ -579,15 +566,13 @@ noreturn void* shim_init(int argc, void* args)
if (PAL_CB(parent_process)) {
/* Notify the parent process */
struct newproc_response res;
res.child_vmid = cur_process.vmid;
res.failure = 0;
PAL_NUM ret = DkStreamWrite(PAL_CB(parent_process), 0,
sizeof(struct newproc_response),
&res, NULL);
if (ret == PAL_STREAM_ERROR)
IDTYPE child_vmid = cur_process.vmid;
PAL_NUM ret = DkStreamWrite(PAL_CB(parent_process), 0, sizeof(child_vmid), &child_vmid,
NULL);
if (ret == PAL_STREAM_ERROR || ret != sizeof(child_vmid))
shim_do_exit(-PAL_ERRNO());
/* FIXME: We shouldn't downgrade communication */
/* Downgrade communication with parent to non-secure (only checkpoint recv is secure).
* Currently only relevant to SGX PAL, other PALs ignore this. */
PAL_STREAM_ATTR attr;
+1 -1
View File
@@ -200,7 +200,7 @@ BEGIN_CP_FUNC(brk) {
__UNUSED(obj);
__UNUSED(size);
__UNUSED(objp);
ADD_CP_FUNC_ENTRY((ptr_t)brk_region.brk_start);
ADD_CP_FUNC_ENTRY((uintptr_t)brk_region.brk_start);
ADD_CP_ENTRY(SIZE, brk_region.brk_current - brk_region.brk_start);
ADD_CP_ENTRY(SIZE, brk_region.brk_end - brk_region.brk_start);
ADD_CP_ENTRY(SIZE, brk_region.data_segment_size);
+2 -1
View File
@@ -357,7 +357,8 @@ int shim_do_clone (int flags, void * user_stack_addr, int * parent_tidptr,
add_thread(thread);
set_as_child(self, thread);
ret = do_migrate_process(&migrate_fork, NULL, NULL, thread);
ret = create_process_and_send_checkpoint(&migrate_fork, /*exec=*/NULL, /*argv=*/NULL,
thread);
thread->shim_tcb = NULL; /* cpu context of forked thread isn't
* needed any more */
if (parent_stack)
+2 -2
View File
@@ -460,7 +460,7 @@ BEGIN_CP_FUNC(epoll_item) {
INIT_LISTP(new_list);
LISTP_FOR_EACH_ENTRY(epoll_item, old_list, list) {
ptr_t off = ADD_CP_OFFSET(sizeof(struct shim_epoll_item));
size_t off = ADD_CP_OFFSET(sizeof(struct shim_epoll_item));
struct shim_epoll_item* new_epoll_item = (struct shim_epoll_item*)(base + off);
@@ -474,7 +474,7 @@ BEGIN_CP_FUNC(epoll_item) {
DO_CP(handle, epoll_item->handle, &new_epoll_item->handle);
}
ADD_CP_FUNC_ENTRY((ptr_t)objp - base);
ADD_CP_FUNC_ENTRY((uintptr_t)objp - base);
}
END_CP_FUNC(epoll_item)
+1 -1
View File
@@ -426,7 +426,7 @@ reopen:
cur_thread->in_vm = false;
unlock(&cur_thread->lock);
ret = do_migrate_process(&migrate_execve, exec, argv, cur_thread, envp);
ret = create_process_and_send_checkpoint(&migrate_execve, exec, argv, cur_thread, envp);
lock(&cur_thread->lock);
cur_thread->stack = stack;
+3 -1
View File
@@ -71,7 +71,9 @@ int shim_do_fork(void) {
add_thread(new_thread);
set_as_child(cur_thread, new_thread);
if ((ret = do_migrate_process(&migrate_fork, NULL, NULL, new_thread)) < 0) {
ret = create_process_and_send_checkpoint(&migrate_fork, /*exec=*/NULL, /*argv=*/NULL,
new_thread);
if (ret < 0) {
put_thread(new_thread);
return ret;
}