"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")
}
virDomainObjLock(domain);
- domain->state = VIR_DOMAIN_SHUTOFF;
+ virDomainObjSetState(domain, VIR_DOMAIN_SHUTOFF,
+ VIR_DOMAIN_SHUTOFF_UNKNOWN);
domain->refs = 1;
virDomainSnapshotObjListInit(&domain->snapshots);
virDomainObjPtr obj;
xmlNodePtr *nodes = NULL;
int i, n;
+ int state;
+ int reason = 0;
if (!(obj = virDomainObjNew(caps)))
return NULL;
"%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);
}
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"));
{
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++) {
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;
+}
};
/* Guest VM runtime state */
+typedef struct _virDomainStateReason virDomainStateReason;
+struct _virDomainStateReason {
+ int state;
+ int reason;
+};
+
typedef struct _virDomainObj virDomainObj;
typedef virDomainObj *virDomainObjPtr;
struct _virDomainObj {
int refs;
int pid;
- int state;
+ virDomainStateReason state;
unsigned int autostart : 1;
unsigned int persistent : 1;
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);
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)
virDomainObjAssignDef;
virDomainObjCopyPersistentDef;
virDomainObjGetPersistentDef;
+virDomainObjGetState;
virDomainObjIsDuplicate;
virDomainObjListDeinit;
virDomainObjListGetActiveIDs;
virDomainObjLock;
virDomainObjRef;
virDomainObjSetDefTransient;
+virDomainObjSetState;
virDomainObjTaint;
virDomainObjUnlock;
virDomainObjUnref;
virDomainSoundDefFree;
virDomainSoundModelTypeFromString;
virDomainSoundModelTypeToString;
+virDomainStateReasonFromString;
+virDomainStateReasonToString;
virDomainStateTypeFromString;
virDomainStateTypeToString;
virDomainTaintTypeFromString;
* 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;
if (vm->persistent) {
vm->def->id = -1;
- vm->state = VIR_DOMAIN_SHUTOFF;
+ virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
}
if ((vm->def->ngraphics == 1) &&
* 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;
return -1;
}
- libxlVmCleanup(driver, vm);
+ libxlVmCleanup(driver, vm, reason);
return 0;
}
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,
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:
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);
}
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);
/* 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);
return;
out:
- libxlVmCleanup(driver, vm);
+ libxlVmCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_UNKNOWN);
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains, vm);
else
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"),
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);
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"),
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);
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;
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;
goto cleanup;
}
- *state = vm->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(vm, reason);
ret = 0;
cleanup:
goto cleanup;
}
- info->state = vm->state;
+ info->state = virDomainObjGetState(vm, NULL);
if (!virDomainObjIsActive(vm) || driver->cgroup == NULL) {
info->cpuTime = 0;
goto cleanup;
}
- *state = vm->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(vm, reason);
ret = 0;
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;
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;
static int lxcVmTerminate(lxc_driver_t *driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ virDomainShutoffReason reason)
{
virCgroupPtr group = NULL;
int rc;
rc = -1;
goto cleanup;
}
- lxcVmCleanup(driver, vm);
+ lxcVmCleanup(driver, vm, reason);
rc = 0;
goto cleanup;
}
- if (lxcVmTerminate(driver, vm) < 0) {
+ if (lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) {
virEventRemoveHandle(watch);
} else {
event = virDomainEventNewFromObj(vm,
* @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
*
*/
static int lxcVmStart(virConnectPtr conn,
lxc_driver_t * driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ virDomainRunningReason reason)
{
int rc = -1, r;
unsigned int i;
}
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;
}
goto cleanup;
}
- ret = lxcVmStart(dom->conn, driver, vm);
+ ret = lxcVmStart(dom->conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
if (ret == 0)
event = virDomainEventNewFromObj(vm,
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;
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);
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"),
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 {
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,
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,
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;
goto cleanup;
}
- info->state = vm->state;
+ info->state = virDomainObjGetState(vm, NULL);
if (!virDomainObjIsActive(vm)) {
info->cpuTime = 0;
goto cleanup;
}
- *state = vm->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(vm, reason);
ret = 0;
cleanup:
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;
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;
}
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;
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;
}
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;
goto cleanup;
ret = 0;
+ virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED);
+
cleanup:
if (vm)
virDomainObjUnlock(vm);
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) {
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;
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:
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;
"%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,
"%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"));
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);
goto cleanup;
}
- info->state = vm->state;
+ info->state = virDomainObjGetState(vm, NULL);
if (!virDomainObjIsActive(vm)) {
info->cpuTime = 0;
goto cleanup;
}
- *state = vm->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(vm, reason);
ret = 0;
cleanup:
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)) {
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,
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");
}
/* 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;
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,
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"));
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,
/* 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"));
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;
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"));
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)) {
/* 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,
*/
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,
goto endjob;
}
- vm->state = snap->def->state;
-
ret = 0;
endjob:
{
int ret;
- ret = qemuProcessStopCPUs(driver, vm);
+ ret = qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION);
if (ret == 0) {
virDomainEventPtr event;
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);
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;
}
}
/* Clean up the source domain. */
- qemuProcessStop(driver, vm, 1);
+ qemuProcessStop(driver, vm, 1, VIR_DOMAIN_SHUTOFF_MIGRATED);
qemuAuditDomainStop(vm, "migrated");
resume = 0;
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
* >= 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"));
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,
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,
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)
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);
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);
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);
int
qemuProcessStartCPUs(struct qemud_driver *driver, virDomainObjPtr vm,
- virConnectPtr conn)
+ virConnectPtr conn, virDomainRunningReason reason)
{
int ret;
qemuDomainObjPrivatePtr priv = vm->privateData;
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;
}
/* 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
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);
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;
* 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;
}
void qemuProcessStop(struct qemud_driver *driver,
virDomainObjPtr vm,
- int migrated)
+ int migrated,
+ virDomainShutoffReason reason)
{
int ret;
int retries = 0;
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);
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);
void qemuProcessStop(struct qemud_driver *driver,
virDomainObjPtr vm,
- int migrated);
+ int migrated,
+ virDomainShutoffReason reason);
void qemuProcessKill(virDomainObjPtr vm);
static void
testDomainShutdownState(virDomainPtr domain,
- virDomainObjPtr privdom)
+ virDomainObjPtr privdom,
+ virDomainShutoffReason reason)
{
if (privdom->newDef) {
virDomainDefFree(privdom->def);
privdom->newDef = NULL;
}
- privdom->state = VIR_DOMAIN_SHUTOFF;
+ virDomainObjSetState(privdom, VIR_DOMAIN_SHUTOFF, reason);
privdom->def->id = -1;
if (domain)
domain->id = -1;
/* Set up domain runtime state */
static int
testDomainStartState(virConnectPtr conn,
- virDomainObjPtr dom)
+ virDomainObjPtr dom,
+ virDomainRunningReason reason)
{
testConnPtr privconn = conn->privateData;
int ret = -1;
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) {
ret = 0;
cleanup:
if (ret < 0)
- testDomainShutdownState(NULL, dom);
+ testDomainShutdownState(NULL, dom, VIR_DOMAIN_SHUTOFF_FAILED);
return ret;
}
domdef = NULL;
domobj->persistent = 1;
- if (testDomainStartState(conn, domobj) < 0) {
+ if (testDomainStartState(conn, domobj, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
virDomainObjUnlock(domobj);
goto error;
}
}
dom->persistent = 1;
- if (testDomainStartState(conn, dom) < 0) {
+ if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
virDomainObjUnlock(dom);
goto error;
}
goto cleanup;
def = NULL;
- if (testDomainStartState(conn, dom) < 0)
+ if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_BOOTED) < 0)
goto cleanup;
event = virDomainEventNewFromObj(dom,
goto cleanup;
}
- testDomainShutdownState(domain, privdom);
+ testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_DESTROYED);
event = virDomainEventNewFromObj(privdom,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
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);
virDomainObjPtr privdom;
virDomainEventPtr event = NULL;
int ret = -1;
+ int state;
testDriverLock(privconn);
privdom = virDomainFindByName(&privconn->domains,
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);
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);
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);
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;
goto cleanup;
}
- *state = privdom->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(privdom, reason);
ret = 0;
cleanup:
}
fd = -1;
- testDomainShutdownState(domain, privdom);
+ testDomainShutdownState(domain, privdom, VIR_DOMAIN_SHUTOFF_SAVED);
event = virDomainEventNewFromObj(privdom,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SAVED);
goto cleanup;
def = NULL;
- if (testDomainStartState(conn, dom) < 0)
+ if (testDomainStartState(conn, dom, VIR_DOMAIN_RUNNING_RESTORED) < 0)
goto cleanup;
event = virDomainEventNewFromObj(dom,
}
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);
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;
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);
static void umlShutdownVMDaemon(virConnectPtr conn,
struct uml_driver *driver,
- virDomainObjPtr vm);
+ virDomainObjPtr vm,
+ virDomainShutoffReason reason);
static int umlMonitorCommand(const struct uml_driver *driver,
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)) {
}
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);
virDomainObjLock(dom);
if (virDomainObjIsActive(dom))
- umlShutdownVMDaemon(NULL, driver, dom);
+ umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
virDomainObjUnlock(dom);
}
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;
vm->pid = -1;
vm->def->id = -1;
- vm->state = VIR_DOMAIN_SHUTOFF;
+ virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
virDomainConfVMNWFilterTeardown(vm);
umlCleanupTapDevices(conn, vm);
goto cleanup;
}
- umlShutdownVMDaemon(dom->conn, driver, vm);
+ umlShutdownVMDaemon(dom->conn, driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
if (!vm->persistent) {
virDomainRemoveInactive(&driver->domains,
vm);
goto cleanup;
}
- info->state = vm->state;
+ info->state = virDomainObjGetState(vm, NULL);
if (!virDomainObjIsActive(vm)) {
info->cpuTime = 0;
goto cleanup;
}
- *state = vm->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(vm, reason);
ret = 0;
cleanup:
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);
}
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",
}
vm->def->id = -1;
- vm->state = VIR_DOMAIN_SHUTOFF;
+ virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
return 0;
}
};
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;
}
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;
}
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) {
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;
if (virRun(cmd, NULL) < 0)
goto cleanup;
- vm->state = VIR_DOMAIN_PAUSED;
+ virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
ret = 0;
cleanup:
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;
if (virRun(cmd, NULL) < 0)
goto cleanup;
- vm->state = VIR_DOMAIN_RUNNING;
+ virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNPAUSED);
ret = 0;
cleanup:
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;
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;
goto cleanup;
}
- *state = vm->state;
- if (reason)
- *reason = 0;
-
+ *state = virDomainObjGetState(vm, reason);
ret = 0;
cleanup: