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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list