[libvirt] [PATCH v2] qemu: enable user-defined cache bypassing while invoking

fuweiwei fuweiwei2 at huawei.com
Fri Aug 26 06:56:12 UTC 2016


in the previous version, I mentioned the scenario of long-term pause while
writing external memory checkpoints:

v1: https://www.redhat.com/archives/libvir-list/2016-August/msg01194.html

Daniel suggested not to hardcode the flag, but wire this upto the API. When
the user invokes the snapshot they can request the
VIR_DOMAIN_SAVE_BYPASS_CACHE flag explicitly. So in this version I
introduce the --bypass-cache option in libvirt snapshot API. When invoking
an external VM snapshots, we may use the command like this:

virsh snapshot-create-as VM snap --memspec /path/to/memsnap --live
 --bypass-cache
 
The VM snapshot can be done with inapparent VM suspend now. Without 
"--bypass-cache" flag, one may experience long-term VM suspend (so that the 
implication of "--live" option is not significant), provided that the VM
has a large amount of dirty pages to save. 

Signed-off-by: fuweiwei <fuweiwei2 at huawei.com>
---
 include/libvirt/libvirt-domain-snapshot.h |  3 +++
 src/qemu/qemu_driver.c                    | 20 ++++++++++++++++++--
 tools/virsh-snapshot.c                    | 12 ++++++++++++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt-domain-snapshot.h b/include/libvirt/libvirt-domain-snapshot.h
index 0f73f24..aeff665 100644
--- a/include/libvirt/libvirt-domain-snapshot.h
+++ b/include/libvirt/libvirt-domain-snapshot.h
@@ -70,6 +70,9 @@ typedef enum {
     VIR_DOMAIN_SNAPSHOT_CREATE_LIVE        = (1 << 8), /* create the snapshot
                                                           while the guest is
                                                           running */
+    VIR_DOMAIN_SNAPSHOT_CREATE_BYPASS_CACHE   = (1 << 9), i/* Bypass cache
+                                                          while writing external
+                                                          checkpoint files. */
 } virDomainSnapshotCreateFlags;
 
 /* Take a snapshot of the current VM state */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2089359..d5f441f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14036,6 +14036,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
     bool pmsuspended = false;
     virQEMUDriverConfigPtr cfg = NULL;
     int compressed = QEMU_SAVE_FORMAT_RAW;
+    unsigned int save_memory_flag = 0;
 
     /* If quiesce was requested, then issue a freeze command, and a
      * counterpart thaw command when it is actually sent to agent.
@@ -14116,8 +14117,12 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
         if (!(xml = qemuDomainDefFormatLive(driver, vm->def, true, true)))
             goto cleanup;
 
+        if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_BYPASS_CACHE)
+            save_memory_flag |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
+
         if ((ret = qemuDomainSaveMemory(driver, vm, snap->def->file,
-                                        xml, compressed, resume, 0,
+                                        xml, compressed, resume,
+                                        save_memory_flag,
                                         QEMU_ASYNC_JOB_SNAPSHOT)) < 0)
             goto cleanup;
 
@@ -14224,7 +14229,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
                   VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT |
                   VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE |
                   VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC |
-                  VIR_DOMAIN_SNAPSHOT_CREATE_LIVE, NULL);
+                  VIR_DOMAIN_SNAPSHOT_CREATE_LIVE |
+                  VIR_DOMAIN_SNAPSHOT_CREATE_BYPASS_CACHE, NULL);
 
     VIR_REQUIRE_FLAG_RET(VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE,
                          VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY,
@@ -14297,6 +14303,16 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
         goto cleanup;
     }
 
+    /* the option of bypass cache is only supported for external checkpoints */
+    if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_BYPASS_CACHE &&
+         (def->memory != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL ||
+         redefine)) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                       _("only external memory snapshots support "
+                         "cache bypass."));
+        goto cleanup;
+    }
+
     /* allow snapshots only in certain states */
     switch ((virDomainState) vm->state.state) {
         /* valid states */
diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c
index f879e7a..0627baf 100644
--- a/tools/virsh-snapshot.c
+++ b/tools/virsh-snapshot.c
@@ -160,6 +160,10 @@ static const vshCmdOptDef opts_snapshot_create[] = {
      .type = VSH_OT_BOOL,
      .help = N_("require atomic operation")
     },
+    {.name = "bypass-cache",
+     .type = VSH_OT_BOOL,
+     .help = N_("bypass system cache while writing external checkpoints")
+    },
     VIRSH_COMMON_OPT_LIVE(N_("take a live snapshot")),
     {.name = NULL}
 };
@@ -191,6 +195,8 @@ cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd)
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC;
     if (vshCommandOptBool(cmd, "live"))
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_LIVE;
+    if (vshCommandOptBool(cmd, "bypass-cache"))
+        flags |= VIR_DOMAIN_SNAPSHOT_CREATE_BYPASS_CACHE;
 
     if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
         goto cleanup;
@@ -358,6 +364,10 @@ static const vshCmdOptDef opts_snapshot_create_as[] = {
      .type = VSH_OT_BOOL,
      .help = N_("require atomic operation")
     },
+    {.name = "bypass-cache",
+     .type = VSH_OT_BOOL,
+     .help = N_("bypass system cache while writing external checkpoints")
+    },
     VIRSH_COMMON_OPT_LIVE(N_("take a live snapshot")),
     {.name = "memspec",
      .type = VSH_OT_STRING,
@@ -404,6 +414,8 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd)
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC;
     if (vshCommandOptBool(cmd, "live"))
         flags |= VIR_DOMAIN_SNAPSHOT_CREATE_LIVE;
+    if (vshCommandOptBool(cmd, "bypass-cache"))
+        flags |= VIR_DOMAIN_SNAPSHOT_CREATE_BYPASS_CACHE;
 
     if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
         return false;
-- 
1.9.5.msysgit.1




More information about the libvir-list mailing list