2010/4/1 Chris Lalancette <clalance(a)redhat.com>:
Hello,
Here is the 4th (and hopefully final) draft for the snapshot API that
we've been discussing. There is one minor change and one major change in
this draft. The minor change is that we've added a virDomainSnapshotHasCurrent
and virDomainSnapshotCurrent methods to get at the current snapshot. The
major change is that I've removed all but one of the possible
virDomainSnapshotDelete() flags. After reviewing ESX, virtualbox, and qemu, it
seems that the deletion of any snapshots that have children will *automatically*
merge the changes from that snapshot into the children to keep the children
viable. Therefore, the MERGE and MERGE_FORCE flags are nonsensical. Since this
is the virDomainSnapshotDelete call, we don't really need a flag to say
"delete",
so I've removed the DISCARD flag. What that leaves us with is a single flag to
the delete API that says to delete this snapshot, and all children of this
snapshot. This could be useful to clean out a tree of snapshots instead of
doing it one-by-one.
If there are no further major objections to this API, we'll be posting
patches later today or tomorrow that implement this API for both qemu and
virtualbox.
Note that I've not included my full notes from last time. If anyone
is still interested in those, I can either repost them or send them privately.
/* Get a handle to the current in-use snapshot for the domain. */
int virDomainSnapshotCurrent(virDomainPtr domain,
unsigned int flags);
/* Start the guest from the snapshot "snapshot". Note that
* the guest may either be running or not.
*
* In the case the VM is running, then the snapshot *must* have
* been taken while the VM was running (i.e. the snapshot <state>
* tag must be "RUNNING"). This will revert the disk and memory to
Basically everything in the libvirt XML formats is lowercase.
Therefore, I think the states should be lowercase too.
* "snapshot".
*
* In the case the VM is not running, then the snapshot may
* have been taken while the VM was not running or not. In
* either case it will revert just the disk to "snapshot".
*/
int virDomainCreateFromSnapshot(virDomainSnapshotPtr snapshot,
unsigned int flags);
What's the reason for this strange semantic of making the behavior of
switching to a snapshot dependent on the current state of the guest?
This means if I have a stopped guest and want to switch to a snapshot
from the running domain, then I have to start the domain first from
it's current state and then switch to the snapshot. In another case I
have to stop the domain first in order to switch to a disk-only
snapshot.
I think I understand what you're trying to achieve, but I think ESX4
models this better with it's suppressPowerOn option for the
RevertToSnapshot_Task.
IMHO this should be modeled as a flag to virDomainCreateFromSnapshot,
instead of making its behavior dependent on the current state of a
domain.
If the domain is currently running and I switch to a disk-only
snapshot then the domain should be stopped afterwards.
If I switch back to a snapshot that was taken in running state, then
the domain should be running afterwards, regardless of the state of
the domain before the virDomainCreateFromSnapshot call. But if I call
virDomainCreateFromSnapshot with the suppressPowerOn flag the domain
should be stopped afterwards, regardless of the domain's state before
the call and regardless of the type of snapshot I switched to.
Another thing is the name: virDomainCreateFromSnapshot. You're
description for this functions says it "starts" the domain, but with
your proposed semantic it just changes the snapshot but doesn't change
the power state at all.
ESX calls this operation "revert" and VirtualBox "restore".
I think this needs still some discussion.
/* Delete a snapshot.
*
* TREE: discard this snapshot and any children snapshots
*
* Note that this operation can happen when the domain is running or shut
* down, though this is hypervisor specific */
*/
typedef enum {
VIR_DOMAIN_SNAPSHOT_DELETE_TREE,
} virDomainSnapshotDelete;
int virDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
unsigned int flags);
int virDomainSnapshotFree(virDomainSnapshotPtr snapshot);
NOTE: During snapshot creation, *none* of the fields are required. That is,
you can call virDomainSnapshotCreateXML() with an XML of
"<domainsnapshot/>".
In this case, the individual driver will make up a <name> for you,
the <creationdate> will be set to the current time+date, <description> will
be
empty, <state> will be the current state of the VM, and <parent> will
be set to the current snapshot (if any). If you do want to specify some
fields during virDomainSnapshotCreateXML(), note that the only ones that are
settable are <name> and <description>;
the rest are ignored, and filled in by the driver when the snapshot is
actually created.
NOTE: <state> refers to the state of the VM when the snapshot was taken.
NOTE: <creationdate> is in the format %Y-%m-%d_%T as defined by strptime.
What about timezone information?
Also note that the granularity of <creationdate> is in
seconds.
<domainsnapshot>
<name>XYZ</name>
<creationdate>...</creationdate>
<description>...</description>
<state>RUNNING</state>
<domain>
<uuid>XXXXX-XXXX-XXXX-XXXX-XXXXXXXXX</uuid>
</domain>
<parent>
<name>ABC</name>
</parent>
</domainsnapshot>
The virsh commands will be:
virsh snapshot-create <dom> [<xmlfile>]
virsh snapshot-list <dom>
virsh snapshot-dumpxml <dom> <name>
virsh start-from-snapshot <dom> <snapshotname>
virsh snapshot-delete <dom> <snapshotname> [--children]
You should either name it --tree or
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, just make the naming consistent.
Matthias