diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in index 91799b42c7..a0940ac4ba 100644 --- a/docs/formatsnapshot.html.in +++ b/docs/formatsnapshot.html.in @@ -6,6 +6,65 @@

Snapshot XML

+

+ There are several types of snapshots: +

+
+
disk snapshot
+
Contents of disks (whether a subset or all disks associated + with the domain) are saved at a given point of time, and can + be restored back to that state. On a running guest, a disk + snapshot is likely to be only crash-consistent rather than + clean (that is, it represents the state of the disk on a + sudden power outage, and may need fsck or journal replays to + be made consistent); on an inactive guest, a disk snapshot is + clean if the disks were clean when the guest was last shut + down. Disk snapshots exist in two forms: internal (file + formats such as qcow2 track both the snapshot and changes + since the snapshot in a single file) and external (the + snapshot is one file, and the changes since the snapshot are + in another file).
+
VM state
+
Tracks only the state of RAM and all other resources in use + by the VM. If the disks are unmodified between the time a VM + state snapshot is taken and restored, then the guest will + resume in a consistent state; but if the disks are modified + externally in the meantime, this is likely to lead to data + corruption.
+
system checkpoint
+
A combination of disk snapshots for all disks as well as VM + state, which can be used to resume the guest from where it + left off with symptoms similar to hibernation (that is, TCP + connections in the guest may have timed out, but no files or + processes are lost).
+
+ +

+ Libvirt can manage all three types of snapshots. For now, VM + state snapshots are created only by + the virDomainSave(), virDomainSaveFlags, + and virDomainManagedSave() functions, and restored + via the virDomainRestore(), + virDomainRestoreFlags(), virDomainCreate(), + and virDomainCreateWithFlags() functions (as well + as via domain autostart). With managed snapshots, libvirt + tracks all information internally; with save images, the user + tracks the snapshot file, but libvirt provides functions such + as virDomainSaveImageGetXMLDesc() to work with + those files. +

+

System checkpoints are created + by virDomainSnapshotCreateXML() with no flags, and + disk snapshots are created by the same function with + the VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY flag; in + both cases, they are restored by + the virDomainRevertToSnapshot() function. For + these types of snapshots, libvirt tracks each snapshot as a + separate virDomainSnapshotPtr object, and maintains + a tree relationship of which snapshots descended from an earlier + point in time. +

+

Attributes of libvirt snapshots are stored as child elements of the domainsnapshot element. At snapshot creation @@ -53,14 +112,21 @@

