[libvirt PATCH] vmx: Don't error out on missing filename for cdrom
by Martin Kletzander
This is perfectly valid in VMWare and the VM just boots with an empty drive. We
used to just skip the whole drive before, but since we changed how we parse
empty cdrom drives this now results in an error and the user not being able to
even dump the XML. Instead of erroring out, just keep the drive empty.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1903953
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/vmx/vmx.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index b86dbe9ca267..40e4ef962992 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -2447,10 +2447,18 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
goto cleanup;
}
+ tmp = ctx->parseFileName(fileName, ctx->opaque);
virDomainDiskSetType(*def, VIR_STORAGE_TYPE_FILE);
- if (!(tmp = ctx->parseFileName(fileName, ctx->opaque)))
- goto cleanup;
- virDomainDiskSetSource(*def, tmp);
+ /* It is easily possible to have a cdrom with non-existing filename
+ * as the image and vmware just provides an empty cdrom.
+ *
+ * See: https://bugzilla.redhat.com/1903953
+ */
+ if (tmp) {
+ virDomainDiskSetSource(*def, tmp);
+ } else {
+ virResetLastError();
+ }
VIR_FREE(tmp);
} else if (deviceType && STRCASEEQ(deviceType, "atapi-cdrom")) {
virDomainDiskSetType(*def, VIR_STORAGE_TYPE_BLOCK);
--
2.29.2
4 years
Hotplugng disk not adding backing layers to apparmor profile
by Russell Cattelan
We have been working on a feature at IBM cloud around snapshots.
One of the workflows is to add a snapshoted disk to a running virtual
instance. This involves adding a disk that has at minimum 2 qcow2 files,
one for the active overlay and one or more backing files.
The problem we are running into is that they dynamic update of the
apparmor profile appears to only add the first file in the chain to the
profile.
It based on some experiments it appears that this should be adding
all the files to the security profile but this seems to only do the
first (topmost) file. "disk->src"
https://gitlab.com/libvirt/libvirt/-/blob/a7db0b757d210071d39e6d116e6a4bc...
I does not appear to loop over the disks where as
qemuBlockStorageSourceChainAttach does
https://gitlab.com/libvirt/libvirt/-/blob/a7db0b757d210071d39e6d116e6a4bc...
The attached disk then fails since apparmor will reject the backing
files access.
This is fairly easy to demonstrate when apparmor is active.
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/mnt2/hotplug2.qcow2' index='1'/>
<backingStore type='file' index='2'>
<format type='qcow2'/>
<source file='/mnt2/hotplug1.qcow2'/>
<backingStore/>
</backingStore>
<target dev='vdc' bus='virtio'/>
</disk>
virsh attach-device test1 /mnt2/attach.xml
[535657.524784] audit: type=1400 audit(1608242451.762:79):
apparmor="DENIED" operation="open"
profile="libvirt-a7fd0ca2-1429-4a60-9ab4-a545660666ce"
name="/mnt2/hotplug1.qcow2" pid=11999 comm="qemu-system-x86"
requested_mask="r" denied_mask="r" fsuid=64055 ouid=64055
-Russell Cattelan
4 years
Hotplugng disk not adding backing layers to apparmor profile
by Russell Cattelan
We have been working on a feature at IBM cloud around snapshots.
One of the workflows is to add a snapshoted disk to a running virtual
instance. This involves adding a disk that has at minimum 2 qcow2 files,
one for the active overlay and one or more backing files.
The problem we are running into is that they dynamic update of the
apparmor profile appears to only add the first file in the chain to the
profile.
It based on some experiments it appears that this should be adding
all the files to the security profile but this seems to only do the
first (topmost) file. "disk->src"
https://gitlab.com/libvirt/libvirt/-/blob/a7db0b757d210071d39e6d116e6a4bc...
I does not appear to loop over the disks where as
qemuBlockStorageSourceChainAttach does
https://gitlab.com/libvirt/libvirt/-/blob/a7db0b757d210071d39e6d116e6a4bc...
The attached disk then fails since apparmor will reject the backing
files access.
This is fairly easy to demonstrate when apparmor is active.
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/mnt2/hotplug2.qcow2' index='1'/>
<backingStore type='file' index='2'>
<format type='qcow2'/>
<source file='/mnt2/hotplug1.qcow2'/>
<backingStore/>
</backingStore>
<target dev='vdc' bus='virtio'/>
</disk>
virsh attach-device test1 /mnt2/attach.xml
[535657.524784] audit: type=1400 audit(1608242451.762:79):
apparmor="DENIED" operation="open"
profile="libvirt-a7fd0ca2-1429-4a60-9ab4-a545660666ce"
name="/mnt2/hotplug1.qcow2" pid=11999 comm="qemu-system-x86"
requested_mask="r" denied_mask="r" fsuid=64055 ouid=64055
-Russell Cattelan
4 years
[libvirt PATCH 00/29] Refactor scripts in tests/cputestdata
by Tim Wiederhake
This series refactors the various scripts found in tests/cputestdata and
adds support for CORE_CAPABILITY MSR, as found on e.g. SnowRidge.
Acquiring test data on a new system is a two step process. "cpu-gather.sh"
gathers information on the target machine and has as few dependencies as
possible. "cpu-parse.sh" processes this information but requires access to
a libvirt source tree and has more dependencies, e.g. "xmltodict".
This series merges three of the four involved scripts (cpu-gather.sh,
cpu-parse.sh and cpu-reformat.py) into a single python3 script. python3
already was a dependency for cpu-gather.sh and care has been taken to not
depend on modules that are not installed by default [1]. Merging the fourth
script, cpu-cpuid.py, will come in a seperate series.
Patches 1 to 14 transform cpu-gather into a python script, preserving the
format of the output (except for consistent "\n" line endings; previously
the tool would output a mix of "\n" and "\r\n").
Patches 15 to 23 merge cpu-parse into the script. In this process, the
format of the intermediary data is changed to json.
Patches 24 to 29 add support for "all in one" operation and extracting
IA32_CORE_CAPABILITY_MSR, which can be found on e.g. SnowRidge CPUs.
Old usage:
./cpu-gather.sh | ./cpu-parse.sh
New:
./cpu-gather.py [--gather] | ./cpu-gather.py --parse
Alternative on single machine:
./cpu-gather.py --gather --parse
[1] https://docs.python.org/3/py-modindex.html
Tim Wiederhake (29):
cpu-cpuid: Shorten overly long line
cpu-gather: Create python wrapper for shell script
cpu-gather: Move model_name to new script
cpu-gather: Allow overwriting model name
cpu-gather: Move cpuid call to new script
cpu-gather: Allow overwriting cpuid binary location
cpu-gather: Move msr decoding to new script
cpu-gather: Move qemu detection to new script
cpu-gather: Move static model expansion to new script
cpu-gather: Move static model extraction to new script
cpu-gather: Move simple model extraction to new script
cpu-gather: Move full model extraction to new script
cpu-gather: Merge model gathering logic
cpu-gather: Delete old script
cpu-gather: Separate data input and output
cpu-parse: Wrap with python script
cpu-gather: Transport data as json
cpu-parse: Move model name detection to new script
cpu-parse: Move file name generation to new script
cpu-parse: Move xml output to new script
cpu-parse: Move json output to new script
cpu-parse: Move call to cpu-cpuid.py to new script
cpu-parse: Delete old script
cpu-gather: Ignore empty responses from qemu
cpu-gather: Ignore shutdown messages from qemu
cpu-gather: Parse cpuid leaves early
cpu-gather: Allow gathering and parsing data in one step.
cpu-gather: Prepare gather_msr for reading multiple msr
cpu-gather: Add IA32_CORE_CAPABILITY_MSR
tests/cputestdata/cpu-cpuid.py | 5 +-
tests/cputestdata/cpu-gather.py | 365 ++++++++++++++++++++++++++++++
tests/cputestdata/cpu-gather.sh | 103 ---------
tests/cputestdata/cpu-parse.sh | 65 ------
tests/cputestdata/cpu-reformat.py | 9 -
5 files changed, 368 insertions(+), 179 deletions(-)
create mode 100755 tests/cputestdata/cpu-gather.py
delete mode 100755 tests/cputestdata/cpu-gather.sh
delete mode 100755 tests/cputestdata/cpu-parse.sh
delete mode 100755 tests/cputestdata/cpu-reformat.py
--
2.26.2
4 years
[libvirt PATCH 0/2] Schema fixes for virsh [hypervisor-]cpu-compare
by Tim Wiederhake
See individual commit messages for more details.
Tim Wiederhake (2):
schemas: Deduplicate cpuTopology in cputypes.rng
schema: Allow counter element in host cpu definition
docs/schemas/cputypes.rng | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--
2.26.2
4 years
[libvirt][PATCH v1 0/3] introduce 'restrictive' mode in numatune
by Luyao Zhong
Before this patch set, numatune only has three memory modes:
static, interleave and prefered. These memory policies are
ultimately set by mbind() system call.
Memory policy could be 'hard coded' into the kernel, but none of
above policies fit our requirment under this case. mbind() support
default memory policy, but it requires a NULL nodemask. So obviously
setting allowed memory nodes is cgroups' mission under this case.
So we introduce a new option for mode in numatune named 'restrictive'.
<numatune>
<memory mode="restrictive" nodeset="1-4,^3"/>
<memnode cellid="0" mode="restrictive" nodeset="1"/>
<memnode cellid="2" mode="restrictive" nodeset="2"/>
</numatune>
The config above means we only use cgroups to restrict the allowed
memory nodes and not setting any specific memory policies explicitly.
RFC discussion:
https://www.redhat.com/archives/libvir-list/2020-November/msg01256.html
Regards,
Luyao
Luyao Zhong (3):
docs: add docs for 'restrictive' option for mode in numatune
schema: add 'restrictive' config option for mode in numatune
qemu: add parser and formatter for 'restrictive' mode in numatune
docs/formatdomain.rst | 7 +++-
docs/schemas/domaincommon.rng | 2 +
include/libvirt/libvirt-domain.h | 1 +
src/conf/numa_conf.c | 9 +++++
src/qemu/qemu_command.c | 6 ++-
src/qemu/qemu_process.c | 27 +++++++++++++
src/util/virnuma.c | 3 ++
.../numatune-memnode-invalid-mode.err | 1 +
.../numatune-memnode-invalid-mode.xml | 33 +++++++++++++++
...emnode-restrictive-mode.x86_64-latest.args | 40 +++++++++++++++++++
.../numatune-memnode-restrictive-mode.xml | 33 +++++++++++++++
tests/qemuxml2argvtest.c | 2 +
...memnode-restrictive-mode.x86_64-latest.xml | 40 +++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
14 files changed, 202 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/numatune-memnode-invalid-mode.err
create mode 100644 tests/qemuxml2argvdata/numatune-memnode-invalid-mode.xml
create mode 100644 tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.xml
create mode 100644 tests/qemuxml2xmloutdata/numatune-memnode-restrictive-mode.x86_64-latest.xml
--
2.25.4
4 years
[PATCH 0/5] Followup to virNetDevGenerateName() patches
by Laine Stump
A few issues came up during review of this series that were better
fixed in cleanups rather than requiring yet another round of
review. (A couple of things I noticed after the other patches were
already pushed).
Laine Stump (5):
util: fix tap device name auto-generation for FreeBSD
bhyve: remove redundant code that adds "template" netdev name
qemu: remove redundant code that adds "template" netdev name
util: simplify virNetDevMacVLanCreateWithVPortProfile()
util: minor comment/formatting changes to virNetDevTapCreate()
src/bhyve/bhyve_command.c | 7 ----
src/qemu/qemu_interface.c | 18 +++--------
src/util/virnetdevmacvlan.c | 64 ++++++-------------------------------
src/util/virnetdevtap.c | 46 +++++++-------------------
4 files changed, 25 insertions(+), 110 deletions(-)
--
2.28.0
4 years
[PATCH] util: Add phys_port_name support on virPCIGetNetName
by Dmytro Linkin
Current virPCIGetNetName() logic is to get net device name by checking
it's phys_port_id, if caller provide it, or by it's index (eg, by it's
position at sysfs net directory). This approach worked fine up until
linux kernel version 5.8, where NVIDIA Mellanox driver implemented
linking of VFs' representors to PCI device in switchdev mode. This mean
that device's sysfs net directory will hold multiple net devices. Ex.:
$ ls '/sys/bus/pci/devices/0000:82:00.0/net'
ens1f0 eth0 eth1
Most switch devices support phys_port_name instead of phys_port_id, so
virPCIGetNetName() will try to get PF name by it's index - 0. The
problem here is that the PF nedev entry may not be the first.
To fix that, for switch devices, we introduce a new logic to select the
PF uplink netdev according to the content of phys_port_name. Extend
virPCIGetNetName() with physPortNameRegex variable to get proper device
by it's phys_port_name scheme, for ex., "p[0-9]+$" to get PF,
"pf[0-9]+vf[0-9]+$" to get VF or "p1$" to get exact net device. So now
virPCIGetNetName() logic work in following sequence:
- filter by phys_port_id, if it's provided,
or
- filter by phys_port_name, if it's regex provided,
or
- get net device by it's index (position) in sysfs net directory.
Also, make getting content of iface sysfs files more generic.
Signed-off-by: Dmytro Linkin <dlinkin(a)nvidia.com>
Reviewed-by: Adrian Chiris <adrianc(a)nvidia.com>
---
src/hypervisor/virhostdev.c | 2 +-
src/util/virnetdev.c | 74 ++++++++++++++++++++++++++++++++++++---------
src/util/virnetdev.h | 4 +++
src/util/virpci.c | 63 ++++++++++++++++++++++++++++++++++++--
src/util/virpci.h | 6 ++++
5 files changed, 130 insertions(+), 19 deletions(-)
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index 69102b8..1f5c347 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -333,7 +333,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev,
* type='hostdev'>, and it is only those devices that should
* end up calling this function.
*/
- if (virPCIGetNetName(sysfs_path, 0, NULL, linkdev) < 0)
+ if (virPCIGetNetName(sysfs_path, 0, NULL, NULL, linkdev) < 0)
return -1;
if (!(*linkdev)) {
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index b42fa86..99e3b35 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1112,6 +1112,29 @@ virNetDevGetPCIDevice(const char *devName)
}
+/* A wrapper to get content of file from ifname SYSFS_NET_DIR
+ */
+static int
+virNetDevGetSysfsFileValue(const char *ifname,
+ const char *fileName,
+ char **sysfsFileData)
+{
+ g_autofree char *sysfsFile = NULL;
+
+ *sysfsFileData = NULL;
+
+ if (virNetDevSysfsFile(&sysfsFile, ifname, fileName) < 0)
+ return -1;
+
+ /* a failure to read just means the driver doesn't support
+ * <fileName>, so set success now and ignore the return from
+ * virFileReadAllQuiet().
+ */
+
+ ignore_value(virFileReadAllQuiet(sysfsFile, 1024, sysfsFileData));
+ return 0;
+}
+
/**
* virNetDevGetPhysPortID:
*
@@ -1130,20 +1153,29 @@ int
virNetDevGetPhysPortID(const char *ifname,
char **physPortID)
{
- g_autofree char *physPortIDFile = NULL;
-
- *physPortID = NULL;
-
- if (virNetDevSysfsFile(&physPortIDFile, ifname, "phys_port_id") < 0)
- return -1;
+ return virNetDevGetSysfsFileValue(ifname, "phys_port_id", physPortID);
+}
- /* a failure to read just means the driver doesn't support
- * phys_port_id, so set success now and ignore the return from
- * virFileReadAllQuiet().
- */
- ignore_value(virFileReadAllQuiet(physPortIDFile, 1024, physPortID));
- return 0;
+/**
+ * virNetDevGetPhysPortName:
+ *
+ * @ifname: name of a netdev
+ *
+ * @physPortName: pointer to char* that will receive @ifname's
+ * phys_port_name from sysfs (null terminated
+ * string). Could be NULL if @ifname's net driver doesn't
+ * support phys_port_name (most netdev drivers
+ * don't). Caller is responsible for freeing the string
+ * when finished.
+ *
+ * Returns 0 on success or -1 on failure.
+ */
+int
+virNetDevGetPhysPortName(const char *ifname,
+ char **physPortName)
+{
+ return virNetDevGetSysfsFileValue(ifname, "phys_port_name", physPortName);
}
@@ -1200,7 +1232,7 @@ virNetDevGetVirtualFunctions(const char *pfname,
}
if (virPCIGetNetName(pci_sysfs_device_link, 0,
- pfPhysPortID, &((*vfname)[i])) < 0) {
+ pfPhysPortID, NULL, &((*vfname)[i])) < 0) {
goto cleanup;
}
@@ -1295,7 +1327,8 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
return -1;
if (virPCIGetNetName(physfn_sysfs_path, 0,
- vfPhysPortID, pfname) < 0) {
+ vfPhysPortID,
+ VIR_PF_PHYS_PORT_NAME_REGEX, pfname) < 0) {
return -1;
}
@@ -1358,7 +1391,7 @@ virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
* isn't bound to a netdev driver, it won't have a netdev name,
* and vfname will be NULL).
*/
- return virPCIGetNetName(virtfnSysfsPath, 0, pfPhysPortID, vfname);
+ return virPCIGetNetName(virtfnSysfsPath, 0, pfPhysPortID, NULL, vfname);
}
@@ -1403,6 +1436,17 @@ virNetDevGetPhysPortID(const char *ifname G_GNUC_UNUSED,
}
int
+virNetDevGetPhysPortName(const char *ifname G_GNUC_UNUSED,
+ char **physPortName)
+{
+ /* this actually should never be called, and is just here to
+ * satisfy the linker.
+ */
+ *physPortName = NULL;
+ return 0;
+}
+
+int
virNetDevGetVirtualFunctions(const char *pfname G_GNUC_UNUSED,
char ***vfname G_GNUC_UNUSED,
virPCIDeviceAddressPtr **virt_fns G_GNUC_UNUSED,
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index 55e3948..712421d 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -229,6 +229,10 @@ int virNetDevGetPhysPortID(const char *ifname,
char **physPortID)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
G_GNUC_WARN_UNUSED_RESULT;
+int virNetDevGetPhysPortName(const char *ifname,
+ char **physPortName)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+ G_GNUC_WARN_UNUSED_RESULT;
int virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname,
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 47c671d..18b3f66 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2409,8 +2409,10 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
* 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)
+ * (ignored if physPortID or physPortNameRegex is set)
* @physPortID: match this string in the netdev's phys_port_id
+ * (or NULL to ignore and use phys_port_name or idx instead)
+ * @physPortNameRegex: match this regex with netdev's phys_port_name
* (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)
@@ -2421,11 +2423,13 @@ int
virPCIGetNetName(const char *device_link_sysfs_path,
size_t idx,
char *physPortID,
+ char *physPortNameRegex,
char **netname)
{
g_autofree char *pcidev_sysfs_net_path = NULL;
g_autofree char *firstEntryName = NULL;
g_autofree char *thisPhysPortID = NULL;
+ g_autofree char *thisPhysPortName = NULL;
int ret = -1;
DIR *dir = NULL;
struct dirent *entry = NULL;
@@ -2466,6 +2470,41 @@ virPCIGetNetName(const char *device_link_sysfs_path,
continue;
}
+ } else if (physPortNameRegex) {
+ /* Most switch devices use phys_port_name instead of
+ * phys_port_id.
+ * NOTE: VFs' representors net devices can be linked to PF's PCI
+ * device, which mean that there'll be multiple net devices
+ * instances and to get a proper net device need to match on
+ * specific regex.
+ * To get PF netdev, for ex., used following regex:
+ * "(p[0-9]+$)|(p[0-9]+s[0-9]+$)"
+ * or to get exact VF's netdev next regex is used:
+ * "pf0vf1$"
+ */
+ if (virNetDevGetPhysPortName(entry->d_name, &thisPhysPortName) < 0)
+ goto cleanup;
+
+ if (thisPhysPortName) {
+ /* if this one doesn't match, keep looking */
+ if (!virStringMatch(thisPhysPortName, physPortNameRegex)) {
+ VIR_FREE(thisPhysPortName);
+ /* Save the first entry we find to use as a failsafe
+ * in case we fail to match on regex.
+ */
+ if (!firstEntryName)
+ firstEntryName = g_strdup(entry->d_name);
+
+ continue;
+ }
+ } else {
+ /* Save the first entry we find to use as a failsafe in case
+ * phys_port_name is not supported.
+ */
+ if (!firstEntryName)
+ firstEntryName = g_strdup(entry->d_name);
+ continue;
+ }
} else {
if (i++ < idx)
continue;
@@ -2494,6 +2533,22 @@ virPCIGetNetName(const char *device_link_sysfs_path,
"phys_port_id '%s' under PCI device at %s"),
physPortID, device_link_sysfs_path);
}
+ } else if (physPortNameRegex) {
+ if (firstEntryName) {
+ /* We didn't match the provided phys_port_name regex, probably
+ * because kernel or NIC driver doesn't support it, so just
+ * return first netname we found.
+ */
+ *netname = firstEntryName;
+ firstEntryName = NULL;
+ ret = 0;
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find network device with "
+ "phys_port_name matching regex '%s' "
+ "under PCI device at %s"),
+ physPortNameRegex, device_link_sysfs_path);
+ }
} else {
ret = 0; /* no netdev at the given index is *not* an error */
}
@@ -2539,7 +2594,7 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
* correct.
*/
if (pfNetDevIdx == -1) {
- if (virPCIGetNetName(vf_sysfs_device_path, 0, NULL, &vfname) < 0)
+ if (virPCIGetNetName(vf_sysfs_device_path, 0, NULL, NULL, &vfname) < 0)
goto cleanup;
if (vfname) {
@@ -2550,7 +2605,8 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
}
if (virPCIGetNetName(pf_sysfs_device_path,
- pfNetDevIdx, vfPhysPortID, pfname) < 0) {
+ pfNetDevIdx, vfPhysPortID,
+ VIR_PF_PHYS_PORT_NAME_REGEX, pfname) < 0) {
goto cleanup;
}
@@ -2688,6 +2744,7 @@ int
virPCIGetNetName(const char *device_link_sysfs_path G_GNUC_UNUSED,
size_t idx G_GNUC_UNUSED,
char *physPortID G_GNUC_UNUSED,
+ char *physPortNameScheme G_GNUC_UNUSED,
char **netname G_GNUC_UNUSED)
{
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
diff --git a/src/util/virpci.h b/src/util/virpci.h
index b3322ba..6ea0873 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -55,6 +55,11 @@ struct _virZPCIDeviceAddress {
#define VIR_PCI_DEVICE_ADDRESS_FMT "%04x:%02x:%02x.%d"
+/* Represents format of PF's phys_port_name in switchdev mode:
+ * 'p%u' or 'p%us%u'. New line checked since value is readed from sysfs file.
+ */
+# define VIR_PF_PHYS_PORT_NAME_REGEX ((char *)"(p[0-9]+$)|(p[0-9]+s[0-9]+$)")
+
struct _virPCIDeviceAddress {
unsigned int domain;
unsigned int bus;
@@ -232,6 +237,7 @@ int virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
int virPCIGetNetName(const char *device_link_sysfs_path,
size_t idx,
char *physPortID,
+ char *physPortNameRegex,
char **netname);
int virPCIGetSysfsFile(char *virPCIDeviceName,
--
1.8.3.1
4 years