From nobody Sat May 4 20:30:06 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 1503573826856104.94628118965193; Thu, 24 Aug 2017 04:23:46 -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 C364713A48; Thu, 24 Aug 2017 11:23:44 +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 933897F1AE; Thu, 24 Aug 2017 11:23:44 +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 8A9A01806106; Thu, 24 Aug 2017 11:23:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7OBNd9H010837 for ; Thu, 24 Aug 2017 07:23:39 -0400 Received: by smtp.corp.redhat.com (Postfix) id E1C827B555; Thu, 24 Aug 2017 11:23:39 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id 43BCB7B52C; Thu, 24 Aug 2017 11:23:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C364713A48 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 24 Aug 2017 13:23:27 +0200 Message-Id: <5361a8926f927b1127606783c8960c2a69511f4d.1503573079.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v3 1/6] nodedev: Introduce udevCheckMonitorFD helper function 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.29]); Thu, 24 Aug 2017 11:23:45 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" We need to perform some sanity checks on the udev monitor before every use so that we know nothing changed in the meantime. The reason for moving the code to a separate function is to be able to perform the same check from a worker thread that will replace the udevEventHandleCallback in terms of poking udev for device events. Signed-off-by: Erik Skultety --- src/node_device/node_device_udev.c | 57 ++++++++++++++++++++++++++--------= ---- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index f4177455c..465d272ba 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1615,47 +1615,68 @@ udevHandleOneDevice(struct udev_device *device) } =20 =20 -static void -udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, - int fd, - int events ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) +/* the caller must be holding the driver lock prior to calling this functi= on */ +static bool +udevCheckMonitorFD(struct udev_monitor *udev_monitor, int fd) { - struct udev_device *device =3D NULL; - struct udev_monitor *udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); - int udev_fd =3D -1; + int real_fd =3D -1; =20 - udev_fd =3D udev_monitor_get_fd(udev_monitor); - if (fd !=3D udev_fd) { + /* sanity check that the monitor socket hasn't changed */ + real_fd =3D udev_monitor_get_fd(udev_monitor); + + if (real_fd !=3D fd) { udevPrivate *priv =3D driver->privateData; =20 virReportError(VIR_ERR_INTERNAL_ERROR, _("File descriptor returned by udev %d does not " "match node device file descriptor %d"), - fd, udev_fd); + real_fd, fd); =20 - /* this is a non-recoverable error, let's remove the handle, so th= at we - * don't get in here again because of some spurious behaviour and = report - * the same error multiple times + /* this is a non-recoverable error, thus the event handle has to be + * removed, so that we don't get into the handler again because of= some + * spurious behaviour */ virEventRemoveHandle(priv->watch); priv->watch =3D -1; =20 - goto cleanup; + return false; } =20 - device =3D udev_monitor_receive_device(udev_monitor); - if (device =3D=3D NULL) { + return true; +} + + +static void +udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, + int fd, + int events ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + struct udev_device *device =3D NULL; + struct udev_monitor *udev_monitor =3D NULL; + + nodeDeviceLock(); + udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); + + if (!udevCheckMonitorFD(udev_monitor, fd)) + goto unlock; + + if (!(device =3D udev_monitor_receive_device(udev_monitor))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("udev_monitor_receive_device returned NULL")); - goto cleanup; + goto unlock; } =20 + nodeDeviceUnlock(); udevHandleOneDevice(device); =20 cleanup: udev_device_unref(device); return; + + unlock: + nodeDeviceUnlock(); + goto cleanup; } =20 =20 --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 20:30:06 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 1503573834898235.99316084081556; Thu, 24 Aug 2017 04:23:54 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 220BE7E423; Thu, 24 Aug 2017 11:23:53 +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 002BD6BF6E; Thu, 24 Aug 2017 11:23:52 +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 BCCFA3FC73; Thu, 24 Aug 2017 11:23:52 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7OBNeE9010847 for ; Thu, 24 Aug 2017 07:23:40 -0400 Received: by smtp.corp.redhat.com (Postfix) id D948E7B555; Thu, 24 Aug 2017 11:23:40 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3ADD47B55E; Thu, 24 Aug 2017 11:23:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 220BE7E423 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 24 Aug 2017 13:23:28 +0200 Message-Id: <2702d98a186c5ff9961cdf94f3fb594a42dd6d0f.1503573079.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v3 2/6] udev: Split udevEventHandleCallback in two functions 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.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 24 Aug 2017 11:23:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This patch splits udevEventHandleCallback in two (introduces udevEventHandleThread) in order to be later able to refactor the latter to actually become a detached thread which will wait some time for the kernel to create the whole sysfs tree for a device as we cannot do that in the event loop directly. Signed-off-by: Erik Skultety --- src/node_device/node_device_udev.c | 54 ++++++++++++++++++++++++++--------= ---- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index 465d272ba..fe943c78b 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1647,36 +1647,56 @@ udevCheckMonitorFD(struct udev_monitor *udev_monito= r, int fd) =20 =20 static void +udevEventHandleThread(void *opaque ATTRIBUTE_UNUSED) +{ + struct udev_device *device =3D NULL; + struct udev_monitor *udev_monitor =3D NULL; + int fd =3D (intptr_t) opaque; + + nodeDeviceLock(); + udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); + + if (!udevCheckMonitorFD(udev_monitor, fd)) + goto unlock; + + device =3D udev_monitor_receive_device(udev_monitor); + if (device =3D=3D NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("udev_monitor_receive_device returned NULL")); + goto unlock; + } + + nodeDeviceUnlock(); + udevHandleOneDevice(device); + + cleanup: + udev_device_unref(device); + return; + + unlock: + nodeDeviceUnlock(); + goto cleanup; +} + + +static void udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, int fd, int events ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { - struct udev_device *device =3D NULL; struct udev_monitor *udev_monitor =3D NULL; =20 nodeDeviceLock(); udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); =20 - if (!udevCheckMonitorFD(udev_monitor, fd)) - goto unlock; - - if (!(device =3D udev_monitor_receive_device(udev_monitor))) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("udev_monitor_receive_device returned NULL")); - goto unlock; + if (!udevCheckMonitorFD(udev_monitor, fd)) { + nodeDeviceUnlock(); + return; } - nodeDeviceUnlock(); - udevHandleOneDevice(device); - - cleanup: - udev_device_unref(device); - return; =20 - unlock: - nodeDeviceUnlock(); - goto cleanup; + udevEventHandleThread((void *)(intptr_t) fd); } =20 =20 --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 20:30:06 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 150357383799116.3555616199385; Thu, 24 Aug 2017 04:23:57 -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 0AA72C0587E9; Thu, 24 Aug 2017 11:23:56 +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 D7EBC7F1B5; Thu, 24 Aug 2017 11:23:55 +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 9CD34180610A; Thu, 24 Aug 2017 11:23:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7OBNf7G010852 for ; Thu, 24 Aug 2017 07:23:41 -0400 Received: by smtp.corp.redhat.com (Postfix) id D184A7B55C; Thu, 24 Aug 2017 11:23:41 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id 329247B52C; Thu, 24 Aug 2017 11:23:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0AA72C0587E9 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 24 Aug 2017 13:23:29 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v3 3/6] udev: Convert udevEventHandleThread to an actual thread routine 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.32]); Thu, 24 Aug 2017 11:23:56 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Adjust udevEventHandleThread to be a proper thread routine running in an infinite loop handling devices. Also introduce udevEventThreadData private structure. Every time there's and incoming event from udev, udevEventHandleCallback only increments the number of events queuing on the monitor and signals the worker thread to handle them. Signed-off-by: Erik Skultety --- src/node_device/node_device_udev.c | 132 ++++++++++++++++++++++++++++++---= ---- 1 file changed, 108 insertions(+), 24 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index fe943c78b..444e5be4d 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -59,6 +59,54 @@ struct _udevPrivate { bool privileged; }; =20 +typedef struct _udevEventThreadData udevEventThreadData; +typedef udevEventThreadData *udevEventThreadDataPtr; + +struct _udevEventThreadData { + virMutex lock; + virCond threadCond; + + bool threadQuit; + int monitor_fd; + unsigned long long nevents; /* number of udev events queuing on monito= r */ +}; + + +static udevEventThreadDataPtr +udevEventThreadDataNew(int fd) +{ + udevEventThreadDataPtr ret =3D NULL; + + if (VIR_ALLOC_QUIET(ret) < 0) + return NULL; + + if (virMutexInit(&ret->lock) < 0) + goto cleanup; + + if (virCondInit(&ret->threadCond) < 0) + goto cleanup_mutex; + + ret->monitor_fd =3D fd; + + return ret; + + cleanup_mutex: + virMutexDestroy(&ret->lock); + + cleanup: + VIR_FREE(ret); + return NULL; +} + + +static void +udevEventThreadDataFree(udevEventThreadDataPtr data) +{ + virMutexDestroy(&data->lock); + virCondDestroy(&data->threadCond); + VIR_FREE(data); +} + =20 static bool udevHasDeviceProperty(struct udev_device *dev, @@ -1647,35 +1695,53 @@ udevCheckMonitorFD(struct udev_monitor *udev_monito= r, int fd) =20 =20 static void -udevEventHandleThread(void *opaque ATTRIBUTE_UNUSED) +udevEventHandleThread(void *opaque) { + udevEventThreadDataPtr privateData =3D opaque; struct udev_device *device =3D NULL; struct udev_monitor *udev_monitor =3D NULL; - int fd =3D (intptr_t) opaque; =20 - nodeDeviceLock(); - udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); + /* continue rather than break from the loop on non-fatal errors */ + while (1) { + virMutexLock(&privateData->lock); + while (privateData->nevents =3D=3D 0 && !privateData->threadQuit) { + if (virCondWait(&privateData->threadCond, &privateData->lock))= { + virReportSystemError(errno, "%s", + _("handler failed to wait on conditio= n")); + goto cleanup; + } + } =20 - if (!udevCheckMonitorFD(udev_monitor, fd)) - goto unlock; + privateData->nevents--; + virMutexUnlock(&privateData->lock); =20 - device =3D udev_monitor_receive_device(udev_monitor); - if (device =3D=3D NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("udev_monitor_receive_device returned NULL")); - goto unlock; + nodeDeviceLock(); + udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); + + if (!udevCheckMonitorFD(udev_monitor, privateData->monitor_fd)) { + nodeDeviceUnlock(); + goto cleanup; + } + + device =3D udev_monitor_receive_device(udev_monitor); + nodeDeviceUnlock(); + + if (!device) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("udev_monitor_receive_device returned NULL")); + goto next; + } + + udevHandleOneDevice(device); + + next: + udev_device_unref(device); } =20 - nodeDeviceUnlock(); - udevHandleOneDevice(device); - cleanup: udev_device_unref(device); + udevEventThreadDataFree(privateData); return; - - unlock: - nodeDeviceUnlock(); - goto cleanup; } =20 =20 @@ -1683,20 +1749,28 @@ static void udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, int fd, int events ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) + void *opaque) { struct udev_monitor *udev_monitor =3D NULL; + udevEventThreadDataPtr threadData =3D opaque; =20 nodeDeviceLock(); udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); - if (!udevCheckMonitorFD(udev_monitor, fd)) { + virMutexLock(&threadData->lock); + threadData->threadQuit =3D true; + virCondSignal(&threadData->threadCond); + virMutexUnlock(&threadData->lock); + nodeDeviceUnlock(); return; } nodeDeviceUnlock(); =20 - udevEventHandleThread((void *)(intptr_t) fd); + virMutexLock(&threadData->lock); + threadData->nevents++; + virCondSignal(&threadData->threadCond); + virMutexUnlock(&threadData->lock); } =20 =20 @@ -1823,6 +1897,9 @@ nodeStateInitialize(bool privileged, { udevPrivate *priv =3D NULL; struct udev *udev =3D NULL; + int monitor_fd =3D -1; + virThread th; + udevEventThreadDataPtr threadData =3D NULL; =20 if (VIR_ALLOC(priv) < 0) return -1; @@ -1883,6 +1960,14 @@ nodeStateInitialize(bool privileged, 128 * 1024 * 1024); #endif =20 + monitor_fd =3D udev_monitor_get_fd(priv->udev_monitor); + if (!(threadData =3D udevEventThreadDataNew(monitor_fd)) || + virThreadCreate(&th, false, udevEventHandleThread, threadData) < 0= ) { + virReportSystemError(errno, "%s", + _("failed to create udev handling thread")); + goto cleanup; + } + /* We register the monitor with the event callback so we are * notified by udev of device changes before we enumerate existing * devices because libvirt will simply recreate the device if we @@ -1891,9 +1976,8 @@ nodeStateInitialize(bool privileged, * enumeration. The alternative is to register the callback after * we enumerate, in which case we will fail to create any devices * that appear while the enumeration is taking place. */ - priv->watch =3D virEventAddHandle(udev_monitor_get_fd(priv->udev_monit= or), - VIR_EVENT_HANDLE_READABLE, - udevEventHandleCallback, NULL, NULL); + priv->watch =3D virEventAddHandle(monitor_fd, VIR_EVENT_HANDLE_READABL= E, + udevEventHandleCallback, threadData, N= ULL); if (priv->watch =3D=3D -1) goto unlock; =20 --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 20:30:06 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 1503573835074522.2690737072953; Thu, 24 Aug 2017 04:23:55 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 274B85F7A9; Thu, 24 Aug 2017 11:23:53 +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 02E9E77D71; Thu, 24 Aug 2017 11:23:53 +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 BE2E31806107; Thu, 24 Aug 2017 11:23:52 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7OBNgnu010857 for ; Thu, 24 Aug 2017 07:23:42 -0400 Received: by smtp.corp.redhat.com (Postfix) id E709D7B55E; Thu, 24 Aug 2017 11:23:42 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A6057B52C; Thu, 24 Aug 2017 11:23:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 274B85F7A9 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 24 Aug 2017 13:23:30 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v3 4/6] nodedev: Disable/re-enable polling on the udev fd 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 24 Aug 2017 11:23:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The event loop may get scheduled earlier than the udev event handler thread which means that it would keep invoking the handler callback with "new" events, while in fact it's most likely still the same event which the handler thread hasn't managed to remove from the socket queue yet. This is due to unwanted increments of the number of events queuing on the socket and causes the handler thread to spam the logs with an error about libudev returning NULL (errno =3D=3D EAGAIN). Signed-off-by: Erik Skultety --- src/node_device/node_device_udev.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index 444e5be4d..e3a647e3d 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1697,6 +1697,7 @@ udevCheckMonitorFD(struct udev_monitor *udev_monitor,= int fd) static void udevEventHandleThread(void *opaque) { + udevPrivate *priv =3D NULL; udevEventThreadDataPtr privateData =3D opaque; struct udev_device *device =3D NULL; struct udev_monitor *udev_monitor =3D NULL; @@ -1716,6 +1717,7 @@ udevEventHandleThread(void *opaque) virMutexUnlock(&privateData->lock); =20 nodeDeviceLock(); + priv =3D driver->privateData; udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); =20 if (!udevCheckMonitorFD(udev_monitor, privateData->monitor_fd)) { @@ -1726,6 +1728,9 @@ udevEventHandleThread(void *opaque) device =3D udev_monitor_receive_device(udev_monitor); nodeDeviceUnlock(); =20 + /* Re-enable polling for new events on the @udev_monitor */ + virEventUpdateHandle(priv->watch, VIR_EVENT_HANDLE_READABLE); + if (!device) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("udev_monitor_receive_device returned NULL")); @@ -1751,10 +1756,12 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, int events ATTRIBUTE_UNUSED, void *opaque) { + udevPrivate *priv =3D NULL; struct udev_monitor *udev_monitor =3D NULL; udevEventThreadDataPtr threadData =3D opaque; =20 nodeDeviceLock(); + priv =3D driver->privateData; udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); if (!udevCheckMonitorFD(udev_monitor, fd)) { virMutexLock(&threadData->lock); @@ -1771,6 +1778,16 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, threadData->nevents++; virCondSignal(&threadData->threadCond); virMutexUnlock(&threadData->lock); + + /* Due to scheduling, the eventloop might poll the udev monitor before= the + * handler thread actually removes the data from the socket, thus caus= ing it + * to spam errors about data not being ready yet, because + * udevEventHandleCallback would be invoked multiple times incrementin= g the + * counter of events queuing for a single event. + * Therefore we need to disable polling on the fd until the thread act= ually + * removes the data from the socket. + */ + virEventUpdateHandle(priv->watch, 0); } =20 =20 --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 20:30:06 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 1503573840379112.32438229069362; Thu, 24 Aug 2017 04:24:00 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 912C1C0587C9; Thu, 24 Aug 2017 11:23:58 +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 6FE9D7D512; Thu, 24 Aug 2017 11:23:58 +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 39E14180610B; Thu, 24 Aug 2017 11:23:58 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7OBNhnZ010870 for ; Thu, 24 Aug 2017 07:23:43 -0400 Received: by smtp.corp.redhat.com (Postfix) id DF13E7B55C; Thu, 24 Aug 2017 11:23:43 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4042C7B52C; Thu, 24 Aug 2017 11:23:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 912C1C0587C9 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 24 Aug 2017 13:23:31 +0200 Message-Id: <99af32dc75bfc0891e4e06dbf9cc59f5395e4bdc.1503573079.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v3 5/6] util: Introduce virFileWaitForAccess 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.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 24 Aug 2017 11:23:59 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Since we have a number of places where we workaround timing issues with devices, attributes (files in general) not being available at the time of processing them by calling usleep in a loop for a fixed number of tries, we could as well have a utility function that would do that. Therefore we won't have to duplicate this ugly workaround even more. Signed-off-by: Erik Skultety --- src/libvirt_private.syms | 1 + src/util/virfile.c | 29 +++++++++++++++++++++++++++++ src/util/virfile.h | 2 ++ 3 files changed, 32 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2149b11b7..b9fb54a79 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1724,6 +1724,7 @@ virFileStripSuffix; virFileTouch; virFileUnlock; virFileUpdatePerm; +virFileWaitForAccess; virFileWrapperFdClose; virFileWrapperFdFree; virFileWrapperFdNew; diff --git a/src/util/virfile.c b/src/util/virfile.c index 2f28e83f4..15b46bcdd 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -4166,3 +4166,32 @@ virFileReadValueString(char **value, const char *for= mat, ...) VIR_FREE(str); return ret; } + + +/** + * virFileWaitForAccess: + * @path: absolute path to a sysfs attribute (can be a symlink) + * @ms: how long to wait (in milliseconds) + * @tries: how many times should we try to wait for @path to become access= ible + * + * Checks the existence of @path. In case the file defined by @path + * doesn't exist, we wait for it to appear in @ms milliseconds (for up to + * @tries attempts). + * + * Returns 0 on success, -1 on error, setting errno appropriately. + */ +int +virFileWaitForAccess(const char *path, size_t ms, size_t tries) +{ + errno =3D 0; + + /* wait for @path to be accessible in @ms milliseconds, up to @tries */ + while (tries-- > 0 && !virFileExists(path)) { + if (tries =3D=3D 0 || errno !=3D ENOENT) + return -1; + + usleep(ms * 1000); + } + + return 0; +} diff --git a/src/util/virfile.h b/src/util/virfile.h index 57ceb8072..42630ebb5 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -347,6 +347,8 @@ int virFileReadValueScaledInt(unsigned long long *value= , const char *format, ... int virFileReadValueString(char **value, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); =20 +int virFileWaitForAccess(const char *path, size_t ms, size_t tries); + =20 int virFileInData(int fd, int *inData, --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 20:30:06 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 1503573838310418.8251951960416; Thu, 24 Aug 2017 04:23:58 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1A756883AC; Thu, 24 Aug 2017 11:23:56 +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 EE2817B5ED; Thu, 24 Aug 2017 11:23:55 +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 B29753FC74; Thu, 24 Aug 2017 11:23:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7OBNi6B010882 for ; Thu, 24 Aug 2017 07:23:44 -0400 Received: by smtp.corp.redhat.com (Postfix) id D641F7B5EA; Thu, 24 Aug 2017 11:23:44 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id 374667B555; Thu, 24 Aug 2017 11:23:44 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 1A756883AC Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 24 Aug 2017 13:23:32 +0200 Message-Id: <90fb72f8fa16f031693d6463b8554252a5d43a0c.1503573079.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v3 6/6] nodedev: Work around the uevent race by hooking up virFileWaitForAccess 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 24 Aug 2017 11:23:56 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" If we find ourselves in the situation that the 'add' uevent has been fired earlier than the sysfs tree for a device was created, we should use the best-effort approach and give kernel some predetermined amount of time, thus waiting for the attributes to be ready rather than discarding the device from our device list forever. If those don't appear in the given time frame, we need to move on, since libvirt can't wait indefinitely. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=3D1463285 Signed-off-by: Erik Skultety --- src/node_device/node_device_udev.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index e3a647e3d..96a87f4ab 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1166,9 +1166,23 @@ udevProcessMediatedDevice(struct udev_device *dev, char *canonicalpath =3D NULL; virNodeDevCapMdevPtr data =3D &def->caps->data.mdev; =20 - if (virAsprintf(&linkpath, "%s/mdev_type", udev_device_get_syspath(dev= )) < 0) + /* Because of a kernel uevent race, we might get the 'add' event prior= to + * the sysfs tree being ready, so any attempt to access any sysfs attr= ibute + * would result in ENOENT and us dropping the device, so let's work ar= ound + * it by waiting for the attributes to become available. + */ + + if (virAsprintf(&linkpath, "%s/mdev_type", + udev_device_get_syspath(dev)) < 0) goto cleanup; =20 + if (virFileWaitForAccess(linkpath, 1, 100) < 0) { + virReportSystemError(errno, + _("failed to wait for file '%s' to appear"), + linkpath); + goto cleanup; + } + if (virFileResolveLink(linkpath, &canonicalpath) < 0) { virReportSystemError(errno, _("failed to resolve '%s'"), linkpath); goto cleanup; --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list