<h2><a name="SnapshotAttributes">Snapshot XML</a></h2>
+ <p>
+ There are several types of snapshots:
+ </p>
+ <dl>
+ <dt>disk snapshot</dt>
+ <dd>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).</dd>
+ <dt>VM state</dt>
+ <dd>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.</dd>
+ <dt>system checkpoint</dt>
+ <dd>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).</dd>
+ </dl>
+
+ <p>
+ Libvirt can manage all three types of snapshots. For now, VM
+ state snapshots are created only by
+ the <code>virDomainSave()</code>, <code>virDomainSaveFlags</code>,
+ and <code>virDomainManagedSave()</code> functions, and restored
+ via the <code>virDomainRestore()</code>,
+ <code>virDomainRestoreFlags()</code>, <code>virDomainCreate()</code>,
+ and <code>virDomainCreateWithFlags()</code> 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 <code>virDomainSaveImageGetXMLDesc()</code> to work with
+ those files.
+ </p>
+ <p>System checkpoints are created
+ by <code>virDomainSnapshotCreateXML()</code> with no flags, and
+ disk snapshots are created by the same function with
+ the <code>VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY</code> flag; in
+ both cases, they are restored by
+ the <code>virDomainRevertToSnapshot()</code> function. For
+ these types of snapshots, libvirt tracks each snapshot as a
+ separate <code>virDomainSnapshotPtr</code> object, and maintains
+ a tree relationship of which snapshots descended from an earlier
+ point in time.
+ </p>
+
<p>
Attributes of libvirt snapshots are stored as child elements of
the <code>domainsnapshot</code> element. At snapshot creation
</dd>
<dt><code>state</code></dt>
<dd>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 <code>virDomainRevertToSnapshot()</code>. Additionally,
+ this field can be the value "disk-snapshot"
+ (<span class="since">since 0.9.5</span>) when it represents
+ only a disk snapshot (no VM state), and reverting to this
+ snapshot will default to an inactive guest. Readonly.
</dd>
<dt><code>parent</code></dt>
- <dd>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.
+ <dd>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.
</dd>
<dt><code>domain</code></dt>
<dd>The domain that this snapshot was taken against. Older
created in, and requires the use of the
<code>VIR_DOMAIN_SNAPSHOT_REVERT_FORCE</code> flag
in <code>virDomainRevertToSnapshot()</code>. Newer versions
- of libvirt store the entire
+ of libvirt (<span class="since">since 0.9.5</span>) store the entire
inactive <a href="formatdomain.html">domain configuration</a>
at the time of the snapshot (<span class="since">since
0.9.5</span>). Readonly.
</optional>
<optional>
<element name='state'>
- <text/>
+ <ref name='state'/>
</element>
</optional>
<optional>
</element>
</define>
+ <define name='state'>
+ <choice>
+ <value>nostate</value>
+ <value>running</value>
+ <value>blocked</value>
+ <value>paused</value>
+ <value>shutdown</value>
+ <value>shutoff</value>
+ <value>crashed</value>
+ <value>disk-snapshot</value>
+ </choice>
+ </define>
+
</grammar>
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 {
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;
"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",
"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,
_("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"),
virBufferEscapeString(&buf, " <description>%s</description>\n",
def->description);
virBufferAsprintf(&buf, " <state>%s</state>\n",
- virDomainStateTypeToString(def->state));
+ virDomainSnapshotStateTypeToString(def->state));
if (def->parent) {
virBufferAddLit(&buf, " <parent>\n");
virBufferEscapeString(&buf, " <name>%s</name>\n", def->parent);
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) {
return virDomainShutoffReasonTypeToString(reason);
case VIR_DOMAIN_CRASHED:
return virDomainCrashedReasonTypeToString(reason);
+ default:
+ return NULL;
}
-
- return NULL;
}
return virDomainShutoffReasonTypeFromString(reason);
case VIR_DOMAIN_CRASHED:
return virDomainCrashedReasonTypeFromString(reason);
+ default:
+ return -1;
}
-
- return -1;
}
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;
char *description;
char *parent;
long long creationTime; /* in seconds */
- int state;
+ int state; /* enum virDomainSnapshotState */
virDomainDefPtr dom;
/* Internal use. */
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)
virDomainSnapshotObjListGetNames;
virDomainSnapshotObjListNum;
virDomainSnapshotObjListRemove;
+virDomainSnapshotStateTypeFromString;
+virDomainSnapshotStateTypeToString;
virDomainSoundDefFree;
virDomainSoundModelTypeFromString;
virDomainSoundModelTypeToString;
--- /dev/null
+<domainsnapshot>
+ <name>my snap name</name>
+ <description>!@#$%^</description>
+ <parent>
+ <name>earlier_snap</name>
+ </parent>
+ <state>disk-snapshot</state>
+ <creationTime>1272917631</creationTime>
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
+ <active>1</active>
+</domainsnapshot>
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");
case VIR_DOMAIN_CRASHED:
return N_("crashed");
case VIR_DOMAIN_NOSTATE:
+ default:
;/*FALLTHROUGH*/
}
return N_("no state"); /* = dom0 state */
;
}
break;
+
+ default:
+ ;
}
return N_("unknown");