87d178
From 8c263758fe196624005f19bd6f46d63e3841c5be Mon Sep 17 00:00:00 2001
87d178
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
87d178
Date: Tue, 11 Dec 2018 23:28:29 +0100
87d178
Subject: [PATCH] meson: make net.naming-scheme= default configurable
87d178
87d178
This is useful for distributions, where the stability of interface names should
87d178
be preseved after an upgrade of systemd. So when some specific release of the
87d178
distro is made available, systemd defaults to the latest & greatest naming
87d178
scheme, and subsequent updates set the same default. This default may still
87d178
be overriden through the kernel and env var options.
87d178
87d178
A special value "latest" is also allowed. Without a specific name, it is harder
87d178
to verride from meson. In case of 'combo' options, meson reads the default
87d178
during the initial configuration, and "remembers" this choice. When systemd is
87d178
updated, old build/ directories could keep the old default, which would be
87d178
annoying. Hence, "latest" is introduced to make it explicit, yet follow the
87d178
upstream. This is actually useful for the user too, because it may be used
87d178
as an override, without having to actually specify a version.
87d178
87d178
(cherry picked from commit 06da5c63dd697ea4087e76c6d809b60b5780b87c)
87d178
87d178
Related: #1827462
87d178
87d178
[msekleta: note that our default is not latest but rhel-8.0]
87d178
---
87d178
 doc/ENVIRONMENT.md             | 15 +++++++-------
87d178
 man/systemd-udevd.service.xml  | 24 ++++++++++++---------
87d178
 meson.build                    |  4 ++++
87d178
 meson_options.txt              |  3 +++
87d178
 src/udev/udev-builtin-net_id.c | 38 ++++++++++++++++++++--------------
87d178
 5 files changed, 51 insertions(+), 33 deletions(-)
87d178
87d178
diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md
87d178
index 1a4aa01ef4..0e763b6302 100644
87d178
--- a/doc/ENVIRONMENT.md
87d178
+++ b/doc/ENVIRONMENT.md
87d178
@@ -77,13 +77,14 @@ systemd-logind:
87d178
   for it.
87d178
 
