[libvirt] [PATCH 00/13] New API: virDominDestroyWithFlags

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. Michal Privoznik (13): destroy: Define new public API virDomainDestroyWithFlags 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 virDomainDestroyWithFlags to allow domain destroying with flags, as the existing API virDomainDestroy misses flags. The set of flags is defined in virDomainDestroyFlags 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..0a06684 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 { + * } virDomainDestroyFlags; + */ 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 virDomainDestroyWithFlags(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..f23a71b 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 + (*virDrvDomainDestroyWithFlags) (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; + virDrvDomainDestroyWithFlags domainDestroyWithFlags; virDrvDomainGetOSType domainGetOSType; virDrvDomainGetMaxMemory domainGetMaxMemory; virDrvDomainSetMaxMemory domainSetMaxMemory; diff --git a/src/libvirt.c b/src/libvirt.c index 16a9a02..44cb019 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -2078,6 +2078,58 @@ error: } /** + * virDomainDestroyWithFlags: + * @domain: a domain object + * @flags: an OR'ed set of virDomainDestroyFlags + * + * 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 +virDomainDestroyWithFlags(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->domainDestroyWithFlags) { + int ret; + ret = conn->driver->domainDestroyWithFlags(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..63ff0da 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; + virDomainDestroyWithFlags; } LIBVIRT_0.9.3; # .... define new API here using predicted next version number .... -- 1.7.5.rc3

On Thu, Jul 21, 2011 at 11:28:28AM +0200, Michal Privoznik wrote:
This introduces new API virDomainDestroyWithFlags to allow domain destroying with flags, as the existing API virDomainDestroy misses flags.
The set of flags is defined in virDomainDestroyFlags 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..0a06684 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 { + * } virDomainDestroyFlags; + */ 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 virDomainDestroyWithFlags(virDomainPtr domain, + unsigned int flags);
This is not our usual naming convention. I'd expect the API to be named 'virDomainDestroyFlags', and give the enum a different typedef name. Regards, 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 :|

于 2011年07月21日 19:13, Daniel P. Berrange 写道:
On Thu, Jul 21, 2011 at 11:28:28AM +0200, Michal Privoznik wrote:
This introduces new API virDomainDestroyWithFlags to allow domain destroying with flags, as the existing API virDomainDestroy misses flags.
The set of flags is defined in virDomainDestroyFlags 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..0a06684 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 { + * } virDomainDestroyFlags; + */ 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 virDomainDestroyWithFlags(virDomainPtr domain, + unsigned int flags); This is not our usual naming convention. I'd expect the API to be named 'virDomainDestroyFlags', and give the enum a different typedef name.
Regards, Daniel
For domainUndefine, the enum is named as virDomainUndefineFlagsValues, so that we can have the API named virDomainUndefineFlags. Osier

--- 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..770d1ee 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 */ + .domainDestroyWithFlags = remoteDomainDestroyWithFlags, /* 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..7236b0a 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_with_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_WITH_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..937251c 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_with_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_WITH_FLAGS = 232, }; -- 1.7.5.rc3

--- src/qemu/qemu_driver.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e13b63b..ddadb08 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 +qemudDomainDestroyWithFlags(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 +qemudDomainDestroy(virDomainPtr dom) +{ + return qemudDomainDestroyWithFlags(dom, 0); +} static char *qemudDomainGetOSType(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; @@ -8621,6 +8631,7 @@ static virDriver qemuDriver = { .domainShutdown = qemuDomainShutdown, /* 0.2.0 */ .domainReboot = qemuDomainReboot, /* 0.9.3 */ .domainDestroy = qemudDomainDestroy, /* 0.2.0 */ + .domainDestroyWithFlags = qemudDomainDestroyWithFlags, /* 0.9.4 */ .domainGetOSType = qemudDomainGetOSType, /* 0.2.2 */ .domainGetMaxMemory = qemudDomainGetMaxMemory, /* 0.4.2 */ .domainSetMaxMemory = qemudDomainSetMaxMemory, /* 0.4.2 */ -- 1.7.5.rc3

于 2011年07月21日 17:28, Michal Privoznik 写道:
--- src/qemu/qemu_driver.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e13b63b..ddadb08 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 +qemudDomainDestroyWithFlags(virDomainPtr dom,
Suggested by Eric, and adopted in undefineFlags series, s/qemudDomain/qemuDomain/.
+ 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 +qemudDomainDestroy(virDomainPtr dom) +{ + return qemudDomainDestroyWithFlags(dom, 0); +}
static char *qemudDomainGetOSType(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; @@ -8621,6 +8631,7 @@ static virDriver qemuDriver = { .domainShutdown = qemuDomainShutdown, /* 0.2.0 */ .domainReboot = qemuDomainReboot, /* 0.9.3 */ .domainDestroy = qemudDomainDestroy, /* 0.2.0 */ + .domainDestroyWithFlags = qemudDomainDestroyWithFlags, /* 0.9.4 */ .domainGetOSType = qemudDomainGetOSType, /* 0.2.2 */ .domainGetMaxMemory = qemudDomainGetMaxMemory, /* 0.4.2 */ .domainSetMaxMemory = qemudDomainSetMaxMemory, /* 0.4.2 */

--- 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..f98c579 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) +esxDomainDestroyWithFlags(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 esxDomainDestroyWithFlags(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 */ + .domainDestroyWithFlags = esxDomainDestroyWithFlags, /* 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..33d8305 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -1526,13 +1526,16 @@ cleanup: } static int -libxlDomainDestroy(virDomainPtr dom) +libxlDomainDestroyWithFlags(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 libxlDomainDestroyWithFlags(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 */ + .domainDestroyWithFlags = libxlDomainDestroyWithFlags, /* 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 | 23 +++++++++++++++++++++-- 1 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index afac879..7fc9921 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: + * lxcDomainDestroyWithFlags: * @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 +lxcDomainDestroyWithFlags(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 lxcDomainDestroyWithFlags(dom, 0); +} + static int lxcCheckNetNsSupport(void) { const char *argv[] = {"ip", "link", "set", "lo", "netns", "-1", NULL}; -- 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..92470d8 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 +openvzDomainShutdownWithFlags(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 openvzDomainShutdownWithFlags(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 */ + .domainDestroyWithFlags = openvzDomainShutdownWithFlags, /* 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..eea229a 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) +phypDomainDestroyWithFlags(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 phypDomainDestroyWithFlags(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 */ + .domainDestroyWithFlags = phypDomainDestroyWithFlags, /* 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..7f2ab13 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 +umlDomainDestroyWithFlags(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 umlDomainDestroyWithFlags(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 */ + .domainDestroyWithFlags = umlDomainDestroyWithFlags, /* 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..19fdaef 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 +vboxDomainDestroyWithFlags(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 vboxDomainDestroyWithFlags(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 */ + .domainDestroyWithFlags = vboxDomainDestroyWithFlags, /* 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..64de663 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) +vmwareDomainShutdownWithFlags(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 vmwareDomainShutdownWithFlags(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 */ + .domainDestroyWithFlags = vmwareDomainShutdownWithFlags, /* 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..ce29fc4 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -925,6 +925,33 @@ xenUnifiedDomainDestroy (virDomainPtr dom) return -1; } +static int +xenUnifiedDomainDestroyWithFlags(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]->domainDestroyWithFlags && + drivers[i]->domainDestroyWithFlags(dom) == 0) + return 0; + + if (priv->opened[XEN_UNIFIED_HYPERVISOR_OFFSET] && + drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainDestroyWithFlags&& + drivers[XEN_UNIFIED_HYPERVISOR_OFFSET]->domainDestroyWithFlags(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 */ + .domainDestroyWithFlags = xenUnifiedDomainDestroyWithFlags, /* 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..1f9c17a 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; + virDrvDomainDestroyWithFlags domainDestroyWithFlags; virDrvDomainGetOSType domainGetOSType; virDrvDomainGetMaxMemory domainGetMaxMemory; virDrvDomainSetMaxMemory domainSetMaxMemory; diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c index 543dfb1..e9920d2 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 */ + xenHypervisorDestroyDomainWithFlags, /* domainDestroyWithFlags */ xenHypervisorDomainGetOSType, /* domainGetOSType */ xenHypervisorGetMaxMemory, /* domainGetMaxMemory */ xenHypervisorSetMaxMemory, /* domainSetMaxMemory */ @@ -3433,19 +3434,26 @@ xenHypervisorResumeDomain(virDomainPtr domain) } /** - * xenHypervisorDestroyDomain: + * xenHypervisorDestroyDomainWithFlags: * @domain: pointer to the domain block + * @flags: an OR'ed set of virDomainDestroyFlags * * 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) +xenHypervisorDestroyDomainWithFlags(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 xenHypervisorDestroyDomainWithFlags + */ +int +xenHypervisorDestroyDomain(virDomainPtr domain) +{ + return xenHypervisorDestroyDomainWithFlags(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..d838ae8 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 xenHypervisorDestroyDomainWithFlags(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..98f3081 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, /* domainDestroyWithFlags */ NULL, /* domainGetOSType */ NULL, /* domainGetMaxMemory */ NULL, /* domainSetMaxMemory */ diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index dec8484..b295035 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -1509,8 +1509,9 @@ xenDaemonDomainReboot(virDomainPtr domain, unsigned int flags) } /** - * xenDaemonDomainDestroy: + * xenDaemonDomainDestroyWithFlags: * @domain: pointer to the Domain block + * @flags: an OR'ed set of virDomainDestroyFlags * * 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) +xenDaemonDomainDestroyWithFlags(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 xenDaemonDomainDestroyWithFlags + */ +int +xenDaemonDomainDestroy(virDomainPtr dom) +{ + return xenDaemonDomainDestroyWithFlags(dom, 0); +} + +/** * xenDaemonDomainGetOSType: * @domain: a domain object * @@ -3941,6 +3960,7 @@ struct xenUnifiedDriver xenDaemonDriver = { xenDaemonDomainShutdown, /* domainShutdown */ xenDaemonDomainReboot, /* domainReboot */ xenDaemonDomainDestroy, /* domainDestroy */ + xenDaemonDomainDestroyWithFlags, /* domainDestroyWithFlags */ xenDaemonDomainGetOSType, /* domainGetOSType */ xenDaemonDomainGetMaxMemory, /* domainGetMaxMemory */ xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */ diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index 6ec295e..b907ade 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, /* domainDestroyWithFlags */ NULL, /* domainGetOSType */ xenXMDomainGetMaxMemory, /* domainGetMaxMemory */ xenXMDomainSetMaxMemory, /* domainSetMaxMemory */ diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c index f62d716..ddd51fa 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, /* domainDestroyWithFlags */ xenStoreDomainGetOSType, /* domainGetOSType */ xenStoreDomainGetMaxMemory, /* domainGetMaxMemory */ NULL, /* domainSetMaxMemory */ -- 1.7.5.rc3

--- 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..75a11e3 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -839,13 +839,19 @@ xenapiDomainReboot (virDomainPtr dom, unsigned int flags) } /* - * xenapiDomaindestroy + * xenapiDomainDestroyWithFlags: + * @dom: domain object + * @flags: an OR'ed set of virDomainDestroyFlags + * + * 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) +xenapiDomainDestroyWithFlags(virDomainPtr dom, + unsigned int flags) { /* vm.hard_shutdown */ xen_vm vm; @@ -874,6 +880,17 @@ xenapiDomainDestroy (virDomainPtr dom) } /* + * xenapiDomainDestroy: + * @dom: domain object + * + * See xenapiDomainDestroyWithFlags + */ +static int +xenapiDomainDestroy(virDomainPtr dom) +{ + return xenapiDomainDestroyWithFlags(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 */ + .domainDestroyWithFlags = xenapiDomainDestroyWithFlags, /* 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 11:28:27AM +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.
Michal Privoznik (13): destroy: Define new public API virDomainDestroyWithFlags 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
I would ACK this whole series if the API naming is fixed. 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 13:15, Daniel P. Berrange wrote:
On Thu, Jul 21, 2011 at 11:28:27AM +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.
Michal Privoznik (13): destroy: Define new public API virDomainDestroyWithFlags 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
I would ACK this whole series if the API naming is fixed.
Daniel What about:
virDomainDestroyFlags for API virDomainDestroyFlagsValues for flags enum Michal

On Thu, Jul 21, 2011 at 01:16:42PM +0200, Michal Privoznik wrote:
On 21.07.2011 13:15, Daniel P. Berrange wrote:
On Thu, Jul 21, 2011 at 11:28:27AM +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.
Michal Privoznik (13): destroy: Define new public API virDomainDestroyWithFlags 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
I would ACK this whole series if the API naming is fixed.
Daniel What about:
virDomainDestroyFlags for API virDomainDestroyFlagsValues for flags enum
Yes, that would work 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 :|
participants (3)
-
Daniel P. Berrange
-
Michal Privoznik
-
Osier Yang