From b046c55d400f9908fbc452fbf9898e8f09ab36fa Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Wed, 4 May 2011 11:07:01 +0200 Subject: [PATCH] Implement domain state reason Only in drivers which use virDomainObj, drivers that query hypervisor for domain status need to be updated separately in case their hypervisor supports this functionality. The reason is also saved into domain state XML so if a domain is not running (i.e., no state XML exists) the reason will be lost by libvirtd restart. I think this is an acceptable limitation. --- src/conf/domain_conf.c | 163 ++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 26 +++++- src/libvirt_private.syms | 4 + src/libxl/libxl_driver.c | 53 +++++++----- src/lxc/lxc_driver.c | 52 ++++++------ src/openvz/openvz_conf.c | 16 ++-- src/openvz/openvz_driver.c | 29 ++++--- src/qemu/qemu_driver.c | 66 ++++++++------- src/qemu/qemu_migration.c | 24 +++--- src/qemu/qemu_process.c | 61 ++++++++------ src/qemu/qemu_process.h | 12 ++- src/test/test_driver.c | 80 ++++++++++-------- src/uml/uml_driver.c | 30 +++---- src/vmware/vmware_conf.c | 3 +- src/vmware/vmware_driver.c | 33 ++++---- 15 files changed, 446 insertions(+), 206 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a0eb43eb0d..498438a489 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -376,6 +376,56 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1, "shutoff", "crashed") +#define VIR_DOMAIN_NOSTATE_LAST (VIR_DOMAIN_NOSTATE_UNKNOWN + 1) +VIR_ENUM_IMPL(virDomainNostateReason, VIR_DOMAIN_NOSTATE_LAST, + "unknown") + +#define VIR_DOMAIN_RUNNING_LAST (VIR_DOMAIN_RUNNING_SAVE_CANCELED + 1) +VIR_ENUM_IMPL(virDomainRunningReason, VIR_DOMAIN_RUNNING_LAST, + "unknown", + "booted", + "migrated", + "restored", + "from snapshot", + "unpaused", + "migration canceled", + "save canceled") + +#define VIR_DOMAIN_BLOCKED_LAST (VIR_DOMAIN_BLOCKED_UNKNOWN + 1) +VIR_ENUM_IMPL(virDomainBlockedReason, VIR_DOMAIN_BLOCKED_LAST, + "unknown") + +#define VIR_DOMAIN_PAUSED_LAST (VIR_DOMAIN_PAUSED_FROM_SNAPSHOT + 1) +VIR_ENUM_IMPL(virDomainPausedReason, VIR_DOMAIN_PAUSED_LAST, + "unknown", + "user", + "migration", + "save", + "dump", + "ioerror", + "watchdog", + "from snapshot") + +#define VIR_DOMAIN_SHUTDOWN_LAST (VIR_DOMAIN_SHUTDOWN_USER + 1) +VIR_ENUM_IMPL(virDomainShutdownReason, VIR_DOMAIN_SHUTDOWN_LAST, + "unknown", + "user") + +#define VIR_DOMAIN_SHUTOFF_LAST (VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT + 1) +VIR_ENUM_IMPL(virDomainShutoffReason, VIR_DOMAIN_SHUTOFF_LAST, + "unknown", + "shutdown", + "destroyed", + "crashed", + "migrated", + "saved", + "failed", + "from snapshot") + +#define VIR_DOMAIN_CRASHED_LAST (VIR_DOMAIN_CRASHED_UNKNOWN + 1) +VIR_ENUM_IMPL(virDomainCrashedReason, VIR_DOMAIN_CRASHED_LAST, + "unknown") + VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST, "dynamic", "static") @@ -1080,7 +1130,8 @@ static virDomainObjPtr virDomainObjNew(virCapsPtr caps) } virDomainObjLock(domain); - domain->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(domain, VIR_DOMAIN_SHUTOFF, + VIR_DOMAIN_SHUTOFF_UNKNOWN); domain->refs = 1; virDomainSnapshotObjListInit(&domain->snapshots); @@ -6240,6 +6291,8 @@ static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps, virDomainObjPtr obj; xmlNodePtr *nodes = NULL; int i, n; + int state; + int reason = 0; if (!(obj = virDomainObjNew(caps))) return NULL; @@ -6263,7 +6316,7 @@ static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps, "%s", _("missing domain state")); goto error; } - if ((obj->state = virDomainStateTypeFromString(tmp)) < 0) { + if ((state = virDomainStateTypeFromString(tmp)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("invalid domain state '%s'"), tmp); VIR_FREE(tmp); @@ -6271,6 +6324,18 @@ static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps, } VIR_FREE(tmp); + if ((tmp = virXPathString("string(./@reason)", ctxt))) { + if ((reason = virDomainStateReasonFromString(state, tmp)) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("invalid domain state reason '%s'"), tmp); + VIR_FREE(tmp); + goto error; + } + VIR_FREE(tmp); + } + + virDomainObjSetState(obj, state, reason); + if ((virXPathLong("string(./@pid)", ctxt, &val)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("invalid pid")); @@ -8463,10 +8528,14 @@ static char *virDomainObjFormat(virCapsPtr caps, { char *config_xml = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; + int state; + int reason; int i; - virBufferAsprintf(&buf, "\n", - virDomainStateTypeToString(obj->state), + state = virDomainObjGetState(obj, &reason); + virBufferAsprintf(&buf, "\n", + virDomainStateTypeToString(state), + virDomainStateReasonToString(state, reason), obj->pid); for (i = 0 ; i < VIR_DOMAIN_TAINT_LAST ; i++) { @@ -9559,3 +9628,89 @@ virDomainObjCopyPersistentDef(virCapsPtr caps, virDomainObjPtr dom) VIR_FREE(xml); return ret; } + + +virDomainState +virDomainObjGetState(virDomainObjPtr dom, int *reason) +{ + if (reason) + *reason = dom->state.reason; + + return dom->state.state; +} + + +void +virDomainObjSetState(virDomainObjPtr dom, virDomainState state, int reason) +{ + int last = -1; + + switch (state) { + case VIR_DOMAIN_NOSTATE: last = VIR_DOMAIN_NOSTATE_LAST; break; + case VIR_DOMAIN_RUNNING: last = VIR_DOMAIN_RUNNING_LAST; break; + case VIR_DOMAIN_BLOCKED: last = VIR_DOMAIN_BLOCKED_LAST; break; + case VIR_DOMAIN_PAUSED: last = VIR_DOMAIN_PAUSED_LAST; break; + case VIR_DOMAIN_SHUTDOWN: last = VIR_DOMAIN_SHUTDOWN_LAST; break; + case VIR_DOMAIN_SHUTOFF: last = VIR_DOMAIN_SHUTOFF_LAST; break; + case VIR_DOMAIN_CRASHED: last = VIR_DOMAIN_CRASHED_LAST; break; + } + + if (last < 0) { + VIR_ERROR(_("invalid domain state: %d"), state); + return; + } + + dom->state.state = state; + if (reason > 0 && reason < last) + dom->state.reason = reason; + else + dom->state.reason = 0; +} + + +const char * +virDomainStateReasonToString(virDomainState state, int reason) +{ + switch (state) { + case VIR_DOMAIN_NOSTATE: + return virDomainNostateReasonTypeToString(reason); + case VIR_DOMAIN_RUNNING: + return virDomainRunningReasonTypeToString(reason); + case VIR_DOMAIN_BLOCKED: + return virDomainBlockedReasonTypeToString(reason); + case VIR_DOMAIN_PAUSED: + return virDomainPausedReasonTypeToString(reason); + case VIR_DOMAIN_SHUTDOWN: + return virDomainShutdownReasonTypeToString(reason); + case VIR_DOMAIN_SHUTOFF: + return virDomainShutoffReasonTypeToString(reason); + case VIR_DOMAIN_CRASHED: + return virDomainCrashedReasonTypeToString(reason); + } + + return NULL; +} + + +int +virDomainStateReasonFromString(virDomainState state, const char *reason) +{ + switch (state) { + case VIR_DOMAIN_NOSTATE: + return virDomainNostateReasonTypeFromString(reason); + case VIR_DOMAIN_RUNNING: + return virDomainRunningReasonTypeFromString(reason); + case VIR_DOMAIN_BLOCKED: + return virDomainBlockedReasonTypeFromString(reason); + case VIR_DOMAIN_PAUSED: + return virDomainPausedReasonTypeFromString(reason); + case VIR_DOMAIN_SHUTDOWN: + return virDomainShutdownReasonTypeFromString(reason); + case VIR_DOMAIN_SHUTOFF: + return virDomainShutoffReasonTypeFromString(reason); + case VIR_DOMAIN_CRASHED: + return virDomainCrashedReasonTypeFromString(reason); + } + + return -1; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a0f820cf74..fe42f21dad 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1193,6 +1193,12 @@ enum virDomainTaintFlags { }; /* Guest VM runtime state */ +typedef struct _virDomainStateReason virDomainStateReason; +struct _virDomainStateReason { + int state; + int reason; +}; + typedef struct _virDomainObj virDomainObj; typedef virDomainObj *virDomainObjPtr; struct _virDomainObj { @@ -1200,7 +1206,7 @@ struct _virDomainObj { int refs; int pid; - int state; + virDomainStateReason state; unsigned int autostart : 1; unsigned int persistent : 1; @@ -1440,6 +1446,13 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk, virDomainDiskDefPathIterator iter, void *opaque); +void +virDomainObjSetState(virDomainObjPtr obj, virDomainState state, int reason) + ATTRIBUTE_NONNULL(1); +virDomainState +virDomainObjGetState(virDomainObjPtr obj, int *reason) + ATTRIBUTE_NONNULL(1); + typedef const char* (*virLifecycleToStringFunc)(int type); typedef int (*virLifecycleFromStringFunc)(const char *type); @@ -1494,6 +1507,17 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression) VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) +VIR_ENUM_DECL(virDomainNostateReason) +VIR_ENUM_DECL(virDomainRunningReason) +VIR_ENUM_DECL(virDomainBlockedReason) +VIR_ENUM_DECL(virDomainPausedReason) +VIR_ENUM_DECL(virDomainShutdownReason) +VIR_ENUM_DECL(virDomainShutoffReason) +VIR_ENUM_DECL(virDomainCrashedReason) + +const char *virDomainStateReasonToString(virDomainState state, int reason); +int virDomainStateReasonFromString(virDomainState state, const char *reason); + VIR_ENUM_DECL(virDomainSeclabel) VIR_ENUM_DECL(virDomainClockOffset) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 21a65ad601..8097154960 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -294,6 +294,7 @@ virDomainNetTypeToString; virDomainObjAssignDef; virDomainObjCopyPersistentDef; virDomainObjGetPersistentDef; +virDomainObjGetState; virDomainObjIsDuplicate; virDomainObjListDeinit; virDomainObjListGetActiveIDs; @@ -303,6 +304,7 @@ virDomainObjListNumOfDomains; virDomainObjLock; virDomainObjRef; virDomainObjSetDefTransient; +virDomainObjSetState; virDomainObjTaint; virDomainObjUnlock; virDomainObjUnref; @@ -326,6 +328,8 @@ virDomainSnapshotObjListRemove; virDomainSoundDefFree; virDomainSoundModelTypeFromString; virDomainSoundModelTypeToString; +virDomainStateReasonFromString; +virDomainStateReasonToString; virDomainStateTypeFromString; virDomainStateTypeToString; virDomainTaintTypeFromString; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 895ff28f0e..1d7d1550b3 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -225,7 +225,9 @@ libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info) * virDomainObjPtr should be locked on invocation */ static void -libxlVmCleanup(libxlDriverPrivatePtr driver, virDomainObjPtr vm) +libxlVmCleanup(libxlDriverPrivatePtr driver, + virDomainObjPtr vm, + virDomainShutoffReason reason) { libxlDomainObjPrivatePtr priv = vm->privateData; int vnc_port; @@ -245,7 +247,7 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, virDomainObjPtr vm) if (vm->persistent) { vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); } if ((vm->def->ngraphics == 1) && @@ -282,7 +284,10 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, virDomainObjPtr vm) * virDomainObjPtr should be locked on invocation */ static int -libxlVmReap(libxlDriverPrivatePtr driver, virDomainObjPtr vm, int force) +libxlVmReap(libxlDriverPrivatePtr driver, + virDomainObjPtr vm, + int force, + virDomainShutoffReason reason) { libxlDomainObjPrivatePtr priv = vm->privateData; @@ -292,7 +297,7 @@ libxlVmReap(libxlDriverPrivatePtr driver, virDomainObjPtr vm, int force) return -1; } - libxlVmCleanup(driver, vm); + libxlVmCleanup(driver, vm, reason); return 0; } @@ -333,6 +338,8 @@ static void libxlEventHandler(int watch, goto cleanup; if (event.type == LIBXL_EVENT_DOMAIN_DEATH) { + virDomainShutoffReason reason; + /* libxl_event_get_domain_death_info returns 1 if death * event was for this domid */ if (libxl_event_get_domain_death_info(&priv->ctx, @@ -346,18 +353,22 @@ static void libxlEventHandler(int watch, switch (info.shutdown_reason) { case SHUTDOWN_poweroff: case SHUTDOWN_crash: - if (info.shutdown_reason == SHUTDOWN_crash) + if (info.shutdown_reason == SHUTDOWN_crash) { dom_event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_CRASHED); - libxlVmReap(driver, vm, 0); + reason = VIR_DOMAIN_SHUTOFF_CRASHED; + } else { + reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; + } + libxlVmReap(driver, vm, 0, reason); if (!vm->persistent) { virDomainRemoveInactive(&driver->domains, vm); vm = NULL; } break; case SHUTDOWN_reboot: - libxlVmReap(driver, vm, 0); + libxlVmReap(driver, vm, 0, VIR_DOMAIN_SHUTOFF_SHUTDOWN); libxlVmStart(driver, vm, 0); break; default: @@ -576,9 +587,9 @@ libxlVmStart(libxlDriverPrivatePtr driver, if (!start_paused) { libxl_domain_unpause(&priv->ctx, domid); - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); } else { - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); } @@ -597,7 +608,7 @@ error: if (domid > 0) { libxl_domain_destroy(&priv->ctx, domid, 0); def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED); } libxl_domain_config_destroy(&d_config); VIR_FREE(dom_xml); @@ -642,7 +653,7 @@ libxlReconnectDomain(void *payload, /* Update domid in case it changed (e.g. reboot) while we were gone? */ vm->def->id = d_info.domid; - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN); /* Recreate domain death et. al. events */ libxlCreateDomEvents(vm); @@ -650,7 +661,7 @@ libxlReconnectDomain(void *payload, return; out: - libxlVmCleanup(driver, vm); + libxlVmCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_UNKNOWN); if (!vm->persistent) virDomainRemoveInactive(&driver->domains, vm); else @@ -1187,7 +1198,7 @@ libxlDomainSuspend(virDomainPtr dom) priv = vm->privateData; - if (vm->state != VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { if (libxl_domain_pause(&priv->ctx, dom->id) != 0) { libxlError(VIR_ERR_INTERNAL_ERROR, _("Failed to suspend domain '%d' with libxenlight"), @@ -1195,7 +1206,7 @@ libxlDomainSuspend(virDomainPtr dom) goto cleanup; } - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); @@ -1246,7 +1257,7 @@ libxlDomainResume(virDomainPtr dom) priv = vm->privateData; - if (vm->state == VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { if (libxl_domain_unpause(&priv->ctx, dom->id) != 0) { libxlError(VIR_ERR_INTERNAL_ERROR, _("Failed to resume domain '%d' with libxenlight"), @@ -1254,7 +1265,8 @@ libxlDomainResume(virDomainPtr dom) goto cleanup; } - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNPAUSED); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); @@ -1387,7 +1399,7 @@ libxlDomainDestroy(virDomainPtr dom) event = virDomainEventNewFromObj(vm,VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - if (libxlVmReap(driver, vm, 1) != 0) { + if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_DESTROYED) != 0) { libxlError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), dom->id); goto cleanup; @@ -1570,7 +1582,7 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) info->memory = d_info.current_memkb; } - info->state = vm->state; + info->state = virDomainObjGetState(vm, NULL); info->maxMem = vm->def->mem.max_balloon; info->nrVirtCpu = vm->def->vcpus; ret = 0; @@ -1603,10 +1615,7 @@ libxlDomainGetState(virDomainPtr dom, goto cleanup; } - *state = vm->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(vm, reason); ret = 0; cleanup: diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 17274657b5..1c55aee5c4 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -525,7 +525,7 @@ static int lxcDomainGetInfo(virDomainPtr dom, goto cleanup; } - info->state = vm->state; + info->state = virDomainObjGetState(vm, NULL); if (!virDomainObjIsActive(vm) || driver->cgroup == NULL) { info->cpuTime = 0; @@ -591,10 +591,7 @@ lxcDomainGetState(virDomainPtr dom, goto cleanup; } - *state = vm->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(vm, reason); ret = 0; cleanup: @@ -987,15 +984,16 @@ cleanup: /** * lxcVmCleanup: - * @conn: pointer to connection * @driver: pointer to driver structure * @vm: pointer to VM to clean up + * @reason: reason for switching the VM to shutoff state * * Cleanout resources associated with the now dead VM * */ static void lxcVmCleanup(lxc_driver_t *driver, - virDomainObjPtr vm) + virDomainObjPtr vm, + virDomainShutoffReason reason) { virCgroupPtr cgroup; int i; @@ -1017,7 +1015,7 @@ static void lxcVmCleanup(lxc_driver_t *driver, virFileDeletePid(driver->stateDir, vm->def->name); virDomainDeleteConfig(driver->stateDir, NULL, vm); - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); vm->pid = -1; vm->def->id = -1; priv->monitor = -1; @@ -1201,7 +1199,8 @@ error: static int lxcVmTerminate(lxc_driver_t *driver, - virDomainObjPtr vm) + virDomainObjPtr vm, + virDomainShutoffReason reason) { virCgroupPtr group = NULL; int rc; @@ -1228,7 +1227,7 @@ static int lxcVmTerminate(lxc_driver_t *driver, rc = -1; goto cleanup; } - lxcVmCleanup(driver, vm); + lxcVmCleanup(driver, vm, reason); rc = 0; @@ -1258,7 +1257,7 @@ static void lxcMonitorEvent(int watch, goto cleanup; } - if (lxcVmTerminate(driver, vm) < 0) { + if (lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) { virEventRemoveHandle(watch); } else { event = virDomainEventNewFromObj(vm, @@ -1392,6 +1391,7 @@ cleanup: * @conn: pointer to connection * @driver: pointer to driver structure * @vm: pointer to virtual machine structure + * @reason: reason for switching vm to running state * * Starts a vm * @@ -1399,7 +1399,8 @@ cleanup: */ static int lxcVmStart(virConnectPtr conn, lxc_driver_t * driver, - virDomainObjPtr vm) + virDomainObjPtr vm, + virDomainRunningReason reason) { int rc = -1, r; unsigned int i; @@ -1499,14 +1500,14 @@ static int lxcVmStart(virConnectPtr conn, } vm->def->id = vm->pid; - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); if ((priv->monitorWatch = virEventAddHandle( priv->monitor, VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP, lxcMonitorEvent, vm, NULL)) < 0) { - lxcVmTerminate(driver, vm); + lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED); goto cleanup; } @@ -1579,7 +1580,7 @@ static int lxcDomainStartWithFlags(virDomainPtr dom, unsigned int flags) goto cleanup; } - ret = lxcVmStart(dom->conn, driver, vm); + ret = lxcVmStart(dom->conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED); if (ret == 0) event = virDomainEventNewFromObj(vm, @@ -1650,7 +1651,7 @@ lxcDomainCreateAndStart(virConnectPtr conn, goto cleanup; def = NULL; - if (lxcVmStart(conn, driver, vm) < 0) { + if (lxcVmStart(conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED) < 0) { virDomainRemoveInactive(&driver->domains, vm); vm = NULL; goto cleanup; @@ -1815,7 +1816,7 @@ static int lxcDomainDestroy(virDomainPtr dom) goto cleanup; } - ret = lxcVmTerminate(driver, vm); + ret = lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); @@ -1863,7 +1864,8 @@ lxcAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu virDomainObjLock(vm); if (vm->autostart && !virDomainObjIsActive(vm)) { - int ret = lxcVmStart(data->conn, data->driver, vm); + int ret = lxcVmStart(data->conn, data->driver, vm, + VIR_DOMAIN_RUNNING_BOOTED); if (ret < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Failed to autostart VM '%s': %s"), @@ -1937,14 +1939,15 @@ lxcReconnectVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) if (vm->pid != 0) { vm->def->id = vm->pid; - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNKNOWN); if ((priv->monitorWatch = virEventAddHandle( priv->monitor, VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP, lxcMonitorEvent, vm, NULL)) < 0) { - lxcVmTerminate(driver, vm); + lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED); goto cleanup; } } else { @@ -2551,13 +2554,13 @@ static int lxcDomainSuspend(virDomainPtr dom) goto cleanup; } - if (vm->state != VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { if (lxcFreezeContainer(driver, vm) < 0) { lxcError(VIR_ERR_OPERATION_FAILED, "%s", _("Suspend operation failed")); goto cleanup; } - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, @@ -2616,13 +2619,14 @@ static int lxcDomainResume(virDomainPtr dom) goto cleanup; } - if (vm->state == VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { if (lxcUnfreezeContainer(driver, vm) < 0) { lxcError(VIR_ERR_OPERATION_FAILED, "%s", _("Resume operation failed")); goto cleanup; } - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNPAUSED); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 45bc398764..c02d131100 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -486,14 +486,20 @@ int openvzLoadDomains(struct openvz_driver *driver) { if (VIR_ALLOC(dom->def) < 0) goto no_memory; - if (STREQ(status, "stopped")) - dom->state = VIR_DOMAIN_SHUTOFF; - else - dom->state = VIR_DOMAIN_RUNNING; + if (STREQ(status, "stopped")) { + virDomainObjSetState(dom, VIR_DOMAIN_SHUTOFF, + VIR_DOMAIN_SHUTOFF_UNKNOWN); + } else { + virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNKNOWN); + } dom->refs = 1; dom->pid = veid; - dom->def->id = dom->state == VIR_DOMAIN_SHUTOFF ? -1 : veid; + if (virDomainObjGetState(dom, NULL) == VIR_DOMAIN_SHUTOFF) + dom->def->id = -1; + else + dom->def->id = veid; /* XXX OpenVZ doesn't appear to have concept of a transient domain */ dom->persistent = 1; diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 51631273d2..897211b371 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -353,7 +353,7 @@ static int openvzDomainGetInfo(virDomainPtr dom, goto cleanup; } - info->state = vm->state; + info->state = virDomainObjGetState(vm, NULL); if (!virDomainObjIsActive(vm)) { info->cpuTime = 0; @@ -399,10 +399,7 @@ openvzDomainGetState(virDomainPtr dom, goto cleanup; } - *state = vm->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(vm, reason); ret = 0; cleanup: @@ -525,12 +522,12 @@ static int openvzDomainSuspend(virDomainPtr dom) { goto cleanup; } - if (vm->state != VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { openvzSetProgramSentinal(prog, vm->def->name); if (virRun(prog, NULL) < 0) { goto cleanup; } - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); } ret = 0; @@ -563,12 +560,12 @@ static int openvzDomainResume(virDomainPtr dom) { goto cleanup; } - if (vm->state == VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { openvzSetProgramSentinal(prog, vm->def->name); if (virRun(prog, NULL) < 0) { goto cleanup; } - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNPAUSED); } ret = 0; @@ -596,7 +593,7 @@ static int openvzDomainShutdown(virDomainPtr dom) { } openvzSetProgramSentinal(prog, vm->def->name); - if (vm->state != VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain is not in running state")); goto cleanup; @@ -606,7 +603,7 @@ static int openvzDomainShutdown(virDomainPtr dom) { goto cleanup; vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_SHUTDOWN); dom->id = -1; ret = 0; @@ -634,7 +631,7 @@ static int openvzDomainReboot(virDomainPtr dom, } openvzSetProgramSentinal(prog, vm->def->name); - if (vm->state != VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain is not in running state")); goto cleanup; @@ -644,6 +641,8 @@ static int openvzDomainReboot(virDomainPtr dom, goto cleanup; ret = 0; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); + cleanup: if (vm) virDomainObjUnlock(vm); @@ -1008,7 +1007,7 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml, vm->pid = strtoI(vm->def->name); vm->def->id = vm->pid; - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); if (vm->def->maxvcpus > 0) { if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) { @@ -1050,7 +1049,7 @@ openvzDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) goto cleanup; } - if (vm->state != VIR_DOMAIN_SHUTOFF) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_SHUTOFF) { openvzError(VIR_ERR_OPERATION_DENIED, "%s", _("domain is not in shutoff state")); goto cleanup; @@ -1064,7 +1063,7 @@ openvzDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) vm->pid = strtoI(vm->def->name); vm->def->id = vm->pid; dom->id = vm->pid; - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); ret = 0; cleanup: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 21d79a281e..27951f46f4 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1320,7 +1320,7 @@ static int qemudDomainSuspend(virDomainPtr dom) { priv = vm->privateData; if (priv->jobActive == QEMU_JOB_MIGRATION_OUT) { - if (vm->state != VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { VIR_DEBUG("Requesting domain pause on %s", vm->def->name); priv->jobSignals |= QEMU_JOB_SIGNAL_SUSPEND; @@ -1336,8 +1336,8 @@ static int qemudDomainSuspend(virDomainPtr dom) { "%s", _("domain is not running")); goto endjob; } - if (vm->state != VIR_DOMAIN_PAUSED) { - if (qemuProcessStopCPUs(driver, vm) < 0) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { + if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_USER) < 0) { goto endjob; } event = virDomainEventNewFromObj(vm, @@ -1389,8 +1389,9 @@ static int qemudDomainResume(virDomainPtr dom) { "%s", _("domain is not running")); goto endjob; } - if (vm->state == VIR_DOMAIN_PAUSED) { - if (qemuProcessStartCPUs(driver, vm, dom->conn) < 0) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + if (qemuProcessStartCPUs(driver, vm, dom->conn, + VIR_DOMAIN_RUNNING_UNPAUSED) < 0) { if (virGetLastError() == NULL) qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resume operation failed")); @@ -1493,7 +1494,7 @@ static int qemudDomainDestroy(virDomainPtr dom) { goto endjob; } - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_DESTROYED); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); @@ -1771,7 +1772,7 @@ static int qemudDomainGetInfo(virDomainPtr dom, goto cleanup; } - info->state = vm->state; + info->state = virDomainObjGetState(vm, NULL); if (!virDomainObjIsActive(vm)) { info->cpuTime = 0; @@ -1853,10 +1854,7 @@ qemuDomainGetState(virDomainPtr dom, goto cleanup; } - *state = vm->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(vm, reason); ret = 0; cleanup: @@ -1982,9 +1980,9 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; /* Pause */ - if (vm->state == VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { header.was_running = 1; - if (qemuProcessStopCPUs(driver, vm) < 0) + if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE) < 0) goto endjob; if (!virDomainObjIsActive(vm)) { @@ -2131,7 +2129,7 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, ret = 0; /* Shut it down */ - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_SAVED); qemuAuditDomainStop(vm, "saved"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, @@ -2147,7 +2145,8 @@ endjob: if (vm) { if (ret != 0) { if (header.was_running && virDomainObjIsActive(vm)) { - rc = qemuProcessStartCPUs(driver, vm, dom->conn); + rc = qemuProcessStartCPUs(driver, vm, dom->conn, + VIR_DOMAIN_RUNNING_SAVE_CANCELED); if (rc < 0) VIR_WARN("Unable to resume guest CPUs after save failure"); } @@ -2459,11 +2458,12 @@ static int qemudDomainCoreDump(virDomainPtr dom, /* Migrate will always stop the VM, so the resume condition is independent of whether the stop command is issued. */ - resume = (vm->state == VIR_DOMAIN_RUNNING); + resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING; /* Pause domain for non-live dump */ - if (!(flags & VIR_DUMP_LIVE) && vm->state == VIR_DOMAIN_RUNNING) { - if (qemuProcessStopCPUs(driver, vm) < 0) + if (!(flags & VIR_DUMP_LIVE) && + virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { + if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_DUMP) < 0) goto endjob; paused = 1; @@ -2482,7 +2482,7 @@ static int qemudDomainCoreDump(virDomainPtr dom, endjob: if ((ret == 0) && (flags & VIR_DUMP_CRASH)) { - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_CRASHED); qemuAuditDomainStop(vm, "crashed"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, @@ -2493,7 +2493,8 @@ endjob: will support synchronous operations so we always get here after the migration is complete. */ else if (resume && paused && virDomainObjIsActive(vm)) { - if (qemuProcessStartCPUs(driver, vm, dom->conn) < 0) { + if (qemuProcessStartCPUs(driver, vm, dom->conn, + VIR_DOMAIN_RUNNING_UNPAUSED) < 0) { if (virGetLastError() == NULL) qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resuming after dump failed")); @@ -2647,7 +2648,8 @@ static void processWatchdogEvent(void *data, void *opaque) qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Dump failed")); - ret = qemuProcessStartCPUs(driver, wdEvent->vm, NULL); + ret = qemuProcessStartCPUs(driver, wdEvent->vm, NULL, + VIR_DOMAIN_RUNNING_UNPAUSED); if (ret < 0) qemuReportError(VIR_ERR_OPERATION_FAILED, @@ -3345,7 +3347,8 @@ qemuDomainSaveImageStartVM(virConnectPtr conn, /* If it was running before, resume it now. */ if (header->was_running) { - if (qemuProcessStartCPUs(driver, vm, conn) < 0) { + if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_RESTORED) < 0) { if (virGetLastError() == NULL) qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("failed to resume domain")); @@ -6474,12 +6477,12 @@ qemuDomainSnapshotCreateActive(virConnectPtr conn, if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) return -1; - if (vm->state == VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { /* savevm monitor command pauses the domain emitting an event which * confuses libvirt since it's not notified when qemu resumes the * domain. Thus we stop and start CPUs ourselves. */ - if (qemuProcessStopCPUs(driver, vm) < 0) + if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_SAVE) < 0) goto cleanup; resume = true; @@ -6496,7 +6499,8 @@ qemuDomainSnapshotCreateActive(virConnectPtr conn, cleanup: if (resume && virDomainObjIsActive(vm) && - qemuProcessStartCPUs(driver, vm, conn) < 0 && + qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_UNPAUSED) < 0 && virGetLastError() == NULL) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resuming after snapshot failed")); @@ -6546,7 +6550,7 @@ static virDomainSnapshotPtr qemuDomainSnapshotCreateXML(virDomainPtr domain, if (!(snap = virDomainSnapshotAssignDef(&vm->snapshots, def))) goto cleanup; - snap->def->state = vm->state; + snap->def->state = virDomainObjGetState(vm, NULL); /* actually do the snapshot */ if (!virDomainObjIsActive(vm)) { @@ -6846,9 +6850,13 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, /* qemu unconditionally starts the domain running again after * loadvm, so let's pause it to keep consistency */ - rc = qemuProcessStopCPUs(driver, vm); + rc = qemuProcessStopCPUs(driver, vm, + VIR_DOMAIN_PAUSED_FROM_SNAPSHOT); if (rc < 0) goto endjob; + } else { + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_FROM_SNAPSHOT); } event = virDomainEventNewFromObj(vm, @@ -6867,7 +6875,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, */ if (virDomainObjIsActive(vm)) { - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT); qemuAuditDomainStop(vm, "from-snapshot"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, @@ -6884,8 +6892,6 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, goto endjob; } - vm->state = snap->def->state; - ret = 0; endjob: diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3214d38dfb..0e971ef756 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -65,7 +65,7 @@ qemuMigrationSetOffline(struct qemud_driver *driver, { int ret; - ret = qemuProcessStopCPUs(driver, vm); + ret = qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION); if (ret == 0) { virDomainEventPtr event; @@ -325,7 +325,7 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver, if (virFDStreamOpen(st, dataFD[1]) < 0) { qemuAuditDomainStart(vm, "migrated", false); - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED); if (!vm->persistent) { if (qemuDomainObjEndJob(vm) > 0) virDomainRemoveInactive(&driver->domains, vm); @@ -1047,8 +1047,9 @@ int qemuMigrationPerform(struct qemud_driver *driver, memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED; - resume = vm->state == VIR_DOMAIN_RUNNING; - if (!(flags & VIR_MIGRATE_LIVE) && vm->state == VIR_DOMAIN_RUNNING) { + resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING; + if (!(flags & VIR_MIGRATE_LIVE) && + virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { if (qemuMigrationSetOffline(driver, vm) < 0) goto endjob; } @@ -1063,7 +1064,7 @@ int qemuMigrationPerform(struct qemud_driver *driver, } /* Clean up the source domain. */ - qemuProcessStop(driver, vm, 1); + qemuProcessStop(driver, vm, 1, VIR_DOMAIN_SHUTOFF_MIGRATED); qemuAuditDomainStop(vm, "migrated"); resume = 0; @@ -1079,9 +1080,10 @@ int qemuMigrationPerform(struct qemud_driver *driver, ret = 0; endjob: - if (resume && vm->state == VIR_DOMAIN_PAUSED) { + if (resume && virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { /* we got here through some sort of failure; start the domain again */ - if (qemuProcessStartCPUs(driver, vm, conn) < 0) { + if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_MIGRATION_CANCELED) < 0) { /* Hm, we already know we are in error here. We don't want to * overwrite the previous error, though, so we just throw something * to the logs and hope for the best @@ -1220,7 +1222,8 @@ qemuMigrationFinish(struct qemud_driver *driver, * >= 0.10.6 to work properly. This isn't strictly necessary on * older qemu's, but it also doesn't hurt anything there */ - if (qemuProcessStartCPUs(driver, vm, dconn) < 0) { + if (qemuProcessStartCPUs(driver, vm, dconn, + VIR_DOMAIN_RUNNING_MIGRATED) < 0) { if (virGetLastError() == NULL) qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("resume operation failed")); @@ -1231,7 +1234,8 @@ qemuMigrationFinish(struct qemud_driver *driver, event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_MIGRATED); - if (vm->state == VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); qemuDomainEventQueue(driver, event); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, @@ -1242,7 +1246,7 @@ qemuMigrationFinish(struct qemud_driver *driver, goto endjob; } } else { - qemuProcessStop(driver, vm, 1); + qemuProcessStop(driver, vm, 1, VIR_DOMAIN_SHUTOFF_FAILED); qemuAuditDomainStop(vm, "failed"); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index f745aead0a..3beb666eac 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -132,7 +132,10 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED, VIR_DOMAIN_EVENT_STOPPED_FAILED : VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, + hasError ? + VIR_DOMAIN_SHUTOFF_CRASHED : + VIR_DOMAIN_SHUTOFF_SHUTDOWN); qemuAuditDomainStop(vm, hasError ? "failed" : "shutdown"); if (!vm->persistent) @@ -340,11 +343,11 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, virDomainEventPtr event = NULL; virDomainObjLock(vm); - if (vm->state == VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { VIR_DEBUG("Transitioned guest %s to paused state due to unknown event", vm->def->name); - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_UNKNOWN); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); @@ -409,10 +412,10 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, watchdogEvent = virDomainEventWatchdogNewFromObj(vm, action); if (action == VIR_DOMAIN_EVENT_WATCHDOG_PAUSE && - vm->state == VIR_DOMAIN_RUNNING) { + virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { VIR_DEBUG("Transitioned guest %s to paused state due to watchdog", vm->def->name); - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_WATCHDOG); lifecycleEvent = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG); @@ -488,10 +491,10 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, ioErrorEvent2 = virDomainEventIOErrorReasonNewFromObj(vm, srcPath, devAlias, action, reason); if (action == VIR_DOMAIN_EVENT_IO_ERROR_PAUSE && - vm->state == VIR_DOMAIN_RUNNING) { + virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name); - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR); lifecycleEvent = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_IOERROR); @@ -1816,7 +1819,7 @@ qemuProcessPrepareMonitorChr(struct qemud_driver *driver, int qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm, - virConnectPtr conn) + virConnectPtr conn, virDomainRunningReason reason) { int ret; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -1824,27 +1827,32 @@ qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm, qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorStartCPUs(priv->mon, conn); qemuDomainObjExitMonitorWithDriver(driver, vm); - if (ret == 0) { - vm->state = VIR_DOMAIN_RUNNING; - } + + if (ret == 0) + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); return ret; } -int qemuProcessStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm) +int qemuProcessStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm, + virDomainPausedReason reason) { int ret; - int oldState = vm->state; + int oldState; + int oldReason; qemuDomainObjPrivatePtr priv = vm->privateData; - vm->state = VIR_DOMAIN_PAUSED; + oldState = virDomainObjGetState(vm, &oldReason); + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason); + qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorStopCPUs(priv->mon); qemuDomainObjExitMonitorWithDriver(driver, vm); - if (ret < 0) { - vm->state = oldState; - } + + if (ret < 0) + virDomainObjSetState(vm, oldState, oldReason); + return ret; } @@ -1950,7 +1958,7 @@ error: /* We can't get the monitor back, so must kill the VM * to remove danger of it ending up running twice if * user tries to start it again later */ - qemuProcessStop(driver, obj, 0); + qemuProcessStop(driver, obj, 0, VIR_DOMAIN_SHUTOFF_FAILED); if (!obj->persistent) virDomainRemoveInactive(&driver->domains, obj); else @@ -2289,7 +2297,6 @@ int qemuProcessStart(virConnectPtr conn, if (migrateFrom) start_paused = true; - vm->state = start_paused ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING; if (ret == -1) /* The VM failed to start; tear filters before taps */ virDomainConfVMNWFilterTeardown(vm); @@ -2333,15 +2340,20 @@ int qemuProcessStart(virConnectPtr conn, if (!start_paused) { VIR_DEBUG("Starting domain CPUs"); /* Allow the CPUS to start executing */ - if (qemuProcessStartCPUs(driver, vm, conn) < 0) { + if (qemuProcessStartCPUs(driver, vm, conn, + VIR_DOMAIN_RUNNING_BOOTED) < 0) { if (virGetLastError() == NULL) qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("resume operation failed")); goto cleanup; } + } else { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, + migrateFrom ? + VIR_DOMAIN_PAUSED_MIGRATION : + VIR_DOMAIN_PAUSED_USER); } - VIR_DEBUG("Writing domain status to disk"); if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) goto cleanup; @@ -2357,7 +2369,7 @@ cleanup: * pretend we never started it */ virCommandFree(cmd); VIR_FORCE_CLOSE(logfile); - qemuProcessStop(driver, vm, 0); + qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED); return -1; } @@ -2405,7 +2417,8 @@ void qemuProcessKill(virDomainObjPtr vm) void qemuProcessStop(struct qemud_driver *driver, virDomainObjPtr vm, - int migrated) + int migrated, + virDomainShutoffReason reason) { int ret; int retries = 0; @@ -2556,7 +2569,7 @@ retry: vm->taint = 0; vm->pid = -1; vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); VIR_FREE(priv->vcpupids); priv->nvcpupids = 0; qemuCapsFree(priv->qemuCaps); diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index d8afab0f18..7ec9d7d70d 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -28,8 +28,13 @@ int qemuProcessPrepareMonitorChr(struct qemud_driver *driver, virDomainChrSourceDefPtr monConfig, const char *vm); -int qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm, virConnectPtr conn); -int qemuProcessStopCPUs(struct qemud_driver *driver, virDomainObjPtr vm); +int qemuProcessStartCPUs(struct qemud_driver *driver, + virDomainObjPtr vm, + virConnectPtr conn, + virDomainRunningReason reason); +int qemuProcessStopCPUs(struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainPausedReason reason); void qemuProcessAutostartAll(struct qemud_driver *driver); void qemuProcessReconnectAll(virConnectPtr conn, struct qemud_driver *driver); @@ -47,7 +52,8 @@ int qemuProcessStart(virConnectPtr conn, void qemuProcessStop(struct qemud_driver *driver, virDomainObjPtr vm, - int migrated); + int migrated, + virDomainShutoffReason reason); void qemuProcessKill(virDomainObjPtr vm); diff --git a/src/test/test_driver.c b/src/test/test_driver.c index ab74ef5674..a9c9846ce8 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -454,7 +454,8 @@ cleanup: static void testDomainShutdownState(virDomainPtr domain, - virDomainObjPtr privdom) + virDomainObjPtr privdom, + virDomainShutoffReason reason) { if (privdom->newDef) { virDomainDefFree(privdom->def); @@ -462,7 +463,7 @@ testDomainShutdownState(virDomainPtr domain, privdom->newDef = NULL; } - privdom->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF, reason); privdom->def->id = -1; if (domain) domain->id = -1; @@ -471,7 +472,8 @@ testDomainShutdownState(virDomainPtr domain, /* Set up domain runtime state */ static int testDomainStartState(virConnectPtr conn, - virDomainObjPtr dom) + virDomainObjPtr dom, + virDomainRunningReason reason) { testConnPtr privconn = conn->privateData; int ret = -1; @@ -479,7 +481,7 @@ testDomainStartState(virConnectPtr conn, if (testDomainUpdateVCPUs(conn, dom, dom->def->vcpus, 1) < 0) goto cleanup; - dom->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, reason); dom->def->id = privconn->nextDomID++; if (virDomainObjSetDefTransient(privconn->caps, dom, false) < 0) { @@ -489,7 +491,7 @@ testDomainStartState(virConnectPtr conn, ret = 0; cleanup: if (ret < 0) - testDomainShutdownState(NULL, dom); + testDomainShutdownState(NULL, dom, VIR_DOMAIN_SHUTOFF_FAILED); return ret; } @@ -560,7 +562,7 @@ static int testOpenDefault(virConnectPtr conn) { domdef = NULL; domobj->persistent = 1; - if (testDomainStartState(conn, domobj) < 0) { + if (testDomainStartState(conn, domobj, VIR_DOMAIN_RUNNING_BOOTED) < 0) { virDomainObjUnlock(domobj); goto error; } @@ -905,7 +907,7 @@ static int testOpenFromFile(virConnectPtr conn, } dom->persistent = 1; - if (testDomainStartState(conn, dom) < 0) { + if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0) { virDomainObjUnlock(dom); goto error; } @@ -1297,7 +1299,7 @@ testDomainCreateXML(virConnectPtr conn, const char *xml, goto cleanup; def = NULL; - if (testDomainStartState(conn, dom) < 0) + if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0) goto cleanup; event = virDomainEventNewFromObj(dom, @@ -1427,7 +1429,7 @@ static int testDestroyDomain (virDomainPtr domain) goto cleanup; } - testDomainShutdownState(domain, privdom); + testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_DESTROYED); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); @@ -1465,13 +1467,14 @@ static int testResumeDomain (virDomainPtr domain) goto cleanup; } - if (privdom->state != VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(privdom, NULL) != VIR_DOMAIN_PAUSED) { testError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not paused"), domain->name); goto cleanup; } - privdom->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(privdom, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNPAUSED); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); @@ -1494,6 +1497,7 @@ static int testPauseDomain (virDomainPtr domain) virDomainObjPtr privdom; virDomainEventPtr event = NULL; int ret = -1; + int state; testDriverLock(privconn); privdom = virDomainFindByName(&privconn->domains, @@ -1505,14 +1509,14 @@ static int testPauseDomain (virDomainPtr domain) goto cleanup; } - if (privdom->state == VIR_DOMAIN_SHUTOFF || - privdom->state == VIR_DOMAIN_PAUSED) { + state = virDomainObjGetState(privdom, NULL); + if (state == VIR_DOMAIN_SHUTOFF || state == VIR_DOMAIN_PAUSED) { testError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not running"), domain->name); goto cleanup; } - privdom->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(privdom, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_PAUSED); @@ -1546,13 +1550,13 @@ static int testShutdownDomain (virDomainPtr domain) goto cleanup; } - if (privdom->state == VIR_DOMAIN_SHUTOFF) { + if (virDomainObjGetState(privdom, NULL) == VIR_DOMAIN_SHUTOFF) { testError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not running"), domain->name); goto cleanup; } - testDomainShutdownState(domain, privdom); + testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SHUTDOWN); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); @@ -1591,31 +1595,38 @@ static int testRebootDomain (virDomainPtr domain, goto cleanup; } - privdom->state = VIR_DOMAIN_SHUTDOWN; + virDomainObjSetState(privdom, VIR_DOMAIN_SHUTDOWN, + VIR_DOMAIN_SHUTDOWN_USER); + switch (privdom->def->onReboot) { case VIR_DOMAIN_LIFECYCLE_DESTROY: - privdom->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF, + VIR_DOMAIN_SHUTOFF_SHUTDOWN); break; case VIR_DOMAIN_LIFECYCLE_RESTART: - privdom->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(privdom, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_BOOTED); break; case VIR_DOMAIN_LIFECYCLE_PRESERVE: - privdom->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF, + VIR_DOMAIN_SHUTOFF_SHUTDOWN); break; case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME: - privdom->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(privdom, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_BOOTED); break; default: - privdom->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF, + VIR_DOMAIN_SHUTOFF_SHUTDOWN); break; } - if (privdom->state == VIR_DOMAIN_SHUTOFF) { - testDomainShutdownState(domain, privdom); + if (virDomainObjGetState(privdom, NULL) == VIR_DOMAIN_SHUTOFF) { + testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SHUTDOWN); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); @@ -1661,7 +1672,7 @@ static int testGetDomainInfo (virDomainPtr domain, goto cleanup; } - info->state = privdom->state; + info->state = virDomainObjGetState(privdom, NULL); info->memory = privdom->def->mem.cur_balloon; info->maxMem = privdom->def->mem.max_balloon; info->nrVirtCpu = privdom->def->vcpus; @@ -1696,10 +1707,7 @@ testDomainGetState(virDomainPtr domain, goto cleanup; } - *state = privdom->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(privdom, reason); ret = 0; cleanup: @@ -1774,7 +1782,7 @@ static int testDomainSave(virDomainPtr domain, } fd = -1; - testDomainShutdownState(domain, privdom); + testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SAVED); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); @@ -1872,7 +1880,7 @@ static int testDomainRestore(virConnectPtr conn, goto cleanup; def = NULL; - if (testDomainStartState(conn, dom) < 0) + if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_RESTORED) < 0) goto cleanup; event = virDomainEventNewFromObj(dom, @@ -1931,7 +1939,7 @@ static int testDomainCoreDump(virDomainPtr domain, } if (flags & VIR_DUMP_CRASH) { - testDomainShutdownState(domain, privdom); + testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_CRASHED); event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_CRASHED); @@ -2484,13 +2492,14 @@ static int testDomainCreateWithFlags(virDomainPtr domain, unsigned int flags) { goto cleanup; } - if (privdom->state != VIR_DOMAIN_SHUTOFF) { + if (virDomainObjGetState(privdom, NULL) != VIR_DOMAIN_SHUTOFF) { testError(VIR_ERR_INTERNAL_ERROR, _("Domain '%s' is already running"), domain->name); goto cleanup; } - if (testDomainStartState(domain->conn, privdom) < 0) + if (testDomainStartState(domain->conn, privdom, + VIR_DOMAIN_RUNNING_BOOTED) < 0) goto cleanup; domain->id = privdom->def->id; @@ -2527,13 +2536,12 @@ static int testDomainUndefine(virDomainPtr domain) { goto cleanup; } - if (privdom->state != VIR_DOMAIN_SHUTOFF) { + if (virDomainObjGetState(privdom, NULL) != VIR_DOMAIN_SHUTOFF) { testError(VIR_ERR_INTERNAL_ERROR, _("Domain '%s' is still running"), domain->name); goto cleanup; } - privdom->state = VIR_DOMAIN_SHUTOFF; event = virDomainEventNewFromObj(privdom, VIR_DOMAIN_EVENT_UNDEFINED, VIR_DOMAIN_EVENT_UNDEFINED_REMOVED); diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 3840d3467a..5a941fa2aa 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -133,7 +133,8 @@ static int umlStartVMDaemon(virConnectPtr conn, static void umlShutdownVMDaemon(virConnectPtr conn, struct uml_driver *driver, - virDomainObjPtr vm); + virDomainObjPtr vm, + virDomainShutoffReason reason); static int umlMonitorCommand(const struct uml_driver *driver, @@ -305,7 +306,7 @@ reread: continue; } - umlShutdownVMDaemon(NULL, driver, dom); + umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN); } else if (e->mask & (IN_CREATE | IN_MODIFY)) { VIR_DEBUG("Got inotify domain startup '%s'", name); if (virDomainObjIsActive(dom)) { @@ -319,14 +320,17 @@ reread: } dom->def->id = driver->nextvmid++; - dom->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_BOOTED); if (umlOpenMonitor(driver, dom) < 0) { VIR_WARN("Could not open monitor for new domain"); - umlShutdownVMDaemon(NULL, driver, dom); + umlShutdownVMDaemon(NULL, driver, dom, + VIR_DOMAIN_SHUTOFF_FAILED); } else if (umlIdentifyChrPTY(driver, dom) < 0) { VIR_WARN("Could not identify charater devices for new domain"); - umlShutdownVMDaemon(NULL, driver, dom); + umlShutdownVMDaemon(NULL, driver, dom, + VIR_DOMAIN_SHUTOFF_FAILED); } } virDomainObjUnlock(dom); @@ -515,7 +519,7 @@ umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) virDomainObjLock(dom); if (virDomainObjIsActive(dom)) - umlShutdownVMDaemon(NULL, driver, dom); + umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN); virDomainObjUnlock(dom); } @@ -907,7 +911,8 @@ cleanup: static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, struct uml_driver *driver ATTRIBUTE_UNUSED, - virDomainObjPtr vm) + virDomainObjPtr vm, + virDomainShutoffReason reason) { int ret; umlDomainObjPrivatePtr priv = vm->privateData; @@ -926,7 +931,7 @@ static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED, vm->pid = -1; vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); virDomainConfVMNWFilterTeardown(vm); umlCleanupTapDevices(conn, vm); @@ -1345,7 +1350,7 @@ static int umlDomainDestroy(virDomainPtr dom) { goto cleanup; } - umlShutdownVMDaemon(dom->conn, driver, vm); + umlShutdownVMDaemon(dom->conn, driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED); if (!vm->persistent) { virDomainRemoveInactive(&driver->domains, vm); @@ -1498,7 +1503,7 @@ static int umlDomainGetInfo(virDomainPtr dom, goto cleanup; } - info->state = vm->state; + info->state = virDomainObjGetState(vm, NULL); if (!virDomainObjIsActive(vm)) { info->cpuTime = 0; @@ -1544,10 +1549,7 @@ umlDomainGetState(virDomainPtr dom, goto cleanup; } - *state = vm->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(vm, reason); ret = 0; cleanup: diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index 6339248a9e..4ec33aebde 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -185,7 +185,8 @@ vmwareLoadDomains(struct vmware_driver *driver) if ((vm->def->id = vmwareExtractPid(vmxPath)) < 0) goto cleanup; /* vmrun list only reports running vms */ - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, + VIR_DOMAIN_RUNNING_UNKNOWN); vm->persistent = 1; virDomainObjUnlock(vm); diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index 93ba5bdb89..a086ca6647 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -178,7 +178,9 @@ vmwareGetVersion(virConnectPtr conn, unsigned long *version) } static int -vmwareStopVM(struct vmware_driver *driver, virDomainObjPtr vm) +vmwareStopVM(struct vmware_driver *driver, + virDomainObjPtr vm, + virDomainShutoffReason reason) { const char *cmd[] = { VMRUN, "-T", PROGRAM_SENTINAL, "stop", @@ -193,7 +195,7 @@ vmwareStopVM(struct vmware_driver *driver, virDomainObjPtr vm) } vm->def->id = -1; - vm->state = VIR_DOMAIN_SHUTOFF; + virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); return 0; } @@ -207,7 +209,7 @@ vmwareStartVM(struct vmware_driver *driver, virDomainObjPtr vm) }; const char *vmxPath = ((vmwareDomainPtr) vm->privateData)->vmxPath; - if (vm->state != VIR_DOMAIN_SHUTOFF) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_SHUTOFF) { vmwareError(VIR_ERR_OPERATION_INVALID, "%s", _("domain is not in shutoff state")); return -1; @@ -225,11 +227,11 @@ vmwareStartVM(struct vmware_driver *driver, virDomainObjPtr vm) } if ((vm->def->id = vmwareExtractPid(vmxPath)) < 0) { - vmwareStopVM(driver, vm); + vmwareStopVM(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED); return -1; } - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); return 0; } @@ -322,13 +324,13 @@ vmwareDomainShutdown(virDomainPtr dom) goto cleanup; } - if (vm->state != VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain is not in running state")); goto cleanup; } - if (vmwareStopVM(driver, vm) < 0) + if (vmwareStopVM(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) goto cleanup; if (!vm->persistent) { @@ -375,7 +377,7 @@ vmwareDomainSuspend(virDomainPtr dom) vmwareSetSentinal(cmd, vmw_types[driver->type]); vmwareSetSentinal(cmd, ((vmwareDomainPtr) vm->privateData)->vmxPath); - if (vm->state != VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain is not in running state")); goto cleanup; @@ -384,7 +386,7 @@ vmwareDomainSuspend(virDomainPtr dom) if (virRun(cmd, NULL) < 0) goto cleanup; - vm->state = VIR_DOMAIN_PAUSED; + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); ret = 0; cleanup: @@ -424,7 +426,7 @@ vmwareDomainResume(virDomainPtr dom) vmwareSetSentinal(cmd, vmw_types[driver->type]); vmwareSetSentinal(cmd, ((vmwareDomainPtr) vm->privateData)->vmxPath); - if (vm->state != VIR_DOMAIN_PAUSED) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain is not in suspend state")); goto cleanup; @@ -433,7 +435,7 @@ vmwareDomainResume(virDomainPtr dom) if (virRun(cmd, NULL) < 0) goto cleanup; - vm->state = VIR_DOMAIN_RUNNING; + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNPAUSED); ret = 0; cleanup: @@ -470,7 +472,7 @@ vmwareDomainReboot(virDomainPtr dom, unsigned int flags ATTRIBUTE_UNUSED) vmwareSetSentinal(cmd, vmxPath); - if (vm->state != VIR_DOMAIN_RUNNING) { + if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain is not in running state")); goto cleanup; @@ -883,7 +885,7 @@ vmwareDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) goto cleanup; } - info->state = vm->state; + info->state = virDomainObjGetState(vm, NULL); info->cpuTime = 0; info->maxMem = vm->def->mem.max_balloon; info->memory = vm->def->mem.cur_balloon; @@ -918,10 +920,7 @@ vmwareDomainGetState(virDomainPtr dom, goto cleanup; } - *state = vm->state; - if (reason) - *reason = 0; - + *state = virDomainObjGetState(vm, reason); ret = 0; cleanup: