Add new virDomainShutdownFlags API

Add a new API virDomainShutdownFlags and define:

    VIR_DOMAIN_SHUTDOWN_DEFAULT        = 0,
    VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN = (1 << 0),
    VIR_DOMAIN_SHUTDOWN_GUEST_AGENT    = (1 << 1),

Also define some flags for the reboot API

    VIR_DOMAIN_REBOOT_DEFAULT        = 0,
    VIR_DOMAIN_REBOOT_ACPI_POWER_BTN = (1 << 0),
    VIR_DOMAIN_REBOOT_GUEST_AGENT    = (1 << 1),

Although these two APIs currently have the same flags, using
separate enums allows them to expand separately in the future.

Add stub impls of the new API for all existing drivers
This commit is contained in:
Daniel P. Berrange 2011-10-05 18:31:55 +01:00 committed by Michal Privoznik
parent c160ce3316
commit 0b7ddf9e77
16 changed files with 194 additions and 10 deletions

View File

@ -1200,7 +1200,22 @@ virDomainPtr virDomainLookupByUUID (virConnectPtr conn,
virDomainPtr virDomainLookupByUUIDString (virConnectPtr conn,
const char *uuid);
typedef enum {
VIR_DOMAIN_SHUTDOWN_DEFAULT = 0, /* hypervisor choice */
VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN = (1 << 0), /* Send ACPI event */
VIR_DOMAIN_SHUTDOWN_GUEST_AGENT = (1 << 1), /* Use guest agent */
} virDomainShutdownFlagValues;
int virDomainShutdown (virDomainPtr domain);
int virDomainShutdownFlags (virDomainPtr domain,
unsigned int flags);
typedef enum {
VIR_DOMAIN_REBOOT_DEFAULT = 0, /* hypervisor choice */
VIR_DOMAIN_REBOOT_ACPI_POWER_BTN = (1 << 0), /* Send ACPI event */
VIR_DOMAIN_REBOOT_GUEST_AGENT = (1 << 1), /* Use guest agent */
} virDomainRebootFlagValues;
int virDomainReboot (virDomainPtr domain,
unsigned int flags);
int virDomainReset (virDomainPtr domain,

View File

@ -793,6 +793,10 @@ typedef int
virTypedParameterPtr params,
int *nparams,
unsigned int flags);
typedef int
(*virDrvDomainShutdownFlags)(virDomainPtr domain,
unsigned int flags);
/**
* _virDriver:
@ -829,6 +833,7 @@ struct _virDriver {
virDrvDomainSuspend domainSuspend;
virDrvDomainResume domainResume;
virDrvDomainShutdown domainShutdown;
virDrvDomainShutdownFlags domainShutdownFlags;
virDrvDomainReboot domainReboot;
virDrvDomainReset domainReset;
virDrvDomainDestroy domainDestroy;

View File

@ -1887,7 +1887,7 @@ esxDomainResume(virDomainPtr domain)
static int
esxDomainShutdown(virDomainPtr domain)
esxDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
{
int result = -1;
esxPrivate *priv = domain->conn->privateData;
@ -1895,6 +1895,8 @@ esxDomainShutdown(virDomainPtr domain)
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
virCheckFlags(0, -1);
if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
@ -1928,6 +1930,12 @@ esxDomainShutdown(virDomainPtr domain)
}
static int
esxDomainShutdown(virDomainPtr domain)
{
return esxDomainShutdownFlags(domain, 0);
}
static int
esxDomainReboot(virDomainPtr domain, unsigned int flags)
@ -4953,6 +4961,7 @@ static virDriver esxDriver = {
.domainSuspend = esxDomainSuspend, /* 0.7.0 */
.domainResume = esxDomainResume, /* 0.7.0 */
.domainShutdown = esxDomainShutdown, /* 0.7.0 */
.domainShutdownFlags = esxDomainShutdownFlags, /* 0.9.10 */
.domainReboot = esxDomainReboot, /* 0.7.0 */
.domainDestroy = esxDomainDestroy, /* 0.7.0 */
.domainDestroyFlags = esxDomainDestroyFlags, /* 0.9.4 */

View File

@ -3105,15 +3105,88 @@ error:
return -1;
}
/**
* virDomainShutdownFlags:
* @domain: a domain object
* @flags: bitwise-OR of virDomainShutdownFlagValues
*
* Shutdown a domain, the domain object is still usable thereafter but
* the domain OS is being stopped. Note that the guest OS may ignore the
* request. For guests that react to a shutdown request, the differences
* from virDomainDestroy() are that the guest's disk storage will be in a
* stable state rather than having the (virtual) power cord pulled, and
* this command returns as soon as the shutdown request is issued rather
* than blocking until the guest is no longer running.
*
* If the domain is transient and has any snapshot metadata (see
* virDomainSnapshotNum()), then that metadata will automatically
* be deleted when the domain quits.
*
* If @flags is set to zero, then the hypervisor will choose the
* method of shutdown it considers best. To have greater control
* pass exactly one of the virDomainShutdownFlagValues.
*
* Returns 0 in case of success and -1 in case of failure.
*/
int
virDomainShutdownFlags(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;
}
if (domain->conn->flags & VIR_CONNECT_RO) {
virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
goto error;
}
/* At most one of these two flags should be set. */
if ((flags & VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN) &&
(flags & VIR_DOMAIN_SHUTDOWN_GUEST_AGENT)) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
conn = domain->conn;
if (conn->driver->domainShutdownFlags) {
int ret;
ret = conn->driver->domainShutdownFlags(domain, flags);
if (ret < 0)
goto error;
return ret;
}
virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
error:
virDispatchError(domain->conn);
return -1;
}
/**
* virDomainReboot:
* @domain: a domain object
* @flags: extra flags; not used yet, so callers should always pass 0
* @flags: bitwise-OR of virDomainRebootFlagValues
*
* Reboot a domain, the domain object is still usable there after but
* the domain OS is being stopped for a restart.
* Note that the guest OS may ignore the request.
*
* If @flags is set to zero, then the hypervisor will choose the
* method of shutdown it considers best. To have greater control
* pass exactly one of the virDomainRebootFlagValues.
*
* To use guest agent (VIR_DOMAIN_REBOOT_GUEST_AGENT) the domain XML
* must have <channel> configured.
*
* Returns 0 in case of success and -1 in case of failure.
*/
int
@ -3135,6 +3208,13 @@ virDomainReboot(virDomainPtr domain, unsigned int flags)
goto error;
}
/* At most one of these two flags should be set. */
if ((flags & VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN) &&
(flags & VIR_DOMAIN_SHUTDOWN_GUEST_AGENT)) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
conn = domain->conn;
if (conn->driver->domainReboot) {

View File

@ -516,4 +516,8 @@ LIBVIRT_0.9.9 {
virDomainSetNumaParameters;
} LIBVIRT_0.9.8;
LIBVIRT_0.9.10 {
global:
virDomainShutdownFlags;
} LIBVIRT_0.9.9;
# .... define new API here using predicted next version number ....

View File

@ -1412,13 +1412,15 @@ cleanup:
}
static int
libxlDomainShutdown(virDomainPtr dom)
libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
{
libxlDriverPrivatePtr driver = dom->conn->privateData;
virDomainObjPtr vm;
int ret = -1;
libxlDomainObjPrivatePtr priv;
virCheckFlags(0, -1);
libxlDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
@ -1455,6 +1457,13 @@ cleanup:
return ret;
}
static int
libxlDomainShutdown(virDomainPtr dom)
{
return libxlDomainShutdownFlags(dom, 0);
}
static int
libxlDomainReboot(virDomainPtr dom, unsigned int flags)
{
@ -3857,6 +3866,7 @@ static virDriver libxlDriver = {
.domainSuspend = libxlDomainSuspend, /* 0.9.0 */
.domainResume = libxlDomainResume, /* 0.9.0 */
.domainShutdown = libxlDomainShutdown, /* 0.9.0 */
.domainShutdownFlags = libxlDomainShutdownFlags, /* 0.9.10 */
.domainReboot = libxlDomainReboot, /* 0.9.0 */
.domainDestroy = libxlDomainDestroy, /* 0.9.0 */
.domainDestroyFlags = libxlDomainDestroyFlags, /* 0.9.4 */

View File

@ -1693,6 +1693,7 @@ static virDriver openvzDriver = {
.domainSuspend = openvzDomainSuspend, /* 0.8.3 */
.domainResume = openvzDomainResume, /* 0.8.3 */
.domainShutdown = openvzDomainShutdown, /* 0.3.1 */
.domainShutdownFlags = openvzDomainShutdownFlags, /* 0.9.10 */
.domainReboot = openvzDomainReboot, /* 0.3.1 */
.domainDestroy = openvzDomainShutdown, /* 0.3.1 */
.domainDestroyFlags = openvzDomainShutdownFlags, /* 0.9.4 */

View File

@ -4617,6 +4617,7 @@ static virDriver remote_driver = {
.domainSuspend = remoteDomainSuspend, /* 0.3.0 */
.domainResume = remoteDomainResume, /* 0.3.0 */
.domainShutdown = remoteDomainShutdown, /* 0.3.0 */
.domainShutdownFlags = remoteDomainShutdownFlags, /* 0.9.10 */
.domainReboot = remoteDomainReboot, /* 0.3.0 */
.domainReset = remoteDomainReset, /* 0.9.7 */
.domainDestroy = remoteDomainDestroy, /* 0.3.0 */

View File

@ -2349,6 +2349,11 @@ struct remote_node_suspend_for_duration_args {
unsigned int flags;
};
struct remote_domain_shutdown_flags_args {
remote_nonnull_domain dom;
unsigned int flags;
};
/*----- Protocol. -----*/
@ -2654,7 +2659,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_NUMA_PARAMETERS = 254, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_NUMA_PARAMETERS = 255, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_SET_INTERFACE_PARAMETERS = 256, /* autogen autogen */
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257 /* skipgen skipgen */
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258 /* autogen autogen */
/*
* Notice how the entries are grouped in sets of 10 ?

View File

@ -1832,6 +1832,10 @@ struct remote_node_suspend_for_duration_args {
uint64_t duration;
u_int flags;
};
struct remote_domain_shutdown_flags_args {
remote_nonnull_domain dom;
u_int flags;
};
enum remote_procedure {
REMOTE_PROC_OPEN = 1,
REMOTE_PROC_CLOSE = 2,
@ -2090,4 +2094,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_GET_NUMA_PARAMETERS = 255,
REMOTE_PROC_DOMAIN_SET_INTERFACE_PARAMETERS = 256,
REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257,
REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258,
};

View File

@ -1542,13 +1542,16 @@ cleanup:
return ret;
}
static int testShutdownDomain (virDomainPtr domain)
static int testShutdownDomainFlags(virDomainPtr domain,
unsigned int flags)
{
testConnPtr privconn = domain->conn->privateData;
virDomainObjPtr privdom;
virDomainEventPtr event = NULL;
int ret = -1;
virCheckFlags(0, -1);
testDriverLock(privconn);
privdom = virDomainFindByName(&privconn->domains,
domain->name);
@ -1585,6 +1588,11 @@ cleanup:
return ret;
}
static int testShutdownDomain (virDomainPtr domain)
{
return testShutdownDomainFlags(domain, 0);
}
/* Similar behaviour as shutdown */
static int testRebootDomain (virDomainPtr domain,
unsigned int action ATTRIBUTE_UNUSED)
@ -5523,6 +5531,7 @@ static virDriver testDriver = {
.domainSuspend = testPauseDomain, /* 0.1.1 */
.domainResume = testResumeDomain, /* 0.1.1 */
.domainShutdown = testShutdownDomain, /* 0.1.1 */
.domainShutdownFlags = testShutdownDomainFlags, /* 0.9.10 */
.domainReboot = testRebootDomain, /* 0.1.1 */
.domainDestroy = testDestroyDomain, /* 0.1.1 */
.domainGetOSType = testGetOSType, /* 0.1.9 */

View File

@ -1513,12 +1513,15 @@ cleanup:
}
static int umlDomainShutdown(virDomainPtr dom) {
static int umlDomainShutdownFlags(virDomainPtr dom,
unsigned int flags) {
struct uml_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
char *info = NULL;
int ret = -1;
virCheckFlags(0, -1);
umlDriverLock(driver);
vm = virDomainFindByID(&driver->domains, dom->id);
umlDriverUnlock(driver);
@ -1544,6 +1547,11 @@ cleanup:
return ret;
}
static int
umlDomainShutdown(virDomainPtr dom)
{
return umlDomainShutdownFlags(dom, 0);
}
static int
umlDomainDestroyFlags(virDomainPtr dom,
@ -2533,6 +2541,7 @@ static virDriver umlDriver = {
.domainLookupByUUID = umlDomainLookupByUUID, /* 0.5.0 */
.domainLookupByName = umlDomainLookupByName, /* 0.5.0 */
.domainShutdown = umlDomainShutdown, /* 0.5.0 */
.domainShutdownFlags = umlDomainShutdownFlags, /* 0.9.10 */
.domainDestroy = umlDomainDestroy, /* 0.5.0 */
.domainDestroyFlags = umlDomainDestroyFlags, /* 0.9.4 */
.domainGetOSType = umlDomainGetOSType, /* 0.5.0 */

View File

@ -1606,7 +1606,8 @@ cleanup:
return ret;
}
static int vboxDomainShutdown(virDomainPtr dom) {
static int vboxDomainShutdownFlags(virDomainPtr dom,
unsigned int flags) {
VBOX_OBJECT_CHECK(dom->conn, int, -1);
IMachine *machine = NULL;
vboxIID iid = VBOX_IID_INITIALIZER;
@ -1615,6 +1616,8 @@ static int vboxDomainShutdown(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)) {
@ -1656,6 +1659,11 @@ cleanup:
return ret;
}
static int vboxDomainShutdown(virDomainPtr dom) {
return vboxDomainShutdownFlags(dom, 0);
}
static int vboxDomainReboot(virDomainPtr dom, unsigned int flags)
{
VBOX_OBJECT_CHECK(dom->conn, int, -1);
@ -9112,6 +9120,7 @@ virDriver NAME(Driver) = {
.domainSuspend = vboxDomainSuspend, /* 0.6.3 */
.domainResume = vboxDomainResume, /* 0.6.3 */
.domainShutdown = vboxDomainShutdown, /* 0.6.3 */
.domainShutdownFlags = vboxDomainShutdownFlags, /* 0.9.10 */
.domainReboot = vboxDomainReboot, /* 0.6.3 */
.domainDestroy = vboxDomainDestroy, /* 0.6.3 */
.domainDestroyFlags = vboxDomainDestroyFlags, /* 0.9.4 */

View File

@ -980,6 +980,7 @@ static virDriver vmwareDriver = {
.domainSuspend = vmwareDomainSuspend, /* 0.8.7 */
.domainResume = vmwareDomainResume, /* 0.8.7 */
.domainShutdown = vmwareDomainShutdown, /* 0.8.7 */
.domainShutdownFlags = vmwareDomainShutdownFlags, /* 0.9.10 */
.domainReboot = vmwareDomainReboot, /* 0.8.7 */
.domainDestroy = vmwareDomainShutdown, /* 0.8.7 */
.domainDestroyFlags = vmwareDomainShutdownFlags, /* 0.9.4 */

View File

@ -851,20 +851,29 @@ xenUnifiedDomainResume (virDomainPtr dom)
}
static int
xenUnifiedDomainShutdown (virDomainPtr dom)
xenUnifiedDomainShutdownFlags(virDomainPtr dom,
unsigned int flags)
{
GET_PRIVATE(dom->conn);
int i;
virCheckFlags(0, -1);
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
if (priv->opened[i] &&
drivers[i]->xenDomainShutdown &&
drivers[i]->xenDomainShutdown (dom) == 0)
drivers[i]->xenDomainShutdown(dom) == 0)
return 0;
return -1;
}
static int
xenUnifiedDomainShutdown(virDomainPtr dom)
{
return xenUnifiedDomainShutdownFlags(dom, 0);
}
static int
xenUnifiedDomainReboot (virDomainPtr dom, unsigned int flags)
{
@ -2187,6 +2196,7 @@ static virDriver xenUnifiedDriver = {
.domainSuspend = xenUnifiedDomainSuspend, /* 0.0.3 */
.domainResume = xenUnifiedDomainResume, /* 0.0.3 */
.domainShutdown = xenUnifiedDomainShutdown, /* 0.0.3 */
.domainShutdownFlags = xenUnifiedDomainShutdownFlags, /* 0.9.10 */
.domainReboot = xenUnifiedDomainReboot, /* 0.1.0 */
.domainDestroy = xenUnifiedDomainDestroy, /* 0.0.3 */
.domainDestroyFlags = xenUnifiedDomainDestroyFlags, /* 0.9.4 */

View File

@ -783,12 +783,15 @@ xenapiDomainResume (virDomainPtr dom)
* Returns 0 on success or -1 in case of error
*/
static int
xenapiDomainShutdown (virDomainPtr dom)
xenapiDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
{
/* vm.clean_shutdown */
xen_vm vm;
xen_vm_set *vms;
xen_session *session = ((struct _xenapiPrivate *)(dom->conn->privateData))->session;
virCheckFlags(0, -1);
if (xen_vm_get_by_name_label(session, &vms, dom->name) && vms->size > 0) {
if (vms->size != 1) {
xenapiSessionErrorHandler(dom->conn, VIR_ERR_INTERNAL_ERROR,
@ -811,6 +814,12 @@ xenapiDomainShutdown (virDomainPtr dom)
return -1;
}
static int
xenapiDomainShutdown(virDomainPtr dom)
{
return xenapiDomainShutdownFlags(dom, 0);
}
/*
* xenapiDomainReboot
*
@ -1928,6 +1937,7 @@ static virDriver xenapiDriver = {
.domainSuspend = xenapiDomainSuspend, /* 0.8.0 */
.domainResume = xenapiDomainResume, /* 0.8.0 */
.domainShutdown = xenapiDomainShutdown, /* 0.8.0 */
.domainShutdownFlags = xenapiDomainShutdownFlags, /* 0.9.10 */
.domainReboot = xenapiDomainReboot, /* 0.8.0 */
.domainDestroy = xenapiDomainDestroy, /* 0.8.0 */
.domainDestroyFlags = xenapiDomainDestroyFlags, /* 0.9.4 */