From nobody Sun May 5 12:28:15 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 1507735320838643.6742078137365; Wed, 11 Oct 2017 08:22:00 -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 388904ACA4; Wed, 11 Oct 2017 15:21:59 +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 41A26179C7; Wed, 11 Oct 2017 15:21: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 2DC884EE50; Wed, 11 Oct 2017 15:21:56 +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 v9BEqqLI009372 for ; Wed, 11 Oct 2017 10:52:52 -0400 Received: by smtp.corp.redhat.com (Postfix) id 556EE6EE28; Wed, 11 Oct 2017 14:52:52 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 995C26957E; Wed, 11 Oct 2017 14:52:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 388904ACA4 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Wed, 11 Oct 2017 16:52:36 +0200 Message-Id: <316414a2c1652129be94df9f56ddd26ffa6ff6f8.1507732721.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v5 1/6] nodedev: Introduce udevEventMonitorSanityCheck 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.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 11 Oct 2017 15:22:00 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" We need to perform a sanity check on the udev monitor before every use so that we know nothing has changed in the meantime. The reason for moving the code to a separate helper is to enhance readability and shift the focus on the important stuff within the udevEventHandleCallback handler. Signed-off-by: Erik Skultety Reviewed-by: John Ferlan --- src/node_device/node_device_udev.c | 43 ++++++++++++++++++++++++----------= ---- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index f4177455c..a9a4c9b6b 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1615,24 +1615,20 @@ udevHandleOneDevice(struct udev_device *device) } =20 =20 -static void -udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, - int fd, - int events ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) +static bool +udevEventMonitorSanityCheck(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 rc =3D -1; =20 - udev_fd =3D udev_monitor_get_fd(udev_monitor); - if (fd !=3D udev_fd) { + rc =3D udev_monitor_get_fd(udev_monitor); + if (fd !=3D rc) { 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); + fd, rc); =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 @@ -1641,21 +1637,36 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, virEventRemoveHandle(priv->watch); priv->watch =3D -1; =20 - goto cleanup; + return false; } =20 + 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; + + udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); + + if (!udevEventMonitorSanityCheck(udev_monitor, fd)) + return; + 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 cleanup; + return; } =20 udevHandleOneDevice(device); - - cleanup: udev_device_unref(device); - return; } =20 =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 12:28:15 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 15077353529761006.3296237637982; Wed, 11 Oct 2017 08:22:32 -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 D726080E7A; Wed, 11 Oct 2017 15:22:31 +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 AFF9363BB7; Wed, 11 Oct 2017 15:22:31 +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 6E5E14ED22; Wed, 11 Oct 2017 15:22:31 +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 v9BEquEg009383 for ; Wed, 11 Oct 2017 10:52:56 -0400 Received: by smtp.corp.redhat.com (Postfix) id 6D4AB6E717; Wed, 11 Oct 2017 14:52:56 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id BF8CD6EE2A; Wed, 11 Oct 2017 14:52:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D726080E7A Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: Erik Skultety To: libvir-list@redhat.com Date: Wed, 11 Oct 2017 16:52:37 +0200 Message-Id: <71ea6c95a4978666015802fd3bbd3fc1cc06bea7.1507732721.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v5 2/6] nodedev: udev: Convert udev private data to a lockable object 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.25]); Wed, 11 Oct 2017 15:22:32 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Since there's going to be a worker thread which needs to have some data protected by a lock, the whole code would just simply get unnecessary complex, since two sets of locks would be necessary, driver lock (for udev monitor and event handle) and a mutex protecting thread-local data. Given the future thread will need to access the udev monitor socket as well, why not protect everything with a single lock, even better, by converting the driver's private data to a lockable object, we get the automatic object disposal feature for free. Signed-off-by: Erik Skultety Reviewed-by: John Ferlan --- src/node_device/node_device_udev.c | 140 ++++++++++++++++++++++++---------= ---- src/node_device/node_device_udev.h | 3 - 2 files changed, 93 insertions(+), 50 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index a9a4c9b6b..bb9787fdb 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -53,12 +53,78 @@ VIR_LOG_INIT("node_device.node_device_udev"); # define TYPE_RAID 12 #endif =20 -struct _udevPrivate { +typedef struct _udevEventData udevEventData; +typedef udevEventData *udevEventDataPtr; + +struct _udevEventData { + virObjectLockable parent; + struct udev_monitor *udev_monitor; int watch; bool privileged; }; =20 +static virClassPtr udevEventDataClass; + +static void +udevEventDataDispose(void *obj) +{ + struct udev *udev =3D NULL; + udevEventDataPtr data =3D obj; + + if (data->watch !=3D -1) + virEventRemoveHandle(data->watch); + + if (data->udev_monitor) + udev =3D udev_monitor_get_udev(data->udev_monitor); + + udev_unref(udev); + udev_monitor_unref(data->udev_monitor); +} + + +static int +udevEventDataOnceInit(void) +{ + if (!(udevEventDataClass =3D virClassNew(virClassForObjectLockable(), + "udevEventData", + sizeof(udevEventData), + udevEventDataDispose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(udevEventData) + +static udevEventDataPtr +udevEventDataNew(void) +{ + udevEventDataPtr ret =3D NULL; + + if (udevEventDataInitialize() < 0) + return NULL; + + if (!(ret =3D virObjectLockableNew(udevEventDataClass))) + return NULL; + + ret->watch =3D -1; + return ret; +} + + +static bool +udevEventDataIsPrivileged(udevEventDataPtr data) +{ + bool privileged; + + virObjectLock(data); + privileged =3D data->privileged; + virObjectUnlock(data); + + return privileged; +} + =20 static bool udevHasDeviceProperty(struct udev_device *dev, @@ -447,7 +513,7 @@ udevProcessPCI(struct udev_device *device, virNodeDevCapPCIDevPtr pci_dev =3D &def->caps->data.pci_dev; virPCIEDeviceInfoPtr pci_express =3D NULL; virPCIDevicePtr pciDev =3D NULL; - udevPrivate *priv =3D driver->privateData; + udevEventDataPtr priv =3D driver->privateData; int ret =3D -1; char *p; =20 @@ -498,7 +564,7 @@ udevProcessPCI(struct udev_device *device, goto cleanup; =20 /* We need to be root to read PCI device configs */ - if (priv->privileged) { + if (udevEventDataIsPrivileged(priv)) { if (virPCIGetHeaderType(pciDev, &pci_dev->hdrType) < 0) goto cleanup; =20 @@ -1559,39 +1625,18 @@ udevPCITranslateDeinit(void) static int nodeStateCleanup(void) { - udevPrivate *priv =3D NULL; - struct udev_monitor *udev_monitor =3D NULL; - struct udev *udev =3D NULL; - if (!driver) return -1; =20 nodeDeviceLock(); =20 + virObjectUnref(driver->privateData); virObjectUnref(driver->nodeDeviceEventState); =20 - priv =3D driver->privateData; - - if (priv) { - if (priv->watch !=3D -1) - virEventRemoveHandle(priv->watch); - - udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); - - if (udev_monitor !=3D NULL) { - udev =3D udev_monitor_get_udev(udev_monitor); - udev_monitor_unref(udev_monitor); - } - } - - if (udev !=3D NULL) - udev_unref(udev); - virNodeDeviceObjListFree(driver->devs); nodeDeviceUnlock(); virMutexDestroy(&driver->lock); VIR_FREE(driver); - VIR_FREE(priv); =20 udevPCITranslateDeinit(); return 0; @@ -1615,16 +1660,17 @@ udevHandleOneDevice(struct udev_device *device) } =20 =20 +/* the caller must be holding the udevEventData object lock prior to calli= ng + * this function + */ static bool -udevEventMonitorSanityCheck(struct udev_monitor *udev_monitor, +udevEventMonitorSanityCheck(udevEventDataPtr priv, int fd) { int rc =3D -1; =20 - rc =3D udev_monitor_get_fd(udev_monitor); + rc =3D udev_monitor_get_fd(priv->udev_monitor); if (fd !=3D rc) { - udevPrivate *priv =3D driver->privateData; - virReportError(VIR_ERR_INTERNAL_ERROR, _("File descriptor returned by udev %d does not " "match node device file descriptor %d"), @@ -1650,15 +1696,19 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, int events ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { + udevEventDataPtr priv =3D driver->privateData; struct udev_device *device =3D NULL; - struct udev_monitor *udev_monitor =3D NULL; =20 - udev_monitor =3D DRV_STATE_UDEV_MONITOR(driver); + virObjectLock(priv); =20 - if (!udevEventMonitorSanityCheck(udev_monitor, fd)) + if (!udevEventMonitorSanityCheck(priv, fd)) { + virObjectUnlock(priv); return; + } + + device =3D udev_monitor_receive_device(priv->udev_monitor); + virObjectUnlock(priv); =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")); @@ -1675,12 +1725,13 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, static void udevGetDMIData(virNodeDevCapSystemPtr syscap) { + udevEventDataPtr priv =3D driver->privateData; struct udev *udev =3D NULL; struct udev_device *device =3D NULL; virNodeDevCapSystemHardwarePtr hardware =3D &syscap->hardware; virNodeDevCapSystemFirmwarePtr firmware =3D &syscap->firmware; =20 - udev =3D udev_monitor_get_udev(DRV_STATE_UDEV_MONITOR(driver)); + udev =3D udev_monitor_get_udev(priv->udev_monitor); =20 device =3D udev_device_new_from_syspath(udev, DMI_DEVPATH); if (device =3D=3D NULL) { @@ -1791,15 +1842,9 @@ nodeStateInitialize(bool privileged, virStateInhibitCallback callback ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED) { - udevPrivate *priv =3D NULL; + udevEventDataPtr priv =3D NULL; struct udev *udev =3D NULL; =20 - if (VIR_ALLOC(priv) < 0) - return -1; - - priv->watch =3D -1; - priv->privileged =3D privileged; - if (VIR_ALLOC(driver) < 0) { VIR_FREE(priv); return -1; @@ -1813,12 +1858,13 @@ nodeStateInitialize(bool privileged, return -1; } =20 + nodeDeviceLock(); + + if (!(driver->devs =3D virNodeDeviceObjListNew()) || + !(priv =3D udevEventDataNew())) + goto unlock; + driver->privateData =3D priv; - nodeDeviceLock(); - - if (!(driver->devs =3D virNodeDeviceObjListNew())) - goto unlock; - driver->nodeDeviceEventState =3D virObjectEventStateNew(); =20 if (udevPCITranslateInit(privileged) < 0) @@ -1836,7 +1882,7 @@ nodeStateInitialize(bool privileged, #endif =20 priv->udev_monitor =3D udev_monitor_new_from_netlink(udev, "udev"); - if (priv->udev_monitor =3D=3D NULL) { + if (!priv->udev_monitor) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("udev_monitor_new_from_netlink returned NULL")); goto unlock; diff --git a/src/node_device/node_device_udev.h b/src/node_device/node_devi= ce_udev.h index 9a07ab77e..f15e5204c 100644 --- a/src/node_device/node_device_udev.h +++ b/src/node_device/node_device_udev.h @@ -23,9 +23,6 @@ #include #include =20 -typedef struct _udevPrivate udevPrivate; - #define SYSFS_DATA_SIZE 4096 -#define DRV_STATE_UDEV_MONITOR(ds) (((udevPrivate *)((ds)->privateData))->= udev_monitor) #define DMI_DEVPATH "/sys/devices/virtual/dmi/id" #define DMI_DEVPATH_FALLBACK "/sys/class/dmi/id" --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 12:28:15 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 1507734336652442.8060588356451; Wed, 11 Oct 2017 08:05:36 -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 5C093C004769; Wed, 11 Oct 2017 15:05:35 +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 E9DDA66D31; Wed, 11 Oct 2017 15:05:34 +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 6B5FE18355DC; Wed, 11 Oct 2017 15:05:34 +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 v9BEqvva009388 for ; Wed, 11 Oct 2017 10:52:57 -0400 Received: by smtp.corp.redhat.com (Postfix) id 749686957C; Wed, 11 Oct 2017 14:52:57 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id C66416EE2B; Wed, 11 Oct 2017 14:52:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 5C093C004769 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: Wed, 11 Oct 2017 16:52:38 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v5 3/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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 11 Oct 2017 15:05:35 +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 normal 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 Reviewed-by: John Ferlan --- src/node_device/node_device_udev.c | 41 +++++++++++++++++++++++++++-------= ---- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index bb9787fdb..f7646cd8a 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1691,32 +1691,49 @@ udevEventMonitorSanityCheck(udevEventDataPtr priv, =20 =20 static void +udevEventHandleThread(void *opaque) +{ + udevEventDataPtr priv =3D driver->privateData; + int fd =3D (intptr_t) opaque; + struct udev_device *device =3D NULL; + + virObjectLock(priv); + + if (!udevEventMonitorSanityCheck(priv, fd)) { + virObjectUnlock(priv); + return; + } + + device =3D udev_monitor_receive_device(priv->udev_monitor); + virObjectUnlock(priv); + + if (device =3D=3D NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("udev_monitor_receive_device returned NULL")); + return; + } + + udevHandleOneDevice(device); + udev_device_unref(device); +} + + +static void udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, int fd, int events ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) { udevEventDataPtr priv =3D driver->privateData; - struct udev_device *device =3D NULL; =20 virObjectLock(priv); - if (!udevEventMonitorSanityCheck(priv, fd)) { virObjectUnlock(priv); return; } - - device =3D udev_monitor_receive_device(priv->udev_monitor); virObjectUnlock(priv); =20 - if (device =3D=3D NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("udev_monitor_receive_device returned NULL")); - return; - } - - udevHandleOneDevice(device); - udev_device_unref(device); + udevEventHandleThread((void *)(intptr_t) fd); } =20 =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 12:28:15 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 1507734357019840.6497379039617; Wed, 11 Oct 2017 08:05:57 -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 8208F7C850; Wed, 11 Oct 2017 15:05:55 +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 4786368D51; Wed, 11 Oct 2017 15:05: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 0678C18355DF; Wed, 11 Oct 2017 15:05:55 +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 v9BEqweh009404 for ; Wed, 11 Oct 2017 10:52:59 -0400 Received: by smtp.corp.redhat.com (Postfix) id EECEA6EE27; Wed, 11 Oct 2017 14:52:58 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4C3016957D; Wed, 11 Oct 2017 14:52:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8208F7C850 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: Wed, 11 Oct 2017 16:52:39 +0200 Message-Id: <0ff65155358dedcd3a1adc5bba0ffbcac992a025.1507732721.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v5 4/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.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 11 Oct 2017 15:05: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. The handler thread pulls all available data from the udev monitor and only then waits until a wakeup signal for new incoming data has been emitted by udevEventHandleCallback. Signed-off-by: Erik Skultety Reviewed-by: John Ferlan --- src/node_device/node_device_udev.c | 125 +++++++++++++++++++++++++++------= ---- 1 file changed, 93 insertions(+), 32 deletions(-) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index f7646cd8a..a6d7e6d70 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -62,6 +62,12 @@ struct _udevEventData { struct udev_monitor *udev_monitor; int watch; bool privileged; + + /* Thread data */ + virThread th; + virCond threadCond; + bool threadQuit; + bool dataReady; }; =20 static virClassPtr udevEventDataClass; @@ -80,6 +86,8 @@ udevEventDataDispose(void *obj) =20 udev_unref(udev); udev_monitor_unref(data->udev_monitor); + + virCondDestroy(&data->threadCond); } =20 =20 @@ -108,9 +116,15 @@ udevEventDataNew(void) if (!(ret =3D virObjectLockableNew(udevEventDataClass))) return NULL; =20 + if (virCondInit(&ret->threadCond) < 0) { + virObjectUnref(ret); + return NULL; + } + ret->watch =3D -1; return ret; -} +}; + =20 =20 static bool @@ -1625,15 +1639,25 @@ udevPCITranslateDeinit(void) static int nodeStateCleanup(void) { + udevEventDataPtr priv =3D NULL; + if (!driver) return -1; =20 + priv =3D driver->privateData; + nodeDeviceLock(); =20 - virObjectUnref(driver->privateData); + virObjectLock(priv); + priv->threadQuit =3D true; + virCondSignal(&priv->threadCond); + virObjectUnlock(priv); + virThreadJoin(&priv->th); + + virObjectUnref(priv); virObjectUnref(driver->nodeDeviceEventState); - virNodeDeviceObjListFree(driver->devs); + nodeDeviceUnlock(); virMutexDestroy(&driver->lock); VIR_FREE(driver); @@ -1691,30 +1715,60 @@ udevEventMonitorSanityCheck(udevEventDataPtr priv, =20 =20 static void -udevEventHandleThread(void *opaque) +udevEventHandleThread(void *opaque ATTRIBUTE_UNUSED) { udevEventDataPtr priv =3D driver->privateData; - int fd =3D (intptr_t) opaque; struct udev_device *device =3D NULL; =20 - virObjectLock(priv); + /* continue rather than break from the loop on non-fatal errors */ + while (1) { + virObjectLock(priv); + while (!priv->dataReady && !priv->threadQuit) { + if (virCondWait(&priv->threadCond, &priv->parent.lock)) { + virReportSystemError(errno, "%s", + _("handler failed to wait on conditio= n")); + virObjectUnlock(priv); + return; + } + } =20 - if (!udevEventMonitorSanityCheck(priv, fd)) { + if (priv->threadQuit) { + virObjectUnlock(priv); + return; + } + + errno =3D 0; + device =3D udev_monitor_receive_device(priv->udev_monitor); virObjectUnlock(priv); - return; - } =20 - device =3D udev_monitor_receive_device(priv->udev_monitor); - virObjectUnlock(priv); + if (!device) { + if (errno =3D=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("udev_monitor_receive_device failed")); + return; + } =20 - if (device =3D=3D NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("udev_monitor_receive_device returned NULL")); - return; - } + /* POSIX allows both EAGAIN and EWOULDBLOCK to be used + * interchangeably when the read would block or timeout was fi= red + */ + VIR_WARNINGS_NO_WLOGICALOP_EQUAL_EXPR + if (errno !=3D EAGAIN && errno !=3D EWOULDBLOCK) { + VIR_WARNINGS_RESET + virReportSystemError(errno, "%s", + _("udev_monitor_receive_device failed= ")); + return; + } + + virObjectLock(priv); + priv->dataReady =3D false; + virObjectUnlock(priv); =20 - udevHandleOneDevice(device); - udev_device_unref(device); + continue; + } + + udevHandleOneDevice(device); + udev_device_unref(device); + } } =20 =20 @@ -1722,18 +1776,19 @@ static void udevEventHandleCallback(int watch ATTRIBUTE_UNUSED, int fd, int events ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) + void *opaque ATTRIBUTE_UNUSED) { udevEventDataPtr priv =3D driver->privateData; =20 virObjectLock(priv); - if (!udevEventMonitorSanityCheck(priv, fd)) { - virObjectUnlock(priv); - return; - } + + if (!udevEventMonitorSanityCheck(priv, fd)) + priv->threadQuit =3D true; + else + priv->dataReady =3D true; + + virCondSignal(&priv->threadCond); virObjectUnlock(priv); - - udevEventHandleThread((void *)(intptr_t) fd); } =20 =20 @@ -1875,29 +1930,29 @@ nodeStateInitialize(bool privileged, return -1; } =20 - nodeDeviceLock(); - if (!(driver->devs =3D virNodeDeviceObjListNew()) || !(priv =3D udevEventDataNew())) - goto unlock; + goto cleanup; =20 driver->privateData =3D priv; driver->nodeDeviceEventState =3D virObjectEventStateNew(); =20 if (udevPCITranslateInit(privileged) < 0) - goto unlock; + goto cleanup; =20 udev =3D udev_new(); if (!udev) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to create udev context")); - goto unlock; + goto cleanup; } #if HAVE_UDEV_LOGGING /* cast to get rid of missing-format-attribute warning */ udev_set_log_fn(udev, (udevLogFunctionPtr) udevLogFunction); #endif =20 + virObjectLock(priv); + priv->udev_monitor =3D udev_monitor_new_from_netlink(udev, "udev"); if (!priv->udev_monitor) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1916,6 +1971,12 @@ nodeStateInitialize(bool privileged, 128 * 1024 * 1024); #endif =20 + if (virThreadCreate(&priv->th, true, udevEventHandleThread, NULL) < 0)= { + virReportSystemError(errno, "%s", + _("failed to create udev handler thread")); + goto unlock; + } + /* 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 @@ -1934,7 +1995,7 @@ nodeStateInitialize(bool privileged, if (udevSetupSystemDev() !=3D 0) goto unlock; =20 - nodeDeviceUnlock(); + virObjectUnlock(priv); =20 /* Populate with known devices */ if (udevEnumerateDevices(udev) !=3D 0) @@ -1947,7 +2008,7 @@ nodeStateInitialize(bool privileged, return -1; =20 unlock: - nodeDeviceUnlock(); + virObjectUnlock(priv); goto cleanup; } =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 12:28:15 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 1507734379249384.27661480466634; Wed, 11 Oct 2017 08:06:19 -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 11E55C0587ED; Wed, 11 Oct 2017 15:06:18 +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 DA9D46C415; Wed, 11 Oct 2017 15:06:17 +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 A2AB2410B5; Wed, 11 Oct 2017 15:06:17 +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 v9BEr0lp009412 for ; Wed, 11 Oct 2017 10:53:00 -0400 Received: by smtp.corp.redhat.com (Postfix) id 2D8F56957D; Wed, 11 Oct 2017 14:53:00 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 800B66957E; Wed, 11 Oct 2017 14:52:59 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 11E55C0587ED 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: Wed, 11 Oct 2017 16:52:40 +0200 Message-Id: <5f6095cf15006d1baa86bf6eb51b0d878ee127b4.1507732721.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v5 5/6] util: Introduce virFileWaitForExists 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]); Wed, 11 Oct 2017 15:06:18 +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 Reviewed-by: John Ferlan --- src/libvirt_private.syms | 1 + src/util/virfile.c | 31 +++++++++++++++++++++++++++++++ src/util/virfile.h | 2 ++ 3 files changed, 34 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 26c5ddb40..d871c813a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1753,6 +1753,7 @@ virFileStripSuffix; virFileTouch; virFileUnlock; virFileUpdatePerm; +virFileWaitForExists; virFileWrapperFdClose; virFileWrapperFdFree; virFileWrapperFdNew; diff --git a/src/util/virfile.c b/src/util/virfile.c index 7ca60052d..82cb36dbc 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -4177,3 +4177,34 @@ virFileReadValueString(char **value, const char *for= mat, ...) VIR_FREE(str); return ret; } + + +/** + * virFileWaitForExists: + * @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 +virFileWaitForExists(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 21fb41b70..91d318622 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -349,6 +349,8 @@ int virFileReadValueScaledInt(unsigned long long *value= , const char *format, ... int virFileReadValueString(char **value, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); =20 +int virFileWaitForExists(const char *path, size_t ms, size_t tries); + =20 int virFileInData(int fd, int *inData, --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 12:28:15 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 1507734360723892.6854292955026; Wed, 11 Oct 2017 08:06:00 -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 9337F653C; Wed, 11 Oct 2017 15:05:59 +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 699996C950; Wed, 11 Oct 2017 15:05:59 +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 26FE91806103; Wed, 11 Oct 2017 15:05:59 +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 v9BEr1iv009431 for ; Wed, 11 Oct 2017 10:53:01 -0400 Received: by smtp.corp.redhat.com (Postfix) id 26F376E717; Wed, 11 Oct 2017 14:53:01 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7AC226957E; Wed, 11 Oct 2017 14:53:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9337F653C 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: Wed, 11 Oct 2017 16:52:41 +0200 Message-Id: <6cb258050d79d7063dd0730eea8227ea316c0ddb.1507732721.git.eskultet@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH v5 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.39]); Wed, 11 Oct 2017 15:06:00 +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 Reviewed-by: John Ferlan --- 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 a6d7e6d70..0329cac90 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1198,9 +1198,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 (virFileWaitForExists(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.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list