[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] tools: VM generation ID save/restore and migrate.



# HG changeset patch
# User Paul Durrant <paul.durrant@xxxxxxxxxx>
# Date 1324047254 0
# Node ID 3c4c5df2cd0e6976aace47275cea070dd8f1295b
# Parent  92630d4b093eca22fdaf4b8b7a02a858a086cad7
tools: 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@xxxxxxxxxx>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
---


diff -r 92630d4b093e -r 3c4c5df2cd0e 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 @@
 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 92630d4b093e -r 3c4c5df2cd0e 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 @@
 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 92630d4b093e -r 3c4c5df2cd0e 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 @@
     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 @@
         }
         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 @@
 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 @@
                 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 92630d4b093e -r 3c4c5df2cd0e 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 @@
 
 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 @@
             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 92630d4b093e -r 3c4c5df2cd0e 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 @@
  */
 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 @@
  * @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 92630d4b093e -r 3c4c5df2cd0e 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 92630d4b093e -r 3c4c5df2cd0e 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 @@
         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 92630d4b093e -r 3c4c5df2cd0e 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 @@
 
     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 @@
     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 @@
                             ? "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 @@
     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 @@
     /* 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 @@
     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;
@@ -538,12 +553,23 @@
     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:
@@ -581,7 +607,8 @@
     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 92630d4b093e -r 3c4c5df2cd0e 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
@@ -223,6 +223,7 @@
 
     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 92630d4b093e -r 3c4c5df2cd0e 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 @@
                                        ("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 92630d4b093e -r 3c4c5df2cd0e 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 @@
         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);
@@ -1364,6 +1366,7 @@
     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)
@@ -1577,6 +1580,8 @@
         }
     }
 
+    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);
 
@@ -2817,6 +2822,7 @@
     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 92630d4b093e -r 3c4c5df2cd0e 
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 hvm, rc;
     int flags = XCFLAGS_LIVE;
+    unsigned long vm_generationid_addr;
 
     if (!s->domid) {
        s->errstr = "checkpoint state not opened";
@@ -185,16 +186,28 @@
 
     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 92630d4b093e -r 3c4c5df2cd0e 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 @@
            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 92630d4b093e -r 3c4c5df2cd0e 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 @@
     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);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.