udev/net_id: don't generate slot based names if multiple devices might claim the same slot

This commit is contained in:
Michal Sekletár
2020-10-19 17:55:44 +02:00
parent 3e545ae5ab
commit 2c8ec0095e
4 changed files with 45 additions and 1 deletions
+14
View File
@@ -192,6 +192,9 @@
<para>SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of <para>SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of
<constant>v</constant> and the virtual device number, with any leading zeros removed. The bus <constant>v</constant> and the virtual device number, with any leading zeros removed. The bus
number is ignored.</para> number is ignored.</para>
<para>In some configurations a parent PCI bridge of a given network controller may be associated
with a slot. In such case we don't generate this device property to avoid possible naming conflicts.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@@ -354,6 +357,17 @@
multiple similarly named containers (who only differ in container name suffix) should be less multiple similarly named containers (who only differ in container name suffix) should be less
likely (but still possible, since the 24bit hash value is very small).</para></listitem> likely (but still possible, since the 24bit hash value is very small).</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><constant>v246</constant></term>
<listitem><para>If the PCI slot is assocated with PCI bridge and that has multiple child network
controllers then all of them might derive the same value of <varname>ID_NET_NAME_SLOT</varname>
property. That could cause naming conflict if the property is selected as a device name. Now, we detect the
situation, slot - bridge relation, and we don't produce the <varname>ID_NET_NAME_SLOT</varname> property to
avoid possible naming conflict.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this <para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
+1
View File
@@ -12,6 +12,7 @@ static const NamingScheme naming_schemes[] = {
{ "v241", NAMING_V241 }, { "v241", NAMING_V241 },
{ "v243", NAMING_V243 }, { "v243", NAMING_V243 },
{ "v245", NAMING_V245 }, { "v245", NAMING_V245 },
{ "v246", NAMING_V246 },
/* … add more schemes here, as the logic to name devices is updated … */ /* … add more schemes here, as the logic to name devices is updated … */
}; };
+2
View File
@@ -31,6 +31,7 @@ typedef enum NamingSchemeFlags {
NAMING_NETDEVSIM = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */ NAMING_NETDEVSIM = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
NAMING_LABEL_NOPREFIX = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */ NAMING_LABEL_NOPREFIX = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */ NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */
NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
/* And now the masks that combine the features above */ /* And now the masks that combine the features above */
NAMING_V238 = 0, NAMING_V238 = 0,
@@ -39,6 +40,7 @@ typedef enum NamingSchemeFlags {
NAMING_V241 = NAMING_V240 | NAMING_STABLE_VIRTUAL_MACS, NAMING_V241 = NAMING_V240 | NAMING_STABLE_VIRTUAL_MACS,
NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX, NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX,
NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH, NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
NAMING_V246 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
_NAMING_SCHEME_FLAGS_INVALID = -1, _NAMING_SCHEME_FLAGS_INVALID = -1,
} NamingSchemeFlags; } NamingSchemeFlags;
+28 -1
View File
@@ -243,6 +243,25 @@ static bool is_pci_ari_enabled(sd_device *dev) {
return streq(a, "1"); return streq(a, "1");
} }
static bool is_pci_bridge(sd_device *dev) {
const char *v, *p;
if (sd_device_get_sysattr_value(dev, "modalias", &v) < 0)
return false;
if (!startswith(v, "pci:"))
return false;
p = strrchr(v, 's');
if (!p)
return false;
if (p[1] != 'c')
return false;
/* PCI device subclass 04 corresponds to PCI bridge */
return strneq(p + 2, "04", 2);
}
static int dev_pci_slot(sd_device *dev, struct netnames *names) { static int dev_pci_slot(sd_device *dev, struct netnames *names) {
unsigned long dev_port = 0; unsigned long dev_port = 0;
unsigned domain, bus, slot, func; unsigned domain, bus, slot, func;
@@ -343,10 +362,18 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
read_one_line_file(str, &address) >= 0 && read_one_line_file(str, &address) >= 0 &&
startswith(sysname, address)) { startswith(sysname, address)) {
hotplug_slot = i; hotplug_slot = i;
/* We found the match between PCI device and slot. However, we won't use the
* slot index if the device is a PCI bridge, because it can have other child
* devices that will try to claim the same index and that would create name
* collision. */
if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(hotplug_slot_dev))
hotplug_slot = 0;
break; break;
} }
} }
if (hotplug_slot > 0) if (hotplug_slot >= 0)
break; break;
if (sd_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL, &hotplug_slot_dev) < 0) if (sd_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL, &hotplug_slot_dev) < 0)
break; break;