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: