From nobody Tue Feb 10 04:14:02 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) client-ip=63.128.21.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 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=1608819371; cv=none; d=zohomail.com; s=zohoarc; b=eb/8Vs6kOV/a0W/OFo2wKLjXQf6R0yy9pF1Wa8GA5yPeZSmqkDjHlUHWqupfffRIYJxg38fwzj8Op3vMA5RI2TlnazjDOYBD2VqonZoOzUmzFOsprGjv3lcDM+hn1L2RxECmLIxVUY1d/nr3yeG8mtragJFBYeUQKXyytGMxVEA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1608819371; 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; bh=+di+rPhrdYF8SvWZj90o1h/Ne4ePSbLkY52RnINuOPc=; b=R2kzoWSs82vZ+gqCHO8PdpPyeaAOOaR6jTq0Ct7zJ8TbzG4RpcPENn0FG1vqNVTMdG0hNqn9g/nyq9wWOB+EOUe3CnjUZ/Yk1OjJZfPnBxQKgWvg7P+ga3akwP+Vrq/hJdzVmEaRDZjLDUWFyuikD8XYNMPq6gMBApBwNhQeuDE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 63.128.21.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.zohomail.com with SMTPS id 1608819371004987.0149703354658; Thu, 24 Dec 2020 06:16:11 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-352-8wCfCUltPuelXg7a7LBgAw-1; Thu, 24 Dec 2020 09:15:23 -0500 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 73243100D694; Thu, 24 Dec 2020 14:15:15 +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 4E5716F929; Thu, 24 Dec 2020 14:15:15 +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 1936F1809CA5; Thu, 24 Dec 2020 14:15:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 0BOEEq1V005651 for ; Thu, 24 Dec 2020 09:14:52 -0500 Received: by smtp.corp.redhat.com (Postfix) id DE9FC71C8D; Thu, 24 Dec 2020 14:14:52 +0000 (UTC) Received: from himantopus.redhat.com (ovpn-112-15.phx2.redhat.com [10.3.112.15]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9976D5C1A3; Thu, 24 Dec 2020 14:14:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1608819369; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=+di+rPhrdYF8SvWZj90o1h/Ne4ePSbLkY52RnINuOPc=; b=RhnYGHUgn6XFjxAIURVAk/9UiWU3K15Zgf6rUNULnVwaegxDnlDSKNvs4ocfdLTsH7UoMj 6mfEC7dBivWhJ+FxR0JQva0pLops/lq89ooJYGepCMslDu369xnOlavg3/2rsI+TzKcao8 NCJRV5GRP4HDskvARL1Mzqr/KCQ7oXA= X-MC-Unique: 8wCfCUltPuelXg7a7LBgAw-1 From: Jonathon Jongsma To: libvir-list@redhat.com Subject: [libvirt PATCH v3 07/21] nodedev: add mdevctl devices to node device list Date: Thu, 24 Dec 2020 08:14:31 -0600 Message-Id: <20201224141445.163819-8-jjongsma@redhat.com> In-Reply-To: <20201224141445.163819-1-jjongsma@redhat.com> References: <20201224141445.163819-1-jjongsma@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Cc: eskultet@redhat.com 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" At startup, query devices that are defined by 'mdevctl' and add them to the node device list. This adds a complication: we now have two potential sources of information for a node device: - udev for all devices and for activated mediated devices - mdevctl for persistent mediated devices Unfortunately, neither backend returns full information for a mediated device. For example, if a persistent mediated device in the list (with information provided from mdevctl) is 'started', that same device will now be detected by udev. If we simply overwrite the existing device definition with the new one provided by the udev backend, we will lose extra information that was provided by mdevctl (e.g. attributes, etc). To avoid this, make sure to copy the extra information into the new device definition. Signed-off-by: Jonathon Jongsma --- src/node_device/node_device_driver.c | 76 ++++++++++++++++++++++++++++ src/node_device/node_device_driver.h | 3 ++ src/node_device/node_device_udev.c | 48 ++++++++++++++++++ 3 files changed, 127 insertions(+) diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_de= vice_driver.c index 5309b8abd5..0267005af1 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -1144,3 +1144,79 @@ nodeDeviceGenerateName(virNodeDeviceDefPtr def, *(def->name + i) =3D '_'; } } + + +static int +virMdevctlListDefined(virNodeDeviceDefPtr **devs) +{ + int status; + g_autofree char *output =3D NULL; + g_autoptr(virCommand) cmd =3D nodeDeviceGetMdevctlListCommand(true, &o= utput); + + if (virCommandRun(cmd, &status) < 0) + return -1; + + if (!output) + return -1; + + return nodeDeviceParseMdevctlJSON(output, devs); +} + + +int +nodeDeviceUpdateMediatedDevices(void) +{ + g_autofree virNodeDeviceDefPtr *devs =3D NULL; + int ndevs; + size_t i; + + if ((ndevs =3D virMdevctlListDefined(&devs)) < 0) { + virReportSystemError(errno, "%s", + _("failed to query mdevs from mdevctl")); + return -1; + } + + for (i =3D 0; i < ndevs; i++) { + virNodeDeviceObjPtr obj; + virObjectEventPtr event; + virNodeDeviceDefPtr dev =3D devs[i]; + bool new_device =3D true; + + dev->driver =3D g_strdup("vfio_mdev"); + + /* If a device defined by mdevctl is already in the list, that mea= ns + * that it was found via the normal device discovery process and t= hus + * is already activated. Active devices contain some additional + * information (e.g. sysfs path) that is not provided by mdevctl, = so + * preserve that info */ + if ((obj =3D virNodeDeviceObjListFindByName(driver->devs, dev->nam= e))) { + virNodeDeviceDefPtr olddef =3D virNodeDeviceObjGetDef(obj); + + /* Copy any data from the existing device */ + dev->sysfs_path =3D g_strdup(olddef->sysfs_path); + dev->parent_sysfs_path =3D g_strdup(olddef->parent_sysfs_path); + dev->driver =3D g_strdup(olddef->driver); + dev->devnode =3D g_strdup(olddef->devnode); + dev->caps->data.mdev.iommuGroupNumber =3D olddef->caps->data.m= dev.iommuGroupNumber; + + virNodeDeviceObjEndAPI(&obj); + new_device =3D false; + } + + if (!(obj =3D virNodeDeviceObjListAssignDef(driver->devs, dev))) { + virNodeDeviceDefFree(dev); + return -1; + } + + if (new_device) + event =3D virNodeDeviceEventLifecycleNew(dev->name, + VIR_NODE_DEVICE_EVENT_C= REATED, + 0); + else + event =3D virNodeDeviceEventUpdateNew(dev->name); + virNodeDeviceObjEndAPI(&obj); + virObjectEventStateQueue(driver->nodeDeviceEventState, event); + } + + return 0; +} diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_de= vice_driver.h index 80ac7c5320..4315f6d6ed 100644 --- a/src/node_device/node_device_driver.h +++ b/src/node_device/node_device_driver.h @@ -126,6 +126,9 @@ int nodeDeviceParseMdevctlJSON(const char *jsonstring, virNodeDeviceDefPtr **devs); =20 +int +nodeDeviceUpdateMediatedDevices(void); + void nodeDeviceGenerateName(virNodeDeviceDefPtr def, const char *subsystem, diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index 632413d046..223ee5a2ff 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1494,6 +1494,50 @@ udevSetParent(struct udev_device *device, return 0; } =20 +static virMediatedDeviceAttrPtr * +virMediatedDeviceAttrsCopy(virMediatedDeviceAttrPtr *attrs, + size_t nattrs) +{ + size_t i; + size_t j =3D 0; + g_autofree virMediatedDeviceAttrPtr *ret =3D NULL; + + if (nattrs =3D=3D 0) + return NULL; + + ret =3D g_new0(virMediatedDeviceAttrPtr, nattrs); + + for (i =3D 0; i < nattrs; i++) { + virMediatedDeviceAttrPtr attr =3D virMediatedDeviceAttrNew(); + attr->name =3D g_strdup(attrs[i]->name); + attr->value =3D g_strdup(attrs[i]->value); + VIR_APPEND_ELEMENT_INPLACE(ret, j, attr); + } + + return g_steal_pointer(ret); +} + +/* An existing device definition may have additional info from mdevctl tha= t is + * not available from udev. Transfer this data to the new definition */ +static void +nodeDeviceDefCopyExtraData(virNodeDeviceDefPtr dst, + virNodeDeviceDefPtr src) +{ + virNodeDevCapMdevPtr srcmdev; + virNodeDevCapMdevPtr dstmdev; + + if (dst->caps->data.type !=3D VIR_NODE_DEV_CAP_MDEV) + return; + + srcmdev =3D &src->caps->data.mdev; + dstmdev =3D &dst->caps->data.mdev; + + dstmdev->persistent =3D srcmdev->persistent; + dstmdev->nattributes =3D srcmdev->nattributes; + dstmdev->attributes =3D virMediatedDeviceAttrsCopy(srcmdev->attributes, + srcmdev->nattributes); +} + =20 static int udevAddOneDevice(struct udev_device *device) @@ -1527,6 +1571,8 @@ udevAddOneDevice(struct udev_device *device) goto cleanup; =20 if ((obj =3D virNodeDeviceObjListFindByName(driver->devs, def->name)))= { + nodeDeviceDefCopyExtraData(def, virNodeDeviceObjGetDef(obj)); + virNodeDeviceObjEndAPI(&obj); new_device =3D false; } @@ -1953,6 +1999,8 @@ nodeStateInitializeEnumerate(void *opaque) /* Populate with known devices */ if (udevEnumerateDevices(udev) !=3D 0) goto error; + if (nodeDeviceUpdateMediatedDevices() !=3D 0) + goto error; =20 nodeDeviceLock(); driver->initialized =3D true; --=20 2.26.2