udev: net_id: introduce predictable names for xen-netfront

Those devices show up as /sys/devices/vif-N, let's use that number
to name them enXN.

Without this, all schemes fail and they keep the kernel names, which can
be racy.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Benjamin Herrenschmidt 2021-10-20 15:18:59 +11:00 committed by Lennart Poettering
parent ac33cf9282
commit d6eda677b3
4 changed files with 81 additions and 0 deletions

View file

@ -128,6 +128,7 @@
<varlistentry>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]</varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable><constant>v</constant><replaceable>slot</replaceable></varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable><constant>x</constant><replaceable>slot</replaceable></varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>b</constant><replaceable>number</replaceable></varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>u</constant><replaceable>port</replaceable>…[<constant>c</constant><replaceable>config</replaceable>][<constant>i</constant><replaceable>interface</replaceable>]</varname></term>
<term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>v</constant><replaceable>slot</replaceable></varname></term>
@ -159,6 +160,11 @@
<entry>VIO slot number (IBM PowerVM)</entry>
</row>
<row>
<entry><replaceable>prefix</replaceable> <constant>X</constant><replaceable>number</replaceable></entry>
<entry>VIF interface number (Xen)</entry>
</row>
<row>
<entry>… <constant>b</constant><replaceable>number</replaceable></entry>
<entry>Broadcom bus (BCMA) core number</entry>
@ -389,6 +395,14 @@
</listitem>
</varlistentry>
<varlistentry>
<term><constant>v250</constant></term>
<listitem><para>Added naming scheme for Xen netfront "vif" interfaces based on the guest side
VIF number set from the Xen config (or the interface index in AWS EC2).</para>
</listitem>
</varlistentry>
</variablelist>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this

View file

@ -21,6 +21,7 @@ static const NamingScheme naming_schemes[] = {
{ "v245", NAMING_V245 },
{ "v247", NAMING_V247 },
{ "v249", NAMING_V249 },
{ "v250", NAMING_V250 },
/* … add more schemes here, as the logic to name devices is updated … */
EXTRA_NET_NAMING_MAP

View file

@ -35,6 +35,7 @@ typedef enum NamingSchemeFlags {
NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
NAMING_16BIT_INDEX = 1 << 11, /* Allow full 16-bit for the onboard index */
NAMING_REPLACE_STRICTLY = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
NAMING_XEN_VIF = 1 << 13, /* GEnerate names for Xen netfront devices */
/* And now the masks that combine the features above */
NAMING_V238 = 0,
@ -45,6 +46,7 @@ typedef enum NamingSchemeFlags {
NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY,
NAMING_V250 = NAMING_V249 | NAMING_XEN_VIF,
EXTRA_NET_NAMING_SCHEMES

View file

@ -49,6 +49,7 @@ typedef enum NetNameType {
NET_VIRTIO,
NET_CCW,
NET_VIO,
NET_XENVIF,
NET_PLATFORM,
NET_NETDEVSIM,
} NetNameType;
@ -66,6 +67,7 @@ typedef struct NetNames {
char bcma_core[ALTIFNAMSIZ];
char ccw_busid[ALTIFNAMSIZ];
char vio_slot[ALTIFNAMSIZ];
char xen_slot[ALTIFNAMSIZ];
char platform_path[ALTIFNAMSIZ];
char netdevsim_path[ALTIFNAMSIZ];
} NetNames;
@ -813,6 +815,59 @@ static int names_netdevsim(sd_device *dev, const LinkInfo *info, NetNames *names
return 0;
}
static int names_xen(sd_device *dev, NetNames *names) {
sd_device *parent;
unsigned id;
const char *syspath, *subsystem, *p, *p2;
int r;
assert(dev);
assert(names);
if (!naming_scheme_has(NAMING_XEN_VIF))
return 0;
/* check if our direct parent is a Xen VIF device with no other bus in-between */
r = sd_device_get_parent(dev, &parent);
if (r < 0)
return r;
/* Do an exact-match on subsystem "xen". This will miss on "xen-backend" on
* purpose as the VIFs on the backend (dom0) have their own naming scheme
* which we don't want to affect
*/
r = sd_device_get_subsystem(parent, &subsystem);
if (r < 0)
return r;
if (!streq("xen", subsystem))
return -ENOENT;
/* Use the vif-n name to extract "n" */
r = sd_device_get_syspath(dev, &syspath);
if (r < 0)
return r;
p = path_startswith(syspath, "/sys/devices/");
if (!p)
return -ENOENT;
p = startswith(p, "vif-");
if (!p)
return -ENOENT;
p2 = strchr(p, '/');
if (!p2)
return -ENOENT;
p = strndupa_safe(p, p2 - p);
if (!p)
return -ENOENT;
r = safe_atou_full(p, SAFE_ATO_REFUSE_PLUS_MINUS | SAFE_ATO_REFUSE_LEADING_ZERO |
SAFE_ATO_REFUSE_LEADING_WHITESPACE | 10, &id);
if (r < 0)
return r;
xsprintf(names->xen_slot, "X%u", id);
names->type = NET_XENVIF;
return 0;
}
/* IEEE Organizationally Unique Identifier vendor string */
static int ieee_oui(sd_device *dev, const LinkInfo *info, bool test) {
char str[32];
@ -945,6 +1000,15 @@ static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg
return 0;
}
/* get xen vif "slot" based names. */
if (names_xen(dev, &names) >= 0 && names.type == NET_XENVIF) {
char str[ALTIFNAMSIZ];
if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.xen_slot))
udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
return 0;
}
/* get PCI based path names, we compose only PCI based paths */
if (names_pci(dev, &info, &names) < 0)
return 0;