}
+int
+qemuMonitorGetStatus(qemuMonitorPtr mon, bool *running)
+{
+ int ret;
+ VIR_DEBUG("mon=%p, running=%p", mon, running);
+
+ if (!mon || !running) {
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("both monitor and running must not be NULL"));
+ return -1;
+ }
+
+ if (mon->json)
+ ret = qemuMonitorJSONGetStatus(mon, running);
+ else
+ ret = qemuMonitorTextGetStatus(mon, running);
+ return ret;
+}
+
+
int qemuMonitorSystemPowerdown(qemuMonitorPtr mon)
{
int ret;
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
int qemuMonitorStopCPUs(qemuMonitorPtr mon);
+int qemuMonitorGetStatus(qemuMonitorPtr mon, bool *running);
int qemuMonitorSystemPowerdown(qemuMonitorPtr mon);
}
+int
+qemuMonitorJSONGetStatus(qemuMonitorPtr mon, bool *running)
+{
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr data;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-status", NULL)))
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ if (ret < 0)
+ goto cleanup;
+
+ ret = -1;
+
+ if (!(data = virJSONValueObjectGet(reply, "return"))) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-status reply was missing return data"));
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectGetBoolean(data, "running", running) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-status reply was missing running state"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+
int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon)
{
int ret;
int qemuMonitorJSONStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
int qemuMonitorJSONStopCPUs(qemuMonitorPtr mon);
+int qemuMonitorJSONGetStatus(qemuMonitorPtr mon, bool *running);
int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon);
}
+int
+qemuMonitorTextGetStatus(qemuMonitorPtr mon, bool *running)
+{
+ char *reply;
+ int ret = -1;
+
+ if (qemuMonitorHMPCommand(mon, "info status", &reply) < 0) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("cannot get status info"));
+ return -1;
+ }
+
+ if (strstr(reply, "running")) {
+ *running = true;
+ } else if (strstr(reply, "paused")) {
+ *running = false;
+ } else {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("unexpected reply from info status: %s"), reply);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(reply);
+ return ret;
+}
+
+
int qemuMonitorTextSystemPowerdown(qemuMonitorPtr mon) {
char *info;
int qemuMonitorTextStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
int qemuMonitorTextStopCPUs(qemuMonitorPtr mon);
+int qemuMonitorTextGetStatus(qemuMonitorPtr mon, bool *running);
int qemuMonitorTextSystemPowerdown(qemuMonitorPtr mon);
return err;
}
+static int
+qemuProcessUpdateState(struct qemud_driver *driver, virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virDomainState state;
+ bool running;
+ int ret;
+
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ ret = qemuMonitorGetStatus(priv->mon, &running);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+ if (ret < 0 || !virDomainObjIsActive(vm))
+ return -1;
+
+ state = virDomainObjGetState(vm, NULL);
+
+ if (state == VIR_DOMAIN_PAUSED && running) {
+ VIR_DEBUG("Domain %s was unpaused while its monitor was disconnected;"
+ " changing state to running", vm->def->name);
+ virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
+ VIR_DOMAIN_RUNNING_UNPAUSED);
+ } else if (state == VIR_DOMAIN_RUNNING && !running) {
+ VIR_DEBUG("Domain %s was paused while its monitor was disconnected;"
+ " changing state to paused", vm->def->name);
+ virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_UNKNOWN);
+ }
+
+ return 0;
+}
+
struct qemuProcessReconnectData {
virConnectPtr conn;
struct qemud_driver *driver;
goto error;
}
+ if (qemuProcessUpdateState(driver, obj) < 0)
+ goto error;
+
/* If upgrading from old libvirtd we won't have found any
* caps in the domain status, so re-query them
*/
if (qemuProcessFiltersInstantiate(conn, obj->def))
goto error;
+ /* update domain state XML with possibly updated state in virDomainObj */
+ if (virDomainSaveStatus(driver->caps, driver->stateDir, obj) < 0)
+ goto error;
+
if (obj->def->id >= driver->nextvmid)
driver->nextvmid = obj->def->id + 1;