From nobody Mon Feb 9 06:26:34 2026 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; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1562947650; cv=none; d=zoho.com; s=zohoarc; b=McbPslMpvE3mBDTe1N64bGL9i8IlWwN0Ti344b7cKE+PSAVpFtZI2BNJoNihNliYAiwuIPtBN+AxXbyj+j5RjaFb2H3hk80ZJlOe0WDxlhFu/67uTwXBsMbaCCVAlUULSf26xuZQWeU29kT/qhrLtuhoTCg4DQ+PzdZc7YVJuSk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1562947650; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=aAtwlxTaXQ5zBRgjiB1BWKy/ynllkusUKnGdWiL87IQ=; b=RgjOzKT+/0PfOcU6KXDypQ9jQHz7wt0WQ74oxXtt6NRjp31VnxbYOmlP4eqkxSJk3/7HvSJ4tZW/uNh2nhbcaenJNSsAn3X6AhzYDxs9vYBeOCNvJxLHD77+SEvtNil8aRTsB633WFZkqeOYe1UOKAlLm9IRqKTwc3t55OJmAEo= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1562947650147497.15411162291923; Fri, 12 Jul 2019 09:07:30 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7CA4930C5859; Fri, 12 Jul 2019 16:07:28 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 57AE9379F; Fri, 12 Jul 2019 16:07:28 +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 1923C206D9; Fri, 12 Jul 2019 16:07:28 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x6CG7OGg017398 for ; Fri, 12 Jul 2019 12:07:24 -0400 Received: by smtp.corp.redhat.com (Postfix) id 77E7A60C79; Fri, 12 Jul 2019 16:07:24 +0000 (UTC) Received: from angien.brq.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id D1B0D60C70; Fri, 12 Jul 2019 16:07:23 +0000 (UTC) From: Peter Krempa To: libvir-list@redhat.com Date: Fri, 12 Jul 2019 18:05:59 +0200 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Peter Krempa Subject: [libvirt] [PATCH 18/25] qemu: blockjob: Add modern block job event handler 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: , 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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 12 Jul 2019 16:07:29 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Add the infrastructure to handle block job events in the -blockdev era. Some complexity is required as qemu does not bother to notify whether the job was concluded successfully or failed. Thus it's necessary to re-query the monitor. To minimize the possibility of stuck jobs save the state into the XML prior to handling everything so that the reconnect code can potentially continue with the cleanup. Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_blockjob.c | 168 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index dd6071dae1..8b142f1aba 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -423,6 +423,169 @@ qemuBlockJobEventProcessLegacy(virQEMUDriverPtr drive= r, } +static void +qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob AT= TRIBUTE_UNUSED) +{ + switch ((qemuBlockjobState) job->newstate) { + case QEMU_BLOCKJOB_STATE_COMPLETED: + switch ((qemuBlockJobType) job->type) { + case QEMU_BLOCKJOB_TYPE_PULL: + case QEMU_BLOCKJOB_TYPE_COMMIT: + case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT: + case QEMU_BLOCKJOB_TYPE_COPY: + case QEMU_BLOCKJOB_TYPE_NONE: + case QEMU_BLOCKJOB_TYPE_INTERNAL: + case QEMU_BLOCKJOB_TYPE_LAST: + default: + break; + } + break; + + case QEMU_BLOCKJOB_STATE_FAILED: + case QEMU_BLOCKJOB_STATE_CANCELLED: + switch ((qemuBlockJobType) job->type) { + case QEMU_BLOCKJOB_TYPE_PULL: + case QEMU_BLOCKJOB_TYPE_COMMIT: + case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT: + case QEMU_BLOCKJOB_TYPE_COPY: + case QEMU_BLOCKJOB_TYPE_NONE: + case QEMU_BLOCKJOB_TYPE_INTERNAL: + case QEMU_BLOCKJOB_TYPE_LAST: + default: + break; + } + break; + + /* states below are impossible in this handler */ + case QEMU_BLOCKJOB_STATE_READY: + case QEMU_BLOCKJOB_STATE_NEW: + case QEMU_BLOCKJOB_STATE_RUNNING: + case QEMU_BLOCKJOB_STATE_CONCLUDED: + case QEMU_BLOCKJOB_STATE_LAST: + default: + break; + } + + qemuBlockJobEmitEvents(driver, vm, job->disk, job->type, job->newstate= ); + job->state =3D job->newstate; + job->newstate =3D -1; +} + + +static void +qemuBlockJobEventProcessConcluded(qemuBlockJobDataPtr job, + virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuDomainAsyncJob asyncJob) +{ + qemuMonitorJobInfoPtr *jobinfo =3D NULL; + size_t njobinfo =3D 0; + size_t i; + int rc =3D 0; + bool dismissed =3D false; + bool refreshed =3D false; + + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + goto cleanup; + + /* we need to fetch the error state as the event does not propagate it= */ + if (job->newstate =3D=3D QEMU_BLOCKJOB_STATE_CONCLUDED && + (rc =3D qemuMonitorGetJobInfo(qemuDomainGetMonitor(vm), &jobinfo, = &njobinfo)) =3D=3D 0) { + + for (i =3D 0; i < njobinfo; i++) { + if (STRNEQ_NULLABLE(job->name, jobinfo[i]->id)) + continue; + + if (VIR_STRDUP(job->errmsg, jobinfo[i]->error) < 0) + rc =3D -1; + + if (job->errmsg) + job->newstate =3D QEMU_BLOCKJOB_STATE_FAILED; + else + job->newstate =3D QEMU_BLOCKJOB_STATE_COMPLETED; + + refreshed =3D true; + + break; + } + + if (i =3D=3D njobinfo) { + VIR_WARN("failed to refresh job '%s'", job->name); + rc =3D -1; + } + } + + /* dismiss job in qemu */ + if (rc >=3D 0) { + if ((rc =3D qemuMonitorJobDismiss(qemuDomainGetMonitor(vm), job->n= ame)) >=3D 0) + dismissed =3D true; + } + + if (job->invalidData) { + VIR_WARN("terminating job '%s' with invalid data", job->name); + goto cleanup; + } + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + goto cleanup; + + if (refreshed) + qemuDomainSaveStatus(vm); + + VIR_DEBUG("handling job '%s' state '%d' newstate '%d'", job->name, job= ->state, job->newstate); + + qemuBlockJobEventProcessConcludedTransition(job, driver, vm, asyncJob); + + cleanup: + if (dismissed) { + qemuBlockJobUnregister(job, vm); + job =3D NULL; + qemuDomainSaveConfig(vm); + } + + for (i =3D 0; i < njobinfo; i++) + qemuMonitorJobInfoFree(jobinfo[i]); + VIR_FREE(jobinfo); +} + + +static void +qemuBlockJobEventProcess(virQEMUDriverPtr driver, + virDomainObjPtr vm, + qemuBlockJobDataPtr job, + qemuDomainAsyncJob asyncJob) + +{ + switch ((qemuBlockjobState) job->newstate) { + case QEMU_BLOCKJOB_STATE_COMPLETED: + case QEMU_BLOCKJOB_STATE_FAILED: + case QEMU_BLOCKJOB_STATE_CANCELLED: + case QEMU_BLOCKJOB_STATE_CONCLUDED: + qemuBlockJobEventProcessConcluded(job, driver, vm, asyncJob); + break; + + case QEMU_BLOCKJOB_STATE_READY: + if (job->disk && job->disk->mirror) { + job->disk->mirrorState =3D VIR_DOMAIN_BLOCK_JOB_READY; + qemuBlockJobEmitEvents(driver, vm, job->disk, job->type, job->= newstate); + } + job->state =3D job->newstate; + job->newstate =3D -1; + qemuDomainSaveStatus(vm); + break; + + case QEMU_BLOCKJOB_STATE_NEW: + case QEMU_BLOCKJOB_STATE_RUNNING: + case QEMU_BLOCKJOB_STATE_LAST: + default: + job->newstate =3D -1; + } +} + + /** * qemuBlockJobUpdate: * @vm: domain @@ -444,7 +607,10 @@ qemuBlockJobUpdate(virDomainObjPtr vm, if (job->newstate =3D=3D -1) return -1; - qemuBlockJobEventProcessLegacy(priv->driver, vm, job, asyncJob); + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) + qemuBlockJobEventProcess(priv->driver, vm, job, asyncJob); + else + qemuBlockJobEventProcessLegacy(priv->driver, vm, job, asyncJob); return job->state; } --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list