[unchanged in v2]
Add managed save API entry points
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.
* include/libvirt/libvirt.h.in src/libvirt.c src/libvirt_public.syms:
adds the new entry points virDomainManagedSave(),
virDomainHasManagedSaveImage() and virDomainManagedSaveRemove()
* src/driver.h src/esx/esx_driver.c src/lxc/lxc_driver.c
src/opennebula/one_driver.c src/openvz/openvz_driver.c
src/phyp/phyp_driver.c src/qemu/qemu_driver.c src/vbox/vbox_tmpl.c
src/remote/remote_driver.c src/test/test_driver.c src/uml/uml_driver.c
src/xen/xen_driver.c: add corresponding new internal drivers entry
points
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 6d8552f..431e485 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -639,6 +639,16 @@ int virDomainRestore (virConnectPtr conn,
const char *from);
/*
+ * Managed domain save
+ */
+int virDomainManagedSave (virDomainPtr dom,
+ unsigned int flags);
+int virDomainHasManagedSaveImage(virDomainPtr dom,
+ unsigned int flags);
+int virDomainManagedSaveRemove(virDomainPtr dom,
+ unsigned int flags);
+
+/*
* Domain core dump
*/
int virDomainCoreDump (virDomainPtr domain,
diff --git a/src/driver.h b/src/driver.h
index 8f86463..7e2536d 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -402,6 +402,15 @@ typedef int
(*virDrvDomainEventDeregisterAny)(virConnectPtr conn,
int callbackID);
+typedef int
+ (*virDrvDomainManagedSave)(virDomainPtr domain, unsigned int flags);
+
+typedef int
+ (*virDrvDomainHasManagedSaveImage)(virDomainPtr domain, unsigned int flags);
+
+typedef int
+ (*virDrvDomainManagedSaveRemove)(virDomainPtr domain, unsigned int flags);
+
/**
* _virDriver:
*
@@ -499,6 +508,9 @@ struct _virDriver {
virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime;
virDrvDomainEventRegisterAny domainEventRegisterAny;
virDrvDomainEventDeregisterAny domainEventDeregisterAny;
+ virDrvDomainManagedSave domainManagedSave;
+ virDrvDomainHasManagedSaveImage domainHasManagedSaveImage;
+ virDrvDomainManagedSaveRemove domainManagedSaveRemove;
};
typedef int
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 663c560..7e57fff 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -3408,6 +3408,9 @@ static virDriver esxDriver = {
NULL, /* domainMigrateSetMaxDowntime */
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
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;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 2f812a1..24a422f 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -378,6 +378,9 @@ LIBVIRT_0.7.8 {
virNWFilterRef;
virNWFilterDefineXML;
virNWFilterUndefine;
+ virDomainManagedSave;
+ virDomainHasManagedSaveImage;
+ virDomainManagedSaveRemove;
} LIBVIRT_0.7.7;
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 7ebc7ae..1049f1b 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2544,6 +2544,9 @@ static virDriver lxcDriver = {
NULL, /* domainMigrateSetMaxDowntime */
lxcDomainEventRegisterAny, /* domainEventRegisterAny */
lxcDomainEventDeregisterAny, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
static virStateDriver lxcStateDriver = {
diff --git a/src/opennebula/one_driver.c b/src/opennebula/one_driver.c
index e901a03..91d7459 100644
--- a/src/opennebula/one_driver.c
+++ b/src/opennebula/one_driver.c
@@ -792,6 +792,9 @@ static virDriver oneDriver = {
NULL, /* domainMigrateSetMaxDowntime */
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
static virStateDriver oneStateDriver = {
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 6176577..32bc3c2 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1544,6 +1544,9 @@ static virDriver openvzDriver = {
NULL, /* domainMigrateSetMaxDowntime */
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
int openvzRegister(void) {
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 4f7efdb..0e1d35f 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -1651,6 +1651,9 @@ virDriver phypDriver = {
NULL, /* domainMigrateSetMaxDowntime */
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
int
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9ee5da7..17e6118 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10240,6 +10240,9 @@ static virDriver qemuDriver = {
qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
qemuDomainEventRegisterAny, /* domainEventRegisterAny */
qemuDomainEventDeregisterAny, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 3b8be21..9b500d0 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -9818,6 +9818,9 @@ static virDriver remote_driver = {
remoteDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
remoteDomainEventRegisterAny, /* domainEventRegisterAny */
remoteDomainEventDeregisterAny, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
static virNetworkDriver network_driver = {
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 646c7db..105f825 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -5306,6 +5306,9 @@ static virDriver testDriver = {
NULL, /* domainMigrateSetMaxDowntime */
testDomainEventRegisterAny, /* domainEventRegisterAny */
testDomainEventDeregisterAny, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
static virNetworkDriver testNetworkDriver = {
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 835e5d4..5fa1beb 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1936,6 +1936,9 @@ static virDriver umlDriver = {
NULL, /* domainMigrateSetMaxDowntime */
NULL, /* domainEventRegisterAny */
NULL, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index f7a9b9f..86f6a5a 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -7188,6 +7188,9 @@ virDriver NAME(Driver) = {
vboxDomainEventRegisterAny, /* domainEventRegisterAny */
vboxDomainEventDeregisterAny, /* domainEventDeregisterAny */
#endif
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
virNetworkDriver NAME(NetworkDriver) = {
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index ebdc600..a5d58d0 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1980,6 +1980,9 @@ static virDriver xenUnifiedDriver = {
NULL, /* domainMigrateSetMaxDowntime */
xenUnifiedDomainEventRegisterAny, /* domainEventRegisterAny */
xenUnifiedDomainEventDeregisterAny, /* domainEventDeregisterAny */
+ NULL, /* domainManagedSave */
+ NULL, /* domainHasManagedSaveImage */
+ NULL, /* domainManagedSaveRemove */
};
/**
--
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/