Skip to contentSkip to conversation

Support for VM generation ID save/restore and migrate

PATCH New Paul Durrant 3 participants 10 messages Dec 14, 2011 – Dec 15, 2011 Arm/actions semi architecture

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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. The vast majority of the code is in second patch. The first patch merely changes the xenstore key name used by hvmloader to store the buffer address.

#1 lore raw

PATCH 1/1 Re-name xenstore key used to save VM generation ID buffer address

# HG changeset patch
# User Paul Durrant <[email protected]>
# Date 1323854952 0
# Node ID fded65be5d82461e87de54960db14ce8feb4625f
# Parent 03138a08366b895d79e143119d4c9c72833cdbcd Re-name xenstore key used to save VM generation ID buffer address.

tools/firmware/hvmloader/acpi/build.c +1 -1
diff -r 03138a08366b -r fded65be5d82 tools/firmware/hvmloader/acpi/build.c
@@ -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("data/generation-id-address", addr);
 
     gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0);
     *(uint64_t *)buf = gid;
#2 lore raw

Re: [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 13 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]>
# Date 1323854952 0
# Node ID fded65be5d82461e87de54960db14ce8feb4625f
# Parent 03138a08366b895d79e143119d4c9c72833cdbcd Re-name xenstore key used to save VM generation ID buffer address.

diff -r 03138a08366b -r fded65be5d82 tools/firmware/hvmloader/acpi/build.c

tools/firmware/hvmloader/acpi/build.c unsigned long new_vm_gid(void) · line 312

Quoted 5 lines
tools/firmware/hvmloader/acpi/build.c +1 -1
@@ -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("data/generation-id-address", addr);

data/ seems like an odd home for this, isn't that the area where guests can expect to store their own bits and bobs, agent stuff etc?

Although this key is going to be guest writeable (so hvmloader can write it) it really ought to be off somewhere out of the way. We select the bios with /local/domain/<domid>/hvmloader/bios so perhaps something under there or /local/domain/<domid>/platform?

(/me adds "do archaeology and document valid/best-practice xenstore paths to TODO list)

Ian.

Quoted 8 lines
tools/firmware/hvmloader/acpi/build.c +0 -0
     gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0);
     *(uint64_t *)buf = gid;
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#3 lore raw

