From nobody Fri May 16 05:41:16 2025 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 1502415784467296.7433364053353; Thu, 10 Aug 2017 18:43:04 -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 3B596A49FF; Fri, 11 Aug 2017 01:43:02 +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 12C7698159; Fri, 11 Aug 2017 01:43:02 +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 AF259388B; Fri, 11 Aug 2017 01:43:01 +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 v7B1gXuk003151 for ; Thu, 10 Aug 2017 21:42:33 -0400 Received: by smtp.corp.redhat.com (Postfix) id 308979814C; Fri, 11 Aug 2017 01:42:33 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-36.phx2.redhat.com [10.3.117.36]) by smtp.corp.redhat.com (Postfix) with ESMTP id B447A71C33; Fri, 11 Aug 2017 01:42:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 3B596A49FF Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=laine.org Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 3B596A49FF From: Laine Stump To: libvir-list@redhat.com Date: Thu, 10 Aug 2017 21:42:18 -0400 Message-Id: <20170811014222.29548-4-laine@laine.org> In-Reply-To: <20170811014222.29548-1-laine@laine.org> References: <20170811014222.29548-1-laine@laine.org> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Cc: mprivozn@redhat.com, moshele@mellanox.com Subject: [libvirt] [PATCH v2 3/7] util: make virPCIGetNetName() more versatile 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.25]); Fri, 11 Aug 2017 01:43:03 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" A single PCI device may have multiple netdevs associated with it. Each of those netdevs will have a different phys_port_id entry in sysfs. This patch modifies virPCIGetNetName() to allow selecting one of the potential many netdevs in two different ways: 1) by setting the "idx" argument, the caller can select the 1st (0), 2nd (1), etc. netdev from the PCI device's net subdirectory. 2) If the physPortID arg is set (to a null-terminated string) then virPCIGetNetName() returns the netdev that has that phys_port_id in the sysfs file of the same name in the netdev's directory. --- Change from V1 - in V1 I had only added the physPortID arg. In V2 I also added the idx arg to allow choosing port 1 or 2 regardless of physPortID (because in some situations you can't know the physPortID). src/util/virhostdev.c | 2 +- src/util/virnetdev.c | 9 ++++--- src/util/virpci.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----= ---- src/util/virpci.h | 5 +++- 4 files changed, 66 insertions(+), 16 deletions(-) diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c index 579563c3f..580f0fac0 100644 --- a/src/util/virhostdev.c +++ b/src/util/virhostdev.c @@ -326,7 +326,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, cha= r **linkdev, * type=3D'hostdev'>, and it is only those devices that should * end up calling this function. */ - if (virPCIGetNetName(sysfs_path, linkdev) < 0) + if (virPCIGetNetName(sysfs_path, 0, NULL, linkdev) < 0) goto cleanup; =20 if (!linkdev) { diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index a2664de78..b6ef00e2e 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1262,8 +1262,10 @@ virNetDevGetVirtualFunctions(const char *pfname, goto cleanup; } =20 - if (virPCIGetNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0) + if (virPCIGetNetName(pci_sysfs_device_link, 0, + NULL, &((*vfname)[i])) < 0) { goto cleanup; + } =20 if (!(*vfname)[i]) VIR_INFO("VF does not have an interface name"); @@ -1362,7 +1364,8 @@ virNetDevGetPhysicalFunction(const char *ifname, char= **pfname) if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0) return ret; =20 - if (virPCIGetNetName(physfn_sysfs_path, pfname) < 0) + if (virPCIGetNetName(physfn_sysfs_path, 0, + NULL, pfname) < 0) goto cleanup; =20 if (!*pfname) { @@ -1422,7 +1425,7 @@ virNetDevPFGetVF(const char *pfname, int vf, char **v= fname) * isn't bound to a netdev driver, it won't have a netdev name, * and vfname will be NULL). */ - ret =3D virPCIGetNetName(virtfnSysfsPath, vfname); + ret =3D virPCIGetNetName(virtfnSysfsPath, 0, NULL, vfname); =20 cleanup: VIR_FREE(virtfnName); diff --git a/src/util/virpci.c b/src/util/virpci.c index 110d9741c..62a36b380 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -24,6 +24,7 @@ #include =20 #include "virpci.h" +#include "virnetdev.h" =20 #include #include @@ -2853,16 +2854,30 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddress= Ptr addr, return 0; } =20 -/* - * Returns the network device name of a pci device +/** + * virPCIGetNetName: + * @device_link_sysfs_path: sysfs path to the PCI device + * @idx: used to choose which netdev when there are several + * (ignored if physPortID is set) + * @physPortID: match this string in the netdev's phys_port_id + * (or NULL to ignore and use idx instead) + * @netname: used to return the name of the netdev + * (set to NULL (but returns success) if there is no netdev) + * + * Returns 0 on success, -1 on error (error has been logged) */ int -virPCIGetNetName(const char *device_link_sysfs_path, char **netname) +virPCIGetNetName(const char *device_link_sysfs_path, + size_t idx, + char *physPortID, + char **netname) { char *pcidev_sysfs_net_path =3D NULL; int ret =3D -1; DIR *dir =3D NULL; struct dirent *entry =3D NULL; + char *thisPhysPortID =3D NULL; + size_t i =3D 0; =20 if (virBuildPath(&pcidev_sysfs_net_path, device_link_sysfs_path, "net") =3D=3D -1) { @@ -2873,21 +2888,48 @@ virPCIGetNetName(const char *device_link_sysfs_path= , char **netname) if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) { /* this *isn't* an error - caller needs to check for netname =3D= =3D NULL */ ret =3D 0; - goto out; + goto cleanup; } =20 while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) { - /* Assume a single directory entry */ - if (VIR_STRDUP(*netname, entry->d_name) > 0) - ret =3D 0; + /* if the caller sent a physPortID, compare it to the + * physportID of this netdev. If not, look for entry[idx]. + */ + if (physPortID) { + if (virNetDevGetPhysPortID(entry->d_name, &thisPhysPortID) < 0) + goto cleanup; + + /* if this one doesn't match, keep looking */ + if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) { + VIR_FREE(thisPhysPortID); + continue; + } + } else { + if (i++ < idx) + continue; + } + + if (VIR_STRDUP(*netname, entry->d_name) < 0) + goto cleanup; + + ret =3D 0; break; } =20 + if (ret < 0) { + if (physPortID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find network device with " + "phys_port_id '%s' under PCI device at %s"), + physPortID, device_link_sysfs_path); + } else { + ret =3D 0; /* no netdev at the given index is *not* an error */ + } + } + cleanup: VIR_DIR_CLOSE(dir); - - out: VIR_FREE(pcidev_sysfs_net_path); - + VIR_FREE(thisPhysPortID); return ret; } =20 @@ -2915,7 +2957,7 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_dev= ice_path, goto cleanup; } =20 - if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0) + if (virPCIGetNetName(pf_sysfs_device_path, 0, NULL, pfname) < 0) goto cleanup; =20 if (!*pfname) { @@ -2992,6 +3034,8 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPt= r dev ATTRIBUTE_UNUSED, =20 int virPCIGetNetName(const char *device_link_sysfs_path ATTRIBUTE_UNUSED, + size_t idx ATTRIBUTE_UNUSED, + char *physPortID ATTRIBUTE_UNUSED, char **netname ATTRIBUTE_UNUSED) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); diff --git a/src/util/virpci.h b/src/util/virpci.h index 82d4ddc61..adf336706 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -207,7 +207,10 @@ int virPCIGetVirtualFunctionIndex(const char *pf_sysfs= _device_link, int virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr, char **pci_sysfs_device_link); =20 -int virPCIGetNetName(const char *device_link_sysfs_path, char **netname); +int virPCIGetNetName(const char *device_link_sysfs_path, + size_t idx, + char *physPortID, + char **netname); =20 int virPCIGetSysfsFile(char *virPCIDeviceName, char **pci_sysfs_device_link) --=20 2.13.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list