[libvirt] [PATCHv2 00/13] New API: virDominDestroyFlags

This series creates new API which adds flags to virDomainDestroy. As mentioned here many times, it is a bad luck all APIs don't have flags parameter. Parameter for this might be needed to select different ways of destroying a domain. For example, qemu has 'quit' command, which force it to flush internal caches a thus preventing from data loss. Or vice versa - in cases where we are doing hypervisor assisted destroy we might want to send signals, because hypervisor is not responding. Currently, no new functionality is implemented, but this paves the way for creating multiple ways of domain destroying. Therefore, calling this new API is the same as calling its predecessor. diff to v1: -rename virDominDestroyWithFlags() to virDominDestroyFlags() -rename enum virDominDestroyFlags to virDominDestroyFlagsValues Michal Privoznik (13): destroy: Define new public API virDomainDestroyFlags destroy: Wire up the remote protocol destroy: Implement internal API for qemu driver destroy: Implement internal API for ESX driver destroy: Implement internal API for libxl driver destroy: Implement internal API for lxc driver destroy: Implement internal API for openvz driver destroy: Implement internal API for phyp driver destroy: Implement internal API for uml driver destroy: Implement internal API for vbox driver destroy: Implement internal API for vmware driver destroy: Implement internal API for xen driver destroy: Implement internal API for xenapi driver include/libvirt/libvirt.h.in | 7 +++++ src/driver.h | 4 +++ src/esx/esx_driver.c | 12 +++++++++- src/libvirt.c | 52 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/libxl/libxl_driver.c | 12 +++++++++- src/lxc/lxc_driver.c | 23 +++++++++++++++++- src/openvz/openvz_driver.c | 13 +++++++++- src/phyp/phyp_driver.c | 12 +++++++++- src/qemu/qemu_driver.c | 13 +++++++++- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 8 +++++- src/remote_protocol-structs | 5 ++++ src/uml/uml_driver.c | 14 ++++++++++- src/vbox/vbox_tmpl.c | 14 ++++++++++- src/vmware/vmware_driver.c | 12 +++++++++- src/xen/xen_driver.c | 28 ++++++++++++++++++++++ src/xen/xen_driver.h | 1 + src/xen/xen_hypervisor.c | 24 +++++++++++++++++- src/xen/xen_hypervisor.h | 3 ++ src/xen/xen_inotify.c | 1 + src/xen/xend_internal.c | 24 +++++++++++++++++- src/xen/xm_internal.c | 1 + src/xen/xs_internal.c | 1 + src/xenapi/xenapi_driver.c | 22 ++++++++++++++++- 25 files changed, 291 insertions(+), 17 deletions(-) -- 1.7.5.rc3

