123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465 |
- typedef uint64_t ptr_t;
- extern char __migratable;
- extern char __migratable_end;
- struct shim_cp_entry
- {
- ptr_t cp_type;
- union
- {
- ptr_t cp_val;
-
- } cp_un;
- };
- struct shim_mem_entry {
- struct shim_mem_entry * prev;
- void * addr;
- size_t size;
- void ** paddr;
- int prot;
- void * data;
- };
- struct shim_gipc_entry {
- struct shim_mem_entry mem;
- unsigned long first_hash;
- };
- struct shim_palhdl_entry {
- struct shim_palhdl_entry * prev;
- PAL_HANDLE handle;
- struct shim_qstr * uri;
- PAL_HANDLE * phandle;
- };
- struct shim_cp_store {
-
- void * cp_map;
- struct shim_handle * cp_file;
-
- void * (*alloc) (struct shim_cp_store *, void *, size_t);
-
- ptr_t base, offset, bound;
-
- bool use_gipc;
- struct shim_gipc_entry * last_gipc_entry;
- int gipc_nentries;
-
- struct shim_mem_entry * last_mem_entry;
- int mem_nentries;
- int mem_size;
-
- struct shim_palhdl_entry * last_palhdl_entry;
- int palhdl_nentries;
- };
- struct shim_cp_store * store, void * obj, size_t size, void ** objp
- struct shim_cp_entry * entry, ptr_t base, ptr_t * offset, long rebase
- typedef int (*cp_func) (CP_FUNC_ARGS);
- typedef int (*rs_func) (RS_FUNC_ARGS);
- extern const char * __cp_name;
- extern const cp_func __cp_func;
- extern const rs_func __rs_func;
- enum {
- CP_NULL = 0,
- CP_IGNORE,
- CP_OOB,
- CP_ADDR,
- CP_SIZE,
- CP_FUNC_BASE,
- };
- ({ extern const cp_func cp_func_
- ({ \
- ptr_t _off = store->offset; \
- if (store->offset + (size) > store->bound) { \
- ptr_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); \
- if (!buf) \
- return -ENOMEM; \
- \
- store->bound = new_bound; \
- } \
- store->offset += (size); \
- _off; })
- ({ \
- struct shim_cp_entry * tmp = \
- (void *) base + \
- __ADD_CP_OFFSET(sizeof(struct shim_cp_entry)); \
- tmp->cp_type = CP_
- tmp->cp_un.cp_val = (ptr_t) (value); \
- if (DEBUG_CHECKPOINT) \
- debug("ADD CP_"
- store->offset); \
- tmp; })
- ({ \
- size_t _size = ((size) + sizeof(void *) - 1) & \
- ~(sizeof(void *) - 1); \
- 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); \
- _off; })
- ({ \
- 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; })
- ({ struct shim_cp_entry * tmp; \
- while (1) { \
- tmp = (void *) base + *offset; \
- if (tmp->cp_type == CP_NULL) { \
- tmp = NULL; \
- break; \
- } \
- *offset += sizeof(struct shim_cp_entry); \
- if (tmp->cp_type == CP_OOB) \
- *offset += tmp->cp_un.cp_val; \
- else \
- break; \
- } \
- tmp; })
- ({ struct shim_cp_entry * tmp = NEXT_CP_ENTRY(); \
- \
- while (tmp->cp_type != CP_
- tmp = NEXT_CP_ENTRY(); \
- \
- \
- tmp->cp_un.cp_val; })
- ({
- \
- entry->cp_un.cp_val; })
- const char * cp_name_
- __attribute__((section(".cp_name."
- extern DEFINE_CP_FUNC(name); \
- extern DEFINE_RS_FUNC(name); \
- const cp_func cp_func_
- __attribute__((section(".cp_func."
- const rs_func rs_func_
- __attribute__((section(".rs_func."
- \
- DEFINE_PROFILE_INTERVAL(cp_
- DEFINE_PROFILE_INTERVAL(rs_
- \
- DEFINE_CP_FUNC(name) \
- { \
- int CP_FUNC_TYPE __attribute__((unused)) = CP_FUNC(name); \
- const char * CP_FUNC_NAME __attribute__((unused)) =
- ptr_t base __attribute__((unused)) = store->base; \
- BEGIN_PROFILE_INTERVAL(); \
- ASSIGN_PROFILE_INTERVAL(cp_
- SAVE_PROFILE_INTERVAL_ASSIGNED(); \
- return 0; \
- }
- END_CP_FUNC(name) \
- BEGIN_RS_FUNC(name) {__UNUSED(entry); __UNUSED(base); \
- __UNUSED(offset); __UNUSED(rebase); } END_RS_FUNC(name)
- DEFINE_RS_FUNC(name) \
- { \
- int CP_FUNC_TYPE __attribute__((unused)) = CP_FUNC(name); \
- const char * CP_FUNC_NAME __attribute__((unused)) =
- BEGIN_PROFILE_INTERVAL(); \
- ASSIGN_PROFILE_INTERVAL(rs_
- SAVE_PROFILE_INTERVAL_ASSIGNED(); \
- return 0; \
- }
- do { \
- void * _ptr = &(obj); \
- size_t _size = sizeof(obj); \
- void ** _p; \
- for (_p = _ptr ; _p < (void **)(_ptr + _size) ; _p++) \
- if (*_p) \
- *_p += rebase; \
- } while (0)
- do { \
- extern DEFINE_CP_FUNC(name); \
- int ret = cp_
- if (ret < 0) return ret; \
- } while (0)
- DO_CP_SIZE(name, obj, sizeof(*(obj)), objp)
- DO_CP(name, (obj)->member, &((newobj)->member));
- #define DO_CP_IN_MEMBER(name, obj, member) \
- DO_CP(name, &((obj)->member), NULL)
- struct shim_cp_map_entry { void * addr; ptr_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) \
- ({ \
- struct shim_cp_map_entry * e = \
- get_cp_map_entry(store->cp_map, obj, false); \
- e ? e->off : 0; })
- #define ADD_TO_CP_MAP(obj, off) \
- do { \
- struct shim_cp_map_entry * e = \
- get_cp_map_entry(store->cp_map, obj, true); \
- e->off = (off); \
- } while (0)
- int migrate_
- { \
- int ret = 0; \
- ptr_t base = store->base;
- ADD_CP_ENTRY(NULL, 0); \
- return 0; \
- }
- do { \
- extern DEFINE_CP_FUNC(name); \
- if ((ret = cp_
- return ret; \
- } while (0)
- debug("GET %s(0x%08lx): " fmt "\n", CP_FUNC_NAME, entry->cp_un.cp_val, \
-
- ({ int ret = 0; \
- do { \
- BEGIN_PROFILE_INTERVAL(); \
- \
- if (!((store)->cp_map = create_cp_map())) { \
- ret = -ENOMEM; \
- goto out; \
- } \
- SAVE_PROFILE_INTERVAL(checkpoint_create_map); \
- \
- ret = migrate_##name(store, ##__VA_ARGS__); \
- if (ret < 0) \
- goto out; \
- \
- SAVE_PROFILE_INTERVAL(checkpoint_copy); \
- ADD_PROFILE_OCCURENCE(checkpoint_total_size, (store)->offset); \
- INC_PROFILE_OCCURENCE(checkpoint_count); \
- \
- debug("complete checkpointing data\n"); \
- out: \
- destroy_cp_map((store)->cp_map); \
- SAVE_PROFILE_INTERVAL(checkpoint_destroy_map); \
- } while (0); \
- 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 gipc_header {
- char uri[16];
- unsigned long entoffset;
- int nentries;
- } gipc;
- };
- struct newproc_header {
- struct newproc_cp_header checkpoint;
- int failure;
- #ifdef PROFILE
- unsigned long begin_create_time;
- unsigned long create_time;
- unsigned long write_proc_time;
- #endif
- };
- struct newproc_response {
- IDTYPE child_vmid;
- int failure;
- };
- 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, ...);
- int init_from_checkpoint_file (const char * filename,
- struct newproc_cp_header * hdr,
- void ** cpptr);
- int restore_from_file (const char * filename, struct newproc_cp_header * hdr,
- void ** cpptr);
- void restore_context (struct shim_context * context);
- int create_checkpoint (const char * cpdir, IDTYPE * session);
- int join_checkpoint (struct shim_thread * cur, IDTYPE sid);
- #endif /* _SHIM_CHECKPOINT_H_ */
|