snapshot: expose --running and --paused in virsh

Pretty straight-forward exposure of new flags.  For most commands,
we let the API reject mutually exclusive flags; but for save-image-edit,
we do the sanity check ourselves to avoid looping on flag failure if
the edit cycle is ever enhanced to allow the user to retry an edit
to fix up an xml validation error.

* tools/virsh.c (cmdManagedSave, cmdRestore, cmdSave)
(cmdSaveImageDefine, cmdSaveImageEdit): Add new flags.
* tools/virsh.pod (managedsave, restore, save, save-image-define)
(save-image-edit): Document them.
This commit is contained in:
Eric Blake 2011-08-27 08:16:04 -06:00
parent 3cff66f487
commit 42c52d53c3
2 changed files with 99 additions and 10 deletions

View File

@ -1641,6 +1641,8 @@ static const vshCmdOptDef opts_save[] = {
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("where to save the data")},
{"xml", VSH_OT_STRING, 0,
N_("filename containing updated XML for the target")},
{"running", VSH_OT_BOOL, 0, N_("set domain to be running on restore")},
{"paused", VSH_OT_BOOL, 0, N_("set domain to be paused on restore")},
{NULL, 0, 0, NULL}
};
@ -1663,6 +1665,10 @@ cmdSave(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "bypass-cache"))
flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
if (vshCommandOptBool(cmd, "running"))
flags |= VIR_DOMAIN_SAVE_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_SAVE_PAUSED;
if (vshCommandOptString(cmd, "xml", &xmlfile) < 0) {
vshError(ctl, "%s", _("malformed xml argument"));
@ -1750,6 +1756,8 @@ static const vshCmdOptDef opts_save_image_define[] = {
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to modify")},
{"xml", VSH_OT_STRING, VSH_OFLAG_REQ,
N_("filename containing updated XML for the target")},
{"running", VSH_OT_BOOL, 0, N_("set domain to be running on restore")},
{"paused", VSH_OT_BOOL, 0, N_("set domain to be paused on restore")},
{NULL, 0, 0, NULL}
};
@ -1760,6 +1768,12 @@ cmdSaveImageDefine(vshControl *ctl, const vshCmd *cmd)
bool ret = false;
const char *xmlfile = NULL;
char *xml = NULL;
unsigned int flags = 0;
if (vshCommandOptBool(cmd, "running"))
flags |= VIR_DOMAIN_SAVE_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_SAVE_PAUSED;
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
@ -1799,6 +1813,8 @@ static const vshCmdInfo info_save_image_edit[] = {
static const vshCmdOptDef opts_save_image_edit[] = {
{"file", VSH_OT_DATA, VSH_OFLAG_REQ, N_("saved state file to edit")},
{"running", VSH_OT_BOOL, 0, N_("set domain to be running on restore")},
{"paused", VSH_OT_BOOL, 0, N_("set domain to be paused on restore")},
{NULL, 0, 0, NULL}
};
@ -1810,7 +1826,22 @@ cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
char *tmp = NULL;
char *doc = NULL;
char *doc_edited = NULL;
unsigned int flags = VIR_DOMAIN_XML_SECURE;
unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE;
unsigned int define_flags = 0;
if (vshCommandOptBool(cmd, "running"))
define_flags |= VIR_DOMAIN_SAVE_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
define_flags |= VIR_DOMAIN_SAVE_PAUSED;
/* Normally, we let the API reject mutually exclusive flags.
* However, in the edit cycle, we let the user retry if the define
* step fails, but the define step will always fail on invalid
* flags, so we reject it up front to avoid looping. */
if (define_flags == (VIR_DOMAIN_SAVE_RUNNING | VIR_DOMAIN_SAVE_PAUSED)) {
vshError(ctl, "%s", _("--running and --saved are mutually exclusive"));
return false;
}
if (!vshConnectionUsability(ctl, ctl->conn))
return false;
@ -1819,7 +1850,7 @@ cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
return false;
/* Get the XML configuration of the saved image. */
doc = virDomainSaveImageGetXMLDesc(ctl->conn, file, flags);
doc = virDomainSaveImageGetXMLDesc(ctl->conn, file, getxml_flags);
if (!doc)
goto cleanup;
@ -1837,8 +1868,9 @@ cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
if (!doc_edited)
goto cleanup;
/* Compare original XML with edited. Has it changed at all? */
if (STREQ(doc, doc_edited)) {
/* Compare original XML with edited. Short-circuit if it did not
* change, and we do not have any flags. */
if (STREQ(doc, doc_edited) && !define_flags) {
vshPrint(ctl, _("Saved image %s XML configuration not changed.\n"),
file);
ret = true;
@ -1846,7 +1878,8 @@ cmdSaveImageEdit(vshControl *ctl, const vshCmd *cmd)
}
/* Everything checks out, so redefine the xml. */
if (virDomainSaveImageDefineXML(ctl->conn, file, doc_edited, 0) < 0) {
if (virDomainSaveImageDefineXML(ctl->conn, file, doc_edited,
define_flags) < 0) {
vshError(ctl, _("Failed to update %s"), file);
goto cleanup;
}
@ -1879,6 +1912,8 @@ static const vshCmdInfo info_managedsave[] = {
static const vshCmdOptDef opts_managedsave[] = {
{"bypass-cache", VSH_OT_BOOL, 0, N_("avoid file system cache when saving")},
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
{"running", VSH_OT_BOOL, 0, N_("set domain to be running on next start")},
{"paused", VSH_OT_BOOL, 0, N_("set domain to be paused on next start")},
{NULL, 0, 0, NULL}
};
@ -1895,6 +1930,10 @@ cmdManagedSave(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "bypass-cache"))
flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
if (vshCommandOptBool(cmd, "running"))
flags |= VIR_DOMAIN_SAVE_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_SAVE_PAUSED;
if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
return false;
@ -2238,6 +2277,8 @@ static const vshCmdOptDef opts_restore[] = {
N_("avoid file system cache when restoring")},
{"xml", VSH_OT_STRING, 0,
N_("filename containing updated XML for the target")},
{"running", VSH_OT_BOOL, 0, N_("restore domain into running state")},
{"paused", VSH_OT_BOOL, 0, N_("restore domain into paused state")},
{NULL, 0, 0, NULL}
};
@ -2258,6 +2299,10 @@ cmdRestore(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "bypass-cache"))
flags |= VIR_DOMAIN_SAVE_BYPASS_CACHE;
if (vshCommandOptBool(cmd, "running"))
flags |= VIR_DOMAIN_SAVE_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_SAVE_PAUSED;
if (vshCommandOptString(cmd, "xml", &xmlfile) < 0) {
vshError(ctl, "%s", _("malformed xml argument"));
@ -12392,6 +12437,8 @@ static const vshCmdInfo info_snapshot_revert[] = {
static const vshCmdOptDef opts_snapshot_revert[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
{"snapshotname", VSH_OT_DATA, VSH_OFLAG_REQ, N_("snapshot name")},
{"running", VSH_OT_BOOL, 0, N_("after reverting, change state to running")},
{"paused", VSH_OT_BOOL, 0, N_("after reverting, change state to paused")},
{NULL, 0, 0, NULL}
};
@ -12402,6 +12449,12 @@ cmdDomainSnapshotRevert(vshControl *ctl, const vshCmd *cmd)
bool ret = false;
const char *name = NULL;
virDomainSnapshotPtr snapshot = NULL;
unsigned int flags = 0;
if (vshCommandOptBool(cmd, "running"))
flags |= VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING;
if (vshCommandOptBool(cmd, "paused"))
flags |= VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED;
if (!vshConnectionUsability(ctl, ctl->conn))
goto cleanup;
@ -12417,7 +12470,7 @@ cmdDomainSnapshotRevert(vshControl *ctl, const vshCmd *cmd)
if (snapshot == NULL)
goto cleanup;
if (virDomainRevertToSnapshot(snapshot, 0) < 0)
if (virDomainRevertToSnapshot(snapshot, flags) < 0)
goto cleanup;
ret = true;

View File

@ -623,6 +623,7 @@ The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
variables, and defaults to C<vi>.
=item B<managedsave> I<domain-id> [I<--bypass-cache>]
[{I<--running> | I<--paused>}]
Save and destroy (stop) a running domain, so it can be restarted from the same
state at a later time. When the virsh B<start> command is next run for
@ -630,6 +631,11 @@ the domain, it will automatically be started from this saved state.
If I<--bypass-cache> is specified, the save will avoid the file system
cache, although this may slow down the operation.
Normally, starting a managed save will decide between running or paused
based on the state the domain was in when the save was done; passing
either the I<--running> or I<--paused> flag will allow overriding which
state the B<start> should use.
The B<dominfo> command can be used to query whether a domain currently
has any managed save image.
@ -716,6 +722,7 @@ The exact behavior of a domain when it reboots is set by the
I<on_reboot> parameter in the domain's XML definition.
=item B<restore> I<state-file> [I<--bypass-cache>] [I<--xml> B<file>]
[{I<--running> | I<--paused>}]
Restores a domain from a B<virsh save> state file. See I<save> for more info.
@ -728,12 +735,18 @@ in the host-specific portions of the domain XML. For example, it can
be used to account for file naming differences in underlying storage
due to disk snapshots taken after the guest was saved.
Normally, restoring a saved image will use the state recorded in the
save image to decide between running or paused; passing either the
I<--running> or I<--paused> flag will allow overriding which state the
domain should be started in.
B<Note>: To avoid corrupting file system contents within the domain, you
should not reuse the saved state file for a second B<restore> unless you
have also reverted all storage volumes back to the same contents as when
the state file was created.
=item B<save> I<domain-id> I<state-file> [I<--bypass-cache>] [I<--xml> B<file>]
[{I<--running> | I<--paused>}]
Saves a running domain (RAM, but not disk state) to a state file so that
it can be restored
@ -753,12 +766,17 @@ in the host-specific portions of the domain XML. For example, it can
be used to account for file naming differences that are planned to
be made via disk snapshots of underlying storage after the guest is saved.
Normally, restoring a saved image will decide between running or paused
based on the state the domain was in when the save was done; passing
either the I<--running> or I<--paused> flag will allow overriding which
state the B<restore> should use.
Domain saved state files assume that disk images will be unchanged
between the creation and restore point. For a more complete system
restore point, where the disk state is saved alongside the memory
state, see the B<snapshot> family of commands.
=item B<save-image-define> I<file> I<xml>
=item B<save-image-define> I<file> I<xml> [{I<--running> | I<--paused>}]
Update the domain XML that will be used when I<file> is later
used in the B<restore> command. The I<xml> argument must be a file
@ -767,17 +785,27 @@ host-specific portions of the domain XML. For example, it can
be used to account for file naming differences resulting from creating
disk snapshots of underlying storage after the guest was saved.
The save image records whether the domain should be restored to a
running or paused state. Normally, this command does not alter the
recorded state; passing either the I<--running> or I<--paused> flag
will allow overriding which state the B<restore> should use.
=item B<save-image-dumpxml> I<file> [I<--security-info>]
Extract the domain XML that was in effect at the time the saved state
file I<file> was created with the B<save> command. Using
I<--security-info> will also include security sensitive information.
=item B<save-image-edit> I<file>
=item B<save-image-edit> I<file> [{I<--running> | I<--paused>}]
Edit the XML configuration associated with a saved state file I<file>
created by the B<save> command.
The save image records whether the domain should be restored to a
running or paused state. Normally, this command does not alter the
recorded state; passing either the I<--running> or I<--paused> flag
will allow overriding which state the B<restore> should use.
This is equivalent to:
virsh save-image-dumpxml state-file > state-file.xml
@ -1691,14 +1719,22 @@ Output the snapshot XML for the domain's snapshot named I<snapshot>.
Output the name of the parent snapshot for the given I<snapshot>, if any.
=item B<snapshot-revert> I<domain> I<snapshot>
=item B<snapshot-revert> I<domain> I<snapshot> [{I<--running> | I<--paused>}]
Revert the given domain to the snapshot specified by I<snapshot>. Be aware
that this is a destructive action; any changes in the domain since the
that this is a destructive action; any changes in the domain since the last
snapshot was taken will be lost. Also note that the state of the domain after
snapshot-revert is complete will be the state of the domain at the time
the original snapshot was taken.
Normally, reverting to a snapshot leaves the domain in the state it was
at the time the snapshot was created, except that a disk snapshot with
no vm state leaves the domain in an inactive state. Passing either the
I<--running> or I<--paused> flag will perform additional state changes
(such as booting an inactive domain, or pausing a running domain). Since
transient domains cannot be inactive, it is required to use one of these
flags when reverting to a disk snapshot of a transient domain.
=item B<snapshot-delete> I<domain> I<snapshot> I<--children>
Delete the snapshot for the domain named I<snapshot>. If this snapshot