state
The state of the domain at the time this snapshot was taken. - When the domain is reverted to this snapshot, the domain's - state will default to whatever is in this field. Readonly. + If the snapshot was created as a system checkpoint, then this + is the state of the domain at that time; when the domain is + reverted to this snapshot, the domain's state will default to + whatever is in this field unless additional flags are passed + to virDomainRevertToSnapshot(). Additionally, + this field can be the value "disk-snapshot" + (since 0.9.5) when it represents + only a disk snapshot (no VM state), and reverting to this + snapshot will default to an inactive guest. Readonly.
parent
-
The parent of this snapshot. This element contains exactly - one child element, name. This specifies the name of the parent - snapshot of this snapshot, and is used to represent trees of - snapshots, as described above. Readonly. +
The parent of this snapshot. If present, this element + contains exactly one child element, name. This specifies the + name of the parent snapshot of this snapshot, and is used to + represent trees of snapshots. Readonly.
domain
The domain that this snapshot was taken against. Older @@ -70,7 +136,7 @@ created in, and requires the use of the VIR_DOMAIN_SNAPSHOT_REVERT_FORCE flag in virDomainRevertToSnapshot(). Newer versions - of libvirt store the entire + of libvirt (since 0.9.5) store the entire inactive domain configuration at the time of the snapshot (since 0.9.5). Readonly. diff --git a/docs/schemas/domainsnapshot.rng b/docs/schemas/domainsnapshot.rng index a16d73132c..130dad9ca6 100644 --- a/docs/schemas/domainsnapshot.rng +++ b/docs/schemas/domainsnapshot.rng @@ -22,7 +22,7 @@ - + @@ -59,4 +59,17 @@ + + + nostate + running + blocked + paused + shutdown + shutoff + crashed + disk-snapshot + + + diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 0f0efc1a4e..4292736f8a 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -86,7 +86,14 @@ typedef enum { VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */ VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */ VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */ - VIR_DOMAIN_CRASHED = 6 /* the domain is crashed */ + VIR_DOMAIN_CRASHED = 6, /* the domain is crashed */ + + /* + * NB: this enum value will increase over time as new events are + * added to the libvirt API. It reflects the last state supported + * by this version of the libvirt API. + */ + VIR_DOMAIN_LAST } virDomainState; typedef enum { @@ -1892,6 +1899,11 @@ typedef enum { VIR_KEYCODE_SET_WIN32 = 8, VIR_KEYCODE_SET_RFB = 9, + /* + * NB: this enum value will increase over time as new events are + * added to the libvirt API. It reflects the last keycode set supported + * by this version of the libvirt API. + */ VIR_KEYCODE_SET_LAST, } virKeycodeSet; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c9e6e38bfa..270d02dcd2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -437,7 +437,13 @@ VIR_ENUM_IMPL(virDomainHostdevSubsys, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST, "usb", "pci") -VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1, +VIR_ENUM_IMPL(virDomainHub, VIR_DOMAIN_HUB_TYPE_LAST, + "usb") + +VIR_ENUM_IMPL(virDomainRedirdevBus, VIR_DOMAIN_REDIRDEV_BUS_LAST, + "usb") + +VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_LAST, "nostate", "running", "blocked", @@ -446,11 +452,16 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1, "shutoff", "crashed") -VIR_ENUM_IMPL(virDomainHub, VIR_DOMAIN_HUB_TYPE_LAST, - "usb") - -VIR_ENUM_IMPL(virDomainRedirdevBus, VIR_DOMAIN_REDIRDEV_BUS_LAST, - "usb") +/* virDomainSnapshotState is really virDomainState plus one extra state */ +VIR_ENUM_IMPL(virDomainSnapshotState, VIR_DOMAIN_DISK_SNAPSHOT+1, + "nostate", + "running", + "blocked", + "paused", + "shutdown", + "shutoff", + "crashed", + "disk-snapshot") #define VIR_DOMAIN_NOSTATE_LAST (VIR_DOMAIN_NOSTATE_UNKNOWN + 1) VIR_ENUM_IMPL(virDomainNostateReason, VIR_DOMAIN_NOSTATE_LAST, @@ -11486,7 +11497,7 @@ virDomainSnapshotDefParseString(const char *xmlStr, _("missing state from existing snapshot")); goto cleanup; } - def->state = virDomainStateTypeFromString(state); + def->state = virDomainSnapshotStateTypeFromString(state); if (def->state < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid state '%s' in domain snapshot XML"), @@ -11559,7 +11570,7 @@ char *virDomainSnapshotDefFormat(char *domain_uuid, virBufferEscapeString(&buf, " %s\n", def->description); virBufferAsprintf(&buf, " %s\n", - virDomainStateTypeToString(def->state)); + virDomainSnapshotStateTypeToString(def->state)); if (def->parent) { virBufferAddLit(&buf, " \n"); virBufferEscapeString(&buf, " %s\n", def->parent); @@ -12139,6 +12150,7 @@ virDomainObjSetState(virDomainObjPtr dom, virDomainState state, int reason) case VIR_DOMAIN_SHUTDOWN: last = VIR_DOMAIN_SHUTDOWN_LAST; break; case VIR_DOMAIN_SHUTOFF: last = VIR_DOMAIN_SHUTOFF_LAST; break; case VIR_DOMAIN_CRASHED: last = VIR_DOMAIN_CRASHED_LAST; break; + default: last = -1; } if (last < 0) { @@ -12172,9 +12184,9 @@ virDomainStateReasonToString(virDomainState state, int reason) return virDomainShutoffReasonTypeToString(reason); case VIR_DOMAIN_CRASHED: return virDomainCrashedReasonTypeToString(reason); + default: + return NULL; } - - return NULL; } @@ -12196,9 +12208,9 @@ virDomainStateReasonFromString(virDomainState state, const char *reason) return virDomainShutoffReasonTypeFromString(reason); case VIR_DOMAIN_CRASHED: return virDomainCrashedReasonTypeFromString(reason); + default: + return -1; } - - return -1; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 7e09c0abb4..749fcce86d 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -253,6 +253,11 @@ enum virDomainDiskSnapshot { VIR_DOMAIN_DISK_SNAPSHOT_LAST }; +enum virDomainSnapshotState { + /* Inherit the VIR_DOMAIN_* states from virDomainState. */ + VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST, +}; + /* Stores the virtual disk configuration */ typedef struct _virDomainDiskDef virDomainDiskDef; typedef virDomainDiskDef *virDomainDiskDefPtr; @@ -1395,7 +1400,7 @@ struct _virDomainSnapshotDef { char *description; char *parent; long long creationTime; /* in seconds */ - int state; + int state; /* enum virDomainSnapshotState */ virDomainDefPtr dom; /* Internal use. */ @@ -1832,6 +1837,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression) VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode) VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste) VIR_ENUM_DECL(virDomainNumatuneMemMode) +VIR_ENUM_DECL(virDomainSnapshotState) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainNostateReason) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 60e2f14e69..2341110ce9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -399,6 +399,8 @@ virDomainSnapshotHasChildren; virDomainSnapshotObjListGetNames; virDomainSnapshotObjListNum; virDomainSnapshotObjListRemove; +virDomainSnapshotStateTypeFromString; +virDomainSnapshotStateTypeToString; virDomainSoundDefFree; virDomainSoundModelTypeFromString; virDomainSoundModelTypeToString; diff --git a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml new file mode 100644 index 0000000000..391bb5762d --- /dev/null +++ b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml @@ -0,0 +1,35 @@ + + my snap name + !@#$%^ + + earlier_snap + + disk-snapshot + 1272917631 + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + + 1 + diff --git a/tools/virsh.c b/tools/virsh.c index d1ebc4093a..7ae5b404e0 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -14588,6 +14588,8 @@ vshDomainState(vshControl *ctl, virDomainPtr dom, int *reason) static const char * vshDomainStateToString(int state) { + /* Can't use virDomainStateTypeToString, because we want to mark + * strings for translation. */ switch ((virDomainState) state) { case VIR_DOMAIN_RUNNING: return N_("running"); @@ -14602,6 +14604,7 @@ vshDomainStateToString(int state) case VIR_DOMAIN_CRASHED: return N_("crashed"); case VIR_DOMAIN_NOSTATE: + default: ;/*FALLTHROUGH*/ } return N_("no state"); /* = dom0 state */ @@ -14703,6 +14706,9 @@ vshDomainStateReasonToString(int state, int reason) ; } break; + + default: + ; } return N_("unknown");