The current API provides the following Save abd Restore functions:
int virDomainSave (virDomainPtr domain,
const char *to);
int virDomainRestore (virConnectPtr conn,
const char *from);
where the user provide the path to the file used to hold the domain
saved state.
However it can be really useful to have a managed version where
libvirt itself stores the data. It can then automatically reuse it
once the domain is to be restarted. This also avoid the problem of
keeping stale saved data once a domain has been restarted independantly.
One of our use case was to save the running domains state on shutdown,
and unfortunately virDomainSave()/virDomainRestore() can't be used
for that because if one of the domain is labelled as autorestart,
as soon as the daemon would restart it would recreate the guest but
without knowledge of the backup state.
So we propose the 3 following new APIs to deal with managed saves:
int virDomainManagedSave(virDomainPtr dom, unsigned int flags);
int virDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags);
int virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags);
virDomainManagedSave() is to be run on a running domain. Once the call
complete, as in virDomainSave() the domain is stopped upon completion,
but there is no restore counterpart as any order to start the domain
from the API would load the state from the managed file, similary if
the domain is autostarted when libvirtd starts.
Once a domain has restarted his managed save image is destroyed,
basically managed save image can only exist for a stopped domain,
for a running domain that would be by definition outdated data.
Suggested new entry points in libvirt.c are below, thanks in advance for
any feedback (and thanks to Chris Lalancette who started this work):
diff --git a/src/libvirt.c b/src/libvirt.c
index cc5b4c5..293ea17 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -12135,3 +12135,143 @@ error:
virDispatchError(conn);
return -1;
}
+
+/**
+ * virDomainManagedSave:
+ * @dom: pointer to the domain
+ * @flags: optional flags currently unused
+ *
+ * This method will suspend a domain and save its memory contents to
+ * a file on disk. After the call, if successful, the domain is not
+ * listed as running anymore.
+ * The difference from virDomainSave() is that libvirt is keeping track of
+ * the saved state itself, and will reuse it once the domain is being
+ * restarted (automatically or via an explicit libvirt call).
+ * As a result any running domain is sure to not have a managed saved image.
+ *
+ * Returns 0 in case of success or -1 in case of failure
+ */
+int virDomainManagedSave(virDomainPtr dom, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("dom=%p, flags=%u", dom, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ conn = dom->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(dom, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainManagedSave) {
+ int ret;
+
+ ret = conn->driver->domainManagedSave(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virDomainHasManagedSaveImage:
+ * @dom: pointer to the domain
+ * @flags: optional flags currently unused
+ *
+ * Check if a domain has a managed save image as created by
+ * virDomainManagedSave(). Note that any running domain should not have
+ * such an image, as it should have been removed on restart.
+ *
+ * Returns 0 if no image is present, 1 if an image is present, and
+ * -1 in case of error
+ */
+int virDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("dom=%p, flags=%u", dom, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ conn = dom->conn;
+
+ if (conn->driver->domainHasManagedSaveImage) {
+ int ret;
+
+ ret = conn->driver->domainHasManagedSaveImage(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
+
+/**
+ * virDomainManagedSaveRemove:
+ * @dom: pointer to the domain
+ * @flags: optional flags currently unused
+ *
+ * Remove any managed save image as for this domain.
+ *
+ * Returns 0 in case of success, and -1 in case of error
+ */
+int virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("dom=%p, flags=%u", dom, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ conn = dom->conn;
+ if (conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(dom, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainManagedSaveRemove) {
+ int ret;
+
+ ret = conn->driver->domainManagedSaveRemove(dom, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(conn);
+ return -1;
+}
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit
http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/