[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] VM generation ID save/restore and migrate
Ping? > -----Original Message----- > From: Paul Durrant [mailto:paul.durrant@xxxxxxxxxx] > Sent: 05 December 2011 10:07 > To: xen-devel@xxxxxxxxxxxxxxxxxxx > Cc: Paul Durrant > Subject: [PATCH] VM generation ID save/restore and migrate > > # HG changeset patch > # User Paul Durrant <paul.durrant@xxxxxxxxxx> # Date 1323079290 0 # > Node ID 152a79fbe918d8a6c63ab15a03aebb9d7d305843 > # Parent a4d7c27ec1f190ecbb9a909609f6ef0eca250c00 > VM generation ID save/restore and migrate. > > Add code to track the address of the VM generation id buffer across > a save/restore or migrate and increment it as necessary. > The address of the buffer is written into xenstore by hvmloader at > boot time. It must be read from xenstore by the caller of > xc_domain_save() and then written back again by the caller of > xc_domain_restore(). > > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > > diff -r a4d7c27ec1f1 -r 152a79fbe918 > tools/libxc/ia64/xc_ia64_linux_restore.c > --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Fri Dec 02 13:51:17 > 2011 -0800 > +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Mon Dec 05 10:01:30 > 2011 +0000 > @@ -548,7 +548,8 @@ int > xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, > unsigned int store_evtchn, unsigned long > *store_mfn, > unsigned int console_evtchn, unsigned long > *console_mfn, > - unsigned int hvm, unsigned int pae, int > superpages) > + unsigned int hvm, unsigned int pae, int > superpages, > + int increment_gid, unsigned long *vm_gid_addr) > { > DECLARE_DOMCTL; > int rc = 1; > diff -r a4d7c27ec1f1 -r 152a79fbe918 > tools/libxc/ia64/xc_ia64_linux_save.c > --- a/tools/libxc/ia64/xc_ia64_linux_save.c Fri Dec 02 13:51:17 > 2011 -0800 > +++ b/tools/libxc/ia64/xc_ia64_linux_save.c Mon Dec 05 10:01:30 > 2011 +0000 > @@ -382,7 +382,8 @@ out: > int > xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t > max_iters, > uint32_t max_factor, uint32_t flags, > - struct save_callbacks* callbacks, int hvm) > + struct save_callbacks* callbacks, int hvm, > + unsigned long vm_gid_addr) > { > DECLARE_DOMCTL; > xc_dominfo_t info; > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/libxc/xc_domain_restore.c > --- a/tools/libxc/xc_domain_restore.c Fri Dec 02 13:51:17 2011 - > 0800 > +++ b/tools/libxc/xc_domain_restore.c Mon Dec 05 10:01:30 2011 > +0000 > @@ -681,6 +681,7 @@ typedef struct { > uint64_t console_pfn; > uint64_t acpi_ioport_location; > uint64_t viridian; > + uint64_t vm_gid_addr; > } pagebuf_t; > > static int pagebuf_init(pagebuf_t* buf) @@ -860,6 +861,17 @@ static > int pagebuf_get_one(xc_interface > } > return compbuf_size; > > + case XC_SAVE_ID_HVM_GENERATION_ID_ADDR: > + /* Skip padding 4 bytes then read the generation id buffer > location. */ > + if ( RDEXACT(fd, &buf->vm_gid_addr, sizeof(uint32_t)) || > + RDEXACT(fd, &buf->vm_gid_addr, sizeof(uint64_t)) ) > + { > + PERROR("error read the generation id buffer location"); > + return -1; > + } > + DPRINTF("read generation id buffer address"); > + return pagebuf_get_one(xch, ctx, buf, fd, dom); > + > default: > if ( (count > MAX_BATCH_SIZE) || (count < 0) ) { > ERROR("Max batch size exceeded (%d). Giving up.", > count); @@ -1248,7 +1260,8 @@ static int apply_batch(xc_interface > *xch int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t > dom, > unsigned int store_evtchn, unsigned long > *store_mfn, > unsigned int console_evtchn, unsigned long > *console_mfn, > - unsigned int hvm, unsigned int pae, int > superpages) > + unsigned int hvm, unsigned int pae, int > superpages, > + int no_increment_gid, unsigned long > *vm_gid_addr) > { > DECLARE_DOMCTL; > int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, > ext_vcpucontext = 0; @@ -1449,6 +1462,39 @@ int > xc_domain_restore(xc_interface *xch, > xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, > pagebuf.vm86_tss); > if ( pagebuf.console_pfn ) > console_pfn = pagebuf.console_pfn; > + if ( pagebuf.vm_gid_addr ) { > + if ( !no_increment_gid ) { > + unsigned int offset; > + unsigned char *buf; > + unsigned long long gid; > + > + /* > + * Map the VM generation id buffer and inject > the new value. > + */ > + > + pfn = pagebuf.vm_gid_addr >> PAGE_SHIFT; > + offset = pagebuf.vm_gid_addr & (PAGE_SIZE - 1); > + > + if ( (pfn >= dinfo->p2m_size) || > + (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB) > ) > + { > + ERROR("generation id buffer frame is bad"); > + goto out; > + } > + > + mfn = ctx->p2m[pfn]; > + buf = xc_map_foreign_range(xch, dom, PAGE_SIZE, > + PROT_READ | > PROT_WRITE, > + mfn); > + > + gid = *(unsigned long long *)(buf + offset); > + *(unsigned long long *)(buf + offset) = gid + > 1; > + > + munmap(buf, PAGE_SIZE); > + } > + > + *vm_gid_addr = pagebuf.vm_gid_addr; > + } > + > break; /* our work here is done */ > } > > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/libxc/xc_domain_save.c > --- a/tools/libxc/xc_domain_save.c Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxc/xc_domain_save.c Mon Dec 05 10:01:30 2011 +0000 > @@ -804,7 +804,8 @@ static int save_tsc_info(xc_interface *x > > int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, > uint32_t max_iters, > uint32_t max_factor, uint32_t flags, > - struct save_callbacks* callbacks, int hvm) > + struct save_callbacks* callbacks, int hvm, > + unsigned long vm_gid_addr) > { > xc_dominfo_t info; > DECLARE_DOMCTL; > @@ -1616,6 +1617,16 @@ int xc_domain_save(xc_interface *xch, in > uint64_t data; > } chunk = { 0, }; > > + chunk.id = XC_SAVE_ID_HVM_GENERATION_ID_ADDR; > + chunk.data = vm_gid_addr; > + > + if ( (chunk.data != 0) && > + wrexact(io_fd, &chunk, sizeof(chunk)) ) > + { > + PERROR("Error when writing the generation id buffer > location for guest"); > + goto out; > + } > + > chunk.id = XC_SAVE_ID_HVM_IDENT_PT; > chunk.data = 0; > xc_get_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, diff -r > a4d7c27ec1f1 -r 152a79fbe918 tools/libxc/xenguest.h > --- a/tools/libxc/xenguest.h Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxc/xenguest.h Mon Dec 05 10:01:30 2011 +0000 > @@ -58,7 +58,8 @@ struct save_callbacks { > */ > int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, > uint32_t max_iters, > uint32_t max_factor, uint32_t flags /* > XCFLAGS_xxx */, > - struct save_callbacks* callbacks, int hvm); > + struct save_callbacks* callbacks, int hvm, > + unsigned long vm_gid_addr); > > > /** > @@ -72,12 +73,15 @@ int xc_domain_save(xc_interface *xch, in > * @parm hvm non-zero if this is a HVM restore > * @parm pae non-zero if this HVM domain has PAE support enabled > * @parm superpages non-zero to allocate guest memory with > superpages > + * @parm gid the new generation id of the VM > + * @parm vm_gid_addr returned with the address of the generation id > + buffer > * @return 0 on success, -1 on failure > */ > int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, > unsigned int store_evtchn, unsigned long > *store_mfn, > unsigned int console_evtchn, unsigned long > *console_mfn, > - unsigned int hvm, unsigned int pae, int > superpages); > + unsigned int hvm, unsigned int pae, int > superpages, > + int increment_gid, unsigned long > *vm_gid_addr); > /** > * xc_domain_restore writes a file to disk that contains the device > * model saved state. > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/libxc/xg_save_restore.h > --- a/tools/libxc/xg_save_restore.h Fri Dec 02 13:51:17 2011 - > 0800 > +++ b/tools/libxc/xg_save_restore.h Mon Dec 05 10:01:30 2011 > +0000 > @@ -253,6 +253,7 @@ > #define XC_SAVE_ID_HVM_VIRIDIAN -11 > #define XC_SAVE_ID_COMPRESSED_DATA -12 /* Marker to indicate > arrival of compressed data */ > #define XC_SAVE_ID_ENABLE_COMPRESSION -13 /* Marker to enable > compression logic at receiver side */ > +#define XC_SAVE_ID_HVM_GENERATION_ID_ADDR -14 > > /* > ** We process save/restore/migrate in batches of pages; the below > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxl/libxl_create.c Mon Dec 05 10:01:30 2011 +0000 > @@ -101,6 +101,7 @@ int libxl_init_build_info(libxl_ctx *ctx > b_info->u.hvm.vpt_align = 1; > b_info->u.hvm.timer_mode = 1; > b_info->u.hvm.nested_hvm = 0; > + b_info->u.hvm.no_increment_gid = 0; > break; > case LIBXL_DOMAIN_TYPE_PV: > b_info->u.pv.slack_memkb = 8 * 1024; diff -r a4d7c27ec1f1 - > r 152a79fbe918 tools/libxl/libxl_dom.c > --- a/tools/libxl/libxl_dom.c Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxl/libxl_dom.c Mon Dec 05 10:01:30 2011 +0000 > @@ -125,7 +125,7 @@ int libxl__build_post(libxl__gc *gc, uin > if (info->cpuid != NULL) > libxl_cpuid_set(ctx, domid, info->cpuid); > > - ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, > sizeof(char *)); > + ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, > + sizeof(char *)); > ents[0] = "memory/static-max"; > ents[1] = libxl__sprintf(gc, "%d", info->max_memkb); > ents[2] = "memory/target"; > @@ -138,9 +138,11 @@ int libxl__build_post(libxl__gc *gc, uin > ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port); > ents[10] = "store/ring-ref"; > ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn); > + ents[12] = "data/generation-id"; > + ents[13] = libxl__sprintf(gc, "0x%lx", state->vm_gid_addr); > for (i = 0; i < info->max_vcpus; i++) { > - ents[12+(i*2)] = libxl__sprintf(gc, > "cpu/%d/availability", i); > - ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info- > >cur_vcpus & (1 << i))) > + ents[14+(i*2)] = libxl__sprintf(gc, > "cpu/%d/availability", i); > + ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info- > >cur_vcpus & > + (1 << i))) > ? "offline" : "online"; > } > > @@ -357,16 +359,19 @@ int libxl__domain_restore_common(libxl__ > /* read signature */ > int rc; > int hvm, pae, superpages; > + int no_increment_gid; > switch (info->type) { > case LIBXL_DOMAIN_TYPE_HVM: > hvm = 1; > superpages = 1; > pae = info->u.hvm.pae; > + no_increment_gid = info->u.hvm.no_increment_gid; > break; > case LIBXL_DOMAIN_TYPE_PV: > hvm = 0; > superpages = 0; > pae = 1; > + no_increment_gid = 0; > break; > default: > return ERROR_INVAL; > @@ -374,7 +379,7 @@ int libxl__domain_restore_common(libxl__ > rc = xc_domain_restore(ctx->xch, fd, domid, > state->store_port, &state->store_mfn, > state->console_port, &state- > >console_mfn, > - hvm, pae, superpages); > + hvm, pae, superpages, no_increment_gid, > + &state->vm_gid_addr); > if ( rc ) { > LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring > domain"); > return ERROR_FAIL; > @@ -540,12 +545,22 @@ int libxl__domain_suspend_common(libxl__ > struct save_callbacks callbacks; > struct suspendinfo si; > int hvm, rc = ERROR_FAIL; > + unsigned long vm_gid_addr; > > switch (type) { > - case LIBXL_DOMAIN_TYPE_HVM: > + case LIBXL_DOMAIN_TYPE_HVM: { > + char *path; > + char *addr; > + > + path = libxl__sprintf(gc, "%s/data/generation-id", > libxl__xs_get_dompath(gc, domid)); > + addr = libxl__xs_read(gc, XBT_NULL, path); > + > + vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; > hvm = 1; > break; > + } > case LIBXL_DOMAIN_TYPE_PV: > + vm_gid_addr = 0; > hvm = 0; > break; > default: > @@ -583,7 +598,8 @@ int libxl__domain_suspend_common(libxl__ > callbacks.switch_qemu_logdirty = > libxl__domain_suspend_common_switch_qemu_logdirty; > callbacks.data = &si; > > - rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, > &callbacks, hvm); > + rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, > &callbacks, > + hvm, vm_gid_addr); > if ( rc ) { > LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain: > %s", > si.guest_responded ? > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/libxl/libxl_internal.h > --- a/tools/libxl/libxl_internal.h Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxl/libxl_internal.h Mon Dec 05 10:01:30 2011 +0000 > @@ -199,6 +199,7 @@ typedef struct { > > uint32_t console_port; > unsigned long console_mfn; > + unsigned long vm_gid_addr; > } libxl__domain_build_state; > > _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid, diff -r > a4d7c27ec1f1 -r 152a79fbe918 tools/libxl/libxl_types.idl > --- a/tools/libxl/libxl_types.idl Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxl/libxl_types.idl Mon Dec 05 10:01:30 2011 +0000 > @@ -184,6 +184,7 @@ libxl_domain_build_info = Struct("domain > ("vpt_align", bool), > ("timer_mode", integer), > ("nested_hvm", bool), > + ("no_increment_gid", bool), > ])), > ("pv", Struct(None, [("kernel", > libxl_file_reference), > ("slack_memkb", uint32), diff > -r a4d7c27ec1f1 -r 152a79fbe918 tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/libxl/xl_cmdimpl.c Mon Dec 05 10:01:30 2011 +0000 > @@ -360,6 +360,7 @@ static void printf_info(int domid, > printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align); > printf("\t\t\t(timer_mode %d)\n", b_info- > >u.hvm.timer_mode); > printf("\t\t\t(nestedhvm %d)\n", b_info->u.hvm.nested_hvm); > + printf("\t\t\t(no_increment_gid %d)\n", > + b_info->u.hvm.no_increment_gid); > > printf("\t\t\t(device_model %s)\n", dm_info->device_model ? > : "default"); > printf("\t\t\t(videoram %d)\n", dm_info->videoram); @@ - > 1362,6 +1363,7 @@ struct domain_create { > const char *restore_file; > int migrate_fd; /* -1 means none */ > char **migration_domname_r; /* from malloc */ > + int no_increment_gid; > }; > > static int freemem(libxl_domain_build_info *b_info, > libxl_device_model_info *dm_info) @@ -1575,6 +1577,8 @@ static int > create_domain(struct domain_c > } > } > > + d_config.b_info.u.hvm.no_increment_gid = > + dom_info->no_increment_gid; > + > if (debug || dom_info->dryrun) > printf_info(-1, &d_config, &d_config.dm_info); > > @@ -2800,6 +2804,7 @@ static void migrate_receive(int debug, i > dom_info.restore_file = "incoming migration stream"; > dom_info.migrate_fd = 0; /* stdin */ > dom_info.migration_domname_r = &migration_domname; > + dom_info.no_increment_gid = 1; > > rc = create_domain(&dom_info); > if (rc < 0) { > diff -r a4d7c27ec1f1 -r 152a79fbe918 > tools/python/xen/lowlevel/checkpoint/libcheckpoint.c > --- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Fri > Dec 02 13:51:17 2011 -0800 > +++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Mon > Dec 05 10:01:30 2011 +0000 > @@ -175,6 +175,7 @@ int checkpoint_start(checkpoint_state* s { > int hvm, rc; > int flags = XCFLAGS_LIVE; > + unsigned long vm_gid_addr; > > if (!s->domid) { > s->errstr = "checkpoint state not opened"; @@ -185,16 > +186,27 @@ int checkpoint_start(checkpoint_state* s > > hvm = s->domtype > dt_pv; > if (hvm) { > + char path[128]; > + char *addr; > + > + sprintf(path, "/local/domain/%u/data/generation-id", s- > >domid); > + addr = xs_read(s->xsh, XBT_NULL, path, NULL); > + > + vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; > + free(addr); > + > flags |= XCFLAGS_HVM; > if (switch_qemu_logdirty(s, 1)) > return -1; > + } else { > + vm_gid_addr = 0; > } > if (remus_flags & CHECKPOINT_FLAGS_COMPRESSION) > flags |= XCFLAGS_CHECKPOINT_COMPRESS; > > callbacks->switch_qemu_logdirty = noop_switch_logdirty; > > - rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, > callbacks, hvm); > + rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, > callbacks, > + hvm, vm_gid_addr); > > if (hvm) > switch_qemu_logdirty(s, 0); > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/xcutils/xc_restore.c > --- a/tools/xcutils/xc_restore.c Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/xcutils/xc_restore.c Mon Dec 05 10:01:30 2011 +0000 > @@ -23,7 +23,8 @@ main(int argc, char **argv) > xc_interface *xch; > int io_fd, ret; > int superpages; > - unsigned long store_mfn, console_mfn; > + unsigned long store_mfn, console_mfn, vm_gid_addr; > + int no_increment_gid; > > if ( (argc != 8) && (argc != 9) ) > errx(1, "usage: %s iofd domid store_evtchn " > @@ -40,19 +41,25 @@ main(int argc, char **argv) > hvm = atoi(argv[5]); > pae = atoi(argv[6]); > apic = atoi(argv[7]); > - if ( argc == 9 ) > + if ( argc >= 9 ) > superpages = atoi(argv[8]); > else > superpages = !!hvm; > + if ( argc >= 10 ) > + no_increment_gid = !atoi(argv[9]); > + else > + no_increment_gid = 0; > > ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, > &store_mfn, > - console_evtchn, &console_mfn, hvm, pae, > superpages); > + console_evtchn, &console_mfn, hvm, pae, > superpages, > + no_increment_gid, &vm_gid_addr); > > if ( ret == 0 ) > { > printf("store-mfn %li\n", store_mfn); > if ( !hvm ) > printf("console-mfn %li\n", console_mfn); > + printf("vm-gid-addr %lx\n", vm_gid_addr); > fflush(stdout); > } > > diff -r a4d7c27ec1f1 -r 152a79fbe918 tools/xcutils/xc_save.c > --- a/tools/xcutils/xc_save.c Fri Dec 02 13:51:17 2011 -0800 > +++ b/tools/xcutils/xc_save.c Mon Dec 05 10:01:30 2011 +0000 > @@ -169,6 +169,10 @@ main(int argc, char **argv) > unsigned int maxit, max_f; > int io_fd, ret, port; > struct save_callbacks callbacks; > + char path[128]; > + struct xs_handle *xs; > + char *addr; > + unsigned long vm_gid_addr; > > if (argc != 6) > errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]); > @@ -207,8 +211,21 @@ main(int argc, char **argv) > memset(&callbacks, 0, sizeof(callbacks)); > callbacks.suspend = suspend; > callbacks.switch_qemu_logdirty = switch_qemu_logdirty; > + > + sprintf(path, "/local/domain/%d/data/generation-id", si.domid); > + > + if ((xs = xs_daemon_open()) == NULL) > + errx(1, "Couldn't contact xenstore"); > + > + addr = xs_read(xs, XBT_NULL, path, NULL); > + > + xs_daemon_close(xs); > + > + vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; > + free(addr); > + > ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, > si.flags, > - &callbacks, !!(si.flags & XCFLAGS_HVM)); > + &callbacks, !!(si.flags & XCFLAGS_HVM), > + vm_gid_addr); > > if (si.suspend_evtchn > 0) > xc_suspend_evtchn_release(si.xch, si.xce, si.domid, > si.suspend_evtchn); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |