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

[Xen-devel] [PATCH v2 1/1] tools: Handle xc_maxmem adjustments



This fixes an issue where "xl save" followed by "xl restore" reports:
"xc: error: Failed to allocate memory for batch.!: Internal error"

One of the ways to get into this state is to have more then 4 e1000
nics configured.

Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx>
---
Changes from v1 to v2:

Renamed from "xc_domain_restore: Allow QEMU to increase memory"

Reworked completely to have xc_domain_save save the domain config
data that is needed.  And xc_domain_restore to use the new saved
data in recreating the domain.

 tools/libxc/xc_domain_restore.c | 21 +++++++++++++++++++++
 tools/libxc/xc_domain_save.c    | 16 ++++++++++++++++
 tools/libxc/xg_save_restore.h   |  2 ++
 3 files changed, 39 insertions(+)

diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index a382701..359fe41 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -769,6 +769,19 @@ static void pagebuf_free(pagebuf_t* buf)
     }
 }
 
+static int xc_maxmem_restore(xc_interface *xch, struct restore_ctx *ctx,
+                             int dom, int fd)
+{
+    uint64_t maxkb;
+
+    if ( RDEXACT(fd, &maxkb, sizeof(maxkb)) )
+    {
+        PERROR("Error when reading maxmem");
+        return -1;
+    }
+    return xc_domain_setmaxmem(xch, dom, maxkb);
+}
+
 static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx,
                            pagebuf_t* buf, int fd, uint32_t dom)
 {
@@ -1013,6 +1026,14 @@ static int pagebuf_get_one(xc_interface *xch, struct 
restore_ctx *ctx,
         }
         return pagebuf_get_one(xch, ctx, buf, fd, dom);
 
+    case XC_SAVE_ID_XC_MAXMEM:
+        DPRINTF("xc_domain_restore start maxmem\n");
+        if ( xc_maxmem_restore(xch, ctx, dom, fd) ) {
+            PERROR("error reading/restoring maxmem");
+            return -1;
+        }
+        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);
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 254fdb3..381b95e 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -782,6 +782,16 @@ static xen_pfn_t *map_and_save_p2m_table(xc_interface *xch,
     return success ? p2m : NULL;
 }
 
+static int xc_maxmem_save(int io_fd, uint64_t maxkb)
+{
+    int marker = XC_SAVE_ID_XC_MAXMEM;
+
+    if ( write_exact(io_fd, &marker, sizeof(marker)) ||
+         write_exact(io_fd, &maxkb, sizeof(maxkb)) )
+        return -1;
+    return 0;
+}
+
 /* must be done AFTER suspend_and_state() */
 static int save_tsc_info(xc_interface *xch, uint32_t dom, int io_fd)
 {
@@ -1098,6 +1108,12 @@ int xc_domain_save(xc_interface *xch, int io_fd, 
uint32_t dom, uint32_t max_iter
 
     print_stats(xch, dom, 0, &time_stats, &shadow_stats, 0);
 
+    if ( xc_maxmem_save(io_fd, info.max_memkb) < 0 )
+    {
+        PERROR("Error when writing to state file (maxmem)");
+        goto out;
+    }
+
     tmem_saved = xc_tmem_save(xch, dom, io_fd, live, XC_SAVE_ID_TMEM);
     if ( tmem_saved == -1 )
     {
diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h
index bdd9009..4123a84 100644
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -262,6 +262,8 @@
 /* These are a pair; it is an error for one to exist without the other */
 #define XC_SAVE_ID_HVM_IOREQ_SERVER_PFN -19
 #define XC_SAVE_ID_HVM_NR_IOREQ_SERVER_PAGES -20
+/* QEMU auto size handling */
+#define XC_SAVE_ID_XC_MAXMEM          -21
 
 /*
 ** We process save/restore/migrate in batches of pages; the below
-- 
1.8.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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