From 15c647a91e8c5bcfcb02ac4e755160c5c99a2a1e Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Thu, 1 Apr 2010 10:46:28 +0200 Subject: [PATCH] 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 --- include/libvirt/libvirt.h.in | 10 +++ src/driver.h | 12 +++ src/esx/esx_driver.c | 3 + src/libvirt.c | 140 +++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 3 + src/lxc/lxc_driver.c | 3 + src/opennebula/one_driver.c | 3 + src/openvz/openvz_driver.c | 3 + src/phyp/phyp_driver.c | 3 + src/qemu/qemu_driver.c | 3 + src/remote/remote_driver.c | 3 + src/test/test_driver.c | 3 + src/uml/uml_driver.c | 3 + src/vbox/vbox_tmpl.c | 3 + src/xen/xen_driver.c | 3 + 15 files changed, 198 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 7cb483e76e..a9be8798f6 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -638,6 +638,16 @@ int virDomainSave (virDomainPtr domain, 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 */ diff --git a/src/driver.h b/src/driver.h index 8f864638c7..7e2536d3c4 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 7a92c4dc4b..e55c948724 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -3389,6 +3389,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 5247fe7265..fb683c0a73 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -12136,3 +12136,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 2f812a1585..24a422fc63 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 9caefa13a4..01330ec352 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2538,6 +2538,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 e901a03fa3..91d7459cd9 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 61765771f1..32bc3c2e70 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 4f7efdbb48..0e1d35fa01 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 70d2781ef7..94f7fef522 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10312,6 +10312,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 3b8be2159d..9b500d0901 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 646c7db519..105f8250c4 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 08fbf930bd..443d82ed90 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1937,6 +1937,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 59ad1b8ad7..8450266003 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -7184,6 +7184,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 ebdc6009e6..a5d58d0418 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 */ }; /**