int main(int argc, char **argv) { int r; int send_back_fd, recv_fd; #define NEXTARG (++argv, assert(*argv), *argv) const char *mode = *++argv; assert(mode); if (!strcmp(mode,"--save-domain")) { io_fd = atoi(NEXTARG); recv_fd = atoi(NEXTARG); uint32_t dom = strtoul(NEXTARG,0,10); uint32_t max_iters = strtoul(NEXTARG,0,10); uint32_t max_factor = strtoul(NEXTARG,0,10); uint32_t flags = strtoul(NEXTARG,0,10); int hvm = atoi(NEXTARG); unsigned cbflags = strtoul(NEXTARG,0,10); xc_migration_stream_t stream_type = strtoul(NEXTARG,0,10); assert(!*++argv); helper_setcallbacks_save(&helper_save_callbacks, cbflags); startup("save"); setup_signals(save_signal_handler); r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags, &helper_save_callbacks, hvm, stream_type, recv_fd); complete(r); } else if (!strcmp(mode,"--restore-domain")) { io_fd = atoi(NEXTARG); send_back_fd = atoi(NEXTARG); uint32_t dom = strtoul(NEXTARG,0,10); unsigned store_evtchn = strtoul(NEXTARG,0,10); domid_t store_domid = strtoul(NEXTARG,0,10); unsigned console_evtchn = strtoul(NEXTARG,0,10); domid_t console_domid = strtoul(NEXTARG,0,10); unsigned int hvm = strtoul(NEXTARG,0,10); unsigned int pae = strtoul(NEXTARG,0,10); int superpages = strtoul(NEXTARG,0,10); unsigned cbflags = strtoul(NEXTARG,0,10); xc_migration_stream_t stream_type = strtoul(NEXTARG,0,10); assert(!*++argv); helper_setcallbacks_restore(&helper_restore_callbacks, cbflags); unsigned long store_mfn = 0; unsigned long console_mfn = 0; startup("restore"); setup_signals(SIG_DFL); r = xc_domain_restore(xch, io_fd, dom, store_evtchn, &store_mfn, store_domid, console_evtchn, &console_mfn, console_domid, hvm, pae, superpages, stream_type, &helper_restore_callbacks, send_back_fd); helper_stub_restore_results(store_mfn,console_mfn,0); complete(r); } else { assert(!"unexpected mode argument"); } }
int stub_xc_domain_restore(int fd, int store_evtchn, int console_evtchn, int hvm, unsigned long *store_mfn, unsigned long *console_mfn) { int r = 0; struct flags f; get_flags(&f); if ( hvm ) { /* * We have to do this even in the domain restore case as XenServers * prior to 6.0.2 did not create a viridian save record. */ if (f.viridian) hvm_set_viridian_features(&f); xc_set_hvm_param(xch, domid, HVM_PARAM_HPET_ENABLED, f.hpet); #ifdef HAVE_CORES_PER_SOCKET if ( f.cores_per_socket > 0 ) r = xc_domain_set_cores_per_socket(xch, domid, f.cores_per_socket); #endif if ( r ) failwith_oss_xc("xc_domain_set_cores_per_socket"); } configure_vcpus(f); r = xc_domain_restore(xch, fd, domid, store_evtchn, store_mfn, 0, console_evtchn, console_mfn, 0, hvm, f.pae, 0, 0, NULL); if ( r ) failwith_oss_xc("xc_domain_restore"); /* * The legacy -> migration v2 code in XenServer 6.5 didn't combine the * out-of-band HVM_PARAM_PAE_ENABLED into the converted stream, and * xenguest didn't set it, as the v2 restore code was expected to. * * This causes xc_cpuid_apply_policy() to hide the PAE bit from the domain * cpuid policy, which went unnoticed (and without incident, despite being * a guest-visible change) until Xen-4.5 became stricter with its checks * for when a guest writes to %cr4. * * The correct value is still available out-of-band, so clobber the result * from the stream, in case the stream is from XenServer 6.5 and is a VM * which hasn't rebooted and has a bad HVM PARAM in the v2 stream. */ if ( hvm ) xc_set_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, f.pae); r = construct_cpuid_policy(&f, hvm); if ( r ) failwith_oss_xc("construct_cpuid_policy"); free_flags(&f); if ( hvm ) { r = set_genid(); if (r) exit(1); } return 0; }
CAMLprim value stub_xc_domain_restore(value handle, value fd, value domid, value store_evtchn, value store_domid, value console_evtchn, value console_domid, value hvm, value no_incr_generationid) { CAMLparam5(handle, fd, domid, store_evtchn, console_evtchn); CAMLxparam1(hvm); CAMLlocal1(result); unsigned long store_mfn, console_mfn; domid_t c_store_domid, c_console_domid; unsigned long c_vm_generationid_addr; char c_vm_generationid_addr_s[32]; unsigned int c_store_evtchn, c_console_evtchn; int r; size_t size, written; struct flags f; get_flags(&f,_D(domid)); c_store_evtchn = Int_val(store_evtchn); c_store_domid = Int_val(store_domid); c_console_evtchn = Int_val(console_evtchn); c_console_domid = Int_val(console_domid); #ifdef HVM_PARAM_VIRIDIAN xc_set_hvm_param(_H(handle), _D(domid), HVM_PARAM_VIRIDIAN, f.viridian); #endif configure_vcpus(_H(handle), _D(domid), f); caml_enter_blocking_section(); r = xc_domain_restore(_H(handle), Int_val(fd), _D(domid), c_store_evtchn, &store_mfn, #ifdef XENGUEST_4_2 c_store_domid, #endif c_console_evtchn, &console_mfn, #ifdef XENGUEST_4_2 c_console_domid, #endif Bool_val(hvm), f.pae, 0 /*superpages*/ #ifdef XENGUEST_4_2 , Bool_val(no_incr_generationid), &c_vm_generationid_addr, NULL /* restore_callbacks */ #endif ); if (!r) { size = sizeof(c_vm_generationid_addr_s) - 1; /* guarantee a NULL remains on the end */ written = snprintf(c_vm_generationid_addr_s, size, "0x%lx", c_vm_generationid_addr); if (written < size) r = xenstore_puts(_D(domid), c_vm_generationid_addr_s, GENERATION_ID_ADDRESS); else { syslog(LOG_ERR|LOG_DAEMON,"Failed to write %s (%d >= %d)", GENERATION_ID_ADDRESS, written, size); r = 1; } } caml_leave_blocking_section(); if (r) failwith_oss_xc(_H(handle), "xc_domain_restore"); result = caml_alloc_tuple(2); Store_field(result, 0, caml_copy_nativeint(store_mfn)); Store_field(result, 1, caml_copy_nativeint(console_mfn)); CAMLreturn(result); }
int main(int argc, char **argv) { int r; #define NEXTARG (++argv, assert(*argv), *argv) const char *mode = *++argv; assert(mode); if (!strcmp(mode,"--save-domain")) { int io_fd = atoi(NEXTARG); uint32_t dom = strtoul(NEXTARG,0,10); uint32_t max_iters = strtoul(NEXTARG,0,10); uint32_t max_factor = strtoul(NEXTARG,0,10); uint32_t flags = strtoul(NEXTARG,0,10); int hvm = atoi(NEXTARG); unsigned long genidad = strtoul(NEXTARG,0,10); toolstack_save_fd = atoi(NEXTARG); toolstack_save_len = strtoul(NEXTARG,0,10); unsigned cbflags = strtoul(NEXTARG,0,10); assert(!*++argv); if (toolstack_save_fd >= 0) helper_save_callbacks.toolstack_save = toolstack_save_cb; helper_setcallbacks_save(&helper_save_callbacks, cbflags); startup("save"); r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags, &helper_save_callbacks, hvm, genidad); complete(r); } else if (!strcmp(mode,"--restore-domain")) { int io_fd = atoi(NEXTARG); uint32_t dom = strtoul(NEXTARG,0,10); unsigned store_evtchn = strtoul(NEXTARG,0,10); domid_t store_domid = strtoul(NEXTARG,0,10); unsigned console_evtchn = strtoul(NEXTARG,0,10); domid_t console_domid = strtoul(NEXTARG,0,10); unsigned int hvm = strtoul(NEXTARG,0,10); unsigned int pae = strtoul(NEXTARG,0,10); int superpages = strtoul(NEXTARG,0,10); int no_incr_genidad = strtoul(NEXTARG,0,10); unsigned cbflags = strtoul(NEXTARG,0,10); assert(!*++argv); helper_setcallbacks_restore(&helper_restore_callbacks, cbflags); unsigned long store_mfn = 0; unsigned long console_mfn = 0; unsigned long genidad = 0; startup("restore"); r = xc_domain_restore(xch, io_fd, dom, store_evtchn, &store_mfn, store_domid, console_evtchn, &console_mfn, console_domid, hvm, pae, superpages, no_incr_genidad, &genidad, &helper_restore_callbacks); helper_stub_restore_results(store_mfn,console_mfn,genidad,0); complete(r); } else { assert(!"unexpected mode argument"); } }