Easy enough to emulate even with older servers.
* tools/virsh.c (cmdSnapshotCreate, cmdSnapshotCreateAs): Add
--halt flag.
(vshSnapshotCreate): Emulate halt when flag is unsupported.
* tools/virsh.pod (snapshot-create, snapshot-create-as): Document
it.
---
tools/virsh.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
tools/virsh.pod | 9 +++++++--
2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index e2f08ca..49ce814 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -12089,15 +12089,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;
+ }
+
doc = virDomainSnapshotGetXMLDesc(snapshot, 0);
if (!doc)
goto cleanup;
@@ -12142,6 +12172,7 @@ static const vshCmdInfo info_snapshot_create[] = {
static const vshCmdOptDef opts_snapshot_create[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or
uuid")},
{"xmlfile", VSH_OT_DATA, 0, N_("domain snapshot XML")},
+ {"halt", VSH_OT_BOOL, 0, N_("halt domain after snapshot is
created")},
{NULL, 0, 0, NULL}
};
@@ -12152,6 +12183,10 @@ cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd)
bool ret = false;
const char *from = NULL;
char *buffer = NULL;
+ int flags = 0;
+
+ if (vshCommandOptBool(cmd, "halt"))
+ flags |= VIR_DOMAIN_SNAPSHOT_CREATE_HALT;
if (!vshConnectionUsability(ctl, ctl->conn))
goto cleanup;
@@ -12177,7 +12212,7 @@ cmdSnapshotCreate(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
- ret = vshSnapshotCreate(ctl, dom, buffer, 0, from);
+ ret = vshSnapshotCreate(ctl, dom, buffer, flags, from);
cleanup:
VIR_FREE(buffer);
@@ -12201,6 +12236,7 @@ static const vshCmdOptDef opts_snapshot_create_as[] = {
{"name", VSH_OT_DATA, 0, N_("name of snapshot")},
{"description", VSH_OT_DATA, 0, N_("description of snapshot")},
{"print-xml", VSH_OT_BOOL, 0, N_("print XML document rather than
create")},
+ {"halt", VSH_OT_BOOL, 0, N_("halt domain after snapshot is
created")},
{NULL, 0, 0, NULL}
};
@@ -12213,6 +12249,10 @@ cmdSnapshotCreateAs(vshControl *ctl, const vshCmd *cmd)
const char *name = NULL;
const char *desc = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ int flags = 0;
+
+ if (vshCommandOptBool(cmd, "halt"))
+ flags |= VIR_DOMAIN_SNAPSHOT_CREATE_HALT;
if (!vshConnectionUsability(ctl, ctl->conn))
goto cleanup;
@@ -12241,12 +12281,17 @@ 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;
}
- ret = vshSnapshotCreate(ctl, dom, buffer, 0, NULL);
+ ret = vshSnapshotCreate(ctl, dom, buffer, flags, NULL);
cleanup:
VIR_FREE(buffer);
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 4005242..0af0f3c 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1581,7 +1581,7 @@ used to represent properties of snapshots.
=over 4
-=item B<snapshot-create> I<domain> [I<xmlfile>]
+=item B<snapshot-create> I<domain> [I<xmlfile>] [I<--halt>]
Create a snapshot for domain I<domain> with the properties specified in
I<xmlfile>. The only properties settable for a domain snapshot are the
@@ -1589,13 +1589,18 @@ I<xmlfile>. The only properties settable for a domain
snapshot are the
automatically filled in by libvirt. If I<xmlfile> is completely omitted,
then libvirt will choose a value for all fields.
-=item B<snapshot-create-as> I<domain> [I<--print-xml>]
+If I<--halt> is specified, the domain will be left in an inactive state
+after the snapshot is created.
+
+=item B<snapshot-create-as> I<domain> [{I<--print-xml> |
I<--halt>}]
[I<name>] [I<description>]
Create a snapshot for domain I<domain> with the given <name> and
<description>; if either value is omitted, libvirt will choose a
value. If I<--print-xml> is specified, then XML appropriate for
I<snapshot-create> 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.
=item B<snapshot-current> I<domain> [I<--name>]
[I<--security-info>]
--
1.7.4.4