Paul Durrant
2011-Dec-16 14:45 UTC
[PATCH 0 of 4] Support for VM generation ID save/restore and migrate
This patch series adds support for preservation of the VM generation ID buffer address in xenstore across save/restore and migrate, and also code to increment the value in all cases except for migration. Patch 1 modifies the guest ro and rw node creation to an open coding style and cleans up some extraneous node creation. Patch 2 modifies creation of the hvmloader key in xenstore and adds creation of a new read/write hvmloader/generation-id-addr key. Patch 3 changes hvmloader to use the new key (as opposed to the old data/generation-id key). Note that it is safe to apply this patch independently of the others but it logically belongs at this position in the series. Patch 4 adds the infrastructure to save and restore the VM generation ID address in xenstore and the code to increment the value.
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324044735 0 # Node ID a8c26cdf079cd6e3aa934e5011e554e36f33fce3 # Parent 03138a08366b895d79e143119d4c9c72833cdbcd Open code rw and ro path creation. Use a new libxl__xs_mkdir() to do this and also clean up extraneous path creation while in the neighbourhood. Checking ''xenstore-ls -fp'' output before and after shows that, as well as the disappearance of error, drivers, messages and domid, the following perms change is also present: -device/suspend = "" (ndomU) +device/suspend = "" (n0,rdomU) I believe the new perms are more desirable than the old ones. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r 03138a08366b -r a8c26cdf079c tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Dec 09 16:19:36 2011 +0000 +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:12:15 2011 +0000 @@ -320,11 +320,8 @@ int libxl__domain_make(libxl__gc *gc, li * on exit (even error exit), domid may be valid and refer to a domain */ { libxl_ctx *ctx = libxl__gc_owner(gc); - int flags, ret, i, rc; + int flags, ret, rc; char *uuid_string; - char *rw_paths[] = { "control/shutdown", "device", "device/suspend/event-channel" , "data"}; - char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", - "control", "attr", "messages" }; char *dom_path, *vm_path, *libxl_path; struct xs_permissions roperm[2]; struct xs_permissions rwperm[1]; @@ -384,6 +381,7 @@ int libxl__domain_make(libxl__gc *gc, li rc = ERROR_FAIL; goto out; } + noperm[0].id = 0; noperm[0].perms = XS_PERM_NONE; @@ -391,6 +389,7 @@ int libxl__domain_make(libxl__gc *gc, li roperm[0].perms = XS_PERM_NONE; roperm[1].id = *domid; roperm[1].perms = XS_PERM_READ; + rwperm[0].id = *domid; rwperm[0].perms = XS_PERM_NONE; @@ -398,32 +397,42 @@ retry_transaction: t = xs_transaction_start(ctx->xsh); xs_rm(ctx->xsh, t, dom_path); - xs_mkdir(ctx->xsh, t, dom_path); - xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, dom_path, roperm, ARRAY_SIZE(roperm)); + xs_rm(ctx->xsh, t, vm_path); - xs_mkdir(ctx->xsh, t, vm_path); - xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, vm_path, roperm, ARRAY_SIZE(roperm)); xs_rm(ctx->xsh, t, libxl_path); - xs_mkdir(ctx->xsh, t, libxl_path); - xs_set_permissions(ctx->xsh, t, libxl_path, noperm, ARRAY_SIZE(noperm)); + libxl__xs_mkdir(gc, t, libxl_path, noperm, ARRAY_SIZE(noperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl__domain_rename(gc, *domid, 0, info->name, t); if (rc) goto out; - for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { - char *path = libxl__sprintf(gc, "%s/%s", dom_path, rw_paths[i]); - xs_mkdir(ctx->xsh, t, path); - xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); - } - for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { - char *path = libxl__sprintf(gc, "%s/%s", dom_path, ro_paths[i]); - xs_mkdir(ctx->xsh, t, path); - xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - } + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/cpu", dom_path), + roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/memory", dom_path), + roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/device", dom_path), + roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/control", dom_path), + roperm, ARRAY_SIZE(roperm)); + + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/control/shutdown", dom_path), + rwperm, ARRAY_SIZE(rwperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/device/suspend/event-channel", dom_path), + rwperm, ARRAY_SIZE(rwperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/data", dom_path), + rwperm, ARRAY_SIZE(rwperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), info->name, strlen(info->name)); diff -r 03138a08366b -r a8c26cdf079c tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Dec 09 16:19:36 2011 +0000 +++ b/tools/libxl/libxl_internal.h Fri Dec 16 14:12:15 2011 +0000 @@ -204,6 +204,9 @@ _hidden char *libxl__xs_read(libxl__gc * _hidden char **libxl__xs_directory(libxl__gc *gc, xs_transaction_t t, const char *path, unsigned int *nb); /* On error: returns NULL, sets errno (no logging) */ +_hidden bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, + const char *path, struct xs_permissions *perms, + unsigned int num_perms); _hidden char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid); diff -r 03138a08366b -r a8c26cdf079c tools/libxl/libxl_xshelp.c --- a/tools/libxl/libxl_xshelp.c Fri Dec 09 16:19:36 2011 +0000 +++ b/tools/libxl/libxl_xshelp.c Fri Dec 16 14:12:15 2011 +0000 @@ -122,6 +122,16 @@ char **libxl__xs_directory(libxl__gc *gc return ret; } +bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, + const char *path, struct xs_permissions *perms, + unsigned int num_perms) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + if (!xs_mkdir(ctx->xsh, t, path)) + return false; + return xs_set_permissions(ctx->xsh, t, path, perms, num_perms); +} + char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid) { libxl_ctx *ctx = libxl__gc_owner(gc);
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324046220 0 # Node ID 83dad81a557e4499827830f693139f27986f4139 # Parent a8c26cdf079cd6e3aa934e5011e554e36f33fce3 Add hvm specific ro and rw nodes. The hvmloader node was created by libxl__create_device_model() but it needs to be moved earlier so that it can parent the new rw generation-id-address node. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r a8c26cdf079c -r 83dad81a557e tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Dec 16 14:12:15 2011 +0000 +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:37:00 2011 +0000 @@ -423,6 +423,10 @@ retry_transaction: libxl__xs_mkdir(gc, t, libxl__sprintf(gc, "%s/control", dom_path), roperm, ARRAY_SIZE(roperm)); + if (info->type == LIBXL_DOMAIN_TYPE_HVM) + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/hvmloader", dom_path), + roperm, ARRAY_SIZE(roperm)); libxl__xs_mkdir(gc, t, libxl__sprintf(gc, "%s/control/shutdown", dom_path), @@ -433,6 +437,10 @@ retry_transaction: libxl__xs_mkdir(gc, t, libxl__sprintf(gc, "%s/data", dom_path), rwperm, ARRAY_SIZE(rwperm)); + if (info->type == LIBXL_DOMAIN_TYPE_HVM) + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/hvmloader/generation-id-address", dom_path), + rwperm, ARRAY_SIZE(rwperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), info->name, strlen(info->name)); diff -r a8c26cdf079c -r 83dad81a557e tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c Fri Dec 16 14:12:15 2011 +0000 +++ b/tools/libxl/libxl_dm.c Fri Dec 16 14:37:00 2011 +0000 @@ -821,10 +821,10 @@ int libxl__create_device_model(libxl__gc goto out; } - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); - xs_mkdir(ctx->xsh, XBT_NULL, path); - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), + path = xs_get_domain_path(ctx->xsh, info->domid); + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/hvmloader/bios", path), "%s", libxl__domain_bios(gc, info)); + free(path); path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", info->domid); xs_mkdir(ctx->xsh, XBT_NULL, path);
Paul Durrant
2011-Dec-16 14:45 UTC
[PATCH 3 of 4] Re-name xenstore key used to save VM generation ID buffer address
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324046228 0 # Node ID bd8e9eb71611c08850eb5843e915f71748037457 # Parent 83dad81a557e4499827830f693139f27986f4139 Re-name xenstore key used to save VM generation ID buffer address. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r 83dad81a557e -r bd8e9eb71611 tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Fri Dec 16 14:37:00 2011 +0000 +++ b/tools/firmware/hvmloader/acpi/build.c Fri Dec 16 14:37:08 2011 +0000 @@ -309,7 +309,7 @@ unsigned long new_vm_gid(void) if ( snprintf(addr, sizeof(addr), "0x%lx", virt_to_phys(buf)) >= sizeof(addr) ) return 0; - xenstore_write("data/generation-id", addr); + xenstore_write("hvmloader/generation-id-address", addr); gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0); *(uint64_t *)buf = gid;
Paul Durrant
2011-Dec-16 14:45 UTC
[PATCH 4 of 4] VM generation ID save/restore and migrate
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324046228 0 # Node ID 5df9a24e0078e96ee5d45853f75b99db32e07ebe # Parent bd8e9eb71611c08850eb5843e915f71748037457 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(). Note that the changes to xc_save.c and xc_restore.c are merely sufficient for them to build. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxc/ia64/xc_ia64_linux_restore.c --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Fri Dec 16 14:37:08 2011 +0000 @@ -548,7 +548,9 @@ 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_incr_generationid, + unsigned long *vm_generationid_addr) { DECLARE_DOMCTL; int rc = 1; diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxc/ia64/xc_ia64_linux_save.c --- a/tools/libxc/ia64/xc_ia64_linux_save.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxc/ia64/xc_ia64_linux_save.c Fri Dec 16 14:37:08 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_generationid_addr) { DECLARE_DOMCTL; xc_dominfo_t info; diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxc/xc_domain_restore.c --- a/tools/libxc/xc_domain_restore.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxc/xc_domain_restore.c Fri Dec 16 14:37:08 2011 +0000 @@ -681,6 +681,7 @@ typedef struct { uint64_t console_pfn; uint64_t acpi_ioport_location; uint64_t viridian; + uint64_t vm_generationid_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_generationid_addr, sizeof(uint32_t)) || + RDEXACT(fd, &buf->vm_generationid_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,9 @@ 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_incr_generationid, + unsigned long *vm_generationid_addr) { DECLARE_DOMCTL; int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0; @@ -1449,6 +1463,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_generationid_addr ) { + if ( !no_incr_generationid ) { + unsigned int offset; + unsigned char *buf; + unsigned long long generationid; + + /* + * Map the VM generation id buffer and inject the new value. + */ + + pfn = pagebuf.vm_generationid_addr >> PAGE_SHIFT; + offset = pagebuf.vm_generationid_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); + + generationid = *(unsigned long long *)(buf + offset); + *(unsigned long long *)(buf + offset) = generationid + 1; + + munmap(buf, PAGE_SIZE); + } + + *vm_generationid_addr = pagebuf.vm_generationid_addr; + } + break; /* our work here is done */ } diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxc/xc_domain_save.c --- a/tools/libxc/xc_domain_save.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxc/xc_domain_save.c Fri Dec 16 14:37:08 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_generationid_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_generationid_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 bd8e9eb71611 -r 5df9a24e0078 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxc/xenguest.h Fri Dec 16 14:37:08 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_generationid_addr); /** @@ -72,12 +73,16 @@ 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 no_incr_generationid non-zero if generation id is NOT to be incremented + * @parm vm_generationid_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 no_incr_generationid, + unsigned long *vm_generationid_addr); /** * xc_domain_restore writes a file to disk that contains the device * model saved state. diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxc/xg_save_restore.h --- a/tools/libxc/xg_save_restore.h Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxc/xg_save_restore.h Fri Dec 16 14:37:08 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 bd8e9eb71611 -r 5df9a24e0078 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:37:08 2011 +0000 @@ -99,6 +99,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_incr_generationid = 0; break; case LIBXL_DOMAIN_TYPE_PV: b_info->u.pv.slack_memkb = 8 * 1024; diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxl/libxl_dom.c Fri Dec 16 14:37:08 2011 +0000 @@ -106,6 +106,7 @@ int libxl__build_pre(libxl__gc *gc, uint state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); + state->vm_generationid_addr = 0; return 0; } @@ -117,7 +118,7 @@ int libxl__build_post(libxl__gc *gc, uin libxl_ctx *ctx = libxl__gc_owner(gc); char *dom_path, *vm_path; xs_transaction_t t; - char **ents; + char **ents, **hvm_ents; int i; libxl_cpuid_apply_policy(ctx, domid); @@ -143,6 +144,13 @@ int libxl__build_post(libxl__gc *gc, uin ? "offline" : "online"; } + hvm_ents = NULL; + if (info->type == LIBXL_DOMAIN_TYPE_HVM) { + hvm_ents = libxl__calloc(gc, 3, sizeof(char *)); + hvm_ents[0] = "hvmloader/generation-id-address"; + hvm_ents[1] = libxl__sprintf(gc, "0x%lx", state->vm_generationid_addr); + } + dom_path = libxl__xs_get_dompath(gc, domid); if (!dom_path) { return ERROR_FAIL; @@ -153,6 +161,9 @@ retry_transaction: t = xs_transaction_start(ctx->xsh); libxl__xs_writev(gc, t, dom_path, ents); + if (info->type == LIBXL_DOMAIN_TYPE_HVM) + libxl__xs_writev(gc, t, dom_path, hvm_ents); + libxl__xs_writev(gc, t, dom_path, local_ents); libxl__xs_writev(gc, t, vm_path, vms_ents); @@ -356,16 +367,19 @@ int libxl__domain_restore_common(libxl__ /* read signature */ int rc; int hvm, pae, superpages; + int no_incr_generationid; switch (info->type) { case LIBXL_DOMAIN_TYPE_HVM: hvm = 1; superpages = 1; pae = info->u.hvm.pae; + no_incr_generationid = info->u.hvm.no_incr_generationid; break; case LIBXL_DOMAIN_TYPE_PV: hvm = 0; superpages = 0; pae = 1; + no_incr_generationid = 0; break; default: return ERROR_INVAL; @@ -373,7 +387,8 @@ 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_incr_generationid, + &state->vm_generationid_addr); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain"); return ERROR_FAIL; @@ -539,12 +554,23 @@ int libxl__domain_suspend_common(libxl__ struct save_callbacks callbacks; struct suspendinfo si; int hvm, rc = ERROR_FAIL; + unsigned long vm_generationid_addr; switch (type) { - case LIBXL_DOMAIN_TYPE_HVM: + case LIBXL_DOMAIN_TYPE_HVM: { + char *path; + char *addr; + + path = libxl__sprintf(gc, "%s/hvmloader/generation-id-address", + libxl__xs_get_dompath(gc, domid)); + addr = libxl__xs_read(gc, XBT_NULL, path); + + vm_generationid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; hvm = 1; break; + } case LIBXL_DOMAIN_TYPE_PV: + vm_generationid_addr = 0; hvm = 0; break; default: @@ -582,7 +608,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_generationid_addr); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain: %s", si.guest_responded ? diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxl/libxl_internal.h Fri Dec 16 14:37:08 2011 +0000 @@ -221,6 +221,7 @@ typedef struct { uint32_t console_port; unsigned long console_mfn; + unsigned long vm_generationid_addr; } libxl__domain_build_state; _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid, diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxl/libxl_types.idl Fri Dec 16 14:37:08 2011 +0000 @@ -184,6 +184,7 @@ libxl_domain_build_info = Struct("domain ("vpt_align", bool), ("timer_mode", integer), ("nested_hvm", bool), + ("no_incr_generationid", bool), ])), ("pv", Struct(None, [("kernel", libxl_file_reference), ("slack_memkb", uint32), diff -r bd8e9eb71611 -r 5df9a24e0078 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/libxl/xl_cmdimpl.c Fri Dec 16 14:37:08 2011 +0000 @@ -360,6 +360,8 @@ 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_incr_generationid %d)\n", + b_info->u.hvm.no_incr_generationid); 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 +1364,7 @@ struct domain_create { const char *restore_file; int migrate_fd; /* -1 means none */ char **migration_domname_r; /* from malloc */ + int no_incr_generationid; }; static int freemem(libxl_domain_build_info *b_info, libxl_device_model_info *dm_info) @@ -1575,6 +1578,8 @@ static int create_domain(struct domain_c } } + d_config.b_info.u.hvm.no_incr_generationid = dom_info->no_incr_generationid; + if (debug || dom_info->dryrun) printf_info(-1, &d_config, &d_config.dm_info); @@ -2800,6 +2805,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_incr_generationid = 1; rc = create_domain(&dom_info); if (rc < 0) { diff -r bd8e9eb71611 -r 5df9a24e0078 tools/python/xen/lowlevel/checkpoint/libcheckpoint.c --- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Fri Dec 16 14:37:08 2011 +0000 @@ -175,6 +175,7 @@ int checkpoint_start(checkpoint_state* s { int hvm, rc; int flags = XCFLAGS_LIVE; + unsigned long vm_generationid_addr; if (!s->domid) { s->errstr = "checkpoint state not opened"; @@ -185,16 +186,28 @@ int checkpoint_start(checkpoint_state* s hvm = s->domtype > dt_pv; if (hvm) { + char path[128]; + char *addr; + + sprintf(path, "/local/domain/%u/hvmloader/generation-id-address", s->domid); + addr = xs_read(s->xsh, XBT_NULL, path, NULL); + + vm_generationid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; + free(addr); + flags |= XCFLAGS_HVM; if (switch_qemu_logdirty(s, 1)) return -1; + } else { + vm_generationid_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_generationid_addr); if (hvm) switch_qemu_logdirty(s, 0); diff -r bd8e9eb71611 -r 5df9a24e0078 tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/xcutils/xc_restore.c Fri Dec 16 14:37:08 2011 +0000 @@ -46,7 +46,8 @@ main(int argc, char **argv) superpages = !!hvm; 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, + 0, NULL); if ( ret == 0 ) { diff -r bd8e9eb71611 -r 5df9a24e0078 tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Fri Dec 16 14:37:08 2011 +0000 +++ b/tools/xcutils/xc_save.c Fri Dec 16 14:37:08 2011 +0000 @@ -208,7 +208,7 @@ main(int argc, char **argv) callbacks.suspend = suspend; callbacks.switch_qemu_logdirty = switch_qemu_logdirty; 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), 0); if (si.suspend_evtchn > 0) xc_suspend_evtchn_release(si.xch, si.xce, si.domid, si.suspend_evtchn);
Damn. This is a stale version of this patch. I''ll re-send. Paul> -----Original Message----- > From: Paul Durrant [mailto:paul.durrant@citrix.com] > Sent: 16 December 2011 14:45 > To: xen-devel@lists.xensource.com > Cc: Paul Durrant > Subject: [PATCH 1 of 4] Open code rw and ro path creation > > # HG changeset patch > # User Paul Durrant <paul.durrant@citrix.com> # Date 1324044735 0 # > Node ID a8c26cdf079cd6e3aa934e5011e554e36f33fce3 > # Parent 03138a08366b895d79e143119d4c9c72833cdbcd > Open code rw and ro path creation. > > Use a new libxl__xs_mkdir() to do this and also clean up extraneous > path creation while in the neighbourhood. Checking ''xenstore-ls -fp'' > output before and after shows that, as well as the disappearance of > error, drivers, messages and domid, the following perms change is > also present: > > -device/suspend = "" (ndomU) > +device/suspend = "" (n0,rdomU) > > I believe the new perms are more desirable than the old ones. > > Signed-off-by: Paul Durrant <paul.durrant@citrix.com> > > diff -r 03138a08366b -r a8c26cdf079c tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Fri Dec 09 16:19:36 2011 +0000 > +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:12:15 2011 +0000 > @@ -320,11 +320,8 @@ int libxl__domain_make(libxl__gc *gc, li > * on exit (even error exit), domid may be valid and refer to a > domain */ { > libxl_ctx *ctx = libxl__gc_owner(gc); > - int flags, ret, i, rc; > + int flags, ret, rc; > char *uuid_string; > - char *rw_paths[] = { "control/shutdown", "device", > "device/suspend/event-channel" , "data"}; > - char *ro_paths[] = { "cpu", "memory", "device", "error", > "drivers", > - "control", "attr", "messages" }; > char *dom_path, *vm_path, *libxl_path; > struct xs_permissions roperm[2]; > struct xs_permissions rwperm[1]; > @@ -384,6 +381,7 @@ int libxl__domain_make(libxl__gc *gc, li > rc = ERROR_FAIL; > goto out; > } > + > noperm[0].id = 0; > noperm[0].perms = XS_PERM_NONE; > > @@ -391,6 +389,7 @@ int libxl__domain_make(libxl__gc *gc, li > roperm[0].perms = XS_PERM_NONE; > roperm[1].id = *domid; > roperm[1].perms = XS_PERM_READ; > + > rwperm[0].id = *domid; > rwperm[0].perms = XS_PERM_NONE; > > @@ -398,32 +397,42 @@ retry_transaction: > t = xs_transaction_start(ctx->xsh); > > xs_rm(ctx->xsh, t, dom_path); > - xs_mkdir(ctx->xsh, t, dom_path); > - xs_set_permissions(ctx->xsh, t, dom_path, roperm, > ARRAY_SIZE(roperm)); > + libxl__xs_mkdir(gc, t, dom_path, roperm, ARRAY_SIZE(roperm)); > + > > xs_rm(ctx->xsh, t, vm_path); > - xs_mkdir(ctx->xsh, t, vm_path); > - xs_set_permissions(ctx->xsh, t, vm_path, roperm, > ARRAY_SIZE(roperm)); > + libxl__xs_mkdir(gc, t, vm_path, roperm, ARRAY_SIZE(roperm)); > > xs_rm(ctx->xsh, t, libxl_path); > - xs_mkdir(ctx->xsh, t, libxl_path); > - xs_set_permissions(ctx->xsh, t, libxl_path, noperm, > ARRAY_SIZE(noperm)); > + libxl__xs_mkdir(gc, t, libxl_path, noperm, ARRAY_SIZE(noperm)); > > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path), > vm_path, strlen(vm_path)); > rc = libxl__domain_rename(gc, *domid, 0, info->name, t); > if (rc) > goto out; > > - for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { > - char *path = libxl__sprintf(gc, "%s/%s", dom_path, > rw_paths[i]); > - xs_mkdir(ctx->xsh, t, path); > - xs_set_permissions(ctx->xsh, t, path, rwperm, > ARRAY_SIZE(rwperm)); > - } > - for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { > - char *path = libxl__sprintf(gc, "%s/%s", dom_path, > ro_paths[i]); > - xs_mkdir(ctx->xsh, t, path); > - xs_set_permissions(ctx->xsh, t, path, roperm, > ARRAY_SIZE(roperm)); > - } > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/cpu", dom_path), > + roperm, ARRAY_SIZE(roperm)); > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/memory", dom_path), > + roperm, ARRAY_SIZE(roperm)); > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/device", dom_path), > + roperm, ARRAY_SIZE(roperm)); > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/control", dom_path), > + roperm, ARRAY_SIZE(roperm)); > + > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/control/shutdown", > dom_path), > + rwperm, ARRAY_SIZE(rwperm)); > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/device/suspend/event- > channel", dom_path), > + rwperm, ARRAY_SIZE(rwperm)); > + libxl__xs_mkdir(gc, t, > + libxl__sprintf(gc, "%s/data", dom_path), > + rwperm, ARRAY_SIZE(rwperm)); > > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), > uuid_string, strlen(uuid_string)); > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), > info->name, strlen(info->name)); diff -r 03138a08366b -r > a8c26cdf079c tools/libxl/libxl_internal.h > --- a/tools/libxl/libxl_internal.h Fri Dec 09 16:19:36 2011 +0000 > +++ b/tools/libxl/libxl_internal.h Fri Dec 16 14:12:15 2011 +0000 > @@ -204,6 +204,9 @@ _hidden char *libxl__xs_read(libxl__gc * > _hidden char **libxl__xs_directory(libxl__gc *gc, xs_transaction_t > t, > const char *path, unsigned int > *nb); > /* On error: returns NULL, sets errno (no logging) */ > +_hidden bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, > + const char *path, struct > xs_permissions *perms, > + unsigned int num_perms); > > _hidden char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid); > > diff -r 03138a08366b -r a8c26cdf079c tools/libxl/libxl_xshelp.c > --- a/tools/libxl/libxl_xshelp.c Fri Dec 09 16:19:36 2011 +0000 > +++ b/tools/libxl/libxl_xshelp.c Fri Dec 16 14:12:15 2011 +0000 > @@ -122,6 +122,16 @@ char **libxl__xs_directory(libxl__gc *gc > return ret; > } > > +bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, > + const char *path, struct xs_permissions > *perms, > + unsigned int num_perms) > +{ > + libxl_ctx *ctx = libxl__gc_owner(gc); > + if (!xs_mkdir(ctx->xsh, t, path)) > + return false; > + return xs_set_permissions(ctx->xsh, t, path, perms, num_perms); > } > + > char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid) { > libxl_ctx *ctx = libxl__gc_owner(gc);
Paul Durrant
2011-Dec-16 14:54 UTC
[PATCH 0 of 4] Support for VM generation ID save/restore and migrate
This patch series adds support for preservation of the VM generation ID buffer address in xenstore across save/restore and migrate, and also code to increment the value in all cases except for migration. Patch 1 modifies the guest ro and rw node creation to an open coding style and cleans up some extraneous node creation. Patch 2 modifies creation of the hvmloader key in xenstore and adds creation of a new read/write hvmloader/generation-id-addr key. Patch 3 changes hvmloader to use the new key (as opposed to the old data/generation-id key). Note that it is safe to apply this patch independently of the others but it logically belongs at this position in the series. Patch 4 adds the infrastructure to save and restore the VM generation ID address in xenstore and the code to increment the value.
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324047253 0 # Node ID 89d9abeb76c72c634a35ad32c983f2811b270ec9 # Parent 03138a08366b895d79e143119d4c9c72833cdbcd Open code rw and ro node creation. Use a new libxl__xs_mkdir() to do this and also clean up extraneous node creation while in the neighbourhood. Checking ''xenstore-ls -fp'' output before and after shows that, as well as the disappearance of error, drivers, messages and domid, the following perms change is also present: -device/suspend = "" (ndomU) +device/suspend = "" (n0,rdomU) I believe the new perms are more desirable than the old ones. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r 03138a08366b -r 89d9abeb76c7 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Dec 09 16:19:36 2011 +0000 +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:54:13 2011 +0000 @@ -320,11 +320,8 @@ int libxl__domain_make(libxl__gc *gc, li * on exit (even error exit), domid may be valid and refer to a domain */ { libxl_ctx *ctx = libxl__gc_owner(gc); - int flags, ret, i, rc; + int flags, ret, rc; char *uuid_string; - char *rw_paths[] = { "control/shutdown", "device", "device/suspend/event-channel" , "data"}; - char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", - "control", "attr", "messages" }; char *dom_path, *vm_path, *libxl_path; struct xs_permissions roperm[2]; struct xs_permissions rwperm[1]; @@ -384,6 +381,7 @@ int libxl__domain_make(libxl__gc *gc, li rc = ERROR_FAIL; goto out; } + noperm[0].id = 0; noperm[0].perms = XS_PERM_NONE; @@ -391,6 +389,7 @@ int libxl__domain_make(libxl__gc *gc, li roperm[0].perms = XS_PERM_NONE; roperm[1].id = *domid; roperm[1].perms = XS_PERM_READ; + rwperm[0].id = *domid; rwperm[0].perms = XS_PERM_NONE; @@ -398,32 +397,42 @@ retry_transaction: t = xs_transaction_start(ctx->xsh); xs_rm(ctx->xsh, t, dom_path); - xs_mkdir(ctx->xsh, t, dom_path); - xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, dom_path, roperm, ARRAY_SIZE(roperm)); + xs_rm(ctx->xsh, t, vm_path); - xs_mkdir(ctx->xsh, t, vm_path); - xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, vm_path, roperm, ARRAY_SIZE(roperm)); xs_rm(ctx->xsh, t, libxl_path); - xs_mkdir(ctx->xsh, t, libxl_path); - xs_set_permissions(ctx->xsh, t, libxl_path, noperm, ARRAY_SIZE(noperm)); + libxl__xs_mkdir(gc, t, libxl_path, noperm, ARRAY_SIZE(noperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); rc = libxl__domain_rename(gc, *domid, 0, info->name, t); if (rc) goto out; - for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { - char *path = libxl__sprintf(gc, "%s/%s", dom_path, rw_paths[i]); - xs_mkdir(ctx->xsh, t, path); - xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); - } - for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { - char *path = libxl__sprintf(gc, "%s/%s", dom_path, ro_paths[i]); - xs_mkdir(ctx->xsh, t, path); - xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - } + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/cpu", dom_path), + roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/memory", dom_path), + roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/device", dom_path), + roperm, ARRAY_SIZE(roperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/control", dom_path), + roperm, ARRAY_SIZE(roperm)); + + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/control/shutdown", dom_path), + rwperm, ARRAY_SIZE(rwperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/device/suspend/event-channel", dom_path), + rwperm, ARRAY_SIZE(rwperm)); + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/data", dom_path), + rwperm, ARRAY_SIZE(rwperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), info->name, strlen(info->name)); diff -r 03138a08366b -r 89d9abeb76c7 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Dec 09 16:19:36 2011 +0000 +++ b/tools/libxl/libxl_internal.h Fri Dec 16 14:54:13 2011 +0000 @@ -204,6 +204,9 @@ _hidden char *libxl__xs_read(libxl__gc * _hidden char **libxl__xs_directory(libxl__gc *gc, xs_transaction_t t, const char *path, unsigned int *nb); /* On error: returns NULL, sets errno (no logging) */ +_hidden bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, + const char *path, struct xs_permissions *perms, + unsigned int num_perms); _hidden char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid); diff -r 03138a08366b -r 89d9abeb76c7 tools/libxl/libxl_xshelp.c --- a/tools/libxl/libxl_xshelp.c Fri Dec 09 16:19:36 2011 +0000 +++ b/tools/libxl/libxl_xshelp.c Fri Dec 16 14:54:13 2011 +0000 @@ -122,6 +122,16 @@ char **libxl__xs_directory(libxl__gc *gc return ret; } +bool libxl__xs_mkdir(libxl__gc *gc, xs_transaction_t t, + const char *path, struct xs_permissions *perms, + unsigned int num_perms) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + if (!xs_mkdir(ctx->xsh, t, path)) + return false; + return xs_set_permissions(ctx->xsh, t, path, perms, num_perms); +} + char *libxl__xs_libxl_path(libxl__gc *gc, uint32_t domid) { libxl_ctx *ctx = libxl__gc_owner(gc);
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324047253 0 # Node ID 67797c4782d97efa1d9c19f8d13636d6f4730a3b # Parent 89d9abeb76c72c634a35ad32c983f2811b270ec9 Add hvm specific ro and rw nodes. The hvmloader node was created by libxl__create_device_model() but it needs to be moved earlier so that it can parent the new rw generation-id-address node. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r 89d9abeb76c7 -r 67797c4782d9 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:54:13 2011 +0000 @@ -423,6 +423,10 @@ retry_transaction: libxl__xs_mkdir(gc, t, libxl__sprintf(gc, "%s/control", dom_path), roperm, ARRAY_SIZE(roperm)); + if (info->type == LIBXL_DOMAIN_TYPE_HVM) + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/hvmloader", dom_path), + roperm, ARRAY_SIZE(roperm)); libxl__xs_mkdir(gc, t, libxl__sprintf(gc, "%s/control/shutdown", dom_path), @@ -433,6 +437,10 @@ retry_transaction: libxl__xs_mkdir(gc, t, libxl__sprintf(gc, "%s/data", dom_path), rwperm, ARRAY_SIZE(rwperm)); + if (info->type == LIBXL_DOMAIN_TYPE_HVM) + libxl__xs_mkdir(gc, t, + libxl__sprintf(gc, "%s/hvmloader/generation-id-address", dom_path), + rwperm, ARRAY_SIZE(rwperm)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), info->name, strlen(info->name)); diff -r 89d9abeb76c7 -r 67797c4782d9 tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/libxl_dm.c Fri Dec 16 14:54:13 2011 +0000 @@ -821,10 +821,10 @@ int libxl__create_device_model(libxl__gc goto out; } - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); - xs_mkdir(ctx->xsh, XBT_NULL, path); - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), + path = xs_get_domain_path(ctx->xsh, info->domid); + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/hvmloader/bios", path), "%s", libxl__domain_bios(gc, info)); + free(path); path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", info->domid); xs_mkdir(ctx->xsh, XBT_NULL, path);
Paul Durrant
2011-Dec-16 14:54 UTC
[PATCH 3 of 4] Re-name xenstore key used to save VM generation ID buffer address
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324047253 0 # Node ID fa0f840c516b6d6db7f9c8903e06335c1cb87f44 # Parent 67797c4782d97efa1d9c19f8d13636d6f4730a3b Re-name xenstore key used to save VM generation ID buffer address. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r 67797c4782d9 -r fa0f840c516b tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/firmware/hvmloader/acpi/build.c Fri Dec 16 14:54:13 2011 +0000 @@ -309,7 +309,7 @@ unsigned long new_vm_gid(void) if ( snprintf(addr, sizeof(addr), "0x%lx", virt_to_phys(buf)) >= sizeof(addr) ) return 0; - xenstore_write("data/generation-id", addr); + xenstore_write("hvmloader/generation-id-address", addr); gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0); *(uint64_t *)buf = gid;
Paul Durrant
2011-Dec-16 14:54 UTC
[PATCH 4 of 4] VM generation ID save/restore and migrate
# HG changeset patch # User Paul Durrant <paul.durrant@citrix.com> # Date 1324047254 0 # Node ID 2ec1d2a1372cd84d1fa636f54aeedaed57d84791 # Parent fa0f840c516b6d6db7f9c8903e06335c1cb87f44 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(). Note that the changes to xc_save.c and xc_restore.c are merely sufficient for them to build. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxc/ia64/xc_ia64_linux_restore.c --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Fri Dec 16 14:54:14 2011 +0000 @@ -548,7 +548,9 @@ 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_incr_generationid, + unsigned long *vm_generationid_addr) { DECLARE_DOMCTL; int rc = 1; diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxc/ia64/xc_ia64_linux_save.c --- a/tools/libxc/ia64/xc_ia64_linux_save.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxc/ia64/xc_ia64_linux_save.c Fri Dec 16 14:54:14 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_generationid_addr) { DECLARE_DOMCTL; xc_dominfo_t info; diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxc/xc_domain_restore.c --- a/tools/libxc/xc_domain_restore.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxc/xc_domain_restore.c Fri Dec 16 14:54:14 2011 +0000 @@ -681,6 +681,7 @@ typedef struct { uint64_t console_pfn; uint64_t acpi_ioport_location; uint64_t viridian; + uint64_t vm_generationid_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_generationid_addr, sizeof(uint32_t)) || + RDEXACT(fd, &buf->vm_generationid_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,9 @@ 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_incr_generationid, + unsigned long *vm_generationid_addr) { DECLARE_DOMCTL; int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0; @@ -1449,6 +1463,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_generationid_addr ) { + if ( !no_incr_generationid ) { + unsigned int offset; + unsigned char *buf; + unsigned long long generationid; + + /* + * Map the VM generation id buffer and inject the new value. + */ + + pfn = pagebuf.vm_generationid_addr >> PAGE_SHIFT; + offset = pagebuf.vm_generationid_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); + + generationid = *(unsigned long long *)(buf + offset); + *(unsigned long long *)(buf + offset) = generationid + 1; + + munmap(buf, PAGE_SIZE); + } + + *vm_generationid_addr = pagebuf.vm_generationid_addr; + } + break; /* our work here is done */ } diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxc/xc_domain_save.c --- a/tools/libxc/xc_domain_save.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxc/xc_domain_save.c Fri Dec 16 14:54:14 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_generationid_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_generationid_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 fa0f840c516b -r 2ec1d2a1372c tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxc/xenguest.h Fri Dec 16 14:54:14 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_generationid_addr); /** @@ -72,12 +73,16 @@ 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 no_incr_generationid non-zero if generation id is NOT to be incremented + * @parm vm_generationid_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 no_incr_generationid, + unsigned long *vm_generationid_addr); /** * xc_domain_restore writes a file to disk that contains the device * model saved state. diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxc/xg_save_restore.h --- a/tools/libxc/xg_save_restore.h Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxc/xg_save_restore.h Fri Dec 16 14:54:14 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 fa0f840c516b -r 2ec1d2a1372c tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/libxl_create.c Fri Dec 16 14:54:14 2011 +0000 @@ -99,6 +99,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_incr_generationid = 0; break; case LIBXL_DOMAIN_TYPE_PV: b_info->u.pv.slack_memkb = 8 * 1024; diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/libxl_dom.c Fri Dec 16 14:54:14 2011 +0000 @@ -106,6 +106,7 @@ int libxl__build_pre(libxl__gc *gc, uint state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0); + state->vm_generationid_addr = 0; return 0; } @@ -117,7 +118,7 @@ int libxl__build_post(libxl__gc *gc, uin libxl_ctx *ctx = libxl__gc_owner(gc); char *dom_path, *vm_path; xs_transaction_t t; - char **ents; + char **ents, **hvm_ents; int i; libxl_cpuid_apply_policy(ctx, domid); @@ -143,6 +144,13 @@ int libxl__build_post(libxl__gc *gc, uin ? "offline" : "online"; } + hvm_ents = NULL; + if (info->type == LIBXL_DOMAIN_TYPE_HVM) { + hvm_ents = libxl__calloc(gc, 3, sizeof(char *)); + hvm_ents[0] = "hvmloader/generation-id-address"; + hvm_ents[1] = libxl__sprintf(gc, "0x%lx", state->vm_generationid_addr); + } + dom_path = libxl__xs_get_dompath(gc, domid); if (!dom_path) { return ERROR_FAIL; @@ -153,6 +161,9 @@ retry_transaction: t = xs_transaction_start(ctx->xsh); libxl__xs_writev(gc, t, dom_path, ents); + if (info->type == LIBXL_DOMAIN_TYPE_HVM) + libxl__xs_writev(gc, t, dom_path, hvm_ents); + libxl__xs_writev(gc, t, dom_path, local_ents); libxl__xs_writev(gc, t, vm_path, vms_ents); @@ -356,16 +367,19 @@ int libxl__domain_restore_common(libxl__ /* read signature */ int rc; int hvm, pae, superpages; + int no_incr_generationid; switch (info->type) { case LIBXL_DOMAIN_TYPE_HVM: hvm = 1; superpages = 1; pae = info->u.hvm.pae; + no_incr_generationid = info->u.hvm.no_incr_generationid; break; case LIBXL_DOMAIN_TYPE_PV: hvm = 0; superpages = 0; pae = 1; + no_incr_generationid = 0; break; default: return ERROR_INVAL; @@ -373,7 +387,8 @@ 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_incr_generationid, + &state->vm_generationid_addr); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain"); return ERROR_FAIL; @@ -539,12 +554,23 @@ int libxl__domain_suspend_common(libxl__ struct save_callbacks callbacks; struct suspendinfo si; int hvm, rc = ERROR_FAIL; + unsigned long vm_generationid_addr; switch (type) { - case LIBXL_DOMAIN_TYPE_HVM: + case LIBXL_DOMAIN_TYPE_HVM: { + char *path; + char *addr; + + path = libxl__sprintf(gc, "%s/hvmloader/generation-id-address", + libxl__xs_get_dompath(gc, domid)); + addr = libxl__xs_read(gc, XBT_NULL, path); + + vm_generationid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; hvm = 1; break; + } case LIBXL_DOMAIN_TYPE_PV: + vm_generationid_addr = 0; hvm = 0; break; default: @@ -582,7 +608,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_generationid_addr); if ( rc ) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain: %s", si.guest_responded ? diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/libxl_internal.h Fri Dec 16 14:54:14 2011 +0000 @@ -221,6 +221,7 @@ typedef struct { uint32_t console_port; unsigned long console_mfn; + unsigned long vm_generationid_addr; } libxl__domain_build_state; _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid, diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/libxl_types.idl Fri Dec 16 14:54:14 2011 +0000 @@ -184,6 +184,7 @@ libxl_domain_build_info = Struct("domain ("vpt_align", bool), ("timer_mode", integer), ("nested_hvm", bool), + ("no_incr_generationid", bool), ])), ("pv", Struct(None, [("kernel", libxl_file_reference), ("slack_memkb", uint32), diff -r fa0f840c516b -r 2ec1d2a1372c tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/libxl/xl_cmdimpl.c Fri Dec 16 14:54:14 2011 +0000 @@ -360,6 +360,8 @@ 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_incr_generationid %d)\n", + b_info->u.hvm.no_incr_generationid); 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 +1364,7 @@ struct domain_create { const char *restore_file; int migrate_fd; /* -1 means none */ char **migration_domname_r; /* from malloc */ + int no_incr_generationid; }; static int freemem(libxl_domain_build_info *b_info, libxl_device_model_info *dm_info) @@ -1575,6 +1578,8 @@ static int create_domain(struct domain_c } } + d_config.b_info.u.hvm.no_incr_generationid = dom_info->no_incr_generationid; + if (debug || dom_info->dryrun) printf_info(-1, &d_config, &d_config.dm_info); @@ -2800,6 +2805,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_incr_generationid = 1; rc = create_domain(&dom_info); if (rc < 0) { diff -r fa0f840c516b -r 2ec1d2a1372c tools/python/xen/lowlevel/checkpoint/libcheckpoint.c --- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c Fri Dec 16 14:54:14 2011 +0000 @@ -175,6 +175,7 @@ int checkpoint_start(checkpoint_state* s { int hvm, rc; int flags = XCFLAGS_LIVE; + unsigned long vm_generationid_addr; if (!s->domid) { s->errstr = "checkpoint state not opened"; @@ -185,16 +186,28 @@ int checkpoint_start(checkpoint_state* s hvm = s->domtype > dt_pv; if (hvm) { + char path[128]; + char *addr; + + sprintf(path, "/local/domain/%u/hvmloader/generation-id-address", s->domid); + addr = xs_read(s->xsh, XBT_NULL, path, NULL); + + vm_generationid_addr = (addr) ? strtoul(addr, NULL, 0) : 0; + free(addr); + flags |= XCFLAGS_HVM; if (switch_qemu_logdirty(s, 1)) return -1; + } else { + vm_generationid_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_generationid_addr); if (hvm) switch_qemu_logdirty(s, 0); diff -r fa0f840c516b -r 2ec1d2a1372c tools/xcutils/xc_restore.c --- a/tools/xcutils/xc_restore.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/xcutils/xc_restore.c Fri Dec 16 14:54:14 2011 +0000 @@ -46,7 +46,8 @@ main(int argc, char **argv) superpages = !!hvm; 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, + 0, NULL); if ( ret == 0 ) { diff -r fa0f840c516b -r 2ec1d2a1372c tools/xcutils/xc_save.c --- a/tools/xcutils/xc_save.c Fri Dec 16 14:54:13 2011 +0000 +++ b/tools/xcutils/xc_save.c Fri Dec 16 14:54:14 2011 +0000 @@ -208,7 +208,7 @@ main(int argc, char **argv) callbacks.suspend = suspend; callbacks.switch_qemu_logdirty = switch_qemu_logdirty; 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), 0); if (si.suspend_evtchn > 0) xc_suspend_evtchn_release(si.xch, si.xce, si.domid, si.suspend_evtchn);
Paul Durrant
2012-Jan-06 09:35 UTC
Re: [PATCH 0 of 4] Support for VM generation ID save/restore and migrate
Ping? Patch 3 was integrated on Dec 18th but I don''t see the rest as yet. Is there something more I need to do? Paul> -----Original Message----- > From: Paul Durrant [mailto:paul.durrant@citrix.com] > Sent: 16 December 2011 14:55 > To: xen-devel@lists.xensource.com > Cc: Paul Durrant > Subject: [PATCH 0 of 4] Support for VM generation ID save/restore > and migrate > > This patch series adds support for preservation of the VM generation > ID buffer address in xenstore across save/restore and migrate, and > also code to increment the value in all cases except for migration. > > Patch 1 modifies the guest ro and rw node creation to an open coding > style and cleans up some extraneous node creation. > Patch 2 modifies creation of the hvmloader key in xenstore and adds > creation of a new read/write hvmloader/generation-id-addr key. > Patch 3 changes hvmloader to use the new key (as opposed to the old > data/generation-id key). Note that it is safe to apply this patch > independently of the others but it logically belongs at this > position in the series. > Patch 4 adds the infrastructure to save and restore the VM > generation ID address in xenstore and the code to increment the > value. >
Ian Jackson
2012-Jan-10 15:58 UTC
Re: [PATCH 0 of 4] Support for VM generation ID save/restore and migrate
Paul Durrant writes ("Re: [Xen-devel] [PATCH 0 of 4] Support for VM generation ID save/restore and migrate"):> Ping? Patch 3 was integrated on Dec 18th but I don''t see the rest as yet. Is there something more I need to do?I''ve applied 1,2,4 now, thanks. Ian.
Paul Durrant
2012-Jan-10 16:35 UTC
Re: [PATCH 0 of 4] Support for VM generation ID save/restore and migrate
> -----Original Message----- > From: Ian Jackson [mailto:Ian.Jackson@eu.citrix.com] > Sent: 10 January 2012 15:58 > To: Paul Durrant > Cc: xen-devel@lists.xensource.com > Subject: Re: [Xen-devel] [PATCH 0 of 4] Support for VM generation ID > save/restore and migrate > > Paul Durrant writes ("Re: [Xen-devel] [PATCH 0 of 4] Support for VM > generation ID save/restore and migrate"): > > Ping? Patch 3 was integrated on Dec 18th but I don''t see the rest as yet. Is > there something more I need to do? > > I''ve applied 1,2,4 now, thanks. >Excellent. Thanks :-) Paul
Possibly Parallel Threads
- [PATCH 0 of 3] Support for VM generation ID save/restore and migrate
- [PATCH 0 of 2] Support for VM generation ID save/restore and migrate
- [PATCH v5 1/2] libxl: Introduce functions to add and remove USB devices to an HVM guest
- [PATCH] libxl: make libxl communicate with xenstored by socket or xenbus driver
- [PATCH 1/3] libxenlight: Clean up logging arrangements