From nobody Thu May 2 14:04:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) client-ip=209.132.183.25; envelope-from=libvir-list-bounces@redhat.com; helo=mx4-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by mx.zohomail.com with SMTPS id 1488963082989449.1918634149357; Wed, 8 Mar 2017 00:51:22 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v288ldfr007840; Wed, 8 Mar 2017 03:47:40 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v288lcgI024125 for ; Wed, 8 Mar 2017 03:47:38 -0500 Received: from mx1.redhat.com (ext-mx03.extmail.prod.ext.phx2.redhat.com [10.5.110.27]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v288lcRk025786 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 8 Mar 2017 03:47:38 -0500 Received: from dggrg02-dlp.huawei.com (unknown [45.249.212.188]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D864980F8E; Wed, 8 Mar 2017 08:47:31 +0000 (UTC) Received: from 172.30.72.57 (EHLO DGGEML403-HUB.china.huawei.com) ([172.30.72.57]) by dggrg02-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AJO98472; Wed, 08 Mar 2017 14:40:41 +0800 (CST) Received: from localhost (10.177.25.200) by DGGEML403-HUB.china.huawei.com (10.3.17.33) with Microsoft SMTP Server id 14.3.301.0; Wed, 8 Mar 2017 14:40:33 +0800 From: "xinhua.Cao" To: , Date: Wed, 8 Mar 2017 14:39:46 +0800 Message-ID: <20170308063946.24264-1-caoxinhua@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.25.200] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020203.58BFA769.00E7, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: e339011a24e8ac8431ed7ed4ebf1c099 X-Greylist: Delayed for 02:06:46 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 08 Mar 2017 08:47:36 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 08 Mar 2017 08:47:36 +0000 (UTC) for IP:'45.249.212.188' DOMAIN:'[45.249.212.188]' HELO:'dggrg02-dlp.huawei.com' FROM:'caoxinhua@huawei.com' RCPT:'' X-RedHat-Spam-Score: 1.592 * (BAYES_50, RDNS_NONE, SPF_PASS) 45.249.212.188 [45.249.212.188] 45.249.212.188 [45.249.212.188] X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Scanned-By: MIMEDefang 2.78 on 10.5.110.27 X-loop: libvir-list@redhat.com Cc: weidong.huang@huawei.com, weifuqiang@huawei.com, oscar.zhangbo@huawei.com, yanqiangjun@huawei.com, king.wang@huawei.com, "xinhua.Cao" Subject: [libvirt] [PATCH] [Changelog]:If there is a process with a client which registers event callbacks, and it calls libvirt's API which uses the same virConnectPtr in that callback function. When this process exit abnormally lead to client disconnect, there is a possibility that the libvirtd's main thread is use virServerClient to send event just after the virServerClient been freed by job thread. Following is backtrace: 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-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" #0 0x00007fda223d66d8 in virClassIsDerivedFrom (klass=3D0xdeadbeef, pa= rent=3D0x7fda24c81b40) at util/virobject.c:169 #1 0x00007fda223d6a1e in virObjectIsClass (anyobj=3Danyobj@entry=3D0x7= fd9e575b400, klass=3D) at util/virobject.c:365 #2 0x00007fda223d6a44 in virObjectLock (anyobj=3D0x7fd9e575b400) at ut= il/virobject.c:317 #3 0x00007fda22507f71 in virNetServerClientSendMessage (client=3Dclien= t@entry=3D0x7fd9e575b400, msg=3Dmsg@entry=3D0x7fd9ec30de90) at rpc/virnetserverclient.c:1422 #4 0x00007fda230d714d in remoteDispatchObjectEventSend (client=3D0x7fd= 9e575b400, program=3D0x7fda24c844e0, procnr=3D348, proc=3D0x7fda2310e5e0 , d= ata=3D0x7ffc3857fdb0) at remote.c:3803 #5 0x00007fda230dd71b in remoteRelayDomainEventTunable (conn=3D, dom=3D0x7fda27cd7660, params=3D0x7fda27f3aae0, nparams=3D1,opaque= =3D0x7fd9e6c99e00) at remote.c:1033 #6 0x00007fda224484cb in virDomainEventDispatchDefaultFunc (conn=3D0x7= fda27cd0120, event=3D0x7fda2736ea00, cb=3D0x7fda230dd610 , cbopaque=3D0x7fd9e= 6c99e00) at conf/domain_event.c:1910 #7 0x00007fda22446871 in virObjectEventStateDispatchCallbacks (callbac= ks=3D, callbacks=3D, event=3D0x7fda2736ea00,s= tate=3D0x7fda24ca3960) at conf/object_event.c:722 #8 virObjectEventStateQueueDispatch (callbacks=3D0x7fda24c65800, queue= =3D0x7ffc3857fe90, state=3D0x7fda24ca3960) at conf/object_event.c:736 #9 virObjectEventStateFlush (state=3D0x7fda24ca3960) at conf/object_ev= ent.c:814 #10 virObjectEventTimer (timer=3D, opaque=3D0x7fda24ca39= 60) at conf/object_event.c:560 #11 0x00007fda223ae8b9 in virEventPollDispatchTimeouts () at util/virev= entpoll.c:458 #12 virEventPollRunOnce () at util/vireventpoll.c:654 #13 0x00007fda223ad1d2 in virEventRunDefaultImpl () at util/virevent.c:= 314 #14 0x00007fda225046cd in virNetDaemonRun (dmn=3D0x7fda24c775c0) at rpc= /virnetdaemon.c:818 #15 0x00007fda230d6351 in main (argc=3D, argv=3D) at libvirtd.c:1623 Let's clean all event callback when client close. Signed-off-by: xinhua.Cao this patch resolved the bug which reported by Wang King. and the prior = patch link is http://www.redhat.com/archives/libvir-list/2017-February/msg= 00452.html --- daemon/remote.c | 60 +++++++++++++++++++++++++++--------------------------= ---- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 4aa43c223..22330307f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -100,6 +100,7 @@ static void make_nonnull_node_device(remote_nonnull_nod= e_device *dev_dst, virNod static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecr= etPtr secret_src); static void make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWF= ilterPtr nwfilter_src); static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *s= napshot_dst, virDomainSnapshotPtr snapshot_src); +static void remoteClientCleanEventCallbacks(struct daemonClientPrivate *pr= iv); =20 static int remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, @@ -1389,24 +1390,15 @@ void remoteRelayConnectionClosedEvent(virConnectPtr= conn ATTRIBUTE_UNUSED, int r &msg); } =20 -/* - * You must hold lock for at least the client - * We don't free stuff here, merely disconnect the client's - * network socket & resources. - * We keep the libvirt connection open until any async - * jobs have finished, then clean it up elsewhere - */ -void remoteClientFreeFunc(void *data) +static void remoteClientCleanEventCallbacks(struct daemonClientPrivate *pr= iv) { - struct daemonClientPrivate *priv =3D data; - /* Deregister event delivery callback */ - if (priv->conn) { - virIdentityPtr sysident =3D virIdentityGetSystem(); + if (priv && priv->conn) { size_t i; - + virIdentityPtr sysident =3D virIdentityGetSystem(); virIdentitySetCurrent(sysident); =20 + virMutexLock(&priv->lock); for (i =3D 0; i < priv->ndomainEventCallbacks; i++) { int callbackID =3D priv->domainEventCallbacks[i]->callbackID; if (callbackID < 0) { @@ -1420,6 +1412,7 @@ void remoteClientFreeFunc(void *data) VIR_WARN("unexpected domain event deregister failure"); } VIR_FREE(priv->domainEventCallbacks); + priv->ndomainEventCallbacks =3D 0; =20 for (i =3D 0; i < priv->nnetworkEventCallbacks; i++) { int callbackID =3D priv->networkEventCallbacks[i]->callbackID; @@ -1435,21 +1428,7 @@ void remoteClientFreeFunc(void *data) VIR_WARN("unexpected network event deregister failure"); } VIR_FREE(priv->networkEventCallbacks); - - for (i =3D 0; i < priv->nstorageEventCallbacks; i++) { - int callbackID =3D priv->storageEventCallbacks[i]->callbackID; - if (callbackID < 0) { - VIR_WARN("unexpected incomplete storage pool callback %zu"= , i); - continue; - } - VIR_DEBUG("Deregistering remote storage pool event relay %d", - callbackID); - priv->storageEventCallbacks[i]->callbackID =3D -1; - if (virConnectStoragePoolEventDeregisterAny(priv->conn, - callbackID) < 0) - VIR_WARN("unexpected storage pool event deregister failure= "); - } - VIR_FREE(priv->storageEventCallbacks); + priv->nnetworkEventCallbacks =3D 0; =20 for (i =3D 0; i < priv->nqemuEventCallbacks; i++) { int callbackID =3D priv->qemuEventCallbacks[i]->callbackID; @@ -1465,28 +1444,45 @@ void remoteClientFreeFunc(void *data) VIR_WARN("unexpected qemu monitor event deregister failure= "); } VIR_FREE(priv->qemuEventCallbacks); + priv->nqemuEventCallbacks =3D 0; =20 if (priv->closeRegistered) { if (virConnectUnregisterCloseCallback(priv->conn, remoteRelayConnectionClo= sedEvent) < 0) VIR_WARN("unexpected close callback event deregister failu= re"); } - - virConnectClose(priv->conn); - + virMutexUnlock(&priv->lock); virIdentitySetCurrent(NULL); virObjectUnref(sysident); } +} + + +/* + * You must hold lock for at least the client + * We don't free stuff here, merely disconnect the client's + * network socket & resources. + * We keep the libvirt connection open until any async + * jobs have finished, then clean it up elsewhere + */ +void remoteClientFreeFunc(void *data) +{ + struct daemonClientPrivate *priv =3D data; + if (!priv || !priv->conn) + return; + + remoteClientCleanEventCallbacks(priv); + virConnectClose(priv->conn); =20 VIR_FREE(priv); } =20 - static void remoteClientCloseFunc(virNetServerClientPtr client) { struct daemonClientPrivate *priv =3D virNetServerClientGetPrivateData(= client); =20 daemonRemoveAllClientStreams(priv->streams); + remoteClientCleanEventCallbacks(priv); } =20 =20 --=20 2.12.0.windows.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list