From nobody Sun Feb 8 23:06:17 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=VfUXFB2ZBauAe5kG0y+mol1tDNEZ/apaLHrWOKTzQCKmK0L7HFwmxD+Mbap65+1NhZA+ioj8dfcxu3cmeYocRLoyWFbmLerql9eMnmOL52HuUEzPaTS9OUqiM5TaKUWw/9FUMpbd2plN4auAhYaO8GICPTb7gykxDkNh+qOBoz4= 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=YpA3o97B5/1cEhAMXmo8IjG8xTj676zhQmQ1sE2An5s=; b=ROh7f435+0I8D/xmhLMIBGYd3rgjrzMHme1vkb7qSO+6qeVqG7atMvgqB/khMqNXoXdXHsjkaTTnviAQz+O9H7TVKa8SDS+1nKfBMZCOZ1ff2gzor/v/Urn4J1UDw1ZzjE4DNiJNcFFY9JkiVcCWpsmNz5iFr1gvt+a95Z1kItI= 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 1562947650588228.94007602129966; Fri, 12 Jul 2019 09:07:30 -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 F0715308C21C; 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 BD82760639; 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 74FEC206DB; 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 x6CG7QYa017417 for ; Fri, 12 Jul 2019 12:07:26 -0400 Received: by smtp.corp.redhat.com (Postfix) id 301EA60C70; Fri, 12 Jul 2019 16:07:26 +0000 (UTC) Received: from angien.brq.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id 896B660C79; Fri, 12 Jul 2019 16:07:24 +0000 (UTC) From: Peter Krempa To: libvir-list@redhat.com Date: Fri, 12 Jul 2019 18:06:00 +0200 Message-Id: <54d27e6e82c18b964b91dfdc3a4810d3e45a35ba.1562947284.git.pkrempa@redhat.com> 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 19/25] qemu: process: Refresh -blockdev based blockjobs on reconnect to qemu 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.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Fri, 12 Jul 2019 16:07:29 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Refresh the state of the jobs and process any events that might have happened while libvirt was not running. The job state processing requires some care to figure out if a job needs to be bumped. For any invalid job try doing our best to cancel it. Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/qemu/qemu_blockjob.c | 109 +++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_blockjob.h | 5 ++ src/qemu/qemu_process.c | 7 ++- 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index 8b142f1aba..360fc40e61 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -242,6 +242,115 @@ qemuBlockJobIsRunning(qemuBlockJobDataPtr job) } +/* returns 1 for a job we didn't reconnect to */ +static int +qemuBlockJobRefreshJobsFindInactive(const void *payload, + const void *name ATTRIBUTE_UNUSED, + const void *data ATTRIBUTE_UNUSED) +{ + const qemuBlockJobData *job =3D payload; + + return !job->reconnected; +} + + +int +qemuBlockJobRefreshJobs(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + qemuDomainObjPrivatePtr priv =3D vm->privateData; + qemuMonitorJobInfoPtr *jobinfo =3D NULL; + size_t njobinfo =3D 0; + qemuBlockJobDataPtr job =3D NULL; + int newstate; + size_t i; + int ret =3D -1; + int rc; + + qemuDomainObjEnterMonitor(driver, vm); + + rc =3D qemuMonitorGetJobInfo(priv->mon, &jobinfo, &njobinfo); + + if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) + goto cleanup; + + for (i =3D 0; i < njobinfo; i++) { + if (!(job =3D virHashLookup(priv->blockjobs, jobinfo[i]->id))) { + VIR_DEBUG("ignoring untracked job '%s'", jobinfo[i]->id); + continue; + } + + /* try cancelling invalid jobs - this works only if the job is not + * concluded. In such case it will fail. We'll leave such job ling= er + * in qemu and just forget about it in libvirt because there's not= much + * we coud do besides killing the VM */ + if (job->invalidData) { + qemuDomainObjEnterMonitor(driver, vm); + + rc =3D qemuMonitorJobCancel(priv->mon, job->name, true); + if (rc =3D=3D -1 && jobinfo[i]->status =3D=3D QEMU_MONITOR_JOB= _STATUS_CONCLUDED) + VIR_WARN("can't cancel job '%s' with invalid data", job->n= ame); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; + + if (rc < 0) + qemuBlockJobUnregister(job, vm); + job =3D NULL; + continue; + } + + if ((newstate =3D qemuBlockjobConvertMonitorStatus(jobinfo[i]->sta= tus)) < 0) + continue; + + if (newstate !=3D job->state) { + if ((job->state =3D=3D QEMU_BLOCKJOB_STATE_FAILED || + job->state =3D=3D QEMU_BLOCKJOB_STATE_COMPLETED)) { + /* preserve the old state but allow the job to be bumped to + * execute the finishing steps */ + job->newstate =3D job->state; + } else if (newstate =3D=3D QEMU_BLOCKJOB_STATE_CONCLUDED) { + if (VIR_STRDUP(job->errmsg, jobinfo[i]->error) < 0) + goto cleanup; + + if (job->errmsg) + job->newstate =3D QEMU_BLOCKJOB_STATE_FAILED; + else + job->newstate =3D QEMU_BLOCKJOB_STATE_COMPLETED; + } else if (newstate =3D=3D QEMU_BLOCKJOB_STATE_READY) { + /* Apply _READY state only if it was not applied before */ + if (job->state =3D=3D QEMU_BLOCKJOB_STATE_NEW || + job->state =3D=3D QEMU_BLOCKJOB_STATE_RUNNING) + job->newstate =3D newstate; + } + /* don't update the job otherwise */ + } + + job->reconnected =3D true; + + if (job->newstate !=3D -1) + qemuBlockJobUpdate(vm, job, QEMU_ASYNC_JOB_NONE); + job =3D NULL; /* job may have become invalid here */ + } + + /* remove data for job which qemu didn't report (the algorithm is + * inefficient, but the possibility of such jobs is very low */ + while ((job =3D virHashSearch(priv->blockjobs, qemuBlockJobRefreshJobs= FindInactive, NULL, NULL))) { + qemuBlockJobUnregister(job, vm); + job =3D NULL; + } + + ret =3D 0; + + cleanup: + for (i =3D 0; i < njobinfo; i++) + qemuMonitorJobInfoFree(jobinfo[i]); + VIR_FREE(jobinfo); + + return ret; +} + + /** * qemuBlockJobEmitEvents: * diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h index a558b0a5a2..2d8ecdd4c3 100644 --- a/src/qemu/qemu_blockjob.h +++ b/src/qemu/qemu_blockjob.h @@ -84,6 +84,7 @@ struct _qemuBlockJobData { int newstate; /* qemuBlockjobState, subset of events emitted by qemu */ bool invalidData; /* the job data (except name) is not valid */ + bool reconnected; /* internal field for tracking whether job is live a= fter reconnect to qemu */ }; int @@ -122,6 +123,10 @@ void qemuBlockJobStartupFinalize(virDomainObjPtr vm, qemuBlockJobDataPtr job); +int +qemuBlockJobRefreshJobs(virQEMUDriverPtr driver, + virDomainObjPtr vm); + int qemuBlockJobUpdate(virDomainObjPtr vm, qemuBlockJobDataPtr job, int asyncJob); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 416f4f5c9a..3afdaafb23 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7953,7 +7953,12 @@ static int qemuProcessRefreshBlockjobs(virQEMUDriverPtr driver, virDomainObjPtr vm) { - return qemuProcessRefreshLegacyBlockjobs(driver, vm); + qemuDomainObjPrivatePtr priv =3D vm->privateData; + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV)) + return qemuBlockJobRefreshJobs(driver, vm); + else + return qemuProcessRefreshLegacyBlockjobs(driver, vm); } --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list