Re: [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 26 lines

-----Original Message-----
From: Ian Campbell
Sent: 14 December 2011 10:12
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 2 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1323854952 0

#

Quoted 7 lines

Node ID fded65be5d82461e87de54960db14ce8feb4625f
# Parent 03138a08366b895d79e143119d4c9c72833cdbcd Re-name xenstore key used to save VM generation ID buffer address.

diff -r 03138a08366b -r fded65be5d82

tools/firmware/hvmloader/acpi/build.c

Quoted 1 line

--- a/tools/firmware/hvmloader/acpi/build.c Fri Dec 09 16:19:36

2011 +0000

Quoted 1 line

+++ b/tools/firmware/hvmloader/acpi/build.c Wed Dec 14 09:29:12

2011 +0000

Quoted 10 lines

tools/firmware/hvmloader/acpi/build.c unsigned long new_vm_gid(void) · line 312

Quoted 6 lines
tools/firmware/hvmloader/acpi/build.c +1 -1
@@ -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("data/generation-id-address", addr);

data/ seems like an odd home for this, isn't that the area where guests can expect to store their own bits and bobs, agent stuff etc?

No what data is 'for' as such. It seemed like a reasonable place to put something created by the guest and for the tools' consumption. I could move it under hvmloader, but is that the right place? hvmloader/bios is *read* by hvmloader, not written by it.

Paul

Quoted 21 lines

Although this key is going to be guest writeable (so hvmloader can write
it) it really ought to be off somewhere out of the way. We select the bios with /local/domain/<domid>/hvmloader/bios so perhaps something under there or /local/domain/<domid>/platform?

(/me adds "do archaeology and document valid/best-practice xenstore paths to TODO list)

Ian.

Review unsigned long new_vm_gid(void) · line 313

Quoted 2 lines
(quoted diff) +0 -0
     gid = strtoll(xenstore_read("platform/generation-id", "0"),

NULL, 0);

Quoted 6 lines
(quoted diff) +0 -0
     *(uint64_t *)buf = gid;
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#4 lore raw

Re: [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 36 lines · Paul Durrant
Quoted 25 lines

-----Original Message-----
From: Ian Campbell
Sent: 14 December 2011 10:12
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 2 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1323854952 0

#

Quoted 7 lines

Node ID fded65be5d82461e87de54960db14ce8feb4625f
# Parent 03138a08366b895d79e143119d4c9c72833cdbcd Re-name xenstore key used to save VM generation ID buffer address.

diff -r 03138a08366b -r fded65be5d82

tools/firmware/hvmloader/acpi/build.c

Quoted 1 line

--- a/tools/firmware/hvmloader/acpi/build.c Fri Dec 09 16:19:36

2011 +0000

Quoted 1 line

+++ b/tools/firmware/hvmloader/acpi/build.c Wed Dec 14 09:29:12

2011 +0000

Quoted 10 lines

tools/firmware/hvmloader/acpi/build.c unsigned long new_vm_gid(void) · line 312

Quoted 6 lines
tools/firmware/hvmloader/acpi/build.c +1 -1
@@ -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("data/generation-id-address", addr);

data/ seems like an odd home for this, isn't that the area where guests can expect to store their own bits and bobs, agent stuff etc?

Quoted 2 lines

No what data is 'for' as such. It seemed like a reasonable place to put something created by the guest and for the tools' consumption.

Although it runs in guest context hvmloader should really be considered an extension of the tools and not part of the guest.

Quoted 2 lines

I could move it under hvmloader, but is that the right place? hvmloader/bios is *read* by hvmloader, not written by it.

I think it's a good as anywhere else.

Ian.

Quoted 25 lines

Paul

Quoted 21 lines

Although this key is going to be guest writeable (so hvmloader can write
it) it really ought to be off somewhere out of the way. We select the bios with /local/domain/<domid>/hvmloader/bios so perhaps something under there or /local/domain/<domid>/platform?

(/me adds "do archaeology and document valid/best-practice xenstore paths to TODO list)

Ian.

Review unsigned long new_vm_gid(void) · line 313

Quoted 2 lines
(quoted diff) +0 -0
     gid = strtoll(xenstore_read("platform/generation-id", "0"),

NULL, 0);

Quoted 6 lines
(quoted diff) +0 -0
     *(uint64_t *)buf = gid;
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#5 lore raw

Re: [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 56 lines

-----Original Message-----
From: Ian Campbell
Sent: 14 December 2011 11:39
To: Paul Durrant
Cc: [email protected]
Subject: RE: [Xen-devel] [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 7 lines · Paul Durrant
Quoted 7 lines

-----Original Message-----
From: Ian Campbell
Sent: 14 December 2011 10:12
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 2] Re-name xenstore key

used to

Quoted 5 lines
Quoted 5 lines

save VM generation ID buffer address

Quoted 2 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date

1323854952 0

Quoted 4 lines
Quoted 4 lines

#

Quoted 3 lines

Node ID fded65be5d82461e87de54960db14ce8feb4625f # Parent 03138a08366b895d79e143119d4c9c72833cdbcd Re-name xenstore key used to save VM generation ID buffer

address.

Quoted 6 lines
Quoted 6 lines
Quoted 4 lines

diff -r 03138a08366b -r fded65be5d82

tools/firmware/hvmloader/acpi/build.c

Quoted 1 line

--- a/tools/firmware/hvmloader/acpi/build.c Fri Dec 09

16:19:36

Quoted 2 lines
Quoted 2 lines

2011 +0000

Quoted 1 line

+++ b/tools/firmware/hvmloader/acpi/build.c Wed Dec 14

09:29:12

Quoted 3 lines
Quoted 3 lines

2011 +0000

Review unsigned long new_vm_gid(void) · line 309

Quoted 2 lines
(quoted diff) +0 -0
@@ -309,7 +309,7 @@ unsigned long new_vm_gid(void)
     if ( snprintf(addr, sizeof(addr), "0x%lx",

virt_to_phys(buf))

Quoted 7 lines
Quoted 7 lines

tools/firmware/hvmloader/acpi/build.c unsigned long new_vm_gid(void) · line 312

Quoted 4 lines
tools/firmware/hvmloader/acpi/build.c +1 -1
          >= sizeof(addr) )
         return 0;
-    xenstore_write("data/generation-id", addr);
+    xenstore_write("data/generation-id-address", addr);

data/ seems like an odd home for this, isn't that the area where guests can expect to store their own bits and bobs, agent stuff

etc?

Quoted 3 lines
Quoted 1 line

No what data is 'for' as such. It seemed like a reasonable place

to

Quoted 1 line

put something created by the guest and for the tools' consumption.

Quoted 8 lines

Although it runs in guest context hvmloader should really be considered an extension of the tools and not part of the guest.

Quoted 2 lines

I could move it under hvmloader, but is that the right place? hvmloader/bios is *read* by hvmloader, not written by it.

I think it's a good as anywhere else.

Ok, does that mean that we should create hmvloader as writable by the guest, or should we special-case the generation-id-address key?

Paul

#6 lore raw

Re: [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 59 lines · Paul Durrant
Quoted 59 lines

-----Original Message-----
From: Ian Campbell
Sent: 14 December 2011 11:39
To: Paul Durrant
Cc: [email protected]
Subject: RE: [Xen-devel] [PATCH 1 of 2] Re-name xenstore key used to save VM generation ID buffer address

Quoted 7 lines · Paul Durrant
Quoted 7 lines

-----Original Message-----
From: Ian Campbell
Sent: 14 December 2011 10:12
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 2] Re-name xenstore key

used to

Quoted 5 lines
Quoted 5 lines

save VM generation ID buffer address

Quoted 2 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date

1323854952 0

Quoted 4 lines
Quoted 4 lines

#

Quoted 3 lines

Node ID fded65be5d82461e87de54960db14ce8feb4625f # Parent 03138a08366b895d79e143119d4c9c72833cdbcd Re-name xenstore key used to save VM generation ID buffer

address.

Quoted 6 lines
Quoted 6 lines
Quoted 4 lines

diff -r 03138a08366b -r fded65be5d82

tools/firmware/hvmloader/acpi/build.c

Quoted 1 line

--- a/tools/firmware/hvmloader/acpi/build.c Fri Dec 09

16:19:36

Quoted 2 lines
Quoted 2 lines

2011 +0000

Quoted 1 line

+++ b/tools/firmware/hvmloader/acpi/build.c Wed Dec 14

09:29:12

Quoted 3 lines
Quoted 3 lines

2011 +0000

Review unsigned long new_vm_gid(void) · line 309

Quoted 2 lines
(quoted diff) +0 -0
@@ -309,7 +309,7 @@ unsigned long new_vm_gid(void)
     if ( snprintf(addr, sizeof(addr), "0x%lx",

virt_to_phys(buf))

Quoted 7 lines
Quoted 7 lines

tools/firmware/hvmloader/acpi/build.c unsigned long new_vm_gid(void) · line 312

Quoted 4 lines
tools/firmware/hvmloader/acpi/build.c +1 -1
          >= sizeof(addr) )
         return 0;
-    xenstore_write("data/generation-id", addr);
+    xenstore_write("data/generation-id-address", addr);

data/ seems like an odd home for this, isn't that the area where guests can expect to store their own bits and bobs, agent stuff

etc?

Quoted 3 lines
Quoted 1 line

No what data is 'for' as such. It seemed like a reasonable place

to

Quoted 1 line

put something created by the guest and for the tools' consumption.

Although it runs in guest context hvmloader should really be considered an extension of the tools and not part of the guest.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

I could move it under hvmloader, but is that the right place? hvmloader/bios is *read* by hvmloader, not written by it.

I think it's a good as anywhere else.

Ok, does that mean that we should create hmvloader as writable by the guest, or should we special-case the generation-id-address key?

Just the specific key.

Ian.

#7 lore raw

PATCH 1/1 VM generation ID save/restore and migrate

In reply to Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1323854955 0
# Node ID 972927dc84c7e22520f4771d58d4770bf2726816 # Parent fded65be5d82461e87de54960db14ce8feb4625f 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().

tools/libxc/ia64/xc_ia64_linux_restore.c +2 -1
diff -r fded65be5d82 -r 972927dc84c7 tools/libxc/ia64/xc_ia64_linux_restore.c
@@ -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 no_incr_generationid, unsigned long *vm_generationid_addr)
 {
     DECLARE_DOMCTL;
     int rc = 1;
tools/libxc/ia64/xc_ia64_linux_save.c +2 -1
diff -r fded65be5d82 -r 972927dc84c7 tools/libxc/ia64/xc_ia64_linux_save.c
@@ -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;
tools/libxc/xc_domain_restore.c +47 -1

72 lines not on this page · raw message

tools/libxc/xc_domain_save.c +12 -1
diff -r fded65be5d82 -r 972927dc84c7 tools/libxc/xc_domain_save.c
@@ -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,
tools/libxc/xenguest.h +6 -2
diff -r fded65be5d82 -r 972927dc84c7 tools/libxc/xenguest.h
@@ -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,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 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.
tools/libxc/xg_save_restore.h +1 -0
diff -r fded65be5d82 -r 972927dc84c7 tools/libxc/xg_save_restore.h
@@ -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
tools/libxl/libxl_create.c +1 -0
diff -r fded65be5d82 -r 972927dc84c7 tools/libxl/libxl_create.c
@@ -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;
tools/libxl/libxl_dom.c +23 -6
diff -r fded65be5d82 -r 972927dc84c7 tools/libxl/libxl_dom.c
@@ -124,7 +124,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";
@@ -137,9 +137,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-address";
+    ents[13] = libxl__sprintf(gc, "0x%lx", state->vm_generationid_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";
     }
 
@@ -356,16 +358,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 +378,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 +545,22 @@ 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/data/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 +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_generationid_addr);
     if ( rc ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain: %s",
                          si.guest_responded ?
tools/libxl/libxl_internal.h +1 -0
diff -r fded65be5d82 -r 972927dc84c7 tools/libxl/libxl_internal.h
@@ -218,6 +218,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,
tools/libxl/libxl_types.idl +1 -0
diff -r fded65be5d82 -r 972927dc84c7 tools/libxl/libxl_types.idl
@@ -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),
tools/libxl/xl_cmdimpl.c +5 -0
diff -r fded65be5d82 -r 972927dc84c7 tools/libxl/xl_cmdimpl.c
@@ -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_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 +1363,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 +1577,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 +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_incr_generationid = 1;
 
     rc = create_domain(&dom_info);
     if (rc < 0) {
tools/python/xen/lowlevel/checkpoint/libcheckpoint.c +13 -1
diff -r fded65be5d82 -r 972927dc84c7 tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
@@ -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,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-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);
tools/xcutils/xc_restore.c +12 -5
diff -r fded65be5d82 -r 972927dc84c7 tools/xcutils/xc_restore.c
@@ -23,11 +23,12 @@ 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_generationid_addr;
+    int no_incr_generationid;
 
-    if ( (argc != 8) && (argc != 9) )
+    if ( (argc < 8) || (argc > 10) )
         errx(1, "usage: %s iofd domid store_evtchn "
-             "console_evtchn hvm pae apic [superpages]", argv[0]);
+             "console_evtchn hvm pae apic [superpages [no_incr_generationid]]", argv[0]);
 
     xch = xc_interface_open(0,0,0);
     if ( !xch )
@@ -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_incr_generationid = !atoi(argv[9]);
+    else
+	    no_incr_generationid = 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_incr_generationid, &vm_generationid_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_generationid_addr);
 	fflush(stdout);
     }
 
tools/xcutils/xc_save.c +18 -1
diff -r fded65be5d82 -r 972927dc84c7 tools/xcutils/xc_save.c
@@ -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_generationid_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-address", 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_generationid_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_generationid_addr);
 
     if (si.suspend_evtchn > 0)
 	 xc_suspend_evtchn_release(si.xch, si.xce, si.domid, si.suspend_evtchn);
#8 lore raw

Re: [PATCH 2 of 2] VM generation ID save/restore and migrate

Paul Durrant writes ("[Xen-devel] [PATCH 2 of 2] VM generation ID save/restore and migrate"):

Quoted 8 lines

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().

You need to rewrap some of this now I'm afraid.

Ian.

#9 lore raw

Re: [PATCH 2 of 2] VM generation ID save/restore and migrate

Quoted 13 lines

-----Original Message-----
From: Ian Jackson [mailto:[email protected]]
Sent: 15 December 2011 17:26
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 2 of 2] VM generation ID save/restore and migrate

Paul Durrant writes ("[Xen-devel] [PATCH 2 of 2] VM generation ID save/restore and migrate"):

Quoted 3 lines

VM generation ID save/restore and migrate.

Add code to track the address of the VM generation ID buffer

Quoted 9 lines

across a

Quoted 5 lines

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().

You need to rewrap some of this now I'm afraid.

<sigh> OK, I'll post a new series.

Paul