On Tue, May 10, 2011 at 03:39:10PM +0200, Jiri Denemark wrote: > 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. > --- > Notes: > Version 2: > - rebased > - fixed || vs && typo > > 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 d3efec6..bd7c64a 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); > @@ -6273,6 +6324,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; > @@ -6296,7 +6349,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); > @@ -6304,6 +6357,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")); > @@ -8498,10 +8563,14 @@ static char *virDomainObjFormat(virCapsPtr caps, > { > char *config_xml = NULL; > virBuffer buf = VIR_BUFFER_INITIALIZER; > + int state; > + int reason; > int i; > > - virBufferAsprintf(&buf, "<domstatus state='%s' pid='%d'>\n", > - virDomainStateTypeToString(obj->state), > + state = virDomainObjGetState(obj, &reason); > + virBufferAsprintf(&buf, "<domstatus state='%s' reason='%s' pid='%d'>\n", > + virDomainStateTypeToString(state), > + virDomainStateReasonToString(state, reason), > obj->pid); > > for (i = 0 ; i < VIR_DOMAIN_TAINT_LAST ; i++) { > @@ -9604,3 +9673,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 a0f820c..fe42f21 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 e2e706d..1209315 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -292,6 +292,7 @@ virDomainNetTypeToString; > virDomainObjAssignDef; > virDomainObjCopyPersistentDef; > virDomainObjGetPersistentDef; > +virDomainObjGetState; > virDomainObjIsDuplicate; > virDomainObjListDeinit; > virDomainObjListGetActiveIDs; > @@ -301,6 +302,7 @@ virDomainObjListNumOfDomains; > virDomainObjLock; > virDomainObjRef; > virDomainObjSetDefTransient; > +virDomainObjSetState; > virDomainObjTaint; > virDomainObjUnlock; > virDomainObjUnref; > @@ -324,6 +326,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 1fcf723..6962711 100644 > --- a/src/libxl/libxl_driver.c > +++ b/src/libxl/libxl_driver.c > @@ -245,7 +245,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; > @@ -265,7 +267,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) && > @@ -302,7 +304,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; > > @@ -312,7 +317,7 @@ libxlVmReap(libxlDriverPrivatePtr driver, virDomainObjPtr vm, int force) > return -1; > } > > - libxlVmCleanup(driver, vm); > + libxlVmCleanup(driver, vm, reason); > return 0; > } > > @@ -353,6 +358,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, > @@ -366,18 +373,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: > @@ -596,9 +607,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); > } > > > @@ -617,7 +628,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); > @@ -662,7 +673,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); > @@ -670,7 +681,7 @@ libxlReconnectDomain(void *payload, > return; > > out: > - libxlVmCleanup(driver, vm); > + libxlVmCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_UNKNOWN); > if (!vm->persistent) > virDomainRemoveInactive(&driver->domains, vm); > else > @@ -1213,7 +1224,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"), > @@ -1221,7 +1232,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); > @@ -1272,7 +1283,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"), > @@ -1280,7 +1291,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); > @@ -1413,7 +1425,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; > @@ -1596,7 +1608,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; > @@ -1629,10 +1641,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 2d57eb2..aab0c7f 100644 > --- a/src/lxc/lxc_driver.c > +++ b/src/lxc/lxc_driver.c > @@ -522,7 +522,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; > @@ -588,10 +588,7 @@ lxcDomainGetState(virDomainPtr dom, > goto cleanup; > } > > - *state = vm->state; > - if (reason) > - *reason = 0; > - > + *state = virDomainObjGetState(vm, reason); > ret = 0; > > cleanup: > @@ -984,15 +981,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; > @@ -1014,7 +1012,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; > @@ -1198,7 +1196,8 @@ error: > > > static int lxcVmTerminate(lxc_driver_t *driver, > - virDomainObjPtr vm) > + virDomainObjPtr vm, > + virDomainShutoffReason reason) > { > virCgroupPtr group = NULL; > int rc; > @@ -1225,7 +1224,7 @@ static int lxcVmTerminate(lxc_driver_t *driver, > rc = -1; > goto cleanup; > } > - lxcVmCleanup(driver, vm); > + lxcVmCleanup(driver, vm, reason); > > rc = 0; > > @@ -1255,7 +1254,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, > @@ -1481,6 +1480,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 > * > @@ -1488,7 +1488,8 @@ cleanup: > */ > static int lxcVmStart(virConnectPtr conn, > lxc_driver_t * driver, > - virDomainObjPtr vm) > + virDomainObjPtr vm, > + virDomainRunningReason reason) > { > int rc = -1, r; > unsigned int i; > @@ -1588,14 +1589,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; > } > > @@ -1668,7 +1669,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, > @@ -1739,7 +1740,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; > @@ -1930,7 +1931,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); > @@ -1978,7 +1979,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"), > @@ -2052,14 +2054,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 { > @@ -2673,13 +2676,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, > @@ -2738,13 +2741,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 88cd4c8..8c6261f 100644 > --- a/src/openvz/openvz_conf.c > +++ b/src/openvz/openvz_conf.c > @@ -484,14 +484,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 3ab72e8..4ecaea7 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); > @@ -1022,7 +1021,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) { > @@ -1064,7 +1063,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; > @@ -1078,7 +1077,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 a1617bc..1c5f439 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -1325,7 +1325,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; > @@ -1341,8 +1341,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, > @@ -1394,8 +1394,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")); > @@ -1491,7 +1492,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); > @@ -1725,7 +1726,7 @@ static int qemudDomainGetInfo(virDomainPtr dom, > goto cleanup; > } > > - info->state = vm->state; > + info->state = virDomainObjGetState(vm, NULL); > > if (!virDomainObjIsActive(vm)) { > info->cpuTime = 0; > @@ -1807,10 +1808,7 @@ qemuDomainGetState(virDomainPtr dom, > goto cleanup; > } > > - *state = vm->state; > - if (reason) > - *reason = 0; > - > + *state = virDomainObjGetState(vm, reason); > ret = 0; > > cleanup: > @@ -1936,9 +1934,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)) { > @@ -2085,7 +2083,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, > @@ -2101,7 +2099,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_WARN0("Unable to resume guest CPUs after save failure"); > } > @@ -2413,11 +2412,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; > > @@ -2436,7 +2436,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, > @@ -2447,7 +2447,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")); > @@ -2513,7 +2514,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, > @@ -3211,7 +3213,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")); > @@ -6345,12 +6348,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; > @@ -6367,7 +6370,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")); > @@ -6417,7 +6421,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)) { > @@ -6717,9 +6721,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, > @@ -6738,7 +6746,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, > @@ -6755,8 +6763,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 6738a53..b45beb7 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 bd7c932..f74122e 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_DEBUG0("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_DEBUG0("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; > } > @@ -2365,7 +2377,8 @@ cleanup: > > void qemuProcessStop(struct qemud_driver *driver, > virDomainObjPtr vm, > - int migrated) > + int migrated, > + virDomainShutoffReason reason) > { > int ret; > int retries = 0; > @@ -2523,7 +2536,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 f1ab599..40b386d 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,6 +52,7 @@ int qemuProcessStart(virConnectPtr conn, > > void qemuProcessStop(struct qemud_driver *driver, > virDomainObjPtr vm, > - int migrated); > + int migrated, > + virDomainShutoffReason reason); > > #endif /* __QEMU_PROCESS_H__ */ > diff --git a/src/test/test_driver.c b/src/test/test_driver.c > index 4ec2852..ca79309 100644 > --- a/src/test/test_driver.c > +++ b/src/test/test_driver.c > @@ -459,7 +459,8 @@ cleanup: > > static void > testDomainShutdownState(virDomainPtr domain, > - virDomainObjPtr privdom) > + virDomainObjPtr privdom, > + virDomainShutoffReason reason) > { > if (privdom->newDef) { > virDomainDefFree(privdom->def); > @@ -467,7 +468,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; > @@ -476,7 +477,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; > @@ -484,7 +486,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) { > @@ -494,7 +496,7 @@ testDomainStartState(virConnectPtr conn, > ret = 0; > cleanup: > if (ret < 0) > - testDomainShutdownState(NULL, dom); > + testDomainShutdownState(NULL, dom, VIR_DOMAIN_SHUTOFF_FAILED); > return ret; > } > > @@ -565,7 +567,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; > } > @@ -925,7 +927,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; > } > @@ -1327,7 +1329,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, > @@ -1457,7 +1459,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); > @@ -1495,13 +1497,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); > @@ -1523,6 +1526,7 @@ static int testPauseDomain (virDomainPtr domain) > testConnPtr privconn = domain->conn->privateData; > virDomainObjPtr privdom; > virDomainEventPtr event = NULL; > + int state; > int ret = -1; > > testDriverLock(privconn); > @@ -1535,14 +1539,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); > @@ -1576,13 +1580,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); > @@ -1621,31 +1625,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); > @@ -1691,7 +1702,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; > @@ -1726,10 +1737,7 @@ testDomainGetState(virDomainPtr domain, > goto cleanup; > } > > - *state = privdom->state; > - if (reason) > - *reason = 0; > - > + *state = virDomainObjGetState(privdom, reason); > ret = 0; > > cleanup: > @@ -1804,7 +1812,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); > @@ -1902,7 +1910,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, > @@ -1961,7 +1969,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); > @@ -2514,13 +2522,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; > > @@ -2557,13 +2566,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 e6fe019..eebf4af 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_WARN0("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_WARN0("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 6339248..4ec33ae 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 743e136..bd3771d 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: ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list