From nobody Thu May 9 00:57:49 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; 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 1509452867533887.1374705033927; Tue, 31 Oct 2017 05:27:47 -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 AD7FA6CB2B; Tue, 31 Oct 2017 12:27:45 +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 04E9760605; Tue, 31 Oct 2017 12:27:45 +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 84E7F1804485; Tue, 31 Oct 2017 12:27:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v9VCRgMB011840 for ; Tue, 31 Oct 2017 08:27:42 -0400 Received: by smtp.corp.redhat.com (Postfix) id 07C5E60606; Tue, 31 Oct 2017 12:27:42 +0000 (UTC) Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 00FE060605 for ; Tue, 31 Oct 2017 12:27:37 +0000 (UTC) Received: from relay.sw.ru (mailhub.sw.ru [195.214.232.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B9B8F883AE for ; Tue, 31 Oct 2017 12:27:33 +0000 (UTC) Received: from dim-vz7.qa.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v9VC6m9e030953 for ; Tue, 31 Oct 2017 15:06:48 +0300 (MSK) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AD7FA6CB2B Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ext-mx03.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 AD7FA6CB2B DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B9B8F883AE Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=nshirokovskiy@virtuozzo.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B9B8F883AE From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Tue, 31 Oct 2017 15:06:36 +0300 Message-Id: <1509451596-479599-1-git-send-email-nshirokovskiy@virtuozzo.com> X-Greylist: Delayed for 00:20:43 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 31 Oct 2017 12:27:35 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 31 Oct 2017 12:27:35 +0000 (UTC) for IP:'195.214.232.25' DOMAIN:'mailhub.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: -0.001 (SPF_PASS) 195.214.232.25 mailhub.sw.ru 195.214.232.25 mailhub.sw.ru X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC] lib: provide error message in new blockjob 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.27]); Tue, 31 Oct 2017 12:27:46 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" If block job is completed with error qemu additionally provides error messa= ge. This patch introduces new event VIR_DOMAIN_EVENT_ID_BLOCK_JOB_3 to pass err= or message to client. --- The patch is applied on top of [1] patch series (not yet pushed though). Lo= oks like this patch consists of too much boilerplate code only to pass extra st= ring parameter for blockjob event but looks like there is no other way now. Especially ugly looking is adding event3 in src/qemu/qemu_blockjob.c. Actually there is old RFC for providing error message for blockjob event [2= ]. Hope this one gain more attention. [1] https://www.redhat.com/archives/libvir-list/2017-October/msg01292.html [2] https://www.redhat.com/archives/libvir-list/2016-December/msg00093.html daemon/remote.c | 47 ++++++++++++++++++++++++++++++++ examples/object-events/event-test.c | 21 +++++++++++++++ include/libvirt/libvirt-domain.h | 23 ++++++++++++++++ src/conf/domain_event.c | 54 ++++++++++++++++++++++++++++++++-= ---- src/conf/domain_event.h | 13 +++++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_blockjob.c | 9 +++++-- src/qemu/qemu_blockjob.h | 3 ++- src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 10 ++++--- src/qemu/qemu_process.c | 12 ++++++--- src/remote/remote_driver.c | 34 +++++++++++++++++++++++ src/remote/remote_protocol.x | 17 +++++++++++- src/remote_protocol-structs | 9 +++++++ tools/virsh-domain.c | 25 +++++++++++++++++ 15 files changed, 264 insertions(+), 16 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 3f7d2d3..a5b87e6 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1342,6 +1342,52 @@ remoteRelayDomainEventBlockThreshold(virConnectPtr c= onn, } =20 =20 +static int +remoteRelayDomainEventBlockJob3(virConnectPtr conn, + virDomainPtr dom, + const char *dst, + int type, + int status, + const char *error, + void *opaque) +{ + daemonClientEventCallbackPtr callback =3D opaque; + remote_domain_event_block_job_3_msg data; + + if (callback->callbackID < 0 || + !remoteRelayDomainEventCheckACL(callback->client, conn, dom)) + return -1; + + VIR_DEBUG("Relaying domain block job 3 event %s %d %s %i, %i, %s, call= back %d", + dom->name, dom->id, dst, type, status, NULLSTR(error), + callback->callbackID); + + /* build return data */ + memset(&data, 0, sizeof(data)); + data.callbackID =3D callback->callbackID; + if (VIR_STRDUP(data.dst, dst) < 0) + return -1; + if (error) { + if (VIR_ALLOC(data.error) < 0 || + VIR_STRDUP(*(data.error), error) < 0) + goto error; + } + data.type =3D type; + data.status =3D status; + make_nonnull_domain(&data.dom, dom); + + remoteDispatchObjectEventSend(callback->client, remoteProgram, + REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_3, + (xdrproc_t)xdr_remote_domain_event_block= _job_3_msg, &data); + return 0; + + error: + VIR_FREE(data.dst); + VIR_FREE(data.error); + + return -1; +} + static virConnectDomainEventGenericCallback domainEventCallbacks[] =3D { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventLifecycle), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventReboot), @@ -1368,6 +1414,7 @@ static virConnectDomainEventGenericCallback domainEve= ntCallbacks[] =3D { VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceRemovalFailed), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventMetadataChange), VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockThreshold), + VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventBlockJob3), }; =20 verify(ARRAY_CARDINALITY(domainEventCallbacks) =3D=3D VIR_DOMAIN_EVENT_ID_= LAST); diff --git a/examples/object-events/event-test.c b/examples/object-events/e= vent-test.c index a144638..623dbd6 100644 --- a/examples/object-events/event-test.c +++ b/examples/object-events/event-test.c @@ -936,6 +936,26 @@ myDomainEventBlockJobCallback(virConnectPtr conn ATTRI= BUTE_UNUSED, =20 =20 static int +myDomainEventBlockJob3Callback(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + const char *disk, + int type, + int status, + void *opaque, + const char *error) +{ + const char *eventName =3D opaque; + + printf("%s EVENT: Domain %s(%d) block job callback '%s' disk '%s', " + "type '%s' status '%s' error '%s'", + __func__, virDomainGetName(dom), virDomainGetID(dom), eventName, + disk, blockJobTypeToStr(type), blockJobStatusToStr(status), + NULLSTR(error)); + return 0; +} + + +static int myDomainEventBlockThresholdCallback(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, const char *dev, @@ -1082,6 +1102,7 @@ struct domainEventData domainEvents[] =3D { DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED, myDomainEventD= eviceRemovalFailedCallback), DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_METADATA_CHANGE, myDomainEventMetadat= aChangeCallback), DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, myDomainEventBlockTh= resholdCallback), + DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_3, myDomainEventBlockJob3Ca= llback), }; =20 struct storagePoolEventData { diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index 4048acf..4f942da 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4363,6 +4363,28 @@ typedef void (*virConnectDomainEventBlockThresholdCa= llback)(virConnectPtr conn, unsigned long = long excess, void *opaque); =20 + +/** + * virConnectDomainEventBlockJob3Callback: + * @conn: connection object + * @dom: domain on which the event occurred + * @disk: name associated with the affected disk (filename or target + * device, depending on how the callback was registered) + * @type: type of block job (virDomainBlockJobType) + * @status: status of the operation (virConnectDomainEventBlockJobStatus) + * @error: error string + * @opaque: application specified data + * + */ + + +typedef void (*virConnectDomainEventBlockJob3Callback)(virConnectPtr conn, + virDomainPtr dom, + const char *disk, + int type, + int status, + const char *error, + void *opaque); /** * VIR_DOMAIN_EVENT_CALLBACK: * @@ -4405,6 +4427,7 @@ typedef enum { VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED =3D 22, /* virConnectDomainE= ventDeviceRemovalFailedCallback */ VIR_DOMAIN_EVENT_ID_METADATA_CHANGE =3D 23, /* virConnectDomainEventMe= tadataChangeCallback */ VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD =3D 24, /* virConnectDomainEventBl= ockThresholdCallback */ + VIR_DOMAIN_EVENT_ID_BLOCK_JOB_3 =3D 25, /* virConnectDomainEventBlo= ckJob3Callback */ =20 # ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_EVENT_ID_LAST diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 7baccd5..2ea170d 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -145,6 +145,7 @@ struct _virDomainEventBlockJob { virDomainEvent parent; =20 char *disk; /* path or dst, depending on event id */ + char *error; int type; int status; }; @@ -501,6 +502,7 @@ virDomainEventBlockJobDispose(void *obj) VIR_DEBUG("obj=3D%p", event); =20 VIR_FREE(event->disk); + VIR_FREE(event->error); } =20 static void @@ -995,7 +997,8 @@ virDomainEventBlockJobNew(int event, unsigned char *uuid, const char *disk, int type, - int status) + int status, + const char *error) { virDomainEventBlockJobPtr ev; =20 @@ -1007,7 +1010,8 @@ virDomainEventBlockJobNew(int event, id, name, uuid))) return NULL; =20 - if (VIR_STRDUP(ev->disk, disk) < 0) { + if (VIR_STRDUP(ev->disk, disk) < 0 || + VIR_STRDUP(ev->error, error) < 0) { virObjectUnref(ev); return NULL; } @@ -1025,7 +1029,7 @@ virDomainEventBlockJobNewFromObj(virDomainObjPtr obj, { return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB, obj->def->id, obj->def->name, - obj->def->uuid, path, type, status); + obj->def->uuid, path, type, status, N= ULL); } =20 virObjectEventPtr @@ -1036,7 +1040,7 @@ virDomainEventBlockJobNewFromDom(virDomainPtr dom, { return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB, dom->id, dom->name, dom->uuid, - path, type, status); + path, type, status, NULL); } =20 virObjectEventPtr @@ -1047,7 +1051,7 @@ virDomainEventBlockJob2NewFromObj(virDomainObjPtr obj, { return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, obj->def->id, obj->def->name, - obj->def->uuid, dst, type, status); + obj->def->uuid, dst, type, status, NU= LL); } =20 virObjectEventPtr @@ -1058,7 +1062,31 @@ virDomainEventBlockJob2NewFromDom(virDomainPtr dom, { return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, dom->id, dom->name, dom->uuid, - dst, type, status); + dst, type, status, NULL); +} + +virObjectEventPtr +virDomainEventBlockJob3NewFromObj(virDomainObjPtr obj, + const char *dst, + int type, + int status, + const char *error) +{ + return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_3, + obj->def->id, obj->def->name, + obj->def->uuid, dst, type, status, er= ror); +} + +virObjectEventPtr +virDomainEventBlockJob3NewFromDom(virDomainPtr dom, + const char *dst, + int type, + int status, + const char *error) +{ + return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_3, + dom->id, dom->name, dom->uuid, + dst, type, status, error); } =20 virObjectEventPtr @@ -1871,6 +1899,20 @@ virDomainEventDispatchDefaultFunc(virConnectPtr conn, goto cleanup; } =20 + case VIR_DOMAIN_EVENT_ID_BLOCK_JOB_3: + { + virDomainEventBlockJobPtr blockJobEvent; + + blockJobEvent =3D (virDomainEventBlockJobPtr)event; + ((virConnectDomainEventBlockJob3Callback)cb)(conn, dom, + blockJobEvent->dis= k, + blockJobEvent->typ= e, + blockJobEvent->sta= tus, + blockJobEvent->err= or, + cbopaque); + goto cleanup; + } + case VIR_DOMAIN_EVENT_ID_DISK_CHANGE: { virDomainEventDiskChangePtr diskChangeEvent; diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h index 3992a29..1a0f16b 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -138,6 +138,19 @@ virDomainEventBlockJob2NewFromDom(virDomainPtr dom, int status); =20 virObjectEventPtr +virDomainEventBlockJob3NewFromObj(virDomainObjPtr obj, + const char *dst, + int type, + int status, + const char *error); +virObjectEventPtr +virDomainEventBlockJob3NewFromDom(virDomainPtr dom, + const char *dst, + int type, + int status, + const char *error); + +virObjectEventPtr virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj, const char *oldSrcPath, const char *newSrcPath, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 448d962..5f0a212 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -562,6 +562,8 @@ virDomainEventBalloonChangeNewFromDom; virDomainEventBalloonChangeNewFromObj; virDomainEventBlockJob2NewFromDom; virDomainEventBlockJob2NewFromObj; +virDomainEventBlockJob3NewFromDom; +virDomainEventBlockJob3NewFromObj; virDomainEventBlockJobNewFromDom; virDomainEventBlockJobNewFromObj; virDomainEventBlockThresholdNewFromDom; diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 0b1616a..5266823 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -70,7 +70,8 @@ qemuBlockJobUpdate(virQEMUDriverPtr driver, if (status !=3D -1) { qemuBlockJobEventProcess(driver, vm, disk, asyncJob, diskPriv->blockJobType, - diskPriv->blockJobStatus); + diskPriv->blockJobStatus, + diskPriv->blockJobError); diskPriv->blockJobStatus =3D -1; if (error) VIR_STEAL_PTR(*error, diskPriv->blockJobError); @@ -100,10 +101,12 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, virDomainDiskDefPtr disk, qemuDomainAsyncJob asyncJob, int type, - int status) + int status, + const char *error) { virObjectEventPtr event =3D NULL; virObjectEventPtr event2 =3D NULL; + virObjectEventPtr event3 =3D NULL; const char *path; virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); virDomainDiskDefPtr persistDisk =3D NULL; @@ -123,6 +126,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, path =3D virDomainDiskGetSource(disk); event =3D virDomainEventBlockJobNewFromObj(vm, path, type, status); event2 =3D virDomainEventBlockJob2NewFromObj(vm, disk->dst, type, stat= us); + event3 =3D virDomainEventBlockJob3NewFromObj(vm, disk->dst, type, stat= us, error); =20 /* If we completed a block pull or commit, then update the XML * to match. */ @@ -212,6 +216,7 @@ qemuBlockJobEventProcess(virQEMUDriverPtr driver, =20 qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event2); + qemuDomainEventQueue(driver, event3); =20 virObjectUnref(cfg); } diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index e71d691..18bcaaa 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -36,7 +36,8 @@ void qemuBlockJobEventProcess(virQEMUDriverPtr driver, virDomainDiskDefPtr disk, qemuDomainAsyncJob asyncJob, int type, - int status); + int status, + const char *error); =20 void qemuBlockJobSyncBegin(virDomainDiskDefPtr disk); void qemuBlockJobSyncEnd(virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 735e810..99a71b3 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -457,6 +457,7 @@ struct qemuProcessEvent { int action; int status; void *data; + char *error; }; =20 typedef struct _qemuDomainLogContext qemuDomainLogContext; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 725b46a..c6626bb 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4715,7 +4715,8 @@ processBlockJobEvent(virQEMUDriverPtr driver, virDomainObjPtr vm, char *diskAlias, int type, - int status) + int status, + char *error) { virDomainDiskDefPtr disk; =20 @@ -4728,12 +4729,14 @@ processBlockJobEvent(virQEMUDriverPtr driver, } =20 if ((disk =3D qemuProcessFindDomainDiskByAlias(vm, diskAlias))) - qemuBlockJobEventProcess(driver, vm, disk, QEMU_ASYNC_JOB_NONE, ty= pe, status); + qemuBlockJobEventProcess(driver, vm, disk, QEMU_ASYNC_JOB_NONE, + type, status, error); =20 endjob: qemuDomainObjEndJob(driver, vm); cleanup: VIR_FREE(diskAlias); + VIR_FREE(error); } =20 =20 @@ -4815,7 +4818,8 @@ static void qemuProcessEventHandler(void *data, void = *opaque) processBlockJobEvent(driver, vm, processEvent->data, processEvent->action, - processEvent->status); + processEvent->status, + processEvent->error); break; case QEMU_PROCESS_EVENT_MONITOR_EOF: processMonitorEOFEvent(driver, vm); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 4bfad5d..6a3d9bc 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1008,6 +1008,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUT= E_UNUSED, virDomainDiskDefPtr disk; qemuDomainDiskPrivatePtr diskPriv; char *data =3D NULL; + char *errorCopy =3D NULL; =20 virObjectLock(vm); =20 @@ -1018,13 +1019,14 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIB= UTE_UNUSED, goto error; diskPriv =3D QEMU_DOMAIN_DISK_PRIVATE(disk); =20 + ignore_value(VIR_STRDUP_QUIET(errorCopy, error)); + if (diskPriv->blockJobSync) { /* We have a SYNC API waiting for this event, dispatch it back */ diskPriv->blockJobType =3D type; diskPriv->blockJobStatus =3D status; VIR_FREE(diskPriv->blockJobError); - if (error && VIR_STRDUP_QUIET(diskPriv->blockJobError, error) < 0) - VIR_WARN("Can not pass error message further: %s", error); + VIR_STEAL_PTR(diskPriv->blockJobError, errorCopy); virDomainObjBroadcast(vm); } else { /* there is no waiting SYNC API, dispatch the update to a thread */ @@ -1038,6 +1040,7 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUT= E_UNUSED, processEvent->vm =3D vm; processEvent->action =3D type; processEvent->status =3D status; + VIR_STEAL_PTR(processEvent->error, errorCopy); =20 virObjectRef(vm); if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0)= { @@ -1047,11 +1050,14 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIB= UTE_UNUSED, } =20 cleanup: + VIR_FREE(errorCopy); virObjectUnlock(vm); return 0; error: - if (processEvent) + if (processEvent) { VIR_FREE(processEvent->data); + VIR_FREE(processEvent->error); + } VIR_FREE(processEvent); goto cleanup; } diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 06719bb..c73461d 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -405,6 +405,11 @@ remoteConnectNotifyEventConnectionClosed(virNetClientP= rogramPtr prog ATTRIBUTE_U virNetClientPtr client ATTRIBUTE_= UNUSED, void *evdata, void *opaque); =20 +static void +remoteDomainBuildEventBlockJob3(virNetClientProgramPtr prog, + virNetClientPtr client, + void *evdata, void *opaque); + static virNetClientProgramEvent remoteEvents[] =3D { { REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE, remoteDomainBuildEventLifecycle, @@ -611,6 +616,10 @@ static virNetClientProgramEvent remoteEvents[] =3D { remoteDomainBuildEventBlockThreshold, sizeof(remote_domain_event_block_threshold_msg), (xdrproc_t)xdr_remote_domain_event_block_threshold_msg }, + { REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_3, + remoteDomainBuildEventBlockJob3, + sizeof(remote_domain_event_block_job_3_msg), + (xdrproc_t)xdr_remote_domain_event_block_job_3_msg }, }; =20 static void @@ -5610,6 +5619,31 @@ remoteDomainBuildEventBlockThreshold(virNetClientPro= gramPtr prog ATTRIBUTE_UNUSE } =20 =20 +static void +remoteDomainBuildEventBlockJob3(virNetClientProgramPtr prog ATTRIBUTE_UNUS= ED, + virNetClientPtr client ATTRIBUTE_UNUSED, + void *evdata, void *opaque) +{ + virConnectPtr conn =3D opaque; + remote_domain_event_block_job_3_msg *msg =3D evdata; + struct private_data *priv =3D conn->privateData; + virDomainPtr dom; + virObjectEventPtr event =3D NULL; + + dom =3D get_nonnull_domain(conn, msg->dom); + if (!dom) + return; + + event =3D virDomainEventBlockJob3NewFromDom(dom, msg->dst, msg->type, + msg->status, + msg->error ? *msg->error : N= ULL); + + virObjectUnref(dom); + + remoteEventQueue(priv, event, msg->callbackID); +} + + static int remoteStreamSend(virStreamPtr st, const char *data, diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 0aed252..371b640 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3095,6 +3095,15 @@ struct remote_domain_event_block_job_2_msg { int status; }; =20 +struct remote_domain_event_block_job_3_msg { + int callbackID; + remote_nonnull_domain dom; + remote_nonnull_string dst; + remote_string error; + int type; + int status; +}; + struct remote_domain_event_block_threshold_msg { int callbackID; remote_nonnull_domain dom; @@ -6120,5 +6129,11 @@ enum remote_procedure { * @generate: both * @acl: domain:write */ - REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION =3D 390 + REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION =3D 390, + + /** + * @generate: none + * @acl: none + */ + REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_3 =3D 391 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 59b0ace..b8f4065 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2535,6 +2535,14 @@ struct remote_domain_event_block_job_2_msg { int type; int status; }; +struct remote_domain_event_block_job_3_msg { + int callbackID; + remote_nonnull_domain dom; + remote_nonnull_string dst; + remote_string error; + int type; + int status; +}; struct remote_domain_event_block_threshold_msg { int callbackID; remote_nonnull_domain dom; @@ -3262,4 +3270,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC =3D 388, REMOTE_PROC_DOMAIN_MANAGED_SAVE_DEFINE_XML =3D 389, REMOTE_PROC_DOMAIN_SET_LIFECYCLE_ACTION =3D 390, + REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_3 =3D 391, }; diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1e33e82..6377c91 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -13253,6 +13253,29 @@ virshEventBlockThresholdPrint(virConnectPtr conn A= TTRIBUTE_UNUSED, } =20 =20 +static void +virshEventBlockJob3Print(virConnectPtr conn ATTRIBUTE_UNUSED, + virDomainPtr dom, + const char *disk, + int type, + int status, + const char *error, + void *opaque) +{ + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&buf, _("event '%s' for domain %s: %s for %s %s, " + "error: %s\n"), + ((virshDomEventData *) opaque)->cb->name, + virDomainGetName(dom), + virshDomainBlockJobToString(type), + disk, + virshDomainBlockJobStatusToString(status), + NULLSTR(error)); + virshEventPrint(opaque, &buf); +} + + static vshEventCallback vshEventCallbacks[] =3D { { "lifecycle", VIR_DOMAIN_EVENT_CALLBACK(virshEventLifecyclePrint), }, @@ -13302,6 +13325,8 @@ static vshEventCallback vshEventCallbacks[] =3D { VIR_DOMAIN_EVENT_CALLBACK(virshEventMetadataChangePrint), }, { "block-threshold", VIR_DOMAIN_EVENT_CALLBACK(virshEventBlockThresholdPrint), }, + { "block-job-3", + VIR_DOMAIN_EVENT_CALLBACK(virshEventBlockJob3Print), }, }; verify(VIR_DOMAIN_EVENT_ID_LAST =3D=3D ARRAY_CARDINALITY(vshEventCallbacks= )); =20 --=20 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list