From nobody Thu May 2 02:12:34 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1508866539568197.77728733756737; Tue, 24 Oct 2017 10:35:39 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A0F9BB64F; Tue, 24 Oct 2017 17:35:37 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 73CFE6E512; Tue, 24 Oct 2017 17:35:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 35ED81805963; Tue, 24 Oct 2017 17:35:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v9OHZInq024635 for ; Tue, 24 Oct 2017 13:35:18 -0400 Received: by smtp.corp.redhat.com (Postfix) id 2FC255EDE0; Tue, 24 Oct 2017 17:35:18 +0000 (UTC) Received: from mx1.redhat.com (ext-mx07.extmail.prod.ext.phx2.redhat.com [10.5.110.31]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 22F885EDE5; Tue, 24 Oct 2017 17:35:18 +0000 (UTC) Received: from mail-pg0-f65.google.com (mail-pg0-f65.google.com [74.125.83.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 88D76C0005CF; Tue, 24 Oct 2017 17:35:13 +0000 (UTC) Received: by mail-pg0-f65.google.com with SMTP id r25so15087594pgn.4; Tue, 24 Oct 2017 10:35:13 -0700 (PDT) Received: from ps-f25-dev.eng.nutanix.com ([205.209.132.2]) by smtp.gmail.com with ESMTPSA id k2sm1333236pff.126.2017.10.24.10.35.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Oct 2017 10:35:10 -0700 (PDT) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A0F9BB64F Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A0F9BB64F Authentication-Results: mx1.redhat.com; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ig28K6Cc" DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 88D76C0005CF Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=saxenap.ltc@gmail.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 88D76C0005CF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cXVF81ZUAysCldAaWGhPSC2iycNeV13OXkORz+UTtxQ=; b=Ig28K6CcwV/QML/vzGJKybV63Mzzo39hrzqSyZoi2puQFYK1xtvhP15dV8awRQ/XHJ 9O1IrvWrcwKNsLVq3DtfHgutdOFTfYXQdMpV/IFFEcHt9sDVPlKHQaCA2gvOANdybTNk eMsgakRnUEQiUFyi6V/ClPhcUtDIJNy/ks9TUz4YTldDxEdOmuWRBi4P/4Yut+SgMQR8 Yf2lJknel9cI+djwPmz0MBcmr9oMI6ON0nWAykEoe8Mq3NU5KzcE/MYzaHm8UueDkFDc JzxQMdWWaVJGZosFX4qTQEQeOgN/1dMnUtEpcFp5AaHa1s5yi8pVMBauvOcCWh4wQquy LcGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cXVF81ZUAysCldAaWGhPSC2iycNeV13OXkORz+UTtxQ=; b=bMuMbed5/k+94U+4y9htkWeRrCrHY4wWVHIR+iuw850eQ1jI6Yvo0MeklgKZN4mOpW Q9dZ3vRSdTcvZ1wVt1MqyfpOZJLr97OBatBsqbxStZEfE20SHI5Fb2vqASRPSjAE0LnX GQaw9Bc/uuBIIWaRuF6NsBPm86hNrpQ4fQWfiamWkD41dYZdrB/aDwlWSzE2QfN5ciXJ Z1qFpDzQJMWFQ6X5CNMjfXUBiCmux8dZR/DdXtDEV/0OE9V6elqnx8NpJI3I1VK46uGI IuqFRuI8MyWbwjA7eUzw+zpdnX3IL1BVR2oqjJYfo2njTr0hNUuwO+JNWeS07z6Wm4J1 pSRg== X-Gm-Message-State: AMCzsaWcSaE46vdkCUXibImOnRIGH41tGyraQKEJCSQMu7LBusvAkSW5 9jDDy0eEQkC8FkgD9WFIm6BSQ8Kk3hA= X-Google-Smtp-Source: ABhQp+Qp/YoSoy+4myxMrmy+PeqmBsdSvrXoXiZ6Jl3pSynj7XJ+xpjFpdd7sYtmPVcjk2VW6Y0oMg== X-Received: by 10.99.186.73 with SMTP id l9mr14932428pgu.6.1508866511322; Tue, 24 Oct 2017 10:35:11 -0700 (PDT) From: Prerna Saxena To: libvir-list@redhat.com Date: Tue, 24 Oct 2017 10:34:57 -0700 Message-Id: <20171024173501.18105-5-saxenap.ltc@gmail.com> In-Reply-To: <20171024173501.18105-1-saxenap.ltc@gmail.com> References: <20171024173501.18105-1-saxenap.ltc@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 24 Oct 2017 17:35:13 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 24 Oct 2017 17:35:13 +0000 (UTC) for IP:'74.125.83.65' DOMAIN:'mail-pg0-f65.google.com' HELO:'mail-pg0-f65.google.com' FROM:'saxenap.ltc@gmail.com' RCPT:'' X-RedHat-Spam-Score: 0.37 (DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SORBS_SPAM, SPF_PASS) 74.125.83.65 mail-pg0-f65.google.com 74.125.83.65 mail-pg0-f65.google.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.31 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: --jdenemar@redhat.com, --pkrempa@redhat.com Subject: [libvirt] [[RFC] 4/8] Events: Allow monitor to "enqueue" events to a queue. Also introduce a framework of handlers for each event type, that can be called when the handler is running an event. X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 24 Oct 2017 17:35:38 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Prerna Saxena --- src/qemu/qemu_event.c | 11 + src/qemu/qemu_event.h | 8 + src/qemu/qemu_monitor.c | 592 +++++++++++++++++++++++++++----- src/qemu/qemu_monitor.h | 80 +++-- src/qemu/qemu_monitor_json.c | 291 ++++++++++------ src/qemu/qemu_process.c | 789 +++++++++++++++++++++++++++------------= ---- src/qemu/qemu_process.h | 2 + tests/qemumonitortestutils.c | 2 +- 8 files changed, 1273 insertions(+), 502 deletions(-) diff --git a/src/qemu/qemu_event.c b/src/qemu/qemu_event.c index d52fad2..beb309f 100644 --- a/src/qemu/qemu_event.c +++ b/src/qemu/qemu_event.c @@ -50,6 +50,7 @@ VIR_ENUM_IMPL(qemuMonitorEvent, "RTC Change", "Shutdown", "Stop", "Suspend", "Suspend To Disk", "Virtual Serial Port Change", + "Spice migrated", "Wakeup", "Watchdog"); =20 virQemuEventList* virQemuEventListInit(void) @@ -302,3 +303,13 @@ void virDomainConsumeVMEvents(virDomainObjPtr vm, void= *opaque) } return; } + +extern void qemuProcessEmitMonitorEvent(qemuEventPtr ev, void *opaque); + +void virEventRunHandler(qemuEventPtr ev, void *opaque) +{ + if (!ev) + return; + + return qemuProcessEmitMonitorEvent(ev, opaque); +} diff --git a/src/qemu/qemu_event.h b/src/qemu/qemu_event.h index 4173834..8552fd1 100644 --- a/src/qemu/qemu_event.h +++ b/src/qemu/qemu_event.h @@ -51,6 +51,7 @@ typedef enum { QEMU_EVENT_SUSPEND, QEMU_EVENT_SUSPEND_DISK, QEMU_EVENT_SERIAL_CHANGE, + QEMU_EVENT_SPICE_MIGRATED, QEMU_EVENT_WAKEUP, QEMU_EVENT_WATCHDOG, =20 @@ -102,7 +103,12 @@ struct qemuEventTrayChangeData { int reason; }; =20 +struct qemuEventShutdownData { + virTristateBool guest_initiated; +}; + struct qemuEventGuestPanicData { + void *info; }; =20 struct qemuEventMigrationStatusData { @@ -159,6 +165,7 @@ struct _qemuEvent { struct qemuEventBlockThresholdData ev_threshold; struct qemuEventDeviceDeletedData ev_deviceDel; struct qemuEventTrayChangeData ev_tray; + struct qemuEventShutdownData ev_shutdown; struct qemuEventGuestPanicData ev_panic; struct qemuEventMigrationStatusData ev_migStatus; struct qemuEventMigrationPassData ev_migPass; @@ -219,5 +226,6 @@ int virQemuVmEventListInit(virDomainObjPtr vm); int virEnqueueVMEvent(virQemuEventList *qlist, qemuEventPtr ev); qemuEventPtr virDequeueVMEvent(virQemuEventList *qlist, virDomainObjPtr vm= ); void virEventWorkerScanQueue(void *dummy, void *opaque); +void virEventRunHandler(qemuEventPtr ev, void *opaque); void virDomainConsumeVMEvents(virDomainObjPtr vm, void *opaque); #endif diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 7a26785..4e45cf9 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -34,6 +34,7 @@ #include "qemu_monitor_json.h" #include "qemu_domain.h" #include "qemu_process.h" +#include "qemu_event.h" #include "virerror.h" #include "viralloc.h" #include "virlog.h" @@ -1316,6 +1317,14 @@ qemuMonitorGetDiskSecret(qemuMonitorPtr mon, return ret; } =20 +static int +qemuMonitorEnqueueEvent(qemuMonitorPtr mon, qemuEventPtr ev) +{ + int ret =3D -1; + QEMU_MONITOR_CALLBACK(mon, ret, domainEnqueueEvent, ev->vm, ev); + + return ret; +} =20 int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event, @@ -1332,90 +1341,189 @@ qemuMonitorEmitEvent(qemuMonitorPtr mon, const cha= r *event, =20 =20 int -qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest) +qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest, + long long seconds, unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p guest=3D%u", mon, guest); mon->willhangup =3D 1; + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_SHUTDOWN; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_shutdown.guest_initiated =3D guest; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainShutdown, mon->vm, guest); + VIR_DEBUG("Vm %s received shutdown event initiated by %u", + mon->vm->def->name, guest); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitReset(qemuMonitorPtr mon) +qemuMonitorEmitReset(qemuMonitorPtr mon, long long seconds, unsigned int m= icros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_RESET; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainReset, mon->vm); + VIR_DEBUG("Vm %s received reset event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitPowerdown(qemuMonitorPtr mon) +qemuMonitorEmitPowerdown(qemuMonitorPtr mon, long long seconds, unsigned i= nt micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_POWERDOWN; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainPowerdown, mon->vm); + VIR_DEBUG("Vm %s received powerdown event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitStop(qemuMonitorPtr mon) +qemuMonitorEmitStop(qemuMonitorPtr mon, long long seconds, unsigned int mi= cros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_STOP; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainStop, mon->vm); + VIR_DEBUG("Vm %s received stop event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitResume(qemuMonitorPtr mon) +qemuMonitorEmitResume(qemuMonitorPtr mon, long long seconds, unsigned int = micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_RESUME; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainResume, mon->vm); + VIR_DEBUG("Vm %s received resume event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon, - qemuMonitorEventPanicInfoPtr info) + qemuMonitorEventPanicInfoPtr info, + long long seconds, unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); - QEMU_MONITOR_CALLBACK(mon, ret, domainGuestPanic, mon->vm, info); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_GUEST_PANICKED; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_panic.info =3D info; + + VIR_DEBUG("Vm %s received guest panic event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset) +qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset, + long long seconds, unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainRTCChange, mon->vm, offset); + ev->ev_type =3D QEMU_EVENT_RTC_CHANGE; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_rtc.offset =3D offset; + + VIR_DEBUG("Vm %s received RTC change event", mon->vm->def->name); + + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action) +qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action, + long long seconds, unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_WATCHDOG; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_watchdog.action =3D action; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainWatchdog, mon->vm, action); + VIR_DEBUG("Vm %s received watchdog event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 @@ -1424,13 +1532,39 @@ int qemuMonitorEmitIOError(qemuMonitorPtr mon, const char *diskAlias, int action, - const char *reason) + const char *reason, + long long seconds, unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + struct qemuEventIOErrorData *d =3D NULL; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_BLOCK_IO_ERROR; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_IOErr); + d->action =3D action; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainIOError, mon->vm, - diskAlias, action, reason); + if (VIR_STRDUP(d->device, diskAlias) < 0) { + goto cleanup; + } + if (VIR_STRDUP(d->reason, reason) < 0) { + goto cleanup; + } + VIR_DEBUG("Vm %s received block IO error event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); + return ret +; +cleanup: + if (d->device) + VIR_FREE(d->device); + VIR_FREE(ev); return ret; } =20 @@ -1446,15 +1580,73 @@ qemuMonitorEmitGraphics(qemuMonitorPtr mon, const char *remoteService, const char *authScheme, const char *x509dname, - const char *saslUsername) + const char *saslUsername, + long long seconds, unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + struct qemuEventGraphicsData *d; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_GRAPHICS; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_graphics); + + d->phase =3D phase; + d->localFamilyID =3D localFamily; + d->remoteFamilyID =3D remoteFamily; + + if (VIR_STRDUP((d->localNode), localNode) < 0) { + goto cleanup; + } + + if (VIR_STRDUP((d->localService), localService) < 0) { + goto cleanup; + } + + if (VIR_STRDUP((d->remoteNode), remoteNode) < 0) { + goto cleanup; + } + + if (VIR_STRDUP((d->remoteService), remoteService) < 0) { + goto cleanup; + } + + if (VIR_STRDUP((d->authScheme), authScheme) < 0) { + goto cleanup; + } + + if (VIR_STRDUP((d->x509dname), x509dname) < 0) { + goto cleanup; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainGraphics, mon->vm, phase, - localFamily, localNode, localService, - remoteFamily, remoteNode, remoteService, - authScheme, x509dname, saslUsername); + if (VIR_STRDUP((d->saslUsername), saslUsername) < 0) { + goto cleanup; + } + + VIR_DEBUG("Vm %s received Graphics event", mon->vm->def->name); + virObjectRef(ev->vm); + return ret; + +cleanup: + if (d->localNode) + VIR_FREE(d->localNode); + if (d->localService) + VIR_FREE(d->localService); + if (d->remoteNode) + VIR_FREE(d->remoteNode); + if (d->remoteService) + VIR_FREE(d->remoteService); + if (d->authScheme) + VIR_FREE(d->authScheme); + if (d->x509dname) + VIR_FREE(d->x509dname); + VIR_FREE(ev); return ret; } =20 @@ -1462,50 +1654,101 @@ qemuMonitorEmitGraphics(qemuMonitorPtr mon, int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, const char *devAlias, - int reason) + int reason, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + struct qemuEventTrayChangeData *d; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainTrayChange, mon->vm, - devAlias, reason); + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 + ev->ev_type =3D QEMU_EVENT_DEVICE_TRAY_MOVED; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_tray); + + if (VIR_STRDUP((d->devAlias), devAlias) < 0) { + VIR_FREE(ev); + return ret; + } + d->reason =3D reason; + VIR_DEBUG("Vm %s received tray change event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitPMWakeup(qemuMonitorPtr mon) +qemuMonitorEmitPMWakeup(qemuMonitorPtr mon, long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainPMWakeup, mon->vm); + ev->ev_type =3D QEMU_EVENT_WAKEUP; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 + VIR_DEBUG("Vm %s received PM Wakeup event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitPMSuspend(qemuMonitorPtr mon) +qemuMonitorEmitPMSuspend(qemuMonitorPtr mon, long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspend, mon->vm); + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 + ev->ev_type =3D QEMU_EVENT_SUSPEND; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + + VIR_DEBUG("Vm %s received PM Suspend event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon) +qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon, long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainPMSuspendDisk, mon->vm); + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_SUSPEND_DISK; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 + VIR_DEBUG("Vm %s received PM Suspend Disk event", mon->vm->def->name);=20 + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 @@ -1514,51 +1757,122 @@ int qemuMonitorEmitBlockJob(qemuMonitorPtr mon, const char *diskAlias, int type, - int status) + int status, long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + struct qemuEventBlockJobData *d =3D NULL; + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_BLOCK_JOB; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_blockJob); + + if (VIR_STRDUP(d->device, diskAlias) < 0) { + VIR_FREE(ev); + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainBlockJob, mon->vm, - diskAlias, type, status); + d->type =3D type; + d->status =3D status; + VIR_DEBUG("Vm %s received Block Job event", mon->vm->def->name);=20 + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, - unsigned long long actual) + unsigned long long actual, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_BALLOON_CHANGE; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_balloon.actual =3D actual; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainBalloonChange, mon->vm, actual); + VIR_DEBUG("Vm %s received balloon change event", mon->vm->def->name);=20 + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon, - const char *devAlias) + const char *devAlias, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + struct qemuEventDeviceDeletedData *d =3D NULL; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainDeviceDeleted, mon->vm, devAlias= ); + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 + ev->ev_type =3D QEMU_EVENT_DEVICE_DELETED; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_deviceDel); + + if (VIR_STRDUP(d->device, devAlias) < 0) { + VIR_FREE(ev); + return ret; + } + VIR_DEBUG("Vm %s received device deleted event for %s", mon->vm->def->= name, + devAl= ias);=20 + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon, - const char *devAlias) + const char *devAlias, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + struct qemuEventNicRxFilterChangeData *d =3D NULL; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainNicRxFilterChanged, mon->vm, dev= Alias); + ev->ev_type =3D QEMU_EVENT_NIC_RX_FILTER_CHANGED; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_nic); =20 + if (VIR_STRDUP(d->devAlias, devAlias) < 0) { + VIR_FREE(ev); + return ret; + } + VIR_DEBUG("Vm %s received nic RX filter change event for %s", mon->vm-= >def->name, + devAl= ias);=20 + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 @@ -1566,52 +1880,110 @@ qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr m= on, int qemuMonitorEmitSerialChange(qemuMonitorPtr mon, const char *devAlias, - bool connected) + bool connected, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p, devAlias=3D'%s', connected=3D%d", mon, devAlias, = connected); + qemuEventPtr ev; + struct qemuEventSerialChangeData *d =3D NULL; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainSerialChange, mon->vm, devAlias,= connected); + ev->ev_type =3D QEMU_EVENT_SERIAL_CHANGE; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + d =3D &(ev->evData.ev_serial); + d->connected =3D connected; =20 + if (VIR_STRDUP(d->devAlias, devAlias) < 0) { + VIR_FREE(ev); + return ret; + } + VIR_DEBUG("Vm %s received Serial change event for %s", mon->vm->def->n= ame, + devAl= ias);=20 + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int -qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon) +qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon, long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p", mon); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainSpiceMigrated, mon->vm); + ev->ev_type =3D QEMU_EVENT_SPICE_MIGRATED; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; =20 + VIR_DEBUG("Vm %s received spice migrated event", mon->vm->def->name); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int qemuMonitorEmitMigrationStatus(qemuMonitorPtr mon, - int status) + int status, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p, status=3D%s", - mon, NULLSTR(qemuMonitorMigrationStatusTypeToString(status))= ); + qemuEventPtr ev; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationStatus, mon->vm, status= ); + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 + ev->ev_type =3D QEMU_EVENT_MIGRATION; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_migStatus.status =3D status; + + VIR_DEBUG("Vm %s received migration status %s", mon->vm->def->name, + NULLSTR(qemuMonitorMigrationStatusTypeToString(status))); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 =20 int qemuMonitorEmitMigrationPass(qemuMonitorPtr mon, - int pass) + int pass, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p, pass=3D%d", mon, pass); + qemuEventPtr ev; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainMigrationPass, mon->vm, pass); + ev->ev_type =3D QEMU_EVENT_MIGRATION_PASS; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_migPass.pass =3D pass; =20 + VIR_DEBUG("Vm %s received migration pass %d", mon->vm->def->name, + pass); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 @@ -1622,15 +1994,49 @@ qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon, const char *slotType, const char *slot, unsigned int source, - unsigned int status) + unsigned int status, + long long seconds, + unsigned int micros) { int ret =3D -1; - VIR_DEBUG("mon=3D%p, alias=3D'%s', slotType=3D'%s', slot=3D'%s', sourc= e=3D'%u' status=3D%u", - mon, NULLSTR(alias), slotType, slot, source, status); + qemuEventPtr ev; + struct qemuEventAcpiOstInfoData *d =3D NULL; + + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_ACPI_OST; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_acpi.source =3D source; + ev->evData.ev_acpi.status =3D status; + + d =3D &(ev->evData.ev_acpi); + + if (VIR_STRDUP(d->alias, alias) < 0) { + goto cleanup; + } + if (VIR_STRDUP(d->slotType, slotType) < 0) { + goto cleanup; + } + if (VIR_STRDUP(d->slot, slot) < 0) { + goto cleanup; + } =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainAcpiOstInfo, mon->vm, - alias, slotType, slot, source, status); + VIR_DEBUG("Vm %s received ACPI OST event: alias[%s] slotType [%s] slot= [%s]" + " status[%d]", mon->vm->def->name, alias, slotType, slot, st= atus); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); + return ret; =20 +cleanup: + if (d->alias) + VIR_FREE(d->alias); + if (d->slotType) + VIR_FREE(d->slotType); + VIR_FREE(ev); return ret; } =20 @@ -1639,16 +2045,36 @@ int qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon, const char *nodename, unsigned long long threshold, - unsigned long long excess) + unsigned long long excess, + long long seconds, + unsigned int micros) { int ret =3D -1; + qemuEventPtr ev; + struct qemuEventBlockThresholdData *d =3D NULL; =20 - VIR_DEBUG("mon=3D%p, node-name=3D'%s', threshold=3D'%llu', excess=3D'%= llu'", - mon, nodename, threshold, excess); + if (VIR_ALLOC(ev) < 0){ + return ret; + } + + ev->ev_type =3D QEMU_EVENT_BLOCK_WRITE_THRESHOLD; + ev->vm =3D mon->vm; + ev->seconds =3D seconds; + ev->micros =3D micros; + ev->evData.ev_threshold.threshold =3D threshold; + ev->evData.ev_threshold.excess =3D excess; =20 - QEMU_MONITOR_CALLBACK(mon, ret, domainBlockThreshold, mon->vm, - nodename, threshold, excess); + d =3D &(ev->evData.ev_threshold); =20 + if (VIR_STRDUP(d->nodename, nodename) < 0) { + VIR_FREE(ev); + return ret; + } + VIR_DEBUG("Vm %s received Block Threshold event:" + "node-name=3D'%s', threshold=3D'%llu', excess=3D'%llu'", + mon->vm->def->name, nodename, threshold, excess); + virObjectRef(ev->vm); + ret =3D qemuMonitorEnqueueEvent(mon, ev); return ret; } =20 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index d9c27ac..7b5a984 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -35,6 +35,7 @@ # include "device_conf.h" # include "cpu/cpu.h" # include "util/virgic.h" +# include "qemu_event.h" =20 typedef struct _qemuMonitor qemuMonitor; typedef qemuMonitor *qemuMonitorPtr; @@ -89,7 +90,7 @@ struct _qemuMonitorEventPanicInfoHyperv { }; =20 typedef struct _qemuMonitorEventPanicInfo qemuMonitorEventPanicInfo; -typedef qemuMonitorEventPanicInfo *qemuMonitorEventPanicInfoPtr; +typedef qemuMonitorEventPanicInfo * qemuMonitorEventPanicInfoPtr; struct _qemuMonitorEventPanicInfo { qemuMonitorEventPanicInfoType type; union { @@ -128,6 +129,10 @@ typedef int (*qemuMonitorDomainEventCallback)(qemuMoni= torPtr mon, unsigned int micros, const char *details, void *opaque); +typedef int (*qemuMonitorDomainEnqueueEventCallback)(qemuMonitorPtr mon, + virDomainObjPtr vm, + qemuEventPtr ev, + void *opaque); typedef int (*qemuMonitorDomainShutdownCallback)(qemuMonitorPtr mon, virDomainObjPtr vm, virTristateBool guest, @@ -254,6 +259,7 @@ struct _qemuMonitorCallbacks { qemuMonitorErrorNotifyCallback errorNotify; qemuMonitorDiskSecretLookupCallback diskSecretLookup; qemuMonitorDomainEventCallback domainEvent; + qemuMonitorDomainEnqueueEventCallback domainEnqueueEvent; qemuMonitorDomainShutdownCallback domainShutdown; qemuMonitorDomainResetCallback domainReset; qemuMonitorDomainPowerdownCallback domainPowerdown; @@ -345,17 +351,25 @@ int qemuMonitorGetDiskSecret(qemuMonitorPtr mon, int qemuMonitorEmitEvent(qemuMonitorPtr mon, const char *event, long long seconds, unsigned int micros, const char *details); -int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest); -int qemuMonitorEmitReset(qemuMonitorPtr mon); -int qemuMonitorEmitPowerdown(qemuMonitorPtr mon); -int qemuMonitorEmitStop(qemuMonitorPtr mon); -int qemuMonitorEmitResume(qemuMonitorPtr mon); -int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset); -int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action); +int qemuMonitorEmitShutdown(qemuMonitorPtr mon, virTristateBool guest, + long long seconds, unsigned int micros); +int qemuMonitorEmitReset(qemuMonitorPtr mon, + long long seconds, unsigned int micros); +int qemuMonitorEmitPowerdown(qemuMonitorPtr mon, + long long seconds, unsigned int micros); +int qemuMonitorEmitStop(qemuMonitorPtr mon, + long long seconds, unsigned int micros); +int qemuMonitorEmitResume(qemuMonitorPtr mon, + long long seconds, unsigned int micros); +int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset, + long long seconds, unsigned int micros); +int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action, + long long seconds, unsigned int micros); int qemuMonitorEmitIOError(qemuMonitorPtr mon, const char *diskAlias, int action, - const char *reason); + const char *reason, + long long seconds, unsigned int micros); int qemuMonitorEmitGraphics(qemuMonitorPtr mon, int phase, int localFamily, @@ -366,45 +380,61 @@ int qemuMonitorEmitGraphics(qemuMonitorPtr mon, const char *remoteService, const char *authScheme, const char *x509dname, - const char *saslUsername); + const char *saslUsername, + long long seconds, unsigned int micros); int qemuMonitorEmitTrayChange(qemuMonitorPtr mon, const char *devAlias, - int reason); -int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon); -int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon); + int reason, + long long seconds, unsigned int micros); +int qemuMonitorEmitPMWakeup(qemuMonitorPtr mon, + long long seconds, unsigned int micros); +int qemuMonitorEmitPMSuspend(qemuMonitorPtr mon, + long long seconds, unsigned int micros); int qemuMonitorEmitBlockJob(qemuMonitorPtr mon, const char *diskAlias, int type, - int status); + int status, + long long seconds, unsigned int micros); int qemuMonitorEmitBalloonChange(qemuMonitorPtr mon, - unsigned long long actual); -int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon); + unsigned long long actual, + long long seconds, unsigned int micros); +int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon, + long long seconds, unsigned int micros); int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon, - qemuMonitorEventPanicInfoPtr info); + qemuMonitorEventPanicInfoPtr info, + long long seconds, unsigned int micros); int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon, - const char *devAlias); + const char *devAlias, + long long seconds, unsigned int micros); int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon, - const char *devAlias); + const char *devAlias, + long long seconds, unsigned int micr= os); int qemuMonitorEmitSerialChange(qemuMonitorPtr mon, const char *devAlias, - bool connected); -int qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon); + bool connected, + long long seconds, unsigned int micros); +int qemuMonitorEmitSpiceMigrated(qemuMonitorPtr mon, + long long seconds, unsigned int micros); int qemuMonitorEmitMigrationStatus(qemuMonitorPtr mon, - int status); + int status, + long long seconds, unsigned int micros); int qemuMonitorEmitMigrationPass(qemuMonitorPtr mon, - int pass); + int pass, + long long seconds, unsigned int micros); =20 int qemuMonitorEmitAcpiOstInfo(qemuMonitorPtr mon, const char *alias, const char *slotType, const char *slot, unsigned int source, - unsigned int status); + unsigned int status, + long long seconds, unsigned int micros); =20 int qemuMonitorEmitBlockThreshold(qemuMonitorPtr mon, const char *nodename, unsigned long long threshold, - unsigned long long excess); + unsigned long long excess, + long long seconds, unsigned int micros); =20 int qemuMonitorStartCPUs(qemuMonitorPtr mon, virConnectPtr conn); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index a9070fe..b4c7118 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -59,41 +59,73 @@ VIR_LOG_INIT("qemu.qemu_monitor_json"); =20 #define LINE_ENDING "\r\n" =20 -static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValue= Ptr data); -static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr= data); -static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValu= ePtr data); -static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr = data); -static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePt= r data); -static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValu= ePtr data); -static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValue= Ptr data); -static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValueP= tr data); -static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONVal= uePtr data); -static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONV= aluePtr data); -static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJS= ONValuePtr data); -static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJS= ONValuePtr data); -static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONVal= uePtr data); -static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValue= Ptr data); -static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValu= ePtr data); -static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, vir= JSONValuePtr data); -static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJ= SONValuePtr data); -static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONVal= uePtr data); -static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, vi= rJSONValuePtr data); -static void qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon, virJSONV= aluePtr data); -static void qemuMonitorJSONHandleSpiceMigrated(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon, virJS= ONValuePtr data); -static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, virJSON= ValuePtr data); -static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONVa= luePtr data); -static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSO= NValuePtr data); +static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValue= Ptr data, + long long seconds, unsigned int = micros); +static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr= data, + long long seconds, unsigned int mic= ros); +static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValu= ePtr data, + long long seconds, unsigned int= micros); +static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr = data, + long long seconds, unsigned int micr= os); +static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePt= r data, + long long seconds, unsigned int mi= cros); +static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValu= ePtr data, + long long seconds, unsigned int= micros); +static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValue= Ptr data, + long long seconds, unsigned int = micros); +static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValueP= tr data, + long long seconds, unsigned int m= icros); +static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONVal= uePtr data, + long long seconds, unsigned in= t micros); +static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONV= aluePtr data, + long long seconds, unsigned = int micros); +static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJS= ONValuePtr data, + long long seconds, unsign= ed int micros); +static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJS= ONValuePtr data, + long long seconds, unsign= ed int micros); +static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, virJSONVal= uePtr data, + long long seconds, unsigned in= t micros); +static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValue= Ptr data, + long long seconds, unsigned int = micros); +static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValu= ePtr data, + long long seconds, unsigned int= micros); +static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, vir= JSONValuePtr data, + long long seconds, unsi= gned int micros); +static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJ= SONValuePtr data, + long long seconds, unsig= ned int micros); +static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONVal= uePtr data, + long long seconds, unsigned in= t micros); +static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, vi= rJSONValuePtr data, + long long seconds, uns= igned int micros); +static void qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon, virJSONV= aluePtr data, + long long seconds, unsigned = int micros); +static void qemuMonitorJSONHandleSpiceMigrated(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon, virJS= ONValuePtr data, + long long seconds, unsign= ed int micros); +static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros); +static void qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONVa= luePtr data, + long long seconds, unsigned i= nt micros); +static void qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSO= NValuePtr data, + long long seconds, unsigne= d int micros); =20 typedef struct { const char *type; - void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data); + void (*handler)(qemuMonitorPtr mon, virJSONValuePtr data, + long long seconds, unsigned int micros); } qemuEventHandler; =20 static qemuEventHandler eventHandlers[] =3D { @@ -146,7 +178,6 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon, const char *type; qemuEventHandler *handler; virJSONValuePtr data; - char *details =3D NULL; virJSONValuePtr timestamp; long long seconds =3D -1; unsigned int micros =3D 0; @@ -161,23 +192,20 @@ qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon, } =20 /* Not all events have data; and event reporting is best-effort only */ - if ((data =3D virJSONValueObjectGet(obj, "data"))) - details =3D virJSONValueToString(data, false); + ignore_value(data =3D virJSONValueObjectGet(obj, "data")); if ((timestamp =3D virJSONValueObjectGet(obj, "timestamp"))) { ignore_value(virJSONValueObjectGetNumberLong(timestamp, "seconds", &seconds)); ignore_value(virJSONValueObjectGetNumberUint(timestamp, "microseco= nds", µs)); } - qemuMonitorEmitEvent(mon, type, seconds, micros, details); - VIR_FREE(details); =20 handler =3D bsearch(type, eventHandlers, ARRAY_CARDINALITY(eventHandle= rs), sizeof(eventHandlers[0]), qemuMonitorEventCompare); if (handler) { VIR_DEBUG("handle %s handler=3D%p data=3D%p", type, handler->handler, data); - (handler->handler)(mon, data); + (handler->handler)(mon, data, seconds, micros); } return 0; } @@ -523,7 +551,8 @@ qemuMonitorJSONKeywordStringToJSON(const char *str, con= st char *firstkeyword) } =20 =20 -static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValue= Ptr data) +static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValue= Ptr data, + long long seconds, unsigned int = micros) { bool guest =3D false; virTristateBool guest_initiated =3D VIR_TRISTATE_BOOL_ABSENT; @@ -531,27 +560,35 @@ static void qemuMonitorJSONHandleShutdown(qemuMonitor= Ptr mon, virJSONValuePtr da if (data && virJSONValueObjectGetBoolean(data, "guest", &guest) =3D=3D= 0) guest_initiated =3D guest ? VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_B= OOL_NO; =20 - qemuMonitorEmitShutdown(mon, guest_initiated); + qemuMonitorEmitShutdown(mon, guest_initiated, seconds, micros); } =20 -static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr= data ATTRIBUTE_UNUSED) +static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUS= ED, + long long seconds, unsigned int mic= ros) { - qemuMonitorEmitReset(mon); + qemuMonitorEmitReset(mon, seconds, micros); } =20 -static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValu= ePtr data ATTRIBUTE_UNUSED) +static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_= UNUSED, + long long seconds, unsigned int= micros) { - qemuMonitorEmitPowerdown(mon); + qemuMonitorEmitPowerdown(mon, seconds, micros); } =20 -static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr = data ATTRIBUTE_UNUSED) +static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNUSE= D, + long long seconds, unsigned int micr= os) { - qemuMonitorEmitStop(mon); + qemuMonitorEmitStop(mon, seconds, micros); } =20 -static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePt= r data ATTRIBUTE_UNUSED) +static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, + virJSONValuePtr data ATTRIBUTE_UNU= SED, + long long seconds, unsigned int mi= cros) { - qemuMonitorEmitResume(mon); + qemuMonitorEmitResume(mon, seconds, micros); } =20 =20 @@ -599,7 +636,9 @@ qemuMonitorJSONGuestPanicExtractInfo(virJSONValuePtr da= ta) =20 static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, + unsigned int micros) { virJSONValuePtr infojson =3D virJSONValueObjectGetObject(data, "info"); qemuMonitorEventPanicInfoPtr info =3D NULL; @@ -607,25 +646,27 @@ qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, if (infojson) info =3D qemuMonitorJSONGuestPanicExtractInfo(infojson); =20 - qemuMonitorEmitGuestPanic(mon, info); + qemuMonitorEmitGuestPanic(mon, info, seconds, micros); } =20 =20 -static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValu= ePtr data) +static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValu= ePtr data, + long long seconds, unsigned int= micros) { long long offset =3D 0; if (virJSONValueObjectGetNumberLong(data, "offset", &offset) < 0) { VIR_WARN("missing offset in RTC change event"); offset =3D 0; } - qemuMonitorEmitRTCChange(mon, offset); + qemuMonitorEmitRTCChange(mon, offset, seconds, micros); } =20 VIR_ENUM_DECL(qemuMonitorWatchdogAction) VIR_ENUM_IMPL(qemuMonitorWatchdogAction, VIR_DOMAIN_EVENT_WATCHDOG_LAST, "none", "pause", "reset", "poweroff", "shutdown", "debug", "= inject-nmi"); =20 -static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValue= Ptr data) +static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValue= Ptr data, + long long seconds, unsigned int = micros) { const char *action; int actionID; @@ -639,7 +680,7 @@ static void qemuMonitorJSONHandleWatchdog(qemuMonitorPt= r mon, virJSONValuePtr da } else { actionID =3D VIR_DOMAIN_EVENT_WATCHDOG_NONE; } - qemuMonitorEmitWatchdog(mon, actionID); + qemuMonitorEmitWatchdog(mon, actionID, seconds, micros); } =20 VIR_ENUM_DECL(qemuMonitorIOErrorAction) @@ -648,7 +689,8 @@ VIR_ENUM_IMPL(qemuMonitorIOErrorAction, VIR_DOMAIN_EVEN= T_IO_ERROR_LAST, =20 =20 static void -qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data) +qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data, + long long seconds, unsigned int micros) { const char *device; const char *action; @@ -676,7 +718,7 @@ qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSO= NValuePtr data) actionID =3D VIR_DOMAIN_EVENT_IO_ERROR_NONE; } =20 - qemuMonitorEmitIOError(mon, device, actionID, reason); + qemuMonitorEmitIOError(mon, device, actionID, reason, seconds, micros); } =20 =20 @@ -688,7 +730,8 @@ VIR_ENUM_IMPL(qemuMonitorGraphicsAddressFamily, static void qemuMonitorJSONHandleGraphicsVNC(qemuMonitorPtr mon, virJSONValuePtr data, - int phase) + int phase, + long long seconds, unsigned int micros) { const char *localNode, *localService, *localFamily; const char *remoteNode, *remoteService, *remoteFamily; @@ -753,31 +796,39 @@ qemuMonitorJSONHandleGraphicsVNC(qemuMonitorPtr mon, qemuMonitorEmitGraphics(mon, phase, localFamilyID, localNode, localService, remoteFamilyID, remoteNode, remoteService, - authScheme, x509dname, saslUsername); + authScheme, x509dname, saslUsername, + seconds, micros); } =20 -static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONVal= uePtr data) +static void qemuMonitorJSONHandleVNCConnect(qemuMonitorPtr mon, virJSONVal= uePtr data, + long long seconds, unsigned in= t micros) { - qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_= CONNECT); + qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_= CONNECT, + seconds, micros); } =20 =20 -static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSON= ValuePtr data) +static void qemuMonitorJSONHandleVNCInitialize(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros) { - qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_= INITIALIZE); + qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_= INITIALIZE, + seconds, micros); } =20 =20 -static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSON= ValuePtr data) +static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSON= ValuePtr data, + long long seconds, unsigned= int micros) { - qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_= DISCONNECT); + qemuMonitorJSONHandleGraphicsVNC(mon, data, VIR_DOMAIN_EVENT_GRAPHICS_= DISCONNECT, + seconds, micros); } =20 =20 static void qemuMonitorJSONHandleGraphicsSPICE(qemuMonitorPtr mon, virJSONValuePtr data, - int phase) + int phase, + long long seconds, unsigned int micros) { const char *lhost, *lport, *lfamily; const char *rhost, *rport, *rfamily; @@ -834,31 +885,39 @@ qemuMonitorJSONHandleGraphicsSPICE(qemuMonitorPtr mon, } =20 qemuMonitorEmitGraphics(mon, phase, lfamilyID, lhost, lport, rfamilyID, - rhost, rport, auth, NULL, NULL); + rhost, rport, auth, NULL, NULL, + seconds, micros); } =20 =20 -static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONV= aluePtr data) +static void qemuMonitorJSONHandleSPICEConnect(qemuMonitorPtr mon, virJSONV= aluePtr data, + long long seconds, unsigned = int micros) { - qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHIC= S_CONNECT); + qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHIC= S_CONNECT, + seconds, micros); } =20 =20 -static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJS= ONValuePtr data) +static void qemuMonitorJSONHandleSPICEInitialize(qemuMonitorPtr mon, virJS= ONValuePtr data, + long long seconds, unsign= ed int micros) { - qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHIC= S_INITIALIZE); + qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHIC= S_INITIALIZE, + seconds, micros); } =20 =20 -static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJS= ONValuePtr data) +static void qemuMonitorJSONHandleSPICEDisconnect(qemuMonitorPtr mon, virJS= ONValuePtr data, + long long seconds, unsign= ed int micros) { - qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHIC= S_DISCONNECT); + qemuMonitorJSONHandleGraphicsSPICE(mon, data, VIR_DOMAIN_EVENT_GRAPHIC= S_DISCONNECT, + seconds, micros); } =20 static void qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon, virJSONValuePtr data, - int event) + int event, + long long seconds, unsigned int micros) { const char *device; const char *type_str; @@ -908,12 +967,13 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon, } =20 out: - qemuMonitorEmitBlockJob(mon, device, type, event); + qemuMonitorEmitBlockJob(mon, device, type, event, seconds, micros); } =20 static void qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int micros) { const char *devAlias =3D NULL; bool trayOpened; @@ -934,50 +994,58 @@ qemuMonitorJSONHandleTrayChange(qemuMonitorPtr mon, else reason =3D VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE; =20 - qemuMonitorEmitTrayChange(mon, devAlias, reason); + qemuMonitorEmitTrayChange(mon, devAlias, reason, seconds, micros); } =20 static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, - virJSONValuePtr data ATTRIBUTE_UNUSED) + virJSONValuePtr data ATTRIBUTE_UNUSED, + long long seconds, unsigned int micros) { - qemuMonitorEmitPMWakeup(mon); + qemuMonitorEmitPMWakeup(mon, micros, seconds); } =20 static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, - virJSONValuePtr data ATTRIBUTE_UNUSED) + virJSONValuePtr data ATTRIBUTE_UNUSED, + long long seconds, unsigned int micros) { - qemuMonitorEmitPMSuspend(mon); + qemuMonitorEmitPMSuspend(mon, seconds, micros); } =20 static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int mic= ros) { qemuMonitorJSONHandleBlockJobImpl(mon, data, - VIR_DOMAIN_BLOCK_JOB_COMPLETED); + VIR_DOMAIN_BLOCK_JOB_COMPLETED, + seconds, micros); } =20 static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int mic= ros) { qemuMonitorJSONHandleBlockJobImpl(mon, data, - VIR_DOMAIN_BLOCK_JOB_CANCELED); + VIR_DOMAIN_BLOCK_JOB_CANCELED, + seconds, micros); } =20 static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int micros) { qemuMonitorJSONHandleBlockJobImpl(mon, data, - VIR_DOMAIN_BLOCK_JOB_READY); + VIR_DOMAIN_BLOCK_JOB_READY, seconds,= micros); } =20 static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int micros) { unsigned long long actual =3D 0; if (virJSONValueObjectGetNumberUlong(data, "actual", &actual) < 0) { @@ -985,18 +1053,20 @@ qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mo= n, return; } actual =3D VIR_DIV_UP(actual, 1024); - qemuMonitorEmitBalloonChange(mon, actual); + qemuMonitorEmitBalloonChange(mon, actual, seconds, micros); } =20 static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, - virJSONValuePtr data ATTRIBUTE_UNUSED) + virJSONValuePtr data ATTRIBUTE_UNUSED, + long long seconds, unsigned int micros) { - qemuMonitorEmitPMSuspendDisk(mon); + qemuMonitorEmitPMSuspendDisk(mon, seconds, micros); } =20 static void -qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr dat= a) +qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr dat= a, + long long seconds, unsigned int micros) { const char *device; =20 @@ -1005,12 +1075,13 @@ qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr m= on, virJSONValuePtr data) return; } =20 - qemuMonitorEmitDeviceDeleted(mon, device); + qemuMonitorEmitDeviceDeleted(mon, device, seconds, micros); } =20 =20 static void -qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePt= r data) +qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePt= r data, + long long seconds, unsigned int mi= cros) { const char *name; =20 @@ -1019,13 +1090,14 @@ qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitor= Ptr mon, virJSONValuePtr data return; } =20 - qemuMonitorEmitNicRxFilterChanged(mon, name); + qemuMonitorEmitNicRxFilterChanged(mon, name, seconds, micros); } =20 =20 static void qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int micros) { const char *name; bool connected; @@ -1040,21 +1112,23 @@ qemuMonitorJSONHandleSerialChange(qemuMonitorPtr mo= n, return; } =20 - qemuMonitorEmitSerialChange(mon, name, connected); + qemuMonitorEmitSerialChange(mon, name, connected, seconds, micros); } =20 =20 static void qemuMonitorJSONHandleSpiceMigrated(qemuMonitorPtr mon, - virJSONValuePtr data ATTRIBUTE_UNUSED) + virJSONValuePtr data ATTRIBUTE_UNUSED, + long long seconds, unsigned int micros) { - qemuMonitorEmitSpiceMigrated(mon); + qemuMonitorEmitSpiceMigrated(mon, seconds, micros); } =20 =20 static void qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int micro= s) { const char *str; int status; @@ -1069,13 +1143,14 @@ qemuMonitorJSONHandleMigrationStatus(qemuMonitorPtr= mon, return; } =20 - qemuMonitorEmitMigrationStatus(mon, status); + qemuMonitorEmitMigrationStatus(mon, status, seconds, micros); } =20 =20 static void qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr mon, - virJSONValuePtr data) + virJSONValuePtr data, + long long seconds, unsigned int micros) { int pass; =20 @@ -1084,12 +1159,13 @@ qemuMonitorJSONHandleMigrationPass(qemuMonitorPtr m= on, return; } =20 - qemuMonitorEmitMigrationPass(mon, pass); + qemuMonitorEmitMigrationPass(mon, pass, seconds, micros); } =20 =20 static void -qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data) +qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, virJSONValuePtr data, + long long seconds, unsigned int micros) { virJSONValuePtr info; const char *alias; @@ -1116,7 +1192,8 @@ qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, = virJSONValuePtr data) if (virJSONValueObjectGetNumberUint(info, "status", &status) < 0) goto error; =20 - qemuMonitorEmitAcpiOstInfo(mon, alias, slotType, slot, source, status); + qemuMonitorEmitAcpiOstInfo(mon, alias, slotType, slot, source, status, + seconds, micros); return; =20 error: @@ -1126,7 +1203,8 @@ qemuMonitorJSONHandleAcpiOstInfo(qemuMonitorPtr mon, = virJSONValuePtr data) =20 =20 static void -qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr da= ta) +qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mon, virJSONValuePtr da= ta, + long long seconds, unsigned int micros) { const char *nodename; unsigned long long threshold; @@ -1141,7 +1219,8 @@ qemuMonitorJSONHandleBlockThreshold(qemuMonitorPtr mo= n, virJSONValuePtr data) if (virJSONValueObjectGetNumberUlong(data, "amount-exceeded", &excess)= < 0) goto error; =20 - qemuMonitorEmitBlockThreshold(mon, nodename, threshold, excess); + qemuMonitorEmitBlockThreshold(mon, nodename, threshold, excess, + seconds, micros); return; =20 error: diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 8e6498e..ee8bae5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -82,6 +82,12 @@ =20 VIR_LOG_INIT("qemu.qemu_process"); =20 +typedef struct { + qemuMonitorEventType type; + void (*handler_func)(qemuEventPtr ev, void *opaque); +} qemuEventFuncTable; + + /** * qemuProcessRemoveDomainStatus * @@ -474,20 +480,24 @@ qemuProcessFindVolumeQcowPassphrase(qemuMonitorPtr mo= n ATTRIBUTE_UNUSED, return ret; } =20 - -static int -qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - void *opaque) +static void +qemuProcessEventHandleReset(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event; qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); - int ret =3D -1; =20 - virObjectLock(vm); + if (!ev) + return; =20 + if (!ev->vm) { + VIR_INFO("Dropping reset event for unknown VM"); + return; + } + vm =3D ev->vm; event =3D virDomainEventRebootNewFromObj(vm); priv =3D vm->privateData; if (priv->agent) @@ -516,12 +526,10 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_U= NUSED, qemuDomainObjEndJob(driver, vm); } =20 - ret =3D 0; cleanup: - virObjectUnlock(vm); qemuDomainEventQueue(driver, event); virObjectUnref(cfg); - return ret; + return; } =20 =20 @@ -623,60 +631,69 @@ qemuProcessShutdownOrReboot(virQEMUDriverPtr driver, } =20 =20 -static int -qemuProcessHandleEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *eventName, - long long seconds, - unsigned int micros, - const char *details, - void *opaque) + +void +qemuProcessEmitMonitorEvent(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; + virDomainObjPtr vm; + const char * eventName; =20 - VIR_DEBUG("vm=3D%p", vm); + if (!ev) + return; + + vm =3D ev->vm; + + eventName =3D qemuMonitorEventTypeToString(ev->ev_type); + VIR_DEBUG("vm=3D%s monitor event %s", vm->def->name, eventName); =20 - virObjectLock(vm); event =3D virDomainQemuMonitorEventNew(vm->def->id, vm->def->name, vm->def->uuid, eventName, - seconds, micros, details); - - virObjectUnlock(vm); - qemuDomainEventQueue(driver, event); + ev->seconds, ev->micros, NULL); + if (event) + qemuDomainEventQueue(driver, event); =20 - return 0; + return; } =20 =20 -static int -qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - virTristateBool guest_initiated, - void *opaque) +static void +qemuProcessEventHandleShutdown(qemuEventPtr ev, + + void *opaque) { virQEMUDriverPtr driver =3D opaque; qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; + virTristateBool guest_initiated; virObjectEventPtr event =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); int detail =3D 0; =20 - VIR_DEBUG("vm=3D%p", vm); + if (!ev) + return; + vm =3D ev->vm; =20 - virObjectLock(vm); + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping SHUTDOWN event"); + goto exit; + } =20 + VIR_DEBUG("Processing SHUTDOWN event for VM %s", vm->def->name); priv =3D vm->privateData; if (priv->gotShutdown) { VIR_DEBUG("Ignoring repeated SHUTDOWN event from domain %s", vm->def->name); - goto unlock; + goto exit; } else if (!virDomainObjIsActive(vm)) { VIR_DEBUG("Ignoring SHUTDOWN event from inactive domain %s", vm->def->name); - goto unlock; + goto exit; } priv->gotShutdown =3D true; - + guest_initiated =3D ev->evData.ev_shutdown.guest_initiated; VIR_DEBUG("Transitioned guest %s to shutdown state", vm->def->name); virDomainObjSetState(vm, @@ -710,34 +727,39 @@ qemuProcessHandleShutdown(qemuMonitorPtr mon ATTRIBUT= E_UNUSED, qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SHUTDOWN); =20 qemuProcessShutdownOrReboot(driver, vm); - - unlock: - virObjectUnlock(vm); qemuDomainEventQueue(driver, event); - virObjectUnref(cfg); =20 - return 0; + virObjectUnref(cfg); +exit: + return; } =20 - -static int -qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - void *opaque) +static void +qemuProcessEventHandleStop(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; virDomainPausedReason reason =3D VIR_DOMAIN_PAUSED_UNKNOWN; virDomainEventSuspendedDetailType detail =3D VIR_DOMAIN_EVENT_SUSPENDE= D_PAUSED; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping STOP event"); + goto exit; + } =20 - virObjectLock(vm); if (virDomainObjGetState(vm, NULL) =3D=3D VIR_DOMAIN_RUNNING) { qemuDomainObjPrivatePtr priv =3D vm->privateData; =20 if (priv->gotShutdown) { VIR_DEBUG("Ignoring STOP event after SHUTDOWN"); - goto unlock; + goto exit; } =20 if (priv->job.asyncJob =3D=3D QEMU_ASYNC_JOB_MIGRATION_OUT) { @@ -776,31 +798,38 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UN= USED, } } =20 - unlock: - virObjectUnlock(vm); +exit: qemuDomainEventQueue(driver, event); virObjectUnref(cfg); =20 - return 0; + return; } =20 =20 -static int -qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, +static void +qemuProcessEventHandleResume(qemuEventPtr ev, void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; + virDomainObjPtr vm; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping RESUME event"); + goto exit; + } + if (virDomainObjGetState(vm, NULL) =3D=3D VIR_DOMAIN_PAUSED) { qemuDomainObjPrivatePtr priv =3D vm->privateData; =20 if (priv->gotShutdown) { VIR_DEBUG("Ignoring RESUME event after SHUTDOWN"); - goto unlock; + goto exit; } =20 VIR_DEBUG("Transitioned guest %s out of paused into resumed state", @@ -818,25 +847,32 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_= UNUSED, } } =20 - unlock: - virObjectUnlock(vm); +exit: qemuDomainEventQueue(driver, event); virObjectUnref(cfg); - return 0; + return; } =20 -static int -qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - long long offset, - void *opaque) +static void +qemuProcessEventHandleRTCChange(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; + virDomainObjPtr vm; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + unsigned long long offset; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping RTC event"); + goto exit; + } =20 + offset =3D ev->evData.ev_rtc.offset; if (vm->def->clock.offset =3D=3D VIR_DOMAIN_CLOCK_OFFSET_VARIABLE) { /* when a basedate is manually given on the qemu commandline * rather than simply "-rtc base=3Dutc", the offset sent by qemu @@ -862,26 +898,33 @@ qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBU= TE_UNUSED, =20 event =3D virDomainEventRTCChangeNewFromObj(vm, offset); =20 - virObjectUnlock(vm); - - qemuDomainEventQueue(driver, event); + if (event) + qemuDomainEventQueue(driver, event); virObjectUnref(cfg); - return 0; +exit: + return; } =20 - -static int -qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - int action, - void *opaque) +static void +qemuProcessEventHandleWatchdog1(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr watchdogEvent =3D NULL; virObjectEventPtr lifecycleEvent =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + int action; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Watchdog event"); + goto exit; + } + action =3D ev->evData.ev_watchdog.action; watchdogEvent =3D virDomainEventWatchdogNewFromObj(vm, action); =20 if (action =3D=3D VIR_DOMAIN_EVENT_WATCHDOG_PAUSE && @@ -923,22 +966,16 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUT= E_UNUSED, } } =20 - if (vm) - virObjectUnlock(vm); qemuDomainEventQueue(driver, watchdogEvent); qemuDomainEventQueue(driver, lifecycleEvent); =20 virObjectUnref(cfg); - return 0; +exit: + return; } =20 - -static int -qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *diskAlias, - int action, - const char *reason, +static void +qemuProcessEventHandleIOError(qemuEventPtr ev, void *opaque) { virQEMUDriverPtr driver =3D opaque; @@ -949,8 +986,24 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_= UNUSED, const char *devAlias; virDomainDiskDefPtr disk; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + const char *diskAlias; + int action; + const char *reason; + + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping IO Error event"); + goto exit; + } + + diskAlias =3D ev->evData.ev_IOErr.device; + action =3D ev->evData.ev_IOErr.action; + reason =3D ev->evData.ev_IOErr.reason; =20 - virObjectLock(vm); disk =3D qemuProcessFindDomainDiskByAlias(vm, diskAlias); =20 if (disk) { @@ -975,7 +1028,7 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_= UNUSED, virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOER= ROR); lifecycleEvent =3D virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPEND= ED, - VIR_DOMAIN_EVENT_SUSPEND= ED_IOERROR); + VIR_DOMAIN_PAUSED_IOERRO= R); =20 VIR_FREE(priv->lockState); if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lock= State) < 0) @@ -985,32 +1038,45 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUT= E_UNUSED, if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver-= >caps) < 0) VIR_WARN("Unable to save status on vm %s after IO error", vm->= def->name); } - virObjectUnlock(vm); =20 qemuDomainEventQueue(driver, ioErrorEvent); qemuDomainEventQueue(driver, ioErrorEvent2); qemuDomainEventQueue(driver, lifecycleEvent); + +exit: virObjectUnref(cfg); - return 0; + VIR_FREE(ev->evData.ev_IOErr.device); + VIR_FREE(ev->evData.ev_IOErr.reason); + return; } =20 -static int -qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *diskAlias, - int type, - int status, - void *opaque) +static void +qemuProcessEventHandleBlockJob(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; struct qemuProcessEvent *processEvent =3D NULL; virDomainDiskDefPtr disk; qemuDomainDiskPrivatePtr diskPriv; char *data =3D NULL; + virDomainObjPtr vm; + const char *diskAlias; + int type, status; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; =20 - VIR_DEBUG("Block job for device %s (domain: %p,%s) type %d status %d", + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Block Job event"); + goto cleanup; + } + + diskAlias =3D ev->evData.ev_blockJob.device; + type =3D ev->evData.ev_blockJob.type; + status =3D ev->evData.ev_blockJob.status; + + VIR_INFO("Block job for device %s (domain: %p,%s) type %d status %d", diskAlias, vm, vm->def->name, type, status); =20 if (!(disk =3D qemuProcessFindDomainDiskByAlias(vm, diskAlias))) @@ -1043,8 +1109,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUT= E_UNUSED, } =20 cleanup: - virObjectUnlock(vm); - return 0; + return; error: if (processEvent) VIR_FREE(processEvent->data); @@ -1052,21 +1117,9 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBU= TE_UNUSED, goto cleanup; } =20 - -static int -qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - int phase, - int localFamily, - const char *localNode, - const char *localService, - int remoteFamily, - const char *remoteNode, - const char *remoteService, - const char *authScheme, - const char *x509dname, - const char *saslUsername, - void *opaque) +static void +qemuProcessEventHandleGraphics(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event; @@ -1074,49 +1127,65 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIB= UTE_UNUSED, virDomainEventGraphicsAddressPtr remoteAddr =3D NULL; virDomainEventGraphicsSubjectPtr subject =3D NULL; size_t i; + virDomainObjPtr vm; + struct qemuEventGraphicsData *data; + + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Graphics event"); + goto exit; + } + data =3D &(ev->evData.ev_graphics); =20 if (VIR_ALLOC(localAddr) < 0) goto error; - localAddr->family =3D localFamily; - if (VIR_STRDUP(localAddr->service, localService) < 0 || - VIR_STRDUP(localAddr->node, localNode) < 0) + + localAddr->family =3D data->localFamilyID; + if (VIR_STRDUP(localAddr->service, data->localService) < 0 || + VIR_STRDUP(localAddr->node, data->localNode) < 0) goto error; =20 if (VIR_ALLOC(remoteAddr) < 0) goto error; - remoteAddr->family =3D remoteFamily; - if (VIR_STRDUP(remoteAddr->service, remoteService) < 0 || - VIR_STRDUP(remoteAddr->node, remoteNode) < 0) + remoteAddr->family =3D data->remoteFamilyID; + if (VIR_STRDUP(remoteAddr->service, data->remoteService) < 0 || + VIR_STRDUP(remoteAddr->node, data->remoteNode) < 0) goto error; =20 if (VIR_ALLOC(subject) < 0) goto error; - if (x509dname) { + if (data->x509dname) { if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0) goto error; subject->nidentity++; if (VIR_STRDUP(subject->identities[subject->nidentity-1].type, "x5= 09dname") < 0 || - VIR_STRDUP(subject->identities[subject->nidentity-1].name, x50= 9dname) < 0) + VIR_STRDUP(subject->identities[subject->nidentity-1].name, + data->x509dna= me) < 0) goto error; } - if (saslUsername) { + if (data->saslUsername) { if (VIR_REALLOC_N(subject->identities, subject->nidentity+1) < 0) goto error; subject->nidentity++; if (VIR_STRDUP(subject->identities[subject->nidentity-1].type, "sa= slUsername") < 0 || - VIR_STRDUP(subject->identities[subject->nidentity-1].name, sas= lUsername) < 0) + VIR_STRDUP(subject->identities[subject->nidentity-1].name, + data->saslUserna= me) < 0) goto error; } =20 - virObjectLock(vm); - event =3D virDomainEventGraphicsNewFromObj(vm, phase, localAddr, remot= eAddr, authScheme, subject); - virObjectUnlock(vm); + event =3D virDomainEventGraphicsNewFromObj(vm, data->phase, + localAddr, remoteAddr, + data->authScheme, + subject); =20 qemuDomainEventQueue(driver, event); =20 - return 0; + goto exit; =20 - error: +error: if (localAddr) { VIR_FREE(localAddr->service); VIR_FREE(localAddr->node); @@ -1136,22 +1205,41 @@ qemuProcessHandleGraphics(qemuMonitorPtr mon ATTRIB= UTE_UNUSED, VIR_FREE(subject); } =20 - return -1; +exit: + VIR_FREE(ev->evData.ev_graphics.localNode); + VIR_FREE(ev->evData.ev_graphics.localService); + VIR_FREE(ev->evData.ev_graphics.remoteNode); + VIR_FREE(ev->evData.ev_graphics.remoteService); + VIR_FREE(ev->evData.ev_graphics.x509dname); + VIR_FREE(ev->evData.ev_graphics.saslUsername); + VIR_FREE(ev->evData.ev_graphics.authScheme); + return; } =20 -static int -qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *devAlias, - int reason, - void *opaque) +static void +qemuProcessEventHandleTrayChange(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; virDomainDiskDefPtr disk; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + const char *devAlias; + int reason; + + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Graphics event"); + goto exit; + } + + devAlias =3D ev->evData.ev_tray.devAlias; + reason =3D ev->evData.ev_tray.reason; =20 - virObjectLock(vm); disk =3D qemuProcessFindDomainDiskByAlias(vm, devAlias); =20 if (disk) { @@ -1168,27 +1256,36 @@ qemuProcessHandleTrayChange(qemuMonitorPtr mon ATTR= IBUTE_UNUSED, VIR_WARN("Unable to save status on vm %s after tray moved even= t", vm->def->name); } - - virDomainObjBroadcast(vm); +// Why the broadcast here? +// virDomainObjBroadcast(vm); } =20 - virObjectUnlock(vm); qemuDomainEventQueue(driver, event); virObjectUnref(cfg); - return 0; +exit: + VIR_FREE(ev->evData.ev_tray.devAlias); + return; } =20 -static int -qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - void *opaque) +static void +qemuProcessEventHandlePMWakeup(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; virObjectEventPtr lifecycleEvent =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping PM Wakeup event"); + goto exit; + } =20 - virObjectLock(vm); event =3D virDomainEventPMWakeupNewFromObj(vm); =20 /* Don't set domain status back to running if it wasn't paused @@ -1210,24 +1307,32 @@ qemuProcessHandlePMWakeup(qemuMonitorPtr mon ATTRIB= UTE_UNUSED, } } =20 - virObjectUnlock(vm); qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, lifecycleEvent); virObjectUnref(cfg); - return 0; +exit: + return; } =20 -static int -qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - void *opaque) +static void +qemuProcessEventHandlePMSuspend(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; virObjectEventPtr lifecycleEvent =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping PM Suspend event"); + goto exit; + } =20 - virObjectLock(vm); event =3D virDomainEventPMSuspendNewFromObj(vm); =20 if (virDomainObjGetState(vm, NULL) =3D=3D VIR_DOMAIN_RUNNING) { @@ -1251,25 +1356,33 @@ qemuProcessHandlePMSuspend(qemuMonitorPtr mon ATTRI= BUTE_UNUSED, qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND); } =20 - virObjectUnlock(vm); - qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, lifecycleEvent); virObjectUnref(cfg); - return 0; +exit: + return; } =20 -static int -qemuProcessHandleBalloonChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - unsigned long long actual, - void *opaque) +static void +qemuProcessEventHandleBalloonChange(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; + unsigned long long actual; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Balloon event"); + goto exit; + } + + actual =3D ev->evData.ev_balloon.actual; event =3D virDomainEventBalloonChangeNewFromObj(vm, actual); =20 VIR_DEBUG("Updating balloon from %lld to %lld kb", @@ -1279,24 +1392,30 @@ qemuProcessHandleBalloonChange(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->cap= s) < 0) VIR_WARN("unable to save domain status with balloon change"); =20 - virObjectUnlock(vm); - qemuDomainEventQueue(driver, event); virObjectUnref(cfg); - return 0; +exit: + return; } =20 -static int -qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - void *opaque) +static void +qemuProcessEventHandlePMSuspendDisk(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; virObjectEventPtr lifecycleEvent =3D NULL; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); + virDomainObjPtr vm; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping PM Suspend disk event"); + goto exit; + } event =3D virDomainEventPMSuspendDiskNewFromObj(vm); =20 if (virDomainObjGetState(vm, NULL) =3D=3D VIR_DOMAIN_RUNNING) { @@ -1320,28 +1439,35 @@ qemuProcessHandlePMSuspendDisk(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, qemuAgentNotifyEvent(priv->agent, QEMU_AGENT_EVENT_SUSPEND); } =20 - virObjectUnlock(vm); - qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, lifecycleEvent); virObjectUnref(cfg); - - return 0; +exit: + return; } =20 =20 -static int -qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - qemuMonitorEventPanicInfoPtr info, - void *opaque) +static void +qemuProcessEventHandleGuestPanic(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; struct qemuProcessEvent *processEvent; + virDomainObjPtr vm; + qemuMonitorEventPanicInfoPtr info; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Guest Panic event"); + goto exit; + } + + info =3D ev->evData.ev_panic.info; if (VIR_ALLOC(processEvent) < 0) - goto cleanup; + goto exit; =20 processEvent->eventType =3D QEMU_PROCESS_EVENT_GUESTPANIC; processEvent->action =3D vm->def->onCrash; @@ -1357,26 +1483,31 @@ qemuProcessHandleGuestPanic(qemuMonitorPtr mon ATTR= IBUTE_UNUSED, VIR_FREE(processEvent); } =20 - cleanup: - if (vm) - virObjectUnlock(vm); - - return 0; +exit: + return; } =20 =20 -int -qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *devAlias, - void *opaque) +static void +qemuProcessEventHandleDeviceDeleted(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; struct qemuProcessEvent *processEvent =3D NULL; char *data; + virDomainObjPtr vm; + const char *devAlias; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Device deleted event"); + goto cleanup; + } =20 + devAlias =3D ev->evData.ev_deviceDel.device; VIR_DEBUG("Device %s removed from domain %p %s", devAlias, vm, vm->def->name); =20 @@ -1400,8 +1531,8 @@ qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATT= RIBUTE_UNUSED, } =20 cleanup: - virObjectUnlock(vm); - return 0; + VIR_FREE(ev->evData.ev_deviceDel.device); + return; error: if (processEvent) VIR_FREE(processEvent->data); @@ -1444,20 +1575,34 @@ qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, * Note that qemu does not emit the event for all the documented sources = or * devices. */ -static int -qemuProcessHandleAcpiOstInfo(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *alias, - const char *slotType, - const char *slot, - unsigned int source, - unsigned int status, - void *opaque) + +static void +qemuProcessEventHandleAcpiOstInfo(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; + virDomainObjPtr vm; + const char *alias; + const char *slotType; + const char *slot; + unsigned int source; + unsigned int status; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping ACPI event"); + goto exit; + } + + alias =3D ev->evData.ev_acpi.alias; + slotType =3D ev->evData.ev_acpi.slotType; + slot =3D ev->evData.ev_acpi.slot; + source =3D ev->evData.ev_acpi.source; + status =3D ev->evData.ev_acpi.status; =20 VIR_DEBUG("ACPI OST info for device %s domain %p %s. " "slotType=3D'%s' slot=3D'%s' source=3D%u status=3D%u", @@ -1471,20 +1616,19 @@ qemuProcessHandleAcpiOstInfo(qemuMonitorPtr mon ATT= RIBUTE_UNUSED, event =3D virDomainEventDeviceRemovalFailedNewFromObj(vm, alias); } =20 - virObjectUnlock(vm); qemuDomainEventQueue(driver, event); =20 - return 0; +exit: + VIR_FREE(ev->evData.ev_acpi.alias); + VIR_FREE(ev->evData.ev_acpi.slotType); + VIR_FREE(ev->evData.ev_acpi.slot); + return; } =20 =20 -static int -qemuProcessHandleBlockThreshold(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *nodename, - unsigned long long threshold, - unsigned long long excess, - void *opaque) +static void +qemuProcessEventHandleBlockThreshold(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; virObjectEventPtr event =3D NULL; @@ -1493,8 +1637,23 @@ qemuProcessHandleBlockThreshold(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, unsigned int idx; char *dev =3D NULL; const char *path =3D NULL; + virDomainObjPtr vm; + const char *nodename; + unsigned long long threshold; + unsigned long long excess; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Block Threshold event"); + goto exit; + } + + nodename =3D ev->evData.ev_threshold.nodename; + threshold =3D ev->evData.ev_threshold.threshold; + excess =3D ev->evData.ev_threshold.excess; =20 VIR_DEBUG("BLOCK_WRITE_THRESHOLD event for block node '%s' in domain %= p %s:" "threshold '%llu' exceeded by '%llu'", @@ -1511,25 +1670,33 @@ qemuProcessHandleBlockThreshold(qemuMonitorPtr mon = ATTRIBUTE_UNUSED, } } =20 - virObjectUnlock(vm); qemuDomainEventQueue(driver, event); - - return 0; +exit: + VIR_FREE(ev->evData.ev_threshold.nodename); + return; } =20 =20 -static int -qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *devAlias, - void *opaque) +static void +qemuProcessEventHandleNicRxFilterChanged(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; struct qemuProcessEvent *processEvent =3D NULL; char *data; + virDomainObjPtr vm; + char *devAlias; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Nic Filter Change event"); + goto exit; + } =20 + devAlias =3D ev->evData.ev_nic.devAlias; VIR_DEBUG("Device %s RX Filter changed in domain %p %s", devAlias, vm, vm->def->name); =20 @@ -1548,30 +1715,39 @@ qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr = mon ATTRIBUTE_UNUSED, goto error; } =20 - cleanup: - virObjectUnlock(vm); - return 0; +exit: + VIR_FREE(ev->evData.ev_nic.devAlias); + return; error: if (processEvent) VIR_FREE(processEvent->data); VIR_FREE(processEvent); - goto cleanup; + goto exit; } =20 =20 -static int -qemuProcessHandleSerialChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - const char *devAlias, - bool connected, - void *opaque) +static void +qemuProcessEventHandleSerialChanged(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; struct qemuProcessEvent *processEvent =3D NULL; char *data; + virDomainObjPtr vm; + char *devAlias; + bool connected; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; =20 + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Serial Change event"); + goto cleanup; + } + + devAlias =3D ev->evData.ev_serial.devAlias; + connected =3D ev->evData.ev_serial.connected; VIR_DEBUG("Serial port %s state changed to '%d' in domain %p %s", devAlias, connected, vm, vm->def->name); =20 @@ -1592,8 +1768,8 @@ qemuProcessHandleSerialChanged(qemuMonitorPtr mon ATT= RIBUTE_UNUSED, } =20 cleanup: - virObjectUnlock(vm); - return 0; + VIR_FREE(ev->evData.ev_serial.devAlias); + return; error: if (processEvent) VIR_FREE(processEvent->data); @@ -1602,14 +1778,21 @@ qemuProcessHandleSerialChanged(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, } =20 =20 -static int -qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - void *opaque ATTRIBUTE_UNUSED) +static void +qemuProcessEventHandleSpiceMigrated(qemuEventPtr ev, + void *opaque ATTRIBUTE_UNUSED) { qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Spice Migrated event"); + goto cleanup; + } =20 VIR_DEBUG("Spice migration completed for domain %p %s", vm, vm->def->name); @@ -1621,28 +1804,37 @@ qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, } =20 priv->job.spiceMigrated =3D true; - virDomainObjBroadcast(vm); +// virDomainObjBroadcast(vm); =20 cleanup: - virObjectUnlock(vm); - return 0; + return; } =20 =20 -static int -qemuProcessHandleMigrationStatus(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - int status, - void *opaque ATTRIBUTE_UNUSED) +static void +qemuProcessEventHandleMigrationStatus(qemuEventPtr ev, + void *opaque ATTRIBUTE_UNUSED) { qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; + int status; =20 - virObjectLock(vm); =20 + if (!ev) + return; + vm =3D ev->vm; + + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Migration Status event"); + goto cleanup; + } + + status =3D ev->evData.ev_migStatus.status; VIR_DEBUG("Migration of domain %p %s changed state to %s", vm, vm->def->name, qemuMonitorMigrationStatusTypeToString(status)); =20 + priv =3D vm->privateData; if (priv->job.asyncJob =3D=3D QEMU_ASYNC_JOB_NONE) { VIR_DEBUG("got MIGRATION event without a migration job"); @@ -1650,25 +1842,32 @@ qemuProcessHandleMigrationStatus(qemuMonitorPtr mon= ATTRIBUTE_UNUSED, } =20 priv->job.current->stats.status =3D status; - virDomainObjBroadcast(vm); +// virDomainObjBroadcast(vm); =20 cleanup: - virObjectUnlock(vm); - return 0; + return; } =20 =20 -static int -qemuProcessHandleMigrationPass(qemuMonitorPtr mon ATTRIBUTE_UNUSED, - virDomainObjPtr vm, - int pass, - void *opaque) +static void +qemuProcessEventHandleMigrationPass(qemuEventPtr ev, + void *opaque) { virQEMUDriverPtr driver =3D opaque; qemuDomainObjPrivatePtr priv; + virDomainObjPtr vm; + int pass; =20 - virObjectLock(vm); + if (!ev) + return; + vm =3D ev->vm; =20 + if (!ev->vm) { + VIR_WARN("Unable to locate VM, dropping Migration Pass event"); + goto cleanup; + } + + pass =3D ev->evData.ev_migPass.pass; VIR_DEBUG("Migrating domain %p %s, iteration %d", vm, vm->def->name, pass); =20 @@ -1681,42 +1880,58 @@ qemuProcessHandleMigrationPass(qemuMonitorPtr mon A= TTRIBUTE_UNUSED, qemuDomainEventQueue(driver, virDomainEventMigrationIterationNewFromObj(vm, pa= ss)); =20 - cleanup: - virObjectUnlock(vm); - return 0; +cleanup: + return; } =20 +static qemuEventFuncTable qemuEventFunctions[] =3D { + { QEMU_EVENT_ACPI_OST, qemuProcessEventHandleAcpiOstInfo, }, + { QEMU_EVENT_BALLOON_CHANGE, qemuProcessEventHandleBalloonChange, }, + { QEMU_EVENT_BLOCK_IO_ERROR, qemuProcessEventHandleIOError, }, + { QEMU_EVENT_BLOCK_JOB, qemuProcessEventHandleBlockJob, }, + { QEMU_EVENT_BLOCK_WRITE_THRESHOLD, qemuProcessEventHandleBlockThresho= ld, }, + { QEMU_EVENT_DEVICE_DELETED, qemuProcessEventHandleDeviceDeleted, }, + { QEMU_EVENT_DEVICE_TRAY_MOVED, qemuProcessEventHandleTrayChange, }, + { QEMU_EVENT_GRAPHICS, qemuProcessEventHandleGraphics,}, + { QEMU_EVENT_GUEST_PANICKED, qemuProcessEventHandleGuestPanic,}, + { QEMU_EVENT_MIGRATION, qemuProcessEventHandleMigrationStatus,}, + { QEMU_EVENT_MIGRATION_PASS, qemuProcessEventHandleMigrationPass,}, + { QEMU_EVENT_NIC_RX_FILTER_CHANGED, qemuProcessEventHandleNicRxFilterC= hanged, }, + { QEMU_EVENT_POWERDOWN, NULL, }, + { QEMU_EVENT_RESET, qemuProcessEventHandleReset, }, + { QEMU_EVENT_RESUME, qemuProcessEventHandleResume, }, + { QEMU_EVENT_RTC_CHANGE, qemuProcessEventHandleRTCChange, }, + { QEMU_EVENT_SHUTDOWN, qemuProcessEventHandleShutdown,}, + { QEMU_EVENT_SPICE_MIGRATED, qemuProcessEventHandleSpiceMigrated, }, + { QEMU_EVENT_STOP, qemuProcessEventHandleStop, }, + { QEMU_EVENT_SUSPEND, qemuProcessEventHandlePMSuspend,}, + { QEMU_EVENT_SUSPEND_DISK, qemuProcessEventHandlePMSuspendDisk,}, + { QEMU_EVENT_SERIAL_CHANGE, qemuProcessEventHandleSerialChanged,}, + { QEMU_EVENT_WAKEUP, qemuProcessEventHandlePMWakeup,}, + { QEMU_EVENT_WATCHDOG, qemuProcessEventHandleWatchdog1,}, +}; + +static int +qemuProcessEnqueueEvent(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virDomainObjPtr vm ATTRIBUTE_UNUSED, + qemuEventPtr ev, + void *opaque) +{ + virQEMUDriverPtr driver =3D opaque; + /* Bad code alert: Fix this lookup to scan table for correct index. + * Works for now since event table is sorted */ + ev->handler =3D qemuEventFunctions[ev->ev_type].handler_func; + return virEnqueueVMEvent(driver->ev_list, ev); +} =20 static qemuMonitorCallbacks monitorCallbacks =3D { .eofNotify =3D qemuProcessHandleMonitorEOF, .errorNotify =3D qemuProcessHandleMonitorError, .diskSecretLookup =3D qemuProcessFindVolumeQcowPassphrase, - .domainEvent =3D qemuProcessHandleEvent, - .domainShutdown =3D qemuProcessHandleShutdown, - .domainStop =3D qemuProcessHandleStop, - .domainResume =3D qemuProcessHandleResume, - .domainReset =3D qemuProcessHandleReset, - .domainRTCChange =3D qemuProcessHandleRTCChange, - .domainWatchdog =3D qemuProcessHandleWatchdog, - .domainIOError =3D qemuProcessHandleIOError, - .domainGraphics =3D qemuProcessHandleGraphics, - .domainBlockJob =3D qemuProcessHandleBlockJob, - .domainTrayChange =3D qemuProcessHandleTrayChange, - .domainPMWakeup =3D qemuProcessHandlePMWakeup, - .domainPMSuspend =3D qemuProcessHandlePMSuspend, - .domainBalloonChange =3D qemuProcessHandleBalloonChange, - .domainPMSuspendDisk =3D qemuProcessHandlePMSuspendDisk, - .domainGuestPanic =3D qemuProcessHandleGuestPanic, - .domainDeviceDeleted =3D qemuProcessHandleDeviceDeleted, - .domainNicRxFilterChanged =3D qemuProcessHandleNicRxFilterChanged, - .domainSerialChange =3D qemuProcessHandleSerialChanged, - .domainSpiceMigrated =3D qemuProcessHandleSpiceMigrated, - .domainMigrationStatus =3D qemuProcessHandleMigrationStatus, - .domainMigrationPass =3D qemuProcessHandleMigrationPass, - .domainAcpiOstInfo =3D qemuProcessHandleAcpiOstInfo, - .domainBlockThreshold =3D qemuProcessHandleBlockThreshold, + .domainEnqueueEvent =3D qemuProcessEnqueueEvent, }; =20 + static void qemuProcessMonitorReportLogError(qemuMonitorPtr mon, const char *msg, diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 814b86d..a2bbc4f 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -129,6 +129,8 @@ int qemuProcessFinishStartup(virConnectPtr conn, bool startCPUs, virDomainPausedReason pausedReason); =20 +void qemuProcessEmitMonitorEvent(qemuEventPtr ev, + void *opaque); typedef enum { VIR_QEMU_PROCESS_STOP_MIGRATED =3D 1 << 0, VIR_QEMU_PROCESS_STOP_NO_RELABEL =3D 1 << 1, diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index 5e30fb0..94375a3 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -1013,7 +1013,7 @@ qemuMonitorTestErrorNotify(qemuMonitorPtr mon ATTRIBU= TE_UNUSED, static qemuMonitorCallbacks qemuMonitorTestCallbacks =3D { .eofNotify =3D qemuMonitorTestEOFNotify, .errorNotify =3D qemuMonitorTestErrorNotify, - .domainDeviceDeleted =3D qemuProcessHandleDeviceDeleted, + .domainDeviceDeleted =3D NULL, //qemuProcessHandleDeviceDeleted, }; =20 =20 --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list