87d178
 * `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of
87d178
-  v238, v239, v240 …) as parameter. If specified udev's net_id builtin will
87d178
-  follow the specified naming scheme when determining stable network interface
87d178
-  names. This may be used to revert to naming schemes of older udev versions,
87d178
-  in order to provide more stable naming across updates. This environment
87d178
-  variable takes precedence over the kernel command line option
87d178
-  `net.naming-scheme=`, except if the value is prefixed with `:` in which case
87d178
-  the kernel command line option takes precedence, if it is specified as well.
87d178
+  "rhel-8.0", "rhel-8.1", "rhel-8.2"…, or the special value "latest") as
87d178
+  parameter. If specified udev's net_id builtin will follow the specified
87d178
+  naming scheme when determining stable network interface names. This may be
87d178
+  used to revert to naming schemes of older udev versions, in order to provide
87d178
+  more stable naming across updates. This environment variable takes precedence
87d178
+  over the kernel command line option `net.naming-scheme=`, except if the value
87d178
+  is prefixed with `:` in which case the kernel command line option takes
87d178
+  precedence, if it is specified as well.
87d178
 
87d178
 installed systemd tests:
87d178
 
87d178
diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml
87d178
index 6449103441..b738591c93 100644
87d178
--- a/man/systemd-udevd.service.xml
87d178
+++ b/man/systemd-udevd.service.xml
87d178
@@ -174,16 +174,20 @@
87d178
         <term><varname>net.naming-scheme=</varname></term>
87d178
         <listitem>
87d178
           <para>Network interfaces are renamed to give them predictable names when possible (unless
87d178
-          <varname>net.ifnames=0</varname> is specified, see above). The names are derived from various device metadata
87d178
-          fields. Newer versions of <filename>systemd-udevd.service</filename> take more of these fields into account,
87d178
-          improving (and thus possibly changing) the names used for the same devices. With this kernel command line
87d178
-          option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as
87d178
-          argument. Currently the following identifiers are known: <literal>v238</literal>, <literal>v239</literal>,
87d178
-          <literal>v240</literal> which each implement the naming scheme that was the default in the indicated systemd
87d178
-          version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the
87d178
-          naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated,
87d178
-          previously missing attributes <filename>systemd-udevd.service</filename> is checking might appear, which
87d178
-          affects older name derivation algorithms, too.</para>
87d178
+          <varname>net.ifnames=0</varname> is specified, see above). The names are derived from various
87d178
+          device metadata fields. Newer versions of <filename>systemd-udevd.service</filename> take more of
87d178
+          these fields into account, improving (and thus possibly changing) the names used for the same
87d178
+          devices. With this kernel command line option it is possible to pick a specific version of this
87d178
+          algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers
87d178
+          are known: <literal>rhel-8.0</literal>, <literal>rhel-8.1</literal>, <literal>rhel-8.2</literal>,
87d178
+          <literal>rhel-8.3</literal> which each implement the naming scheme that was the default in the
87d178
+          indicated Red Hat Enterprise Linux minor version. In addition, <literal>latest</literal> may be
87d178
+          used to designate the latest scheme known (to this particular version of
87d178
+          <filename>systemd-udevd.service</filename>).</para>
87d178
+          <para>Note that selecting a specific scheme is not sufficient to fully stabilize interface naming:
87d178
+          the naming is generally derived from driver attributes exposed by the kernel. As the kernel is
87d178
+          updated, previously missing attributes <filename>systemd-udevd.service</filename> is checking might
87d178
+          appear, which affects older name derivation algorithms, too.</para>
87d178
         </listitem>
87d178
       </varlistentry>
87d178
     </variablelist>
87d178
diff --git a/meson.build b/meson.build
87d178
index 65c1d0785e..57de947367 100644
87d178
--- a/meson.build
87d178
+++ b/meson.build
87d178
@@ -639,6 +639,9 @@ else
87d178
         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
87d178
 endif
87d178
 
87d178
+default_net_naming_scheme = get_option('default-net-naming-scheme')
87d178
+conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme)
87d178
+
87d178
 time_epoch = get_option('time-epoch')
87d178
 if time_epoch == ''
87d178
         NEWS = files('NEWS')
87d178
@@ -2925,6 +2928,7 @@ status = [
87d178
         'default DNSSEC mode:               @0@'.format(default_dnssec),
87d178
         'default DNS-over-TLS mode:         @0@'.format(default_dns_over_tls),
87d178
         'default cgroup hierarchy:          @0@'.format(default_hierarchy),
87d178
+        'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme),
87d178
         'default KillUserProcesses setting: @0@'.format(kill_user_processes)]
87d178
 
87d178
 alt_dns_servers = '\n                                            '.join(dns_servers.split(' '))
87d178
diff --git a/meson_options.txt b/meson_options.txt
87d178
index 0996891177..213079ac15 100644
87d178
--- a/meson_options.txt
87d178
+++ b/meson_options.txt
87d178
@@ -158,6 +158,9 @@ option('default-hierarchy', type : 'combo',
87d178
        description : 'default cgroup hierarchy')
87d178
 option('time-epoch', type : 'string',
87d178
        description : 'time epoch for time clients')
87d178
+option('default-net-naming-scheme', type : 'combo',
87d178
+       choices : ['rhel-8.0', 'rhel-8.1', 'rhel-8.2', 'rhel-8.3', 'latest'],
87d178
+       description : 'default net.naming-scheme= value')
87d178
 option('system-uid-max', type : 'string',
87d178
        description : 'maximum system UID')
87d178
 option('system-gid-max', type : 'string',
87d178
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
87d178
index 148696183e..d85dc2848b 100644
87d178
--- a/src/udev/udev-builtin-net_id.c
87d178
+++ b/src/udev/udev-builtin-net_id.c
87d178
@@ -185,6 +185,19 @@ struct virtfn_info {
87d178
         char suffix[IFNAMSIZ];
87d178
 };
87d178
 
87d178
+static const NamingScheme* naming_scheme_from_name(const char *name) {
87d178
+        size_t i;
87d178
+
87d178
+        if (streq(name, "latest"))
87d178
+                return naming_schemes + ELEMENTSOF(naming_schemes) - 1;
87d178
+
87d178
+        for (i = 0; i < ELEMENTSOF(naming_schemes); i++)
87d178
+                if (streq(naming_schemes[i].name, name))
87d178
+                        return naming_schemes + i;
87d178
+
87d178
+        return NULL;
87d178
+}
87d178
+
87d178
 static const NamingScheme* naming_scheme(void) {
87d178
         static const NamingScheme *cache = NULL;
87d178
         _cleanup_free_ char *buffer = NULL;
87d178
@@ -208,25 +221,18 @@ static const NamingScheme* naming_scheme(void) {
87d178
                 k = buffer;
87d178
 
87d178
         if (k) {
87d178
-                size_t i;
87d178
-
87d178
-                for (i = 0; i < ELEMENTSOF(naming_schemes); i++)
87d178
-                        if (streq(naming_schemes[i].name, k)) {
87d178
-                                cache = naming_schemes + i;
87d178
-                                break;
87d178
-                        }
87d178
+                cache = naming_scheme_from_name(k);
87d178
+                if (cache) {
87d178
+                        log_info("Using interface naming scheme '%s'.", cache->name);
87d178
+                        return cache;
87d178
+                }
87d178
 
87d178
-                if (!cache)
87d178
-                        log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k);
87d178
+                log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k);
87d178
         }
87d178
 
87d178
-        if (cache)
87d178
-                log_info("Using interface naming scheme '%s'.", cache->name);
87d178
-        else {
87d178
-                /* RHEL-only: here we differ from the upstream and if no naming scheme was selected we default to naming from systemd-239 */
87d178
-                cache = &naming_schemes[2];
87d178
-                log_info("Using default interface naming scheme '%s'.", cache->name);
87d178
-        }
87d178
+        cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME);
87d178
+        assert(cache);
87d178
+        log_info("Using default interface naming scheme '%s'.", cache->name);
87d178
 
87d178
         return cache;
87d178
 }