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");