This introduces new API virDomainDestroyFlags to allow domain destroying with flags, as the existing API virDomainDestroy misses flags. The set of flags is defined in virDomainDestroyFlagsValues enum, which is currently commented, because it is empty. Calling this API with no flags set (@flags == 0) is equivalent calling virDomainDestroy. --- include/libvirt/libvirt.h.in | 7 +++++ src/driver.h | 4 +++ src/libvirt.c | 52 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + 4 files changed, 64 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 6afd591..c368a9f 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -913,6 +913,11 @@ virConnectPtr virDomainGetConnect (virDomainPtr domain); /* * Domain creation and destruction */ + +/* + * typedef enum { + * } virDomainDestroyFlagsValues; + */ virDomainPtr virDomainCreateXML (virConnectPtr conn, const char *xmlDesc, unsigned int flags); @@ -929,6 +934,8 @@ int virDomainShutdown (virDomainPtr domain); int virDomainReboot (virDomainPtr domain, unsigned int flags); int virDomainDestroy (virDomainPtr domain); +int virDomainDestroyFlags (virDomainPtr domain, + unsigned int flags); int virDomainRef (virDomainPtr domain); int virDomainFree (virDomainPtr domain); diff --git a/src/driver.h b/src/driver.h index 4c4955f..9400fb2 100644 --- a/src/driver.h +++ b/src/driver.h @@ -124,6 +124,9 @@ typedef int unsigned int flags); typedef int (*virDrvDomainDestroy) (virDomainPtr domain); +typedef int + (*virDrvDomainDestroyFlags) (virDomainPtr domain, + unsigned int flags); typedef char * (*virDrvDomainGetOSType) (virDomainPtr domain); typedef unsigned long @@ -701,6 +704,7 @@ struct _virDriver { virDrvDomainShutdown domainShutdown; virDrvDomainReboot domainReboot; virDrvDomainDestroy domainDestroy; + virDrvDomainDestroyFlags domainDestroyFlags; virDrvDomainGetOSType domainGetOSType; virDrvDomainGetMaxMemory domainGetMaxMemory; virDrvDomainSetMaxMemory domainSetMaxMemory; diff --git a/src/libvirt.c b/src/libvirt.c index 16a9a02..baaf5fa 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2078,6 +2078,58 @@ error: } /** + * virDomainDestroyFlags: + * @domain: a domain object + * @flags: an OR'ed set of virDomainDestroyFlagsValues + * + * Destroy the domain object. The running instance is shutdown if not down + * already and all resources used by it are given back to the hypervisor. + * This does not free the associated virDomainPtr object. + * This function may require privileged access. + * + * Calling this function with no @flags set (equal zero) + * is equivalent calling virDomainDestroy. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainDestroyFlags(virDomainPtr domain, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain); + + virResetLastError(); + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + virDispatchError(NULL); + return -1; + } + + conn = domain->conn; + if (conn->flags & VIR_CONNECT_RO) { + virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (conn->driver->domainDestroyFlags) { + int ret; + ret = conn->driver->domainDestroyFlags(domain, flags); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(conn); + return -1; +} + +/** * virDomainFree: * @domain: a domain object * diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 5cc480e..f8b8c2d 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -469,6 +469,7 @@ LIBVIRT_0.9.3 { LIBVIRT_0.9.4 { global: virDomainUndefineFlags; + virDomainDestroyFlags; } LIBVIRT_0.9.3; # .... define new API here using predicted next version number .... -- 1.7.5.rc3

On 07/21/2011 10:08 AM, Michal Privoznik wrote:
This introduces new API virDomainDestroyFlags to allow domain destroying with flags, as the existing API virDomainDestroy misses flags.
The set of flags is defined in virDomainDestroyFlagsValues enum, which is currently commented, because it is empty.
Calling this API with no flags set (@flags == 0) is equivalent calling virDomainDestroy.
We need a counterpart to this for virDomainShutdown. Would you mind doing that as well?
+ * + * Calling this function with no @flags set (equal zero) + * is equivalent calling virDomainDestroy.
If you haven't already pushed, squash in this grammar fix: Calling this function with no @flags set (equal to zero) is equivalent to calling virDomainDestroy().
+++ b/src/libvirt_public.syms @@ -469,6 +469,7 @@ LIBVIRT_0.9.3 { LIBVIRT_0.9.4 { global: virDomainUndefineFlags; + virDomainDestroyFlags;
Also, I've been sorting these within a release. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

--- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 8 +++++++- src/remote_protocol-structs | 5 +++++ 3 files changed, 13 insertions(+), 1 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 82b938c..01e699b 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -4152,6 +4152,7 @@ static virDriver remote_driver = { .domainShutdown = remoteDomainShutdown, /* 0.3.0 */ .domainReboot = remoteDomainReboot, /* 0.3.0 */ .domainDestroy = remoteDomainDestroy, /* 0.3.0 */ + .domainDestroyFlags = remoteDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = remoteDomainGetOSType, /* 0.3.0 */ .domainGetMaxMemory = remoteDomainGetMaxMemory, /* 0.3.0 */ .domainSetMaxMemory = remoteDomainSetMaxMemory, /* 0.3.0 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index ef9dd10..414b088 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -676,6 +676,11 @@ struct remote_domain_destroy_args { remote_nonnull_domain dom; }; +struct remote_domain_destroy_flags_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + struct remote_domain_get_os_type_args { remote_nonnull_domain dom; }; @@ -2390,7 +2395,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_CONTROL_INFO = 229, /* autogen autogen */ REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO = 230, /* skipgen skipgen */ - REMOTE_PROC_DOMAIN_UNDEFINE_FLAGS = 231 /* autogen autogen */ + REMOTE_PROC_DOMAIN_UNDEFINE_FLAGS = 231, /* autogen autogen */ + REMOTE_PROC_DOMAIN_DESTROY_FLAGS = 232 /* autogen autogen */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 96e74eb..1dd75e5 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -390,6 +390,10 @@ struct remote_domain_reboot_args { struct remote_domain_destroy_args { remote_nonnull_domain dom; }; +struct remote_domain_destroy_flags_args { + remote_nonnull_domain dom; + u_int flags; +}; struct remote_domain_get_os_type_args { remote_nonnull_domain dom; }; @@ -1864,4 +1868,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_CONTROL_INFO = 229, REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO = 230, REMOTE_PROC_DOMAIN_UNDEFINE_FLAGS = 231, + REMOTE_PROC_DOMAIN_DESTROY_FLAGS = 232, }; -- 1.7.5.rc3

On 07/21/2011 10:08 AM, Michal Privoznik wrote:
--- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 8 +++++++- src/remote_protocol-structs | 5 +++++ 3 files changed, 13 insertions(+), 1 deletions(-)
Depending on which ack'd series of new APIs gets pushed first (this, or my bypass-cache), we'll have some (easy) merge conflicts to sort out :) -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

