diff --git a/tools/virsh.c b/tools/virsh.c index 363bf419cce8cc5c64caf666fdd1a009c3a48ee4..d1ebc4093ad9fbda9d69ff40540f49127662fe45 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -11996,15 +11996,45 @@ vshSnapshotCreate(vshControl *ctl, virDomainPtr dom, const char *buffer, { bool ret = false; virDomainSnapshotPtr snapshot; + bool halt = false; char *doc = NULL; xmlDocPtr xml = NULL; xmlXPathContextPtr ctxt = NULL; char *name = NULL; snapshot = virDomainSnapshotCreateXML(dom, buffer, flags); + + /* Emulate --halt on older servers. */ + if (!snapshot && last_error->code == VIR_ERR_INVALID_ARG && + (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) { + int persistent; + + virFreeError(last_error); + last_error = NULL; + persistent = virDomainIsPersistent(dom); + if (persistent < 0) { + virshReportError(ctl); + goto cleanup; + } + if (!persistent) { + vshError(ctl, "%s", + _("cannot halt after snapshot of transient domain")); + goto cleanup; + } + if (virDomainIsActive(dom) == 1) + halt = true; + flags &= ~VIR_DOMAIN_SNAPSHOT_CREATE_HALT; + snapshot = virDomainSnapshotCreateXML(dom, buffer, flags); + } + if (snapshot == NULL) goto cleanup; + if (halt && virDomainDestroy(dom) < 0) { + virshReportError(ctl); + goto cleanup; + } + if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA) doc = vshStrdup(ctl, buffer); else @@ -12055,6 +12085,7 @@ static const vshCmdOptDef opts_snapshot_create[] = { {"redefine", VSH_OT_BOOL, 0, N_("redefine metadata for existing snapshot")}, {"current", VSH_OT_BOOL, 0, N_("with redefine, set current snapshot")}, {"no-metadata", VSH_OT_BOOL, 0, N_("take snapshot but create no metadata")}, + {"halt", VSH_OT_BOOL, 0, N_("halt domain after snapshot is created")}, {NULL, 0, 0, NULL} }; @@ -12073,6 +12104,8 @@ cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd) flags |= VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT; if (vshCommandOptBool(cmd, "no-metadata")) flags |= VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA; + if (vshCommandOptBool(cmd, "halt")) + flags |= VIR_DOMAIN_SNAPSHOT_CREATE_HALT; if (!vshConnectionUsability(ctl, ctl->conn)) goto cleanup; @@ -12123,6 +12156,7 @@ static const vshCmdOptDef opts_snapshot_create_as[] = { {"description", VSH_OT_DATA, 0, N_("description of snapshot")}, {"print-xml", VSH_OT_BOOL, 0, N_("print XML document rather than create")}, {"no-metadata", VSH_OT_BOOL, 0, N_("take snapshot but create no metadata")}, + {"halt", VSH_OT_BOOL, 0, N_("halt domain after snapshot is created")}, {NULL, 0, 0, NULL} }; @@ -12139,6 +12173,8 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptBool(cmd, "no-metadata")) flags |= VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA; + if (vshCommandOptBool(cmd, "halt")) + flags |= VIR_DOMAIN_SNAPSHOT_CREATE_HALT; if (!vshConnectionUsability(ctl, ctl->conn)) goto cleanup; @@ -12167,6 +12203,11 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd) } if (vshCommandOptBool(cmd, "print-xml")) { + if (vshCommandOptBool(cmd, "halt")) { + vshError(ctl, "%s", + _("--print-xml and --halt are mutually exclusive")); + goto cleanup; + } vshPrint(ctl, "%s\n", buffer); ret = true; goto cleanup; diff --git a/tools/virsh.pod b/tools/virsh.pod index 3557a0d859ab61d84e0ea074b830f351c9a965ff..8edf30efdd1ab52db73160855d5f357b47e2188e 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1702,7 +1702,7 @@ used to represent properties of snapshots. =over 4 =item B I [I] {[I<--redefine> [I<--current>]] -| [I<--no-metadata>]} +| [I<--no-metadata>] [I<--halt>]} Create a snapshot for domain I with the properties specified in I. Normally, the only properties settable for a domain snapshot @@ -1711,6 +1711,9 @@ ignored, and automatically filled in by libvirt. If I is completely omitted, then libvirt will choose a value for all fields. The new snapshot will become current, as listed by B. +If I<--halt> is specified, the domain will be left in an inactive state +after the snapshot is created. + If I<--redefine> is specified, then all XML elements produced by B are valid; this can be used to migrate snapshot hierarchy from one machine to another, to recreate hierarchy for the @@ -1732,13 +1735,15 @@ a persistent domain. However, for transient domains, snapshot metadata is silently lost when the domain quits running (whether by command such as B or by internal guest action). -=item B I {[I<--print-xml>] | [I<--no-metadata>]} -[I] [I] +=item B I {[I<--print-xml>] +| [I<--no-metadata>] [I<--halt>]} [I] [I] Create a snapshot for domain I with the given and ; if either value is omitted, libvirt will choose a value. If I<--print-xml> is specified, then XML appropriate for I is output, rather than actually creating a snapshot. +Otherwise, if I<--halt> is specified, the domain will be left in an +inactive state after the snapshot is created. If I<--no-metadata> is specified, then the snapshot data is created, but any metadata is immediately discarded (that is, libvirt does not