--- src/qemu/qemu_driver.c | 15 +++++++++++++-- 1 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e13b63b..0e13722 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1556,13 +1556,18 @@ cleanup: } -static int qemudDomainDestroy(virDomainPtr dom) { +static int +qemuDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) +{ struct qemud_driver *driver = dom->conn->privateData; virDomainObjPtr vm; int ret = -1; virDomainEventPtr event = NULL; qemuDomainObjPrivatePtr priv; + virCheckFlags(0, -1); + qemuDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (!vm) { @@ -1620,6 +1625,11 @@ cleanup: return ret; } +static int +qemuDomainDestroy(virDomainPtr dom) +{ + return qemuDomainDestroyFlags(dom, 0); +} static char *qemudDomainGetOSType(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; @@ -8620,7 +8630,8 @@ static virDriver qemuDriver = { .domainResume = qemudDomainResume, /* 0.2.0 */ .domainShutdown = qemuDomainShutdown, /* 0.2.0 */ .domainReboot = qemuDomainReboot, /* 0.9.3 */ - .domainDestroy = qemudDomainDestroy, /* 0.2.0 */ + .domainDestroy = qemuDomainDestroy, /* 0.2.0 */ + .domainDestroyFlags = qemuDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = qemudDomainGetOSType, /* 0.2.2 */ .domainGetMaxMemory = qemudDomainGetMaxMemory, /* 0.4.2 */ .domainSetMaxMemory = qemudDomainSetMaxMemory, /* 0.4.2 */ -- 1.7.5.rc3

--- src/esx/esx_driver.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 5ed6a38..c097651 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -1937,7 +1937,8 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags) static int -esxDomainDestroy(virDomainPtr domain) +esxDomainDestroyFlags(virDomainPtr domain, + unsigned int flags) { int result = -1; esxPrivate *priv = domain->conn->privateData; @@ -1949,6 +1950,8 @@ esxDomainDestroy(virDomainPtr domain) esxVI_TaskInfoState taskInfoState; char *taskInfoErrorMessage = NULL; + virCheckFlags(0, -1); + if (priv->vCenter != NULL) { ctx = priv->vCenter; } else { @@ -2001,6 +2004,12 @@ esxDomainDestroy(virDomainPtr domain) } +static int +esxDomainDestroy(virDomainPtr dom) +{ + return esxDomainDestroyFlags(dom, 0); +} + static char * esxDomainGetOSType(virDomainPtr domain ATTRIBUTE_UNUSED) @@ -4734,6 +4743,7 @@ static virDriver esxDriver = { .domainShutdown = esxDomainShutdown, /* 0.7.0 */ .domainReboot = esxDomainReboot, /* 0.7.0 */ .domainDestroy = esxDomainDestroy, /* 0.7.0 */ + .domainDestroyFlags = esxDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = esxDomainGetOSType, /* 0.7.0 */ .domainGetMaxMemory = esxDomainGetMaxMemory, /* 0.7.0 */ .domainSetMaxMemory = esxDomainSetMaxMemory, /* 0.7.0 */ -- 1.7.5.rc3

--- src/libxl/libxl_driver.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index d52a8b6..76d2ad4 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -1526,13 +1526,16 @@ cleanup: } static int -libxlDomainDestroy(virDomainPtr dom) +libxlDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) { libxlDriverPrivatePtr driver = dom->conn->privateData; virDomainObjPtr vm; int ret = -1; virDomainEventPtr event = NULL; + virCheckFlags(0, -1); + libxlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (!vm) { @@ -1574,6 +1577,12 @@ cleanup: return ret; } +static int +libxlDomainDestroy(virDomainPtr dom) +{ + return libxlDomainDestroyFlags(dom, 0); +} + static char * libxlDomainGetOSType(virDomainPtr dom) { @@ -3842,6 +3851,7 @@ static virDriver libxlDriver = { .domainShutdown = libxlDomainShutdown, /* 0.9.0 */ .domainReboot = libxlDomainReboot, /* 0.9.0 */ .domainDestroy = libxlDomainDestroy, /* 0.9.0 */ + .domainDestroyFlags = libxlDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = libxlDomainGetOSType, /* 0.9.0 */ .domainGetMaxMemory = libxlDomainGetMaxMemory, /* 0.9.0 */ .domainSetMaxMemory = libxlDomainSetMaxMemory, /* 0.9.2 */ -- 1.7.5.rc3

--- src/lxc/lxc_driver.c | 24 ++++++++++++++++++++++-- 1 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index afac879..a2f56ed 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1934,20 +1934,25 @@ static void lxcDomainEventQueue(lxc_driver_t *driver, } /** - * lxcDomainDestroy: + * lxcDomainDestroyFlags: * @dom: pointer to domain to destroy + * @flags: an OR'ed set of virDomainDestroyFlags * * Sends SIGKILL to container root process to terminate the container * * Returns 0 on success or -1 in case of error */ -static int lxcDomainDestroy(virDomainPtr dom) +static int +lxcDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) { lxc_driver_t *driver = dom->conn->privateData; virDomainObjPtr vm; virDomainEventPtr event = NULL; int ret = -1; + virCheckFlags(0, -1); + lxcDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); if (!vm) { @@ -1983,6 +1988,20 @@ cleanup: return ret; } +/** + * lxcDomainDestroy: + * @dom: pointer to domain to destroy + * + * Sends SIGKILL to container root process to terminate the container + * + * Returns 0 on success or -1 in case of error + */ +static int +lxcDomainDestroy(virDomainPtr dom) +{ + return lxcDomainDestroyFlags(dom, 0); +} + static int lxcCheckNetNsSupport(void) { const char *argv[] = {"ip", "link", "set", "lo", "netns", "-1", NULL}; @@ -2928,6 +2947,7 @@ static virDriver lxcDriver = { .domainSuspend = lxcDomainSuspend, /* 0.7.2 */ .domainResume = lxcDomainResume, /* 0.7.2 */ .domainDestroy = lxcDomainDestroy, /* 0.4.4 */ + .domainDestroyFlags = lxcDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = lxcGetOSType, /* 0.4.2 */ .domainGetMaxMemory = lxcDomainGetMaxMemory, /* 0.7.2 */ .domainSetMaxMemory = lxcDomainSetMaxMemory, /* 0.7.2 */ -- 1.7.5.rc3

--- src/openvz/openvz_driver.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index d24a5e3..d9e76f5 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -577,12 +577,16 @@ cleanup: return ret; } -static int openvzDomainShutdown(virDomainPtr dom) { +static int +openvzDomainShutdownFlags(virDomainPtr dom, + unsigned int flags) { struct openvz_driver *driver = dom->conn->privateData; virDomainObjPtr vm; const char *prog[] = {VZCTL, "--quiet", "stop", PROGRAM_SENTINAL, NULL}; int ret = -1; + virCheckFlags(0, -1); + openvzDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); openvzDriverUnlock(driver); @@ -614,6 +618,12 @@ cleanup: return ret; } +static int +openvzDomainShutdown(virDomainPtr dom) +{ + return openvzDomainShutdownFlags(dom, 0); +} + static int openvzDomainReboot(virDomainPtr dom, unsigned int flags) { @@ -1621,6 +1631,7 @@ static virDriver openvzDriver = { .domainShutdown = openvzDomainShutdown, /* 0.3.1 */ .domainReboot = openvzDomainReboot, /* 0.3.1 */ .domainDestroy = openvzDomainShutdown, /* 0.3.1 */ + .domainDestroyFlags = openvzDomainShutdownFlags, /* 0.9.4 */ .domainGetOSType = openvzGetOSType, /* 0.3.1 */ .domainGetInfo = openvzDomainGetInfo, /* 0.3.1 */ .domainGetState = openvzDomainGetState, /* 0.9.2 */ -- 1.7.5.rc3

--- src/phyp/phyp_driver.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index 2489063..613ba9d 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -3497,7 +3497,8 @@ phypDomainGetState(virDomainPtr dom, } static int -phypDomainDestroy(virDomainPtr dom) +phypDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) { int result = -1; ConnectionData *connection_data = dom->conn->networkPrivateData; @@ -3509,6 +3510,8 @@ phypDomainDestroy(virDomainPtr dom) char *ret = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; + virCheckFlags(0, -1); + virBufferAddLit(&buf, "rmsyscfg"); if (system_type == HMC) virBufferAsprintf(&buf, " -m %s", managed_system); @@ -3531,6 +3534,12 @@ cleanup: } static int +phypDomainDestroy(virDomainPtr dom) +{ + return phypDomainDestroyFlags(dom, 0); +} + +static int phypBuildLpar(virConnectPtr conn, virDomainDefPtr def) { int result = -1; @@ -3763,6 +3772,7 @@ static virDriver phypDriver = { .domainShutdown = phypDomainShutdown, /* 0.7.0 */ .domainReboot = phypDomainReboot, /* 0.9.1 */ .domainDestroy = phypDomainDestroy, /* 0.7.3 */ + .domainDestroyFlags = phypDomainDestroyFlags, /* 0.9.4 */ .domainGetInfo = phypDomainGetInfo, /* 0.7.0 */ .domainGetState = phypDomainGetState, /* 0.9.2 */ .domainSetVcpus = phypDomainSetCPU, /* 0.7.3 */ -- 1.7.5.rc3

--- src/uml/uml_driver.c | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 0d6f71a..da547ec 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1417,12 +1417,17 @@ cleanup: } -static int umlDomainDestroy(virDomainPtr dom) { +static int +umlDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) +{ struct uml_driver *driver = dom->conn->privateData; virDomainObjPtr vm; virDomainEventPtr event = NULL; int ret = -1; + virCheckFlags(0, -1); + umlDriverLock(driver); vm = virDomainFindByID(&driver->domains, dom->id); if (!vm) { @@ -1453,6 +1458,12 @@ cleanup: } +static int umlDomainDestroy(virDomainPtr dom) +{ + return umlDomainDestroyFlags(dom, 0); +} + + static char *umlDomainGetOSType(virDomainPtr dom) { struct uml_driver *driver = dom->conn->privateData; virDomainObjPtr vm; @@ -2423,6 +2434,7 @@ static virDriver umlDriver = { .domainLookupByName = umlDomainLookupByName, /* 0.5.0 */ .domainShutdown = umlDomainShutdown, /* 0.5.0 */ .domainDestroy = umlDomainDestroy, /* 0.5.0 */ + .domainDestroyFlags = umlDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = umlDomainGetOSType, /* 0.5.0 */ .domainGetMaxMemory = umlDomainGetMaxMemory, /* 0.5.0 */ .domainSetMaxMemory = umlDomainSetMaxMemory, /* 0.5.0 */ -- 1.7.5.rc3

--- src/vbox/vbox_tmpl.c | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 53bac79..df46263 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -1689,7 +1689,10 @@ cleanup: return ret; } -static int vboxDomainDestroy(virDomainPtr dom) { +static int +vboxDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) +{ VBOX_OBJECT_CHECK(dom->conn, int, -1); IMachine *machine = NULL; vboxIID iid = VBOX_IID_INITIALIZER; @@ -1698,6 +1701,8 @@ static int vboxDomainDestroy(virDomainPtr dom) { PRBool isAccessible = PR_FALSE; nsresult rc; + virCheckFlags(0, -1); + vboxIIDFromUUID(&iid, dom->uuid); rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine); if (NS_FAILED(rc)) { @@ -1746,6 +1751,12 @@ cleanup: return ret; } +static int +vboxDomainDestroy(virDomainPtr dom) +{ + return vboxDomainDestroyFlags(dom, 0); +} + static char *vboxDomainGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) { /* Returning "hvm" always as suggested on list, cause * this functions seems to be badly named and it @@ -8774,6 +8785,7 @@ virDriver NAME(Driver) = { .domainShutdown = vboxDomainShutdown, /* 0.6.3 */ .domainReboot = vboxDomainReboot, /* 0.6.3 */ .domainDestroy = vboxDomainDestroy, /* 0.6.3 */ + .domainDestroyFlags = vboxDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = vboxDomainGetOSType, /* 0.6.3 */ .domainSetMemory = vboxDomainSetMemory, /* 0.6.3 */ .domainGetInfo = vboxDomainGetInfo, /* 0.6.3 */ -- 1.7.5.rc3

--- src/vmware/vmware_driver.c | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 7cec310..dc0382b 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -312,12 +312,15 @@ vmwareDomainDefineXML(virConnectPtr conn, const char *xml) } static int -vmwareDomainShutdown(virDomainPtr dom) +vmwareDomainShutdownFlags(virDomainPtr dom, + unsigned int flags) { struct vmware_driver *driver = dom->conn->privateData; virDomainObjPtr vm; int ret = -1; + virCheckFlags(0, -1); + vmwareDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -351,6 +354,12 @@ vmwareDomainShutdown(virDomainPtr dom) } static int +vmwareDomainShutdown(virDomainPtr dom) +{ + return vmwareDomainShutdownFlags(dom, 0); +} + +static int vmwareDomainSuspend(virDomainPtr dom) { struct vmware_driver *driver = dom->conn->privateData; @@ -968,6 +977,7 @@ static virDriver vmwareDriver = { .domainShutdown = vmwareDomainShutdown, /* 0.8.7 */ .domainReboot = vmwareDomainReboot, /* 0.8.7 */ .domainDestroy = vmwareDomainShutdown, /* 0.8.7 */ + .domainDestroyFlags = vmwareDomainShutdownFlags, /* 0.9.4 */ .domainGetOSType = vmwareGetOSType, /* 0.8.7 */ .domainGetInfo = vmwareDomainGetInfo, /* 0.8.7 */ .domainGetState = vmwareDomainGetState, /* 0.9.2 */ -- 1.7.5.rc3

--- src/xen/xen_driver.c | 28 ++++++++++++++++++++++++++++ src/xen/xen_driver.h | 1 + src/xen/xen_hypervisor.c | 24 ++++++++++++++++++++++-- src/xen/xen_hypervisor.h | 3 +++ src/xen/xen_inotify.c | 1 + src/xen/xend_internal.c | 24 ++++++++++++++++++++++-- src/xen/xm_internal.c | 1 + src/xen/xs_internal.c | 1 + 8 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 3b5df46..4f4533e 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -925,6 +925,33 @@ xenUnifiedDomainDestroy (virDomainPtr dom) return -1; } +static int +xenUnifiedDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) +{ + GET_PRIVATE(dom->conn); + int i; + + virCheckFlags(0, -1); + + /* Try non-hypervisor methods first, then hypervisor direct method + * as a last resort. + */ + for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) + if (i != XEN_UNIFIED_HYPERVISOR_OFFSET && + priv->opened[i] && + drivers[i]->domainDestroyFlags && + drivers[i]->domainDestroyFlags(dom) == 0) + return 0; + + if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] && + drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainDestroyFlags&& + drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainDestroyFlags(dom) == 0) + return 0; + + return -1; +} + static char * xenUnifiedDomainGetOSType (virDomainPtr dom) { @@ -2205,6 +2232,7 @@ static virDriver xenUnifiedDriver = { .domainShutdown = xenUnifiedDomainShutdown, /* 0.0.3 */ .domainReboot = xenUnifiedDomainReboot, /* 0.1.0 */ .domainDestroy = xenUnifiedDomainDestroy, /* 0.0.3 */ + .domainDestroyFlags = xenUnifiedDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = xenUnifiedDomainGetOSType, /* 0.0.3 */ .domainGetMaxMemory = xenUnifiedDomainGetMaxMemory, /* 0.0.3 */ .domainSetMaxMemory = xenUnifiedDomainSetMaxMemory, /* 0.0.3 */ diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h index a6fe475..2151427 100644 --- a/src/xen/xen_driver.h +++ b/src/xen/xen_driver.h @@ -95,6 +95,7 @@ struct xenUnifiedDriver { virDrvDomainShutdown domainShutdown; virDrvDomainReboot domainReboot; virDrvDomainDestroy domainDestroy; + virDrvDomainDestroyFlags domainDestroyFlags; virDrvDomainGetOSType domainGetOSType; virDrvDomainGetMaxMemory domainGetMaxMemory; virDrvDomainSetMaxMemory domainSetMaxMemory; diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 543dfb1..79fe0d4 100644 --- a/src/xen/xen_hypervisor.c +++ b/src/xen/xen_hypervisor.c @@ -816,6 +816,7 @@ struct xenUnifiedDriver xenHypervisorDriver = { NULL, /* domainShutdown */ NULL, /* domainReboot */ xenHypervisorDestroyDomain, /* domainDestroy */ + xenHypervisorDestroyDomainFlags, /* domainDestroyFlags */ xenHypervisorDomainGetOSType, /* domainGetOSType */ xenHypervisorGetMaxMemory, /* domainGetMaxMemory */ xenHypervisorSetMaxMemory, /* domainSetMaxMemory */ @@ -3433,19 +3434,26 @@ xenHypervisorResumeDomain(virDomainPtr domain) } /** - * xenHypervisorDestroyDomain: + * xenHypervisorDestroyDomainFlags: * @domain: pointer to the domain block + * @flags: an OR'ed set of virDomainDestroyFlagsValues * * Do an hypervisor call to destroy the given domain * + * Calling this function with no @flags set (equal zero + * is equivalent calling xenHypervisorDestroyDomain. + * * Returns 0 in case of success, -1 in case of error. */ int -xenHypervisorDestroyDomain(virDomainPtr domain) +xenHypervisorDestroyDomainFlags(virDomainPtr domain, + unsigned int flags) { int ret; xenUnifiedPrivatePtr priv; + virCheckFlags(0, -1); + if (domain->conn == NULL) return -1; @@ -3460,6 +3468,18 @@ xenHypervisorDestroyDomain(virDomainPtr domain) } /** + * xenHypervisorDestroyDomain: + * @domain: pointer to the domain block + * + * See xenHypervisorDestroyDomainFlags + */ +int +xenHypervisorDestroyDomain(virDomainPtr domain) +{ + return xenHypervisorDestroyDomainFlags(domain, 0); +} + +/** * xenHypervisorSetMaxMemory: * @domain: pointer to the domain block * @memory: the max memory size in kilobytes. diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h index d522d5b..efdb81b 100644 --- a/src/xen/xen_hypervisor.h +++ b/src/xen/xen_hypervisor.h @@ -59,6 +59,9 @@ int xenHypervisorGetMaxVcpus (virConnectPtr conn, const char *type); int xenHypervisorDestroyDomain (virDomainPtr domain) ATTRIBUTE_NONNULL (1); +int xenHypervisorDestroyDomainFlags (virDomainPtr domain, + unsigned int flags) + ATTRIBUTE_NONNULL (1); int xenHypervisorResumeDomain (virDomainPtr domain) ATTRIBUTE_NONNULL (1); int xenHypervisorPauseDomain (virDomainPtr domain) diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c index 241dbc7..e679b63 100644 --- a/src/xen/xen_inotify.c +++ b/src/xen/xen_inotify.c @@ -63,6 +63,7 @@ struct xenUnifiedDriver xenInotifyDriver = { NULL, /* domainShutdown */ NULL, /* domainReboot */ NULL, /* domainDestroy */ + NULL, /* domainDestroyFlags */ NULL, /* domainGetOSType */ NULL, /* domainGetMaxMemory */ NULL, /* domainSetMaxMemory */ diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index dec8484..b497528 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1509,8 +1509,9 @@ xenDaemonDomainReboot(virDomainPtr domain, unsigned int flags) } /** - * xenDaemonDomainDestroy: + * xenDaemonDomainDestroyFlags: * @domain: pointer to the Domain block + * @flags: an OR'ed set of virDomainDestroyFlagsValues * * Abruptly halt the domain, the OS is not properly shutdown and the * resources allocated for the domain are immediately freed, mounted @@ -1519,11 +1520,17 @@ xenDaemonDomainReboot(virDomainPtr domain, unsigned int flags) * dying and will go away completely once all of the resources have been * unmapped (usually from the backend devices). * + * Calling this function with no @flags set (equal zero) + * is equivalent calling xenDaemonDomainDestroy. + * * Returns 0 in case of success, -1 (with errno) in case of error. */ int -xenDaemonDomainDestroy(virDomainPtr domain) +xenDaemonDomainDestroyFlags(virDomainPtr domain, + unsigned int flags) { + virCheckFlags(0, -1); + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__); return(-1); @@ -1539,6 +1546,18 @@ xenDaemonDomainDestroy(virDomainPtr domain) } /** + * xenDaemonDomainDestroy: + * @domain: pointer to the Domain block + * + * See xenDaemonDomainDestroyFlags + */ +int +xenDaemonDomainDestroy(virDomainPtr dom) +{ + return xenDaemonDomainDestroyFlags(dom, 0); +} + +/** * xenDaemonDomainGetOSType: * @domain: a domain object * @@ -3941,6 +3960,7 @@ struct xenUnifiedDriver xenDaemonDriver = { xenDaemonDomainShutdown, /* domainShutdown */ xenDaemonDomainReboot, /* domainReboot */ xenDaemonDomainDestroy, /* domainDestroy */ + xenDaemonDomainDestroyFlags, /* domainDestroyFlags */ xenDaemonDomainGetOSType, /* domainGetOSType */ xenDaemonDomainGetMaxMemory, /* domainGetMaxMemory */ xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */ diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 6ec295e..7929393 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -95,6 +95,7 @@ struct xenUnifiedDriver xenXMDriver = { NULL, /* domainShutdown */ NULL, /* domainReboot */ NULL, /* domainDestroy */ + NULL, /* domainDestroyFlags */ NULL, /* domainGetOSType */ xenXMDomainGetMaxMemory, /* domainGetMaxMemory */ xenXMDomainSetMaxMemory, /* domainSetMaxMemory */ diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c index f62d716..a08187d 100644 --- a/src/xen/xs_internal.c +++ b/src/xen/xs_internal.c @@ -56,6 +56,7 @@ struct xenUnifiedDriver xenStoreDriver = { xenStoreDomainShutdown, /* domainShutdown */ xenStoreDomainReboot, /* domainReboot */ NULL, /* domainDestroy */ + NULL, /* domainDestroyFlags */ xenStoreDomainGetOSType, /* domainGetOSType */ xenStoreDomainGetMaxMemory, /* domainGetMaxMemory */ NULL, /* domainSetMaxMemory */ -- 1.7.5.rc3

On 07/21/2011 10:08 AM, Michal Privoznik wrote:
--- src/xen/xen_driver.c | 28 ++++++++++++++++++++++++++++ src/xen/xen_driver.h | 1 + src/xen/xen_hypervisor.c | 24 ++++++++++++++++++++++-- src/xen/xen_hypervisor.h | 3 +++ src/xen/xen_inotify.c | 1 + src/xen/xend_internal.c | 24 ++++++++++++++++++++++-- src/xen/xm_internal.c | 1 + src/xen/xs_internal.c | 1 + 8 files changed, 79 insertions(+), 4 deletions(-)
This is overkill for now. You could have confined your patch to just src/xen/xen_driver.c, which checks that flags is 0, then calls the non-flag version of all the secondary drivers, rather than adding a flag version to all secondary drivers. On the other hand, if we ever do add flags, and want to support those flags in a secondary xen driver (that is, supposing libxl doesn't take over all things xen), then this already gives us the infrastructure to do so. So I'm okay with it as is. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

--- src/xenapi/xenapi_driver.c | 22 ++++++++++++++++++++-- 1 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 97da1d1..8585ea4 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -839,13 +839,19 @@ xenapiDomainReboot (virDomainPtr dom, unsigned int flags) } /* - * xenapiDomaindestroy + * xenapiDomainDestroyFlags: + * @dom: domain object + * @flags: an OR'ed set of virDomainDestroyFlagsValues + * + * Calling this function with no flags set (equal zero) + * is equivalent calling xenapiDomainDestroy. * * A VM is hard shutdown * Returns 0 on success or -1 in case of error */ static int -xenapiDomainDestroy (virDomainPtr dom) +xenapiDomainDestroyFlags(virDomainPtr dom, + unsigned int flags) { /* vm.hard_shutdown */ xen_vm vm; @@ -874,6 +880,17 @@ xenapiDomainDestroy (virDomainPtr dom) } /* + * xenapiDomainDestroy: + * @dom: domain object + * + * See xenapiDomainDestroyFlags + */ +static int +xenapiDomainDestroy(virDomainPtr dom) +{ + return xenapiDomainDestroyFlags(dom, 0); +} +/* * xenapiDomainGetOSType * * @@ -1883,6 +1900,7 @@ static virDriver xenapiDriver = { .domainShutdown = xenapiDomainShutdown, /* 0.8.0 */ .domainReboot = xenapiDomainReboot, /* 0.8.0 */ .domainDestroy = xenapiDomainDestroy, /* 0.8.0 */ + .domainDestroyFlags = xenapiDomainDestroyFlags, /* 0.9.4 */ .domainGetOSType = xenapiDomainGetOSType, /* 0.8.0 */ .domainGetMaxMemory = xenapiDomainGetMaxMemory, /* 0.8.0 */ .domainSetMaxMemory = xenapiDomainSetMaxMemory, /* 0.8.0 */ -- 1.7.5.rc3

On Thu, Jul 21, 2011 at 06:08:31PM +0200, Michal Privoznik wrote:
This series creates new API which adds flags to virDomainDestroy. As mentioned here many times, it is a bad luck all APIs don't have flags parameter.
Parameter for this might be needed to select different ways of destroying a domain. For example, qemu has 'quit' command, which force it to flush internal caches a thus preventing from data loss. Or vice versa - in cases where we are doing hypervisor assisted destroy we might want to send signals, because hypervisor is not responding.
Currently, no new functionality is implemented, but this paves the way for creating multiple ways of domain destroying. Therefore, calling this new API is the same as calling its predecessor.
diff to v1: -rename virDominDestroyWithFlags() to virDominDestroyFlags() -rename enum virDominDestroyFlags to virDominDestroyFlagsValues
Michal Privoznik (13): destroy: Define new public API virDomainDestroyFlags destroy: Wire up the remote protocol destroy: Implement internal API for qemu driver destroy: Implement internal API for ESX driver destroy: Implement internal API for libxl driver destroy: Implement internal API for lxc driver destroy: Implement internal API for openvz driver destroy: Implement internal API for phyp driver destroy: Implement internal API for uml driver destroy: Implement internal API for vbox driver destroy: Implement internal API for vmware driver destroy: Implement internal API for xen driver destroy: Implement internal API for xenapi driver
include/libvirt/libvirt.h.in | 7 +++++ src/driver.h | 4 +++ src/esx/esx_driver.c | 12 +++++++++- src/libvirt.c | 52 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/libxl/libxl_driver.c | 12 +++++++++- src/lxc/lxc_driver.c | 23 +++++++++++++++++- src/openvz/openvz_driver.c | 13 +++++++++- src/phyp/phyp_driver.c | 12 +++++++++- src/qemu/qemu_driver.c | 13 +++++++++- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 8 +++++- src/remote_protocol-structs | 5 ++++ src/uml/uml_driver.c | 14 ++++++++++- src/vbox/vbox_tmpl.c | 14 ++++++++++- src/vmware/vmware_driver.c | 12 +++++++++- src/xen/xen_driver.c | 28 ++++++++++++++++++++++ src/xen/xen_driver.h | 1 + src/xen/xen_hypervisor.c | 24 +++++++++++++++++- src/xen/xen_hypervisor.h | 3 ++ src/xen/xen_inotify.c | 1 + src/xen/xend_internal.c | 24 +++++++++++++++++- src/xen/xm_internal.c | 1 + src/xen/xs_internal.c | 1 + src/xenapi/xenapi_driver.c | 22 ++++++++++++++++- 25 files changed, 291 insertions(+), 17 deletions(-)
ACK to the whole series Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 21.07.2011 18:55, Daniel P. Berrange wrote:
On Thu, Jul 21, 2011 at 06:08:31PM +0200, Michal Privoznik wrote:
This series creates new API which adds flags to virDomainDestroy. As mentioned here many times, it is a bad luck all APIs don't have flags parameter.
Parameter for this might be needed to select different ways of destroying a domain. For example, qemu has 'quit' command, which force it to flush internal caches a thus preventing from data loss. Or vice versa - in cases where we are doing hypervisor assisted destroy we might want to send signals, because hypervisor is not responding.
Currently, no new functionality is implemented, but this paves the way for creating multiple ways of domain destroying. Therefore, calling this new API is the same as calling its predecessor.
diff to v1: -rename virDominDestroyWithFlags() to virDominDestroyFlags() -rename enum virDominDestroyFlags to virDominDestroyFlagsValues
Michal Privoznik (13): destroy: Define new public API virDomainDestroyFlags destroy: Wire up the remote protocol destroy: Implement internal API for qemu driver destroy: Implement internal API for ESX driver destroy: Implement internal API for libxl driver destroy: Implement internal API for lxc driver destroy: Implement internal API for openvz driver destroy: Implement internal API for phyp driver destroy: Implement internal API for uml driver destroy: Implement internal API for vbox driver destroy: Implement internal API for vmware driver destroy: Implement internal API for xen driver destroy: Implement internal API for xenapi driver
include/libvirt/libvirt.h.in | 7 +++++ src/driver.h | 4 +++ src/esx/esx_driver.c | 12 +++++++++- src/libvirt.c | 52 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/libxl/libxl_driver.c | 12 +++++++++- src/lxc/lxc_driver.c | 23 +++++++++++++++++- src/openvz/openvz_driver.c | 13 +++++++++- src/phyp/phyp_driver.c | 12 +++++++++- src/qemu/qemu_driver.c | 13 +++++++++- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 8 +++++- src/remote_protocol-structs | 5 ++++ src/uml/uml_driver.c | 14 ++++++++++- src/vbox/vbox_tmpl.c | 14 ++++++++++- src/vmware/vmware_driver.c | 12 +++++++++- src/xen/xen_driver.c | 28 ++++++++++++++++++++++ src/xen/xen_driver.h | 1 + src/xen/xen_hypervisor.c | 24 +++++++++++++++++- src/xen/xen_hypervisor.h | 3 ++ src/xen/xen_inotify.c | 1 + src/xen/xend_internal.c | 24 +++++++++++++++++- src/xen/xm_internal.c | 1 + src/xen/xs_internal.c | 1 + src/xenapi/xenapi_driver.c | 22 ++++++++++++++++- 25 files changed, 291 insertions(+), 17 deletions(-)
ACK to the whole series
Daniel
Thanks, incorporated Eric's suggestions and pushed. Michal
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Michal Privoznik