diff --git a/SOURCES/0475-man-mention-System-Administrator-s-Guide-in-systemct.patch b/SOURCES/0475-man-mention-System-Administrator-s-Guide-in-systemct.patch new file mode 100644 index 0000000..0fed0ab --- /dev/null +++ b/SOURCES/0475-man-mention-System-Administrator-s-Guide-in-systemct.patch @@ -0,0 +1,35 @@ +From 11a9ea82827d7b57dbce307b77ef8233a4cc028a Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 28 Aug 2014 15:12:10 +0200 +Subject: [PATCH] man: mention System Administrator's Guide in systemctl + manpage + +(cherry picked from commit d4582346f47064de24470b5f92e418966004925f) + +Resolves: #1623116 +--- + man/systemctl.xml | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/man/systemctl.xml b/man/systemctl.xml +index fa08ab6c0a..56f94d084c 100644 +--- a/man/systemctl.xml ++++ b/man/systemctl.xml +@@ -2000,6 +2000,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + ++ ++ Examples ++ ++ For examples how to use systemctl in comparsion ++ with old service and chkconfig command please see: ++ ++ Managing System Services ++ ++ ++ ++ + + See Also + diff --git a/SOURCES/0476-udev-introduce-udev-net_id-naming-schemes.patch b/SOURCES/0476-udev-introduce-udev-net_id-naming-schemes.patch new file mode 100644 index 0000000..d218efb --- /dev/null +++ b/SOURCES/0476-udev-introduce-udev-net_id-naming-schemes.patch @@ -0,0 +1,257 @@ +From 08ac9f7f55c138678c6415139e7510a05a75b81d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Wed, 14 Oct 2020 16:57:44 +0200 +Subject: [PATCH] udev: introduce udev net_id "naming schemes" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With this we can stabilize how naming works for network interfaces. A +user can request through a kernel cmdline option or an env var which +scheme to follow. The idea is that installers use this to set into stone +(a very soft stone though) the scheme used during installation so that +interface naming doesn't change afterwards anymore. + +Why use env vars and kernel cmdline options, and not a config file of +its own? + +Well, first of all there's no obvious existing one to use. But more +importantly: I have the feeling that this logic is kind of an incomplete +hack, and I simply don't want to do advertise this as a perfectly +working solution. So far we used env vars for the non-so-official +options and proper config files for the official stuff. Given how +incomplete this logic is (i.e. the big variable for naming remains the +kernel, which might expose sysfs attributes in newer versions that we +check for and didn't exist in older versions — and other problems like +this), I am simply not confident in giving this first-class exposure in +a primary configuration file. + +Fixes: #10448 + +(cherry-picked from commit f7e81fd96fdfe0ac6dcdb72de43f7cb4720e363a) + +Related: #1827462 + +[msekleta: note that we are introducing our own naming schemes based on +RHEL-8 minor versions. Also we are not backporting all naming scheme +features that appeared in the original commit. We are backporting only +features relevant for v239 while original commit also converted +changes introduced in v240 into naming scheme flags.] +--- + doc/ENVIRONMENT.md | 9 +++ + man/kernel-command-line.xml | 1 + + man/systemd-udevd.service.xml | 16 +++++ + src/udev/udev-builtin-net_id.c | 106 ++++++++++++++++++++++++++++++++- + 4 files changed, 130 insertions(+), 2 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 39a36a52cc..1a4aa01ef4 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -76,6 +76,15 @@ systemd-logind: + hibernation is available even if the swap devices do not provide enough room + for it. + ++* `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of ++ v238, v239, v240 …) as parameter. If specified udev's net_id builtin will ++ follow the specified naming scheme when determining stable network interface ++ names. This may be used to revert to naming schemes of older udev versions, ++ in order to provide more stable naming across updates. This environment ++ variable takes precedence over the kernel command line option ++ `net.naming-scheme=`, except if the value is prefixed with `:` in which case ++ the kernel command line option takes precedence, if it is specified as well. ++ + installed systemd tests: + + * `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if +diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml +index 4d8cb4e50e..b753d0592c 100644 +--- a/man/kernel-command-line.xml ++++ b/man/kernel-command-line.xml +@@ -246,6 +246,7 @@ + udev.event_timeout= + rd.udev.event_timeout= + net.ifnames= ++ net.naming-scheme= + + + Parameters understood by the device event managing +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index 73c77ea690..6449103441 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -170,6 +170,22 @@ + when possible. It is enabled by default; specifying 0 disables it. + + ++ ++ net.naming-scheme= ++ ++ Network interfaces are renamed to give them predictable names when possible (unless ++ net.ifnames=0 is specified, see above). The names are derived from various device metadata ++ fields. Newer versions of systemd-udevd.service take more of these fields into account, ++ improving (and thus possibly changing) the names used for the same devices. With this kernel command line ++ option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as ++ argument. Currently the following identifiers are known: v238, v239, ++ v240 which each implement the naming scheme that was the default in the indicated systemd ++ version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the ++ naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated, ++ previously missing attributes systemd-udevd.service is checking might appear, which ++ affects older name derivation algorithms, too. ++ ++ + + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 147e04ab8c..148696183e 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -96,6 +96,7 @@ + #include "fileio.h" + #include "fs-util.h" + #include "parse-util.h" ++#include "proc-cmdline.h" + #include "stdio-util.h" + #include "string-util.h" + #include "udev.h" +@@ -103,6 +104,52 @@ + + #define ONBOARD_INDEX_MAX (16*1024-1) + ++/* So here's the deal: net_id is supposed to be an excercise in providing stable names for network devices. However, we ++ * also want to keep updating the naming scheme used in future versions of net_id. These two goals of course are ++ * contradictory: on one hand we want things to not change and on the other hand we want them to improve. Our way out ++ * of this dilemma is to introduce the "naming scheme" concept: each time we improve the naming logic we define a new ++ * flag for it. Then, we keep a list of schemes, each identified by a name associated with the flags it implements. Via ++ * a kernel command line and environment variable we then allow the user to pick the scheme they want us to follow: ++ * installers could "freeze" the used scheme at the moment of installation this way. ++ * ++ * Developers: each time you tweak the naming logic here, define a new flag below, and condition the tweak with ++ * it. Each time we do a release we'll then add a new scheme entry and include all newly defined flags. ++ * ++ * Note that this is only half a solution to the problem though: not only udev/net_id gets updated all the time, the ++ * kernel gets too. And thus a kernel that previously didn't expose some sysfs attribute we look for might eventually ++ * do, and thus affect our naming scheme too. Thus, enforcing a naming scheme will make interfacing more stable across ++ * OS versions, but not fully stabilize them. */ ++typedef enum NamingSchemeFlags { ++ /* First, the individual features */ ++ NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a40008b8299529c978ed8e11de8f6*/ ++ NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ ++ ++ /* And now the masks that combine the features above */ ++ NAMING_V238 = 0, ++ NAMING_V239 = NAMING_V238|NAMING_SR_IOV_V|NAMING_NPAR_ARI, ++ NAMING_RHEL_8_0 = NAMING_V239, ++ NAMING_RHEL_8_1 = NAMING_V239, ++ NAMING_RHEL_8_2 = NAMING_V239, ++ NAMING_RHEL_8_3 = NAMING_V239, ++ ++ _NAMING_SCHEME_FLAGS_INVALID = -1, ++} NamingSchemeFlags; ++ ++typedef struct NamingScheme { ++ const char *name; ++ NamingSchemeFlags flags; ++} NamingScheme; ++ ++static const NamingScheme naming_schemes[] = { ++ { "v238", NAMING_V238 }, ++ { "v239", NAMING_V239 }, ++ { "rhel-8.0", NAMING_RHEL_8_0 }, ++ { "rhel-8.1", NAMING_RHEL_8_1 }, ++ { "rhel-8.2", NAMING_RHEL_8_2 }, ++ { "rhel-8.3", NAMING_RHEL_8_3 }, ++ /* … add more schemes here, as the logic to name devices is updated … */ ++}; ++ + enum netname_type{ + NET_UNDEF, + NET_PCI, +@@ -138,6 +185,56 @@ struct virtfn_info { + char suffix[IFNAMSIZ]; + }; + ++static const NamingScheme* naming_scheme(void) { ++ static const NamingScheme *cache = NULL; ++ _cleanup_free_ char *buffer = NULL; ++ const char *e, *k; ++ ++ if (cache) ++ return cache; ++ ++ /* Acquire setting from the kernel command line */ ++ (void) proc_cmdline_get_key("net.naming-scheme", 0, &buffer); ++ ++ /* Also acquire it from an env var */ ++ e = getenv("NET_NAMING_SCHEME"); ++ if (e) { ++ if (*e == ':') { ++ /* If prefixed with ':' the kernel cmdline takes precedence */ ++ k = buffer ?: e + 1; ++ } else ++ k = e; /* Otherwise the env var takes precedence */ ++ } else ++ k = buffer; ++ ++ if (k) { ++ size_t i; ++ ++ for (i = 0; i < ELEMENTSOF(naming_schemes); i++) ++ if (streq(naming_schemes[i].name, k)) { ++ cache = naming_schemes + i; ++ break; ++ } ++ ++ if (!cache) ++ log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); ++ } ++ ++ if (cache) ++ log_info("Using interface naming scheme '%s'.", cache->name); ++ else { ++ /* RHEL-only: here we differ from the upstream and if no naming scheme was selected we default to naming from systemd-239 */ ++ cache = &naming_schemes[2]; ++ log_info("Using default interface naming scheme '%s'.", cache->name); ++ } ++ ++ return cache; ++} ++ ++static bool naming_scheme_has(NamingSchemeFlags flags) { ++ return FLAGS_SET(naming_scheme()->flags, flags); ++} ++ + /* skip intermediate virtio devices */ + static struct udev_device *skip_virtio(struct udev_device *dev) { + struct udev_device *parent = dev; +@@ -299,7 +396,9 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + + if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) + return -ENOENT; +- if (is_pci_ari_enabled(names->pcidev)) ++ ++ if (naming_scheme_has(NAMING_NPAR_ARI) && ++ is_pci_ari_enabled(names->pcidev)) + /* ARI devices support up to 256 functions on a single device ("slot"), and interpret the + * traditional 5-bit slot and 3-bit function number as a single 8-bit function number, + * where the slot makes up the upper 5 bits. */ +@@ -494,7 +593,8 @@ static int names_pci(struct udev_device *dev, struct netnames *names) { + return -ENOENT; + } + +- if (get_virtfn_info(dev, names, &vf_info) >= 0) { ++ if (naming_scheme_has(NAMING_SR_IOV_V) && ++ get_virtfn_info(dev, names, &vf_info) >= 0) { + /* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */ + vf_names.pcidev = vf_info.physfn_pcidev; + dev_pci_onboard(dev, &vf_names); +@@ -741,6 +841,8 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool + prefix = "ww"; + } + ++ udev_builtin_add_property(dev, test, "ID_NET_NAMING_SCHEME", naming_scheme()->name); ++ + err = names_mac(dev, &names); + if (err >= 0 && names.mac_valid) { + char str[IFNAMSIZ]; diff --git a/SOURCES/0477-meson-make-net.naming-scheme-default-configurable.patch b/SOURCES/0477-meson-make-net.naming-scheme-default-configurable.patch new file mode 100644 index 0000000..0c9f850 --- /dev/null +++ b/SOURCES/0477-meson-make-net.naming-scheme-default-configurable.patch @@ -0,0 +1,188 @@ +From 8c263758fe196624005f19bd6f46d63e3841c5be Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 11 Dec 2018 23:28:29 +0100 +Subject: [PATCH] meson: make net.naming-scheme= default configurable + +This is useful for distributions, where the stability of interface names should +be preseved after an upgrade of systemd. So when some specific release of the +distro is made available, systemd defaults to the latest & greatest naming +scheme, and subsequent updates set the same default. This default may still +be overriden through the kernel and env var options. + +A special value "latest" is also allowed. Without a specific name, it is harder +to verride from meson. In case of 'combo' options, meson reads the default +during the initial configuration, and "remembers" this choice. When systemd is +updated, old build/ directories could keep the old default, which would be +annoying. Hence, "latest" is introduced to make it explicit, yet follow the +upstream. This is actually useful for the user too, because it may be used +as an override, without having to actually specify a version. + +(cherry picked from commit 06da5c63dd697ea4087e76c6d809b60b5780b87c) + +Related: #1827462 + +[msekleta: note that our default is not latest but rhel-8.0] +--- + doc/ENVIRONMENT.md | 15 +++++++------- + man/systemd-udevd.service.xml | 24 ++++++++++++--------- + meson.build | 4 ++++ + meson_options.txt | 3 +++ + src/udev/udev-builtin-net_id.c | 38 ++++++++++++++++++++-------------- + 5 files changed, 51 insertions(+), 33 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 1a4aa01ef4..0e763b6302 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -77,13 +77,14 @@ systemd-logind: + for it. + + * `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of +- v238, v239, v240 …) as parameter. If specified udev's net_id builtin will +- follow the specified naming scheme when determining stable network interface +- names. This may be used to revert to naming schemes of older udev versions, +- in order to provide more stable naming across updates. This environment +- variable takes precedence over the kernel command line option +- `net.naming-scheme=`, except if the value is prefixed with `:` in which case +- the kernel command line option takes precedence, if it is specified as well. ++ "rhel-8.0", "rhel-8.1", "rhel-8.2"…, or the special value "latest") as ++ parameter. If specified udev's net_id builtin will follow the specified ++ naming scheme when determining stable network interface names. This may be ++ used to revert to naming schemes of older udev versions, in order to provide ++ more stable naming across updates. This environment variable takes precedence ++ over the kernel command line option `net.naming-scheme=`, except if the value ++ is prefixed with `:` in which case the kernel command line option takes ++ precedence, if it is specified as well. + + installed systemd tests: + +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index 6449103441..b738591c93 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -174,16 +174,20 @@ + net.naming-scheme= + + Network interfaces are renamed to give them predictable names when possible (unless +- net.ifnames=0 is specified, see above). The names are derived from various device metadata +- fields. Newer versions of systemd-udevd.service take more of these fields into account, +- improving (and thus possibly changing) the names used for the same devices. With this kernel command line +- option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as +- argument. Currently the following identifiers are known: v238, v239, +- v240 which each implement the naming scheme that was the default in the indicated systemd +- version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the +- naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated, +- previously missing attributes systemd-udevd.service is checking might appear, which +- affects older name derivation algorithms, too. ++ net.ifnames=0 is specified, see above). The names are derived from various ++ device metadata fields. Newer versions of systemd-udevd.service take more of ++ these fields into account, improving (and thus possibly changing) the names used for the same ++ devices. With this kernel command line option it is possible to pick a specific version of this ++ algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers ++ are known: rhel-8.0, rhel-8.1, rhel-8.2, ++ rhel-8.3 which each implement the naming scheme that was the default in the ++ indicated Red Hat Enterprise Linux minor version. In addition, latest may be ++ used to designate the latest scheme known (to this particular version of ++ systemd-udevd.service). ++ Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: ++ the naming is generally derived from driver attributes exposed by the kernel. As the kernel is ++ updated, previously missing attributes systemd-udevd.service is checking might ++ appear, which affects older name derivation algorithms, too. + + + +diff --git a/meson.build b/meson.build +index 65c1d0785e..57de947367 100644 +--- a/meson.build ++++ b/meson.build +@@ -639,6 +639,9 @@ else + conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL') + endif + ++default_net_naming_scheme = get_option('default-net-naming-scheme') ++conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme) ++ + time_epoch = get_option('time-epoch') + if time_epoch == '' + NEWS = files('NEWS') +@@ -2925,6 +2928,7 @@ status = [ + 'default DNSSEC mode: @0@'.format(default_dnssec), + 'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls), + 'default cgroup hierarchy: @0@'.format(default_hierarchy), ++ 'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme), + 'default KillUserProcesses setting: @0@'.format(kill_user_processes)] + + alt_dns_servers = '\n '.join(dns_servers.split(' ')) +diff --git a/meson_options.txt b/meson_options.txt +index 0996891177..213079ac15 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -158,6 +158,9 @@ option('default-hierarchy', type : 'combo', + description : 'default cgroup hierarchy') + option('time-epoch', type : 'string', + description : 'time epoch for time clients') ++option('default-net-naming-scheme', type : 'combo', ++ choices : ['rhel-8.0', 'rhel-8.1', 'rhel-8.2', 'rhel-8.3', 'latest'], ++ description : 'default net.naming-scheme= value') + option('system-uid-max', type : 'string', + description : 'maximum system UID') + option('system-gid-max', type : 'string', +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 148696183e..d85dc2848b 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -185,6 +185,19 @@ struct virtfn_info { + char suffix[IFNAMSIZ]; + }; + ++static const NamingScheme* naming_scheme_from_name(const char *name) { ++ size_t i; ++ ++ if (streq(name, "latest")) ++ return naming_schemes + ELEMENTSOF(naming_schemes) - 1; ++ ++ for (i = 0; i < ELEMENTSOF(naming_schemes); i++) ++ if (streq(naming_schemes[i].name, name)) ++ return naming_schemes + i; ++ ++ return NULL; ++} ++ + static const NamingScheme* naming_scheme(void) { + static const NamingScheme *cache = NULL; + _cleanup_free_ char *buffer = NULL; +@@ -208,25 +221,18 @@ static const NamingScheme* naming_scheme(void) { + k = buffer; + + if (k) { +- size_t i; +- +- for (i = 0; i < ELEMENTSOF(naming_schemes); i++) +- if (streq(naming_schemes[i].name, k)) { +- cache = naming_schemes + i; +- break; +- } ++ cache = naming_scheme_from_name(k); ++ if (cache) { ++ log_info("Using interface naming scheme '%s'.", cache->name); ++ return cache; ++ } + +- if (!cache) +- log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); ++ log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); + } + +- if (cache) +- log_info("Using interface naming scheme '%s'.", cache->name); +- else { +- /* RHEL-only: here we differ from the upstream and if no naming scheme was selected we default to naming from systemd-239 */ +- cache = &naming_schemes[2]; +- log_info("Using default interface naming scheme '%s'.", cache->name); +- } ++ cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME); ++ assert(cache); ++ log_info("Using default interface naming scheme '%s'.", cache->name); + + return cache; + } diff --git a/SOURCES/0478-man-describe-naming-schemes-in-a-new-man-page.patch b/SOURCES/0478-man-describe-naming-schemes-in-a-new-man-page.patch new file mode 100644 index 0000000..be9f964 --- /dev/null +++ b/SOURCES/0478-man-describe-naming-schemes-in-a-new-man-page.patch @@ -0,0 +1,522 @@ +From af528dcffaab1efea760395cc6676fe4b01e89b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 9 May 2019 12:34:30 +0200 +Subject: [PATCH] man: describe naming schemes in a new man page + +I decided to make this a separate man page because it is freakin' long. +This content could equally well go in systemd-udevd.service(8), systemd.link(5), +or a new man page for the net_id builtin. + +v2: +- rename to systemd.net-naming-scheme +- add udevadm test-builtin net_id example + +(cherry picked from commit 0b1e5b6ed8c6b9a2bc53709eb75e381d360f05bf) + +Related: #1827462 + +[msekleta: I've removed parts that describe features which are not +available in RHEL-8] +--- + man/rules/meson.build | 1 + + man/systemd-udevd.service.xml | 19 +- + man/systemd.link.xml | 10 +- + man/systemd.net-naming-scheme.xml | 385 ++++++++++++++++++++++++++++++ + src/udev/udev-builtin-net_id.c | 1 + + 5 files changed, 402 insertions(+), 14 deletions(-) + create mode 100644 man/systemd.net-naming-scheme.xml + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 7ae94ea265..e6c0a99bbd 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -714,6 +714,7 @@ manpages = [ + ['systemd.kill', '5', [], ''], + ['systemd.link', '5', [], ''], + ['systemd.mount', '5', [], ''], ++ ['systemd.net-naming-scheme', '7', [], ''], + ['systemd.netdev', '5', [], 'ENABLE_NETWORKD'], + ['systemd.network', '5', [], 'ENABLE_NETWORKD'], + ['systemd.nspawn', '5', [], ''], +diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml +index b738591c93..f4cdb2f1e7 100644 +--- a/man/systemd-udevd.service.xml ++++ b/man/systemd-udevd.service.xml +@@ -174,15 +174,11 @@ + net.naming-scheme= + + Network interfaces are renamed to give them predictable names when possible (unless +- net.ifnames=0 is specified, see above). The names are derived from various +- device metadata fields. Newer versions of systemd-udevd.service take more of +- these fields into account, improving (and thus possibly changing) the names used for the same +- devices. With this kernel command line option it is possible to pick a specific version of this +- algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers +- are known: rhel-8.0, rhel-8.1, rhel-8.2, +- rhel-8.3 which each implement the naming scheme that was the default in the +- indicated Red Hat Enterprise Linux minor version. In addition, latest may be +- used to designate the latest scheme known (to this particular version of ++ net.ifnames=0 is specified, see above). With this kernel command line option it ++ is possible to pick a specific version of this algorithm and override the default chosen at ++ compilation time. Expects one of the naming scheme identifiers listed in ++ systemd.net-naming-scheme7, ++ or latest to select the latest scheme known (to this particular version of + systemd-udevd.service). + Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: + the naming is generally derived from driver attributes exposed by the kernel. As the kernel is +@@ -191,9 +187,8 @@ + + + +- +- ++ ++ + + + See Also +diff --git a/man/systemd.link.xml b/man/systemd.link.xml +index 6708753e82..32657308d0 100644 +--- a/man/systemd.link.xml ++++ b/man/systemd.link.xml +@@ -286,6 +286,7 @@ + The name is set based on information given by + the firmware for on-board devices, as exported by the + udev property ID_NET_NAME_ONBOARD. ++ See systemd.net-naming-scheme7. + + + +@@ -295,6 +296,7 @@ + The name is set based on information given by + the firmware for hot-plug devices, as exported by the + udev property ID_NET_NAME_SLOT. ++ See systemd.net-naming-scheme7. + + + +@@ -303,7 +305,9 @@ + + The name is set based on the device's physical + location, as exported by the udev property +- ID_NET_NAME_PATH. ++ ID_NET_NAME_PATH. ++ See systemd.net-naming-scheme7. ++ + + + +@@ -311,7 +315,9 @@ + + The name is set based on the device's persistent + MAC address, as exported by the udev property +- ID_NET_NAME_MAC. ++ ID_NET_NAME_MAC. ++ See systemd.net-naming-scheme7. ++ + + + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +new file mode 100644 +index 0000000000..a12cc3c460 +--- /dev/null ++++ b/man/systemd.net-naming-scheme.xml +@@ -0,0 +1,385 @@ ++ ++ ++ ++ ++ ++ ++ systemd.net-naming-scheme ++ systemd ++ ++ ++ ++ systemd.net-naming-scheme ++ 7 ++ ++ ++ ++ systemd.net-naming-scheme ++ Network device naming schemes ++ ++ ++ ++ Description ++ ++ Network interfaces may be renamed to give them predictable names when there's enough information to ++ generate appropriate names and the use of certain types of names is configured. This page describes the ++ first part, i.e. what possible names may be generated. Those names are generated by the ++ systemd-udevd.service8 ++ builtin net_id and exported as udev properties ++ (ID_NET_NAME_ONBOARD=, ID_NET_LABEL_ONBOARD=, ++ ID_NET_NAME_PATH=, ID_NET_NAME_SLOT=). ++ ++ Names are derived from various device metadata attributes. Newer versions of udev take more of ++ these attributes into account, improving (and thus possibly changing) the names used for the same ++ devices. Differents version of the naming rules are called "naming schemes". The default naming scheme is ++ chosen at compilation time. Usually this will be the latest implemented version, but it is also possible ++ to set one of the older versions to preserve compatibility. This may be useful for example for ++ distributions, which may introduce new versions of systemd in stable releases without changing the naming ++ scheme. The naming scheme may also be overriden using the net.naming-scheme= kernel ++ command line switch, see ++ systemd-udevd.service8. ++ Available naming schemes are described below. ++ ++ After the udev proprties have been generated, appropriate udev rules may be used to actually rename ++ devices based on those properties. See the description of NamePolicy= in ++ systemd.link5. ++ ++ ++ ++ ++ Naming ++ ++ All names start with a two-character prefix that signifies the interface type. ++ ++ ++ Two character prefixes based on the type of interface ++ ++ ++ ++ ++ Prefix ++ Description ++ ++ ++ ++ ++ en ++ Ethernet ++ ++ ++ sl ++ serial line IP (slip) ++ ++ ++ wl ++ Wireless local area network (WLAN) ++ ++ ++ ww ++ Wireless wide area network (WWAN) ++ ++ ++ ++
++ ++ The udev net_id builtin exports the following udev device properties: ++ ++ ++ ++ ID_NET_NAME_ONBOARD=prefixonumber ++ ++ This name is set based on the ordering information given by the firmware for ++ on-board devices. The name consists of the prefix, letter o, and a number ++ specified by the firmware. This is only available for PCI devices. ++ ++ ++ ++ ++ ID_NET_LABEL_ONBOARD=prefix label ++ ++ This property is set based on label given by the firmware for on-board devices. The ++ name consists of the prefix concatenated with the label. This is only available for PCI devices. ++ ++ ++ ++ ++ ++ ID_NET_NAME_MAC=prefixxAABBCCDDEEFF ++ ++ This name consists of the prefix, letter x, and 12 hexadecimal ++ digits of the MAC address. It is available if the device has a fixed MAC address. Because this name ++ is based on an attribute of the card itself, it remains "stable" when the device is moved (even ++ between machines), but will change when the hardware is replaced. ++ ++ ++ ++ ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port] ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]bnumber ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]uport…[cconfig][iinterface] ++ ID_NET_NAME_SLOT=prefix[Pdomain]sslot[ffunction][nport_name|ddev_port]vslot ++ ++ This property describes the slot position. Different schemes are used depending on ++ the bus type, as described in the table below. In all cases, PCI slot information must be known. In ++ case of USB, BCMA, and SR-VIO devices, the full name consists of the prefix, PCI slot identifier, ++ and USB or BCMA or SR-VIO slot identifier. The first two parts are denoted as "…" in the table ++ below. ++ ++ ++ Slot naming schemes ++ ++ ++ ++ ++ Format ++ Description ++ ++ ++ ++ ++ ++ prefix [Pdomainsslot [ffunction] [nport_name | ddev_port] ++ PCI slot number ++ ++ ++ ++ … bnumber ++ Broadcom bus (BCMA) core number ++ ++ ++ ++ … uport… [cconfig] [iinterface] ++ USB port number chain ++ ++ ++ ++ … vslot ++ SR-VIO slot number ++ ++ ++ ++
++ ++ The PCI domain is only prepended when it is not 0. All multi-function PCI devices will carry ++ the ffunction number in the device name, including ++ the function 0 device. For non-multi-function devices, the number is suppressed if 0. The port name ++ port_name is used, or the port number ++ ddev_port if the name is not known. ++ ++ For BCMA devices, the core number is suppressed when 0. ++ ++ For USB devices the full chain of port numbers of hubs is composed. If the name gets longer ++ than the maximum number of 15 characters, the name is not exported. The usual USB configuration ++ number 1 and interface number 0 values are suppressed. ++
++ ++ SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of ++ v and the virtual device number, with any leading zeros removed. The bus ++ number is ignored. This device type is found in IBM PowerVMs. ++
++ ++ ++ ID_NET_NAME_PATH=prefixcbus_id ++ ID_NET_NAME_PATH=prefixavendormodeliinstance ++ ID_NET_NAME_PATH=prefixiaddressnport_name ++ ID_NET_NAME_PATH=prefix[Pdomain]pbussslot[ffunction][nphys_port_name|ddev_port] ++ ID_NET_NAME_PATH=prefix[Pdomain]pbussslot[ffunction][nphys_port_name|ddev_port]bnumber ++ ID_NET_NAME_PATH=prefix[Pdomain]pbussslot[ffunction][nphys_port_name|ddev_port]uport…[cconfig][iinterface] ++ ++ This property describes the device installation location. Different schemes are ++ used depending on the bus type, as described in the table below. For BCMA and USB devices, PCI path ++ information must known, and the full name consists of the prefix, PCI slot identifier, and USB or ++ BCMA location. The first two parts are denoted as "…" in the table below. ++ ++ ++ Path naming schemes ++ ++ ++ ++ ++ Format ++ Description ++ ++ ++ ++ ++ ++ prefix cbus_id ++ CCW or grouped CCW device identifier ++ ++ ++ ++ prefix avendor model iinstance ++ ACPI path names for ARM64 platform devices ++ ++ ++ ++ prefix [Pdomainpbus sslot [ffunction] [nphys_port_name | ddev_port] ++ PCI geographical location ++ ++ ++ ++ … bnumber ++ Broadcom bus (BCMA) core number ++ ++ ++ ++ … uport… [cconfig] [iinterface] ++ USB port number chain ++ ++ ++ ++ ++
++ ++ CCW and grouped CCW devices are found in IBM System Z mainframes. Any leading zeros and ++ dots are suppressed. ++ ++ For PCI, BCMA, and USB devices, the same rules as described above for slot naming are ++ used. ++
++
++
++
++ ++ ++ History ++ ++ The following "naming schemes" have been defined: ++ ++ ++ ++ rhel-8.0 ++ ++ Naming was changed for virtual network interfaces created with SR-IOV and NPAR and ++ for devices where the PCI network controller device does not have a slot number associated. ++ ++ SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of ++ vport, where port is the ++ virtual device number. Previously those virtual devices were named as if completely independent. ++ ++ ++ The ninth and later NPAR virtual devices are named following the scheme used for the first ++ eight NPAR partitions. Previously those devices were not renamed and the kernel default ++ ("ethN") was used. ++ ++ Names are also generated for PCI devices where the PCI network controller device does not ++ have an associated slot number itself, but one of its parents does. Previously those devices were ++ not renamed and the kernel default was used. ++ ++ ++ ++ ++ rhel-8.1 ++ ++ Same as naming scheme rhel-8.0. ++ ++ ++ ++ rhel-8.2 ++ ++ Same as naming scheme rhel-8.0. ++ ++ ++ ++ rhel-8.3 ++ ++ Same as naming scheme rhel-8.0. ++ ++ ++ Note that latest may be used to denote the latest scheme known (to this ++ particular version of systemd. ++ ++ ++ ++ ++ Examples ++ ++ ++ Using <command>udevadm test-builtin</command> to display device properties ++ ++ $ udevadm test-builtin net_id /sys/class/net/enp0s31f6 ++... ++Using default interface naming scheme 'rhel-8.3'. ++ID_NET_NAMING_SCHEME=rhel-8.3 ++ID_NET_NAME_MAC=enx54ee75cb1dc0 ++ID_OUI_FROM_DATABASE=Wistron InfoComm(Kunshan)Co.,Ltd. ++ID_NET_NAME_PATH=enp0s31f6 ++... ++ ++ ++ ++ PCI Ethernet card with firmware index "1" ++ ++ ID_NET_NAME_ONBOARD=eno1 ++ID_NET_NAME_ONBOARD_LABEL=enEthernet Port 1 ++ ++ ++ ++ ++ ++ PCI Ethernet card in hotplug slot with firmware index number ++ ++ # /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1 ++ID_NET_NAME_MAC=enx000000000466 ++ID_NET_NAME_PATH=enp5s0 ++ID_NET_NAME_SLOT=ens1 ++ ++ ++ ++ PCI Ethernet multi-function card with 2 ports ++ ++ # /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0 ++ID_NET_NAME_MAC=enx78e7d1ea46da ++ID_NET_NAME_PATH=enp2s0f0 ++ ++# /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1 ++ID_NET_NAME_MAC=enx78e7d1ea46dc ++ID_NET_NAME_PATH=enp2s0f1 ++ ++ ++ ++ PCI WLAN card ++ ++ # /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0 ++ID_NET_NAME_MAC=wlx0024d7e31130 ++ID_NET_NAME_PATH=wlp3s0 ++ ++ ++ ++ USB built-in 3G modem ++ ++ # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6 ++ID_NET_NAME_MAC=wwx028037ec0200 ++ID_NET_NAME_PATH=wwp0s29u1u4i6 ++ ++ ++ ++ USB Android phone ++ ++ # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2 ++ID_NET_NAME_MAC=enxd626b3450fb5 ++ID_NET_NAME_PATH=enp0s29u1u2 ++ ++ ++ ++ s390 grouped CCW interface ++ ++ # /sys/devices/css0/0.0.0007/0.0.f5f0/group_device/net/encf5f0 ++ID_NET_NAME_MAC=enx026d3c00000a ++ID_NET_NAME_PATH=encf5f0 ++ ++ ++ ++ ++ See Also ++ ++ udev7, ++ udevadm8, ++ the ++ original page describing stable interface names ++ ++ ++ ++
+diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index d85dc2848b..aa553d5ade 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -78,6 +78,7 @@ + * /sys/devices/css0/0.0.0007/0.0.f5f0/group_device/net/encf5f0 + * ID_NET_NAME_MAC=enx026d3c00000a + * ID_NET_NAME_PATH=encf5f0 ++ * When the code here is changed, man/systemd.net-naming-scheme.xml must be updated too. + */ + + #include diff --git a/SOURCES/0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch b/SOURCES/0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch new file mode 100644 index 0000000..ea6dfa2 --- /dev/null +++ b/SOURCES/0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch @@ -0,0 +1,51 @@ +From 462420bc7ea22a05bfc2d021d395aade2b8ee7dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 19 Oct 2020 10:56:11 +0200 +Subject: [PATCH] udev/net_id: parse _SUN ACPI index as a signed integer + +Negative value means there is no match between a PCI device and any of +the slots. In the following commit we will extend this and value of 0 +will indicate that there is a match between some slot and PCI device, +but that device is a PCI bridge. + +(cherry picked from commit 3e545ae5abcf258791eacbee60c829c100a33274) + +Related: #1827462 +--- + src/udev/udev-builtin-net_id.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index aa553d5ade..ede24dee41 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -391,7 +391,8 @@ static bool is_pci_ari_enabled(struct udev_device *dev) { + + static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + struct udev *udev = udev_device_get_udev(names->pcidev); +- unsigned domain, bus, slot, func, dev_port = 0, hotplug_slot = 0; ++ unsigned domain, bus, slot, func, dev_port = 0; ++ int hotplug_slot = -1; + size_t l; + char *s; + const char *attr, *port_name; +@@ -449,15 +450,15 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + hotplug_slot_dev = names->pcidev; + while (hotplug_slot_dev) { + FOREACH_DIRENT_ALL(dent, dir, break) { +- unsigned i; +- int r; ++ int i, r; + char str[PATH_MAX]; + _cleanup_free_ char *address = NULL; + + if (dent->d_name[0] == '.') + continue; +- r = safe_atou_full(dent->d_name, 10, &i); +- if (i < 1 || r < 0) ++ ++ r = safe_atoi(dent->d_name, &i); ++ if (r < 0 || i <= 0) + continue; + + if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && diff --git a/SOURCES/0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch b/SOURCES/0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch new file mode 100644 index 0000000..2bd2478 --- /dev/null +++ b/SOURCES/0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch @@ -0,0 +1,124 @@ +From bb6114af097da0cd9c5081e42db718559130687f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= +Date: Mon, 19 Oct 2020 11:10:31 +0200 +Subject: [PATCH] udev/net_id: don't generate slot based names if multiple + devices might claim the same slot + +(cherry picked from commit 2c8ec0095e6fd2e72879d4915ff8a9e5c0664d0b) + +Resolves: #1827462 +--- + man/systemd.net-naming-scheme.xml | 15 ++++++++++- + src/udev/udev-builtin-net_id.c | 41 ++++++++++++++++++++++++++----- + 2 files changed, 49 insertions(+), 7 deletions(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index a12cc3c460..10e71dcb15 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -176,7 +176,10 @@ + + SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of + v and the virtual device number, with any leading zeros removed. The bus +- number is ignored. This device type is found in IBM PowerVMs. ++ number is ignored. ++ ++ 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. + + + +@@ -288,6 +291,16 @@ + Same as naming scheme rhel-8.0. + + ++ ++ rhel-8.4 ++ ++ 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 ID_NET_NAME_SLOT ++ 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 ID_NET_NAME_SLOT property to ++ avoid possible naming conflict. ++ ++ + Note that latest may be used to denote the latest scheme known (to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ede24dee41..d8c56b62bb 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -124,6 +124,7 @@ typedef enum NamingSchemeFlags { + /* First, the individual features */ + NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a40008b8299529c978ed8e11de8f6*/ + NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ ++ 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 */ + NAMING_V238 = 0, +@@ -132,6 +133,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_1 = NAMING_V239, + NAMING_RHEL_8_2 = NAMING_V239, + NAMING_RHEL_8_3 = NAMING_V239, ++ NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -389,6 +391,26 @@ static bool is_pci_ari_enabled(struct udev_device *dev) { + return streq_ptr(udev_device_get_sysattr_value(dev, "ari_enabled"), "1"); + } + ++static bool is_pci_bridge(struct udev_device *dev) { ++ const char *v, *p; ++ ++ v = udev_device_get_sysattr_value(dev, "modalias"); ++ if (!v) ++ 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(struct udev_device *dev, struct netnames *names) { + struct udev *udev = udev_device_get_udev(names->pcidev); + unsigned domain, bus, slot, func, dev_port = 0; +@@ -461,16 +483,23 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { + if (r < 0 || i <= 0) + continue; + ++ /* match slot address with device by stripping the function */ + if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && +- read_one_line_file(str, &address) >= 0) +- /* match slot address with device by stripping the function */ +- if (startswith(udev_device_get_sysname(hotplug_slot_dev), address)) +- hotplug_slot = i; ++ read_one_line_file(str, &address) >= 0 && ++ startswith(udev_device_get_sysname(hotplug_slot_dev), address)) { ++ 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; + +- if (hotplug_slot > 0) + break; ++ } + } +- if (hotplug_slot > 0) ++ if (hotplug_slot >= 0) + break; + rewinddir(dir); + hotplug_slot_dev = udev_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL); diff --git a/SOURCES/0481-fix-typo-in-ProtectSystem-option.patch b/SOURCES/0481-fix-typo-in-ProtectSystem-option.patch new file mode 100644 index 0000000..06f5f4c --- /dev/null +++ b/SOURCES/0481-fix-typo-in-ProtectSystem-option.patch @@ -0,0 +1,25 @@ +From 573229efeb2c5ade25794deee8cfe2f967414ef7 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 6 Nov 2020 10:13:19 +0100 +Subject: [PATCH] fix typo in ProtectSystem= option + +This was introduced by commit d9ae3222cfbd5d2a48e6dbade6617085cc76f1c1 . + +Resolves: #1871139 +--- + units/systemd-resolved.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in +index aad1a53a5f..f10f1d1690 100644 +--- a/units/systemd-resolved.service.in ++++ b/units/systemd-resolved.service.in +@@ -30,7 +30,7 @@ CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE + PrivateTmp=yes + PrivateDevices=yes +-ProtectSystems=strict ++ProtectSystem=strict + ProtectHome=yes + ProtectControlGroups=yes + ProtectKernelTunables=yes diff --git a/SOURCES/0482-remove-references-of-non-existent-man-pages.patch b/SOURCES/0482-remove-references-of-non-existent-man-pages.patch new file mode 100644 index 0000000..31ae5e0 --- /dev/null +++ b/SOURCES/0482-remove-references-of-non-existent-man-pages.patch @@ -0,0 +1,34 @@ +From 5e74048399c4610da27b5f7fbbb53784030aeb70 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 9 Nov 2020 09:27:02 +0100 +Subject: [PATCH] remove references of non-existent man pages + +This is a follow-up to commit 8ad89170001c9aba8849630ddb5da81d9e24a1bc, +which introduced the man page change. + +Resolves: #1876807 +--- + man/systemd.special.xml | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/man/systemd.special.xml b/man/systemd.special.xml +index c9d4345016..fe6324a4a0 100644 +--- a/man/systemd.special.xml ++++ b/man/systemd.special.xml +@@ -657,16 +657,6 @@ + target unit and pull in the target from it, also with Requires=. Note that by default this + target unit is not part of the initial boot transaction, but is supposed to be pulled in only if required by + units that want to run only on successful boots. +- +- See +- systemd-boot-check-no-failures.service8 +- for a service that implements a generic system health check and orders itself before +- boot-complete.target. +- +- See +- systemd-bless-boot.service8 +- for a service that propagates boot success information to the boot loader, and orders itself after +- boot-complete.target. + + + diff --git a/SOURCES/0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch b/SOURCES/0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch new file mode 100644 index 0000000..72141ba --- /dev/null +++ b/SOURCES/0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch @@ -0,0 +1,91 @@ +From b14c82dd9f9fcc42810614cf02efe8651897d36f Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 10 Jun 2020 20:19:41 +0200 +Subject: [PATCH] log: Prefer logging to CLI unless JOURNAL_STREAM is set + +(cherry picked from commit bc694c06e60505efeb09e5278a7b22cdfa23975e) + +Resolves: #1865840 +--- + src/basic/log.c | 32 +++++++++++++++++++++++++++++--- + test/TEST-21-SYSUSERS/test.sh | 3 +-- + 2 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/src/basic/log.c b/src/basic/log.c +index 48c094b548..9387e56a57 100644 +--- a/src/basic/log.c ++++ b/src/basic/log.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -19,6 +20,7 @@ + #include "sd-messages.h" + + #include "alloc-util.h" ++#include "extract-word.h" + #include "fd-util.h" + #include "format-util.h" + #include "io-util.h" +@@ -220,6 +222,32 @@ fail: + return r; + } + ++static bool stderr_is_journal(void) { ++ _cleanup_free_ char *w = NULL; ++ const char *e; ++ uint64_t dev, ino; ++ struct stat st; ++ ++ e = getenv("JOURNAL_STREAM"); ++ if (!e) ++ return false; ++ ++ if (extract_first_word(&e, &w, ":", EXTRACT_DONT_COALESCE_SEPARATORS) <= 0) ++ return false; ++ if (!e) ++ return false; ++ ++ if (safe_atou64(w, &dev) < 0) ++ return false; ++ if (safe_atou64(e, &ino) < 0) ++ return false; ++ ++ if (fstat(STDERR_FILENO, &st) < 0) ++ return false; ++ ++ return st.st_dev == dev && st.st_ino == ino; ++} ++ + int log_open(void) { + int r; + +@@ -239,9 +267,7 @@ int log_open(void) { + return 0; + } + +- if (log_target != LOG_TARGET_AUTO || +- getpid_cached() == 1 || +- isatty(STDERR_FILENO) <= 0) { ++ if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || stderr_is_journal()) { + + if (!prohibit_ipc && + IN_SET(log_target, LOG_TARGET_AUTO, +diff --git a/test/TEST-21-SYSUSERS/test.sh b/test/TEST-21-SYSUSERS/test.sh +index b1049e720d..3460d71f22 100755 +--- a/test/TEST-21-SYSUSERS/test.sh ++++ b/test/TEST-21-SYSUSERS/test.sh +@@ -108,8 +108,7 @@ test_run() { + echo "*** Running test $f" + prepare_testdir ${f%.input} + cp $f $TESTDIR/usr/lib/sysusers.d/test.conf +- systemd-sysusers --root=$TESTDIR 2> /dev/null +- journalctl -t systemd-sysusers -o cat | tail -n1 > $TESTDIR/tmp/err ++ systemd-sysusers --root=$TESTDIR 2>&1 | tail -n1 > $TESTDIR/tmp/err + if ! diff -u $TESTDIR/tmp/err ${f%.*}.expected-err; then + echo "**** Unexpected error output for $f" + cat $TESTDIR/tmp/err diff --git a/SOURCES/0484-locale-util-add-new-helper-locale_is_installed.patch b/SOURCES/0484-locale-util-add-new-helper-locale_is_installed.patch new file mode 100644 index 0000000..902a685 --- /dev/null +++ b/SOURCES/0484-locale-util-add-new-helper-locale_is_installed.patch @@ -0,0 +1,58 @@ +From f0d9e0cb24958bc11c8d83f0a3de651def2aa1d6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 30 Apr 2020 18:30:56 +0200 +Subject: [PATCH] locale-util: add new helper locale_is_installed() + +This new helper checks whether the specified locale is installed. It's +distinct from locale_is_valid() which just superficially checks if a +string looks like something that could be a valid locale. + +Heavily inspired by @jsynacek's #13964. + +Replaces: #13964 +(cherry picked from commit 23fa786ca67ed3a32930ff1a7b175ac823db187c) + +Related: #1755287 +--- + src/basic/locale-util.c | 15 +++++++++++++++ + src/basic/locale-util.h | 1 + + 2 files changed, 16 insertions(+) + +diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c +index 7cd143ea6f..42ef309ebd 100644 +--- a/src/basic/locale-util.c ++++ b/src/basic/locale-util.c +@@ -204,6 +204,21 @@ bool locale_is_valid(const char *name) { + return true; + } + ++int locale_is_installed(const char *name) { ++ if (!locale_is_valid(name)) ++ return false; ++ ++ if (STR_IN_SET(name, "C", "POSIX")) /* These ones are always OK */ ++ return true; ++ ++ _cleanup_(freelocalep) locale_t loc = ++ newlocale(LC_ALL_MASK, name, 0); ++ if (loc == (locale_t) 0) ++ return errno == ENOMEM ? -ENOMEM : false; ++ ++ return true; ++} ++ + void init_gettext(void) { + setlocale(LC_ALL, ""); + textdomain(GETTEXT_PACKAGE); +diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h +index 368675f286..b40f9c641a 100644 +--- a/src/basic/locale-util.h ++++ b/src/basic/locale-util.h +@@ -31,6 +31,7 @@ typedef enum LocaleVariable { + + int get_locales(char ***l); + bool locale_is_valid(const char *name); ++int locale_is_installed(const char *name); + + #define _(String) gettext(String) + #define N_(String) String diff --git a/SOURCES/0485-test-add-test-case-for-locale_is_installed.patch b/SOURCES/0485-test-add-test-case-for-locale_is_installed.patch new file mode 100644 index 0000000..57abbe8 --- /dev/null +++ b/SOURCES/0485-test-add-test-case-for-locale_is_installed.patch @@ -0,0 +1,53 @@ +From 3d08c7971a80370f60dd14b068779851e0f82c24 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 30 Apr 2020 18:32:55 +0200 +Subject: [PATCH] test: add test case for locale_is_installed() + +(cherry picked from commit b45b0a69bb7ef3e6e66d443eae366b6d1c387cab) + +Related: #1755287 +--- + src/test/test-locale-util.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c +index 0c3f6a62ed..0d50c33ce5 100644 +--- a/src/test/test-locale-util.c ++++ b/src/test/test-locale-util.c +@@ -34,6 +34,28 @@ static void test_locale_is_valid(void) { + assert_se(!locale_is_valid("\x01gar\x02 bage\x03")); + } + ++static void test_locale_is_installed(void) { ++ log_info("/* %s */", __func__); ++ ++ /* Always available */ ++ assert_se(locale_is_installed("POSIX") > 0); ++ assert_se(locale_is_installed("C") > 0); ++ ++ /* Might, or might not be installed. */ ++ assert_se(locale_is_installed("en_EN.utf8") >= 0); ++ assert_se(locale_is_installed("fr_FR.utf8") >= 0); ++ assert_se(locale_is_installed("fr_FR@euro") >= 0); ++ assert_se(locale_is_installed("fi_FI") >= 0); ++ ++ /* Definitely not valid */ ++ assert_se(locale_is_installed("") == 0); ++ assert_se(locale_is_installed("/usr/bin/foo") == 0); ++ assert_se(locale_is_installed("\x01gar\x02 bage\x03") == 0); ++ ++ /* Definitely not installed */ ++ assert_se(locale_is_installed("zz_ZZ") == 0); ++} ++ + static void test_keymaps(void) { + _cleanup_strv_free_ char **kmaps = NULL; + char **p; +@@ -95,6 +117,7 @@ static void dump_special_glyphs(void) { + int main(int argc, char *argv[]) { + test_get_locales(); + test_locale_is_valid(); ++ test_locale_is_installed(); + test_keymaps(); + + dump_special_glyphs(); diff --git a/SOURCES/0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch b/SOURCES/0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch new file mode 100644 index 0000000..cb4ec8d --- /dev/null +++ b/SOURCES/0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch @@ -0,0 +1,232 @@ +From 5813180a75aa1ef90f6d3459fc5beb099b815cfb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 30 Apr 2020 18:32:44 +0200 +Subject: [PATCH] tree-wide: port various bits over to locale_is_installed() + +(cherry picked from commit a00a78b84e2ab352b3144bfae8bc578d172303be) + +Resolves: #1755287 +--- + src/firstboot/firstboot.c | 30 ++++++++------ + src/locale/localed.c | 87 ++++++++++++++++++++++++--------------- + 2 files changed, 71 insertions(+), 46 deletions(-) + +diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c +index a98e53b3a3..7e177a50fa 100644 +--- a/src/firstboot/firstboot.c ++++ b/src/firstboot/firstboot.c +@@ -192,6 +192,14 @@ static int prompt_loop(const char *text, char **l, bool (*is_valid)(const char * + } + } + ++static bool locale_is_ok(const char *name) { ++ ++ if (arg_root) ++ return locale_is_valid(name); ++ ++ return locale_is_installed(name) > 0; ++} ++ + static int prompt_locale(void) { + _cleanup_strv_free_ char **locales = NULL; + int r; +@@ -215,14 +223,14 @@ static int prompt_locale(void) { + + putchar('\n'); + +- r = prompt_loop("Please enter system locale name or number", locales, locale_is_valid, &arg_locale); ++ r = prompt_loop("Please enter system locale name or number", locales, locale_is_ok, &arg_locale); + if (r < 0) + return r; + + if (isempty(arg_locale)) + return 0; + +- r = prompt_loop("Please enter system message locale name or number", locales, locale_is_valid, &arg_locale_messages); ++ r = prompt_loop("Please enter system message locale name or number", locales, locale_is_ok, &arg_locale_messages); + if (r < 0) + return r; + +@@ -780,11 +788,6 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_LOCALE: +- if (!locale_is_valid(optarg)) { +- log_error("Locale %s is not valid.", optarg); +- return -EINVAL; +- } +- + r = free_and_strdup(&arg_locale, optarg); + if (r < 0) + return log_oom(); +@@ -792,11 +795,6 @@ static int parse_argv(int argc, char *argv[]) { + break; + + case ARG_LOCALE_MESSAGES: +- if (!locale_is_valid(optarg)) { +- log_error("Locale %s is not valid.", optarg); +- return -EINVAL; +- } +- + r = free_and_strdup(&arg_locale_messages, optarg); + if (r < 0) + return log_oom(); +@@ -922,6 +920,14 @@ static int parse_argv(int argc, char *argv[]) { + assert_not_reached("Unhandled option"); + } + ++ /* We check if the specified locale strings are valid down here, so that we can take --root= into ++ * account when looking for the locale files. */ ++ ++ if (arg_locale && !locale_is_ok(arg_locale)) ++ return log_error_errno(EINVAL, "Locale %s is not installed.", arg_locale); ++ if (arg_locale_messages && !locale_is_ok(arg_locale_messages)) ++ return log_error_errno(EINVAL, "Locale %s is not installed.", arg_locale_messages); ++ + return 1; + } + +diff --git a/src/locale/localed.c b/src/locale/localed.c +index 253973fd49..d6ed40babe 100644 +--- a/src/locale/localed.c ++++ b/src/locale/localed.c +@@ -259,18 +259,57 @@ static void locale_free(char ***l) { + (*l)[p] = mfree((*l)[p]); + } + ++static int process_locale_list_item( ++ const char *assignment, ++ char *new_locale[static _VARIABLE_LC_MAX], ++ sd_bus_error *error) { ++ ++ assert(assignment); ++ assert(new_locale); ++ ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) { ++ const char *name, *e; ++ ++ assert_se(name = locale_variable_to_string(p)); ++ ++ e = startswith(assignment, name); ++ if (!e) ++ continue; ++ ++ if (*e != '=') ++ continue; ++ ++ e++; ++ ++ if (!locale_is_valid(e)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s is not valid, refusing.", e); ++ if (locale_is_installed(e) <= 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s not installed, refusing.", e); ++ if (new_locale[p]) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name); ++ ++ new_locale[p] = strdup(e); ++ if (!new_locale[p]) ++ return -ENOMEM; ++ ++ return 0; ++ } ++ ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment); ++} ++ + static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *error) { + Context *c = userdata; + _cleanup_strv_free_ char **settings = NULL, **l = NULL; + char *new_locale[_VARIABLE_LC_MAX] = {}, **i; + _cleanup_(locale_free) _unused_ char **dummy = new_locale; + bool modified = false; +- int interactive, p, r; ++ int interactive, r; + + assert(m); + assert(c); + +- r = bus_message_read_strv_extend(m, &l); ++ r = sd_bus_message_read_strv(m, &l); + if (r < 0) + return r; + +@@ -279,11 +318,13 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + return r; + + /* If single locale without variable name is provided, then we assume it is LANG=. */ +- if (strv_length(l) == 1 && !strchr(*l, '=')) { +- if (!locale_is_valid(*l)) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data."); ++ if (strv_length(l) == 1 && !strchr(l[0], '=')) { ++ if (!locale_is_valid(l[0])) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid locale specification: %s", l[0]); ++ if (locale_is_installed(l[0]) <= 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified locale is not installed: %s", l[0]); + +- new_locale[VARIABLE_LANG] = strdup(*l); ++ new_locale[VARIABLE_LANG] = strdup(l[0]); + if (!new_locale[VARIABLE_LANG]) + return -ENOMEM; + +@@ -292,31 +333,9 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + + /* Check whether a variable is valid */ + STRV_FOREACH(i, l) { +- bool valid = false; +- +- for (p = 0; p < _VARIABLE_LC_MAX; p++) { +- size_t k; +- const char *name; +- +- name = locale_variable_to_string(p); +- assert(name); +- +- k = strlen(name); +- if (startswith(*i, name) && +- (*i)[k] == '=' && +- locale_is_valid((*i) + k + 1)) { +- valid = true; +- +- new_locale[p] = strdup((*i) + k + 1); +- if (!new_locale[p]) +- return -ENOMEM; +- +- break; +- } +- } +- +- if (!valid) +- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data."); ++ r = process_locale_list_item(*i, new_locale, error); ++ if (r < 0) ++ return r; + } + + /* If LANG was specified, but not LANGUAGE, check if we should +@@ -339,7 +358,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + } + + /* Merge with the current settings */ +- for (p = 0; p < _VARIABLE_LC_MAX; p++) ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) + if (!isempty(c->locale[p]) && isempty(new_locale[p])) { + new_locale[p] = strdup(c->locale[p]); + if (!new_locale[p]) +@@ -348,7 +367,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + + locale_simplify(new_locale); + +- for (p = 0; p < _VARIABLE_LC_MAX; p++) ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) + if (!streq_ptr(c->locale[p], new_locale[p])) { + modified = true; + break; +@@ -373,7 +392,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er + if (r == 0) + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + +- for (p = 0; p < _VARIABLE_LC_MAX; p++) ++ for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) + free_and_replace(c->locale[p], new_locale[p]); + + r = locale_write_data(c, &settings); diff --git a/SOURCES/0487-install-allow-instantiated-units-to-be-enabled-via-p.patch b/SOURCES/0487-install-allow-instantiated-units-to-be-enabled-via-p.patch new file mode 100644 index 0000000..363f424 --- /dev/null +++ b/SOURCES/0487-install-allow-instantiated-units-to-be-enabled-via-p.patch @@ -0,0 +1,339 @@ +From 4c41ad9418058aefb2d2732b0b65da9c7cdf5151 Mon Sep 17 00:00:00 2001 +From: Ruixin Bao +Date: Tue, 21 Aug 2018 20:40:56 +0000 +Subject: [PATCH] install: allow instantiated units to be enabled via presets + +This patch implements https://github.com/systemd/systemd/issues/9421. + +The .preset file now is able to take a rule in the format of:(e.g) +enable foo@.service bar0 bar1 bar2 + +In the above example, when preset-all is called, all three instances of +foo@bar0.service, foo@bar1.service and foo@bar2.service will be enabled. + +When preset is called on a single service(e.g: foo@bar1.service), only +the mentioned one(foo@bar1.service) will be enabled. + +Tests are added for future regression. + +(cherry picked from commit 4c9565eea534cd233a913c8c21f7920dba229743) + +Resolves: #1812972 +--- + src/shared/install.c | 155 ++++++++++++++++++++++++++++++----- + src/test/test-install-root.c | 57 +++++++++++++ + 2 files changed, 193 insertions(+), 19 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 77ae812878..1d4beaa83b 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -60,6 +60,7 @@ typedef enum { + typedef struct { + char *pattern; + PresetAction action; ++ char **instances; + } PresetRule; + + typedef struct { +@@ -87,8 +88,10 @@ static inline void presets_freep(Presets *p) { + if (!p) + return; + +- for (i = 0; i < p->n_rules; i++) ++ for (i = 0; i < p->n_rules; i++) { + free(p->rules[i].pattern); ++ strv_free(p->rules[i].instances); ++ } + + free(p->rules); + p->n_rules = 0; +@@ -2755,6 +2758,39 @@ int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char * + return 1; + } + ++static int split_pattern_into_name_and_instances(const char *pattern, char **out_unit_name, char ***out_instances) { ++ _cleanup_strv_free_ char **instances = NULL; ++ _cleanup_free_ char *unit_name = NULL; ++ int r; ++ ++ assert(pattern); ++ assert(out_instances); ++ assert(out_unit_name); ++ ++ r = extract_first_word(&pattern, &unit_name, NULL, 0); ++ if (r < 0) ++ return r; ++ ++ /* We handle the instances logic when unit name is extracted */ ++ if (pattern) { ++ /* We only create instances when a rule of templated unit ++ * is seen. A rule like enable foo@.service a b c will ++ * result in an array of (a, b, c) as instance names */ ++ if (!unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) ++ return -EINVAL; ++ ++ instances = strv_split(pattern, WHITESPACE); ++ if (!instances) ++ return -ENOMEM; ++ ++ *out_instances = TAKE_PTR(instances); ++ } ++ ++ *out_unit_name = TAKE_PTR(unit_name); ++ ++ return 0; ++} ++ + static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) { + _cleanup_(presets_freep) Presets ps = {}; + size_t n_allocated = 0; +@@ -2824,15 +2860,20 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres + + parameter = first_word(l, "enable"); + if (parameter) { +- char *pattern; ++ char *unit_name; ++ char **instances = NULL; + +- pattern = strdup(parameter); +- if (!pattern) +- return -ENOMEM; ++ /* Unit_name will remain the same as parameter when no instances are specified */ ++ r = split_pattern_into_name_and_instances(parameter, &unit_name, &instances); ++ if (r < 0) { ++ log_syntax(NULL, LOG_WARNING, *p, n, 0, "Couldn't parse line '%s'. Ignoring.", line); ++ continue; ++ } + + rule = (PresetRule) { +- .pattern = pattern, ++ .pattern = unit_name, + .action = PRESET_ENABLE, ++ .instances = instances, + }; + } + +@@ -2868,15 +2909,71 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres + return 0; + } + +-static int query_presets(const char *name, const Presets presets) { ++static int pattern_match_multiple_instances( ++ const PresetRule rule, ++ const char *unit_name, ++ char ***ret) { ++ ++ _cleanup_free_ char *templated_name = NULL; ++ int r; ++ ++ /* If no ret is needed or the rule itself does not have instances ++ * initalized, we return not matching */ ++ if (!ret || !rule.instances) ++ return 0; ++ ++ r = unit_name_template(unit_name, &templated_name); ++ if (r < 0) ++ return r; ++ if (!streq(rule.pattern, templated_name)) ++ return 0; ++ ++ /* Compose a list of specified instances when unit name is a template */ ++ if (unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) { ++ _cleanup_free_ char *prefix = NULL; ++ _cleanup_strv_free_ char **out_strv = NULL; ++ char **iter; ++ ++ r = unit_name_to_prefix(unit_name, &prefix); ++ if (r < 0) ++ return r; ++ ++ STRV_FOREACH(iter, rule.instances) { ++ _cleanup_free_ char *name = NULL; ++ r = unit_name_build(prefix, *iter, ".service", &name); ++ if (r < 0) ++ return r; ++ r = strv_extend(&out_strv, name); ++ if (r < 0) ++ return r; ++ } ++ ++ *ret = TAKE_PTR(out_strv); ++ return 1; ++ } else { ++ /* We now know the input unit name is an instance name */ ++ _cleanup_free_ char *instance_name = NULL; ++ ++ r = unit_name_to_instance(unit_name, &instance_name); ++ if (r < 0) ++ return r; ++ ++ if (strv_find(rule.instances, instance_name)) ++ return 1; ++ } ++ return 0; ++} ++ ++static int query_presets(const char *name, const Presets presets, char ***instance_name_list) { + PresetAction action = PRESET_UNKNOWN; + size_t i; +- ++ char **s; + if (!unit_name_is_valid(name, UNIT_NAME_ANY)) + return -EINVAL; + + for (i = 0; i < presets.n_rules; i++) +- if (fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) { ++ if (pattern_match_multiple_instances(presets.rules[i], name, instance_name_list) > 0 || ++ fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) { + action = presets.rules[i].action; + break; + } +@@ -2886,7 +2983,11 @@ static int query_presets(const char *name, const Presets presets) { + log_debug("Preset files don't specify rule for %s. Enabling.", name); + return 1; + case PRESET_ENABLE: +- log_debug("Preset files say enable %s.", name); ++ if (instance_name_list && *instance_name_list) ++ STRV_FOREACH(s, *instance_name_list) ++ log_debug("Preset files say enable %s.", *s); ++ else ++ log_debug("Preset files say enable %s.", name); + return 1; + case PRESET_DISABLE: + log_debug("Preset files say disable %s.", name); +@@ -2904,7 +3005,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char + if (r < 0) + return r; + +- return query_presets(name, presets); ++ return query_presets(name, presets, NULL); + } + + static int execute_preset( +@@ -2964,6 +3065,7 @@ static int preset_prepare_one( + size_t *n_changes) { + + _cleanup_(install_context_done) InstallContext tmp = {}; ++ _cleanup_strv_free_ char **instance_name_list = NULL; + UnitFileInstallInfo *i; + int r; + +@@ -2979,19 +3081,34 @@ static int preset_prepare_one( + return 0; + } + +- r = query_presets(name, presets); ++ r = query_presets(name, presets, &instance_name_list); + if (r < 0) + return r; + + if (r > 0) { +- r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; ++ if (instance_name_list) { ++ char **s; ++ STRV_FOREACH(s, instance_name_list) { ++ r = install_info_discover(scope, plus, paths, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); ++ if (r < 0) ++ return r; ++ ++ r = install_info_may_process(i, paths, changes, n_changes); ++ if (r < 0) ++ return r; ++ } ++ } else { ++ r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); ++ if (r < 0) ++ return r; ++ ++ r = install_info_may_process(i, paths, changes, n_changes); ++ if (r < 0) ++ return r; ++ } + +- r = install_info_may_process(i, paths, changes, n_changes); +- if (r < 0) +- return r; + } else + r = install_info_discover(scope, minus, paths, name, SEARCH_FOLLOW_CONFIG_SYMLINKS, + &i, changes, n_changes); +diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c +index 15dd3c6966..dbbcfe4297 100644 +--- a/src/test/test-install-root.c ++++ b/src/test/test-install-root.c +@@ -983,6 +983,62 @@ static void test_with_dropin_template(const char *root) { + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3@instance-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + } + ++static void test_preset_multiple_instances(const char *root) { ++ UnitFileChange *changes = NULL; ++ size_t n_changes = 0; ++ const char *p; ++ UnitFileState state; ++ ++ /* Set up template service files and preset file */ ++ p = strjoina(root, "/usr/lib/systemd/system/foo@.service"); ++ assert_se(write_string_file(p, ++ "[Install]\n" ++ "DefaultInstance=def\n" ++ "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ p = strjoina(root, "/usr/lib/systemd/system-preset/test.preset"); ++ assert_se(write_string_file(p, ++ "enable foo@.service bar0 bar1 bartest\n" ++ "enable emptylist@.service\n" /* This line ensures the old functionality for templated unit still works */ ++ "disable *\n" , WRITE_STRING_FILE_CREATE) >= 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ /* Preset a single instantiated unit specified in the list */ ++ assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ assert_se(n_changes == 1); ++ assert_se(changes[0].type == UNIT_FILE_SYMLINK); ++ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service"); ++ assert_se(streq(changes[0].path, p)); ++ unit_file_changes_free(changes, n_changes); ++ changes = NULL; n_changes = 0; ++ ++ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), &changes, &n_changes) >= 0); ++ assert_se(n_changes == 1); ++ assert_se(changes[0].type == UNIT_FILE_UNLINK); ++ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service"); ++ assert_se(streq(changes[0].path, p)); ++ unit_file_changes_free(changes, n_changes); ++ changes = NULL; n_changes = 0; ++ ++ /* Check for preset-all case, only instances on the list should be enabled, not including the default instance */ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ ++ assert_se(unit_file_preset_all(UNIT_FILE_SYSTEM, 0, root, UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); ++ assert_se(n_changes > 0); ++ ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_ENABLED); ++ ++} ++ + int main(int argc, char *argv[]) { + char root[] = "/tmp/rootXXXXXX"; + const char *p; +@@ -1012,6 +1068,7 @@ int main(int argc, char *argv[]) { + test_indirect(root); + test_preset_and_list(root); + test_preset_order(root); ++ test_preset_multiple_instances(root); + test_revert(root); + test_static_instance(root); + test_with_dropin(root); diff --git a/SOURCES/0488-install-small-refactor-to-combine-two-function-calls.patch b/SOURCES/0488-install-small-refactor-to-combine-two-function-calls.patch new file mode 100644 index 0000000..68e7ae2 --- /dev/null +++ b/SOURCES/0488-install-small-refactor-to-combine-two-function-calls.patch @@ -0,0 +1,127 @@ +From eacb511fc0d1e3c5857cb041ad162fb78b4381cc Mon Sep 17 00:00:00 2001 +From: Ruixin Bao +Date: Sun, 26 Aug 2018 20:00:03 +0000 +Subject: [PATCH] install: small refactor to combine two function calls into + one function + +Combine consecutive function calls of install_info_discover and +install_info_may_process into one short helper function. + +(cherry picked from commit 1e475a0ab4c46eb07f3df3fb24f5a7c3e1fa20b1) + +Related: #1812972 +--- + src/shared/install.c | 61 ++++++++++++++++++++++---------------------- + 1 file changed, 30 insertions(+), 31 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 1d4beaa83b..263b239f10 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -1676,6 +1676,25 @@ static int install_info_discover( + return r; + } + ++static int install_info_discover_and_check( ++ UnitFileScope scope, ++ InstallContext *c, ++ const LookupPaths *paths, ++ const char *name, ++ SearchFlags flags, ++ UnitFileInstallInfo **ret, ++ UnitFileChange **changes, ++ size_t *n_changes) { ++ ++ int r; ++ ++ r = install_info_discover(scope, c, paths, name, flags, ret, changes, n_changes); ++ if (r < 0) ++ return r; ++ ++ return install_info_may_process(ret ? *ret : NULL, paths, changes, n_changes); ++} ++ + static int install_info_symlink_alias( + UnitFileInstallInfo *i, + const LookupPaths *paths, +@@ -2399,11 +2418,8 @@ int unit_file_add_dependency( + if (!config_path) + return -ENXIO; + +- r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &target_info, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(target_info, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &target_info, changes, n_changes); + if (r < 0) + return r; + +@@ -2412,11 +2428,8 @@ int unit_file_add_dependency( + STRV_FOREACH(f, files) { + char ***l; + +- r = install_info_discover(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(i, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, *f, SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + +@@ -2467,11 +2480,8 @@ int unit_file_enable( + return -ENXIO; + + STRV_FOREACH(f, files) { +- r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(i, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + +@@ -2585,10 +2595,7 @@ int unit_file_set_default( + if (r < 0) + return r; + +- r = install_info_discover(scope, &c, &paths, name, 0, &i, changes, n_changes); +- if (r < 0) +- return r; +- r = install_info_may_process(i, &paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, &c, &paths, name, 0, &i, changes, n_changes); + if (r < 0) + return r; + +@@ -3089,22 +3096,14 @@ static int preset_prepare_one( + if (instance_name_list) { + char **s; + STRV_FOREACH(s, instance_name_list) { +- r = install_info_discover(scope, plus, paths, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- +- r = install_info_may_process(i, paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, plus, paths, *s, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + } + } else { +- r = install_info_discover(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, +- &i, changes, n_changes); +- if (r < 0) +- return r; +- +- r = install_info_may_process(i, paths, changes, n_changes); ++ r = install_info_discover_and_check(scope, plus, paths, name, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, ++ &i, changes, n_changes); + if (r < 0) + return r; + } diff --git a/SOURCES/0489-test-fix-a-memleak.patch b/SOURCES/0489-test-fix-a-memleak.patch new file mode 100644 index 0000000..d01dea9 --- /dev/null +++ b/SOURCES/0489-test-fix-a-memleak.patch @@ -0,0 +1,28 @@ +From 7444c6ed3628484dfed2f204c5b78a06a50f4bd8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 29 Aug 2018 23:27:42 +0900 +Subject: [PATCH] test: fix a memleak + +Follow-up for #9901. + +Fixes #9968. + +(cherry picked from commit efa146369398fdb73f1cd177eb2522822ebf559c) + +Related: #1812972 +--- + src/test/test-install-root.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c +index dbbcfe4297..fe1ca5b16f 100644 +--- a/src/test/test-install-root.c ++++ b/src/test/test-install-root.c +@@ -1037,6 +1037,7 @@ static void test_preset_multiple_instances(const char *root) { + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar1.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bartest.service", &state) >= 0 && state == UNIT_FILE_ENABLED); + ++ unit_file_changes_free(changes, n_changes); + } + + int main(int argc, char *argv[]) { diff --git a/SOURCES/0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch b/SOURCES/0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch new file mode 100644 index 0000000..2f726d0 --- /dev/null +++ b/SOURCES/0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch @@ -0,0 +1,55 @@ +From 55df2fd634f900419b718ed354132cc86cd533dd Mon Sep 17 00:00:00 2001 +From: Joerg Behrmann +Date: Tue, 10 Mar 2020 16:34:13 +0100 +Subject: [PATCH] docs: Add syntax for templated units to systemd.preset man + page + +This documents the syntax + + enable template@.service foo bar baz + +that was introduced in #9901 to preset templated units. + +(cherry picked from commit 1f667d8a7cff4355cd23ebebeb4d7179e3498eb8) + +Related: #1812972 +--- + man/systemd.preset.xml | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml +index cf807bd4c8..df401f00f3 100644 +--- a/man/systemd.preset.xml ++++ b/man/systemd.preset.xml +@@ -71,8 +71,11 @@ + either the word enable or + disable followed by a space and a unit name + (possibly with shell style wildcards), separated by newlines. +- Empty lines and lines whose first non-whitespace character is # or +- ; are ignored. ++ Empty lines and lines whose first non-whitespace character is # or ++ ; are ignored. Multiple instance names for unit ++ templates may be specified as a space separated list at the end of ++ the line instead of the customary position between @ ++ and the unit suffix. + + Presets must refer to the "real" unit file, and not to any aliases. See + systemd.unit5 +@@ -124,6 +127,17 @@ disable * + 99-, it will be read last and hence can easily + be overridden by spin or administrator preset policy. + ++ ++ Enable multiple template instances ++ ++ # /usr/lib/systemd/system-preset/80-dirsrv.preset ++ ++enable dirsrv@.service foo bar baz ++ ++ ++ This enables all three of dirsrv@foo.service, ++ dirsrv@bar.service and dirsrv@baz.service. ++ + + A GNOME spin + diff --git a/SOURCES/0491-shared-install-fix-preset-operations-for-non-service.patch b/SOURCES/0491-shared-install-fix-preset-operations-for-non-service.patch new file mode 100644 index 0000000..ea936c9 --- /dev/null +++ b/SOURCES/0491-shared-install-fix-preset-operations-for-non-service.patch @@ -0,0 +1,45 @@ +From db2816ee32fc81ba339175469e46b5dca7af8833 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 22 Aug 2020 11:58:15 +0200 +Subject: [PATCH] shared/install: fix preset operations for non-service + instantiated units + +Fixes https://github.com/coreos/ignition/issues/1064. + +(cherry picked from commit 47ab95fe4315b3f7ee5a3694460a744bb88c52fd) + +Related: #1812972 +--- + src/shared/install.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/shared/install.c b/src/shared/install.c +index 263b239f10..c2847df3f8 100644 +--- a/src/shared/install.c ++++ b/src/shared/install.c +@@ -2937,20 +2937,17 @@ static int pattern_match_multiple_instances( + + /* Compose a list of specified instances when unit name is a template */ + if (unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) { +- _cleanup_free_ char *prefix = NULL; + _cleanup_strv_free_ char **out_strv = NULL; +- char **iter; +- +- r = unit_name_to_prefix(unit_name, &prefix); +- if (r < 0) +- return r; + ++ char **iter; + STRV_FOREACH(iter, rule.instances) { + _cleanup_free_ char *name = NULL; +- r = unit_name_build(prefix, *iter, ".service", &name); ++ ++ r = unit_name_replace_instance(unit_name, *iter, &name); + if (r < 0) + return r; +- r = strv_extend(&out_strv, name); ++ ++ r = strv_consume(&out_strv, TAKE_PTR(name)); + if (r < 0) + return r; + } diff --git a/SOURCES/0492-introduce-setsockopt_int-helper.patch b/SOURCES/0492-introduce-setsockopt_int-helper.patch new file mode 100644 index 0000000..7991184 --- /dev/null +++ b/SOURCES/0492-introduce-setsockopt_int-helper.patch @@ -0,0 +1,30 @@ +From 8cff80d7fc28ca04bd6c8e2257b46d96bea338ce Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 18 Oct 2018 19:48:18 +0200 +Subject: [PATCH] introduce setsockopt_int() helper + +As suggested by @heftig: + +https://github.com/systemd/systemd/commit/6d5e65f6454212cd400d0ebda34978a9f20cc26a#commitcomment-30938667 +(cherry picked from commit 2ff48e981e6cd1ccbfae49943274d9c8319a5e5d) + +Related: #1887181 +--- + src/basic/socket-util.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 82781a0de1..616f2e0d05 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -183,3 +183,10 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng + }) + + int socket_ioctl_fd(void); ++ ++static inline int setsockopt_int(int fd, int level, int optname, int value) { ++ if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0) ++ return -errno; ++ ++ return 0; ++} diff --git a/SOURCES/0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch b/SOURCES/0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch new file mode 100644 index 0000000..aa0679b --- /dev/null +++ b/SOURCES/0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch @@ -0,0 +1,57 @@ +From 96681723232e9eb0182279086fef291283004806 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 May 2020 19:27:51 +0200 +Subject: [PATCH] socket-util: add generic socket_pass_pktinfo() helper + +The helper turns on the protocol specific "packet info" structure cmsg +for three relevant protocols we know. + +(cherry picked from commit 35a3eb9bdc95d1e6ba25bc65c78959ea104e45a1) + +Related: #1887181 +--- + src/basic/socket-util.c | 23 +++++++++++++++++++++++ + src/basic/socket-util.h | 2 ++ + 2 files changed, 25 insertions(+) + +diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c +index 986bc6e67f..053bcba670 100644 +--- a/src/basic/socket-util.c ++++ b/src/basic/socket-util.c +@@ -1246,3 +1246,26 @@ int socket_ioctl_fd(void) { + + return fd; + } ++ ++int socket_pass_pktinfo(int fd, bool b) { ++ int af; ++ socklen_t sl = sizeof(af); ++ ++ if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0) ++ return -errno; ++ ++ switch (af) { ++ ++ case AF_INET: ++ return setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, b); ++ ++ case AF_INET6: ++ return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, b); ++ ++ case AF_NETLINK: ++ return setsockopt_int(fd, SOL_NETLINK, NETLINK_PKTINFO, b); ++ ++ default: ++ return -EAFNOSUPPORT; ++ } ++} +diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h +index 616f2e0d05..c7c9ad34d6 100644 +--- a/src/basic/socket-util.h ++++ b/src/basic/socket-util.h +@@ -190,3 +190,5 @@ static inline int setsockopt_int(int fd, int level, int optname, int value) { + + return 0; + } ++ ++int socket_pass_pktinfo(int fd, bool b); diff --git a/SOURCES/0494-core-add-new-PassPacketInfo-socket-unit-property.patch b/SOURCES/0494-core-add-new-PassPacketInfo-socket-unit-property.patch new file mode 100644 index 0000000..561e77c --- /dev/null +++ b/SOURCES/0494-core-add-new-PassPacketInfo-socket-unit-property.patch @@ -0,0 +1,156 @@ +From 905a97ce65352d80af7260d34b74fd8342792c35 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 May 2020 19:36:56 +0200 +Subject: [PATCH] core: add new PassPacketInfo= socket unit property + +(cherry picked from commit a3d19f5d99c44940831a33df8b5bece4aaf749f7) + +Resolves: #1887181 +--- + doc/TRANSIENT-SETTINGS.md | 1 + + man/systemd.socket.xml | 9 +++++++++ + src/core/dbus-socket.c | 4 ++++ + src/core/load-fragment-gperf.gperf.m4 | 1 + + src/core/socket.c | 8 ++++++++ + src/core/socket.h | 1 + + src/shared/bus-unit-util.c | 3 +-- + test/fuzz/fuzz-unit-file/directives.service | 1 + + 8 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md +index 995b8797ef..de0ef9cc49 100644 +--- a/doc/TRANSIENT-SETTINGS.md ++++ b/doc/TRANSIENT-SETTINGS.md +@@ -410,6 +410,7 @@ Most socket unit settings are available to transient units. + ✓ Broadcast= + ✓ PassCredentials= + ✓ PassSecurity= ++✓ PassPacketInfo= + ✓ TCPCongestion= + ✓ ReusePort= + ✓ MessageQueueMaxMessages= +diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml +index 8676b4e03f..a908d5b6d8 100644 +--- a/man/systemd.socket.xml ++++ b/man/systemd.socket.xml +@@ -712,6 +712,15 @@ + Defaults to . + + ++ ++ PassPacketInfo= ++ Takes a boolean value. This controls the IP_PKTINFO, ++ IPV6_RECVPKTINFO and NETLINK_PKTINFO socket options, which ++ enable reception of additional per-packet metadata as ancillary message, on ++ AF_INET, AF_INET6 and AF_UNIX sockets. ++ Defaults to . ++ ++ + + TCPCongestion= + Takes a string value. Controls the TCP +diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c +index fa6bbe2c6f..17494b80c8 100644 +--- a/src/core/dbus-socket.c ++++ b/src/core/dbus-socket.c +@@ -104,6 +104,7 @@ const sd_bus_vtable bus_socket_vtable[] = { + SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST), ++ SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST), +@@ -205,6 +206,9 @@ static int bus_socket_set_transient_property( + if (streq(name, "PassSecurity")) + return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error); + ++ if (streq(name, "PassPacketInfo")) ++ return bus_set_transient_bool(u, name, &s->pass_pktinfo, message, flags, error); ++ + if (streq(name, "ReusePort")) + return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error); + +diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 +index 156a4d0a6d..7d683cc84b 100644 +--- a/src/core/load-fragment-gperf.gperf.m4 ++++ b/src/core/load-fragment-gperf.gperf.m4 +@@ -381,6 +381,7 @@ Socket.Transparent, config_parse_bool, 0, + Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast) + Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred) + Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec) ++Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo) + Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion) + Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port) + Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg) +diff --git a/src/core/socket.c b/src/core/socket.c +index 97c3a7fc9a..50c32ed8f4 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -660,6 +660,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + "%sBroadcast: %s\n" + "%sPassCredentials: %s\n" + "%sPassSecurity: %s\n" ++ "%sPassPacketInfo: %s\n" + "%sTCPCongestion: %s\n" + "%sRemoveOnStop: %s\n" + "%sWritable: %s\n" +@@ -678,6 +679,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { + prefix, yes_no(s->broadcast), + prefix, yes_no(s->pass_cred), + prefix, yes_no(s->pass_sec), ++ prefix, yes_no(s->pass_pktinfo), + prefix, strna(s->tcp_congestion), + prefix, yes_no(s->remove_on_stop), + prefix, yes_no(s->writable), +@@ -1099,6 +1101,12 @@ static void socket_apply_socket_options(Socket *s, int fd) { + log_unit_warning_errno(UNIT(s), errno, "SO_PASSSEC failed: %m"); + } + ++ if (s->pass_pktinfo) { ++ r = socket_pass_pktinfo(fd, true); ++ if (r < 0) ++ log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m"); ++ } ++ + if (s->priority >= 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0) + log_unit_warning_errno(UNIT(s), errno, "SO_PRIORITY failed: %m"); +diff --git a/src/core/socket.h b/src/core/socket.h +index b7a25d91fd..2409dbf2a0 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -121,6 +121,7 @@ struct Socket { + bool broadcast; + bool pass_cred; + bool pass_sec; ++ bool pass_pktinfo; + + /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */ + SocketAddressBindIPv6Only bind_ipv6_only; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index daa2c2dce5..9010448aaf 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -1478,8 +1478,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons + if (STR_IN_SET(field, + "Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast", + "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet", +- "FlushPending")) +- ++ "FlushPending", "PassPacketInfo")) + return bus_append_parse_boolean(m, field, eq); + + if (STR_IN_SET(field, "Priority", "IPTTL", "Mark")) +diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service +index 9d0530df72..8fde27fc90 100644 +--- a/test/fuzz/fuzz-unit-file/directives.service ++++ b/test/fuzz/fuzz-unit-file/directives.service +@@ -161,6 +161,7 @@ PIDFile= + PartOf= + PassCredentials= + PassSecurity= ++PassPacketInfo= + PathChanged= + PathExists= + PathExistsGlob= diff --git a/SOURCES/0495-resolved-tweak-cmsg-calculation.patch b/SOURCES/0495-resolved-tweak-cmsg-calculation.patch new file mode 100644 index 0000000..5ce13b6 --- /dev/null +++ b/SOURCES/0495-resolved-tweak-cmsg-calculation.patch @@ -0,0 +1,30 @@ +From 6ece87bef14ac5741fc870644504737b00607546 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 27 May 2020 19:38:38 +0200 +Subject: [PATCH] resolved: tweak cmsg calculation + +We ask for the TTL, then have enough space for it. + +We probably can drop the extra cmsg space now, but let's figure that out +another time, since the extra cmsg space is used elsewhere in resolved +as well. + +(cherry picked from commit 08ab18618ec59022582f1513c0718ba369f5ba85) + +Related: #1887181 +--- + src/resolve/resolved-dns-stream.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index 066daef96e..555e200a23 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -70,6 +70,7 @@ static int dns_stream_identify(DnsStream *s) { + union { + struct cmsghdr header; /* For alignment */ + uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo)) ++ + CMSG_SPACE(int) + /* for the TTL */ + + EXTRA_CMSG_SPACE /* kernel appears to require extra space */]; + } control; + struct msghdr mh = {}; diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index 5147231..b4ce6a3 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 42%{?dist} +Release: 43%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -524,6 +524,27 @@ Patch0471: 0471-user-util-Allow-names-starting-with-a-digit.patch Patch0472: 0472-shared-user-util-allow-usernames-with-dots-in-specif.patch Patch0473: 0473-user-util-switch-order-of-checks-in-valid_user_group.patch Patch0474: 0474-user-util-rework-how-we-validate-user-names.patch +Patch0475: 0475-man-mention-System-Administrator-s-Guide-in-systemct.patch +Patch0476: 0476-udev-introduce-udev-net_id-naming-schemes.patch +Patch0477: 0477-meson-make-net.naming-scheme-default-configurable.patch +Patch0478: 0478-man-describe-naming-schemes-in-a-new-man-page.patch +Patch0479: 0479-udev-net_id-parse-_SUN-ACPI-index-as-a-signed-intege.patch +Patch0480: 0480-udev-net_id-don-t-generate-slot-based-names-if-multi.patch +Patch0481: 0481-fix-typo-in-ProtectSystem-option.patch +Patch0482: 0482-remove-references-of-non-existent-man-pages.patch +Patch0483: 0483-log-Prefer-logging-to-CLI-unless-JOURNAL_STREAM-is-s.patch +Patch0484: 0484-locale-util-add-new-helper-locale_is_installed.patch +Patch0485: 0485-test-add-test-case-for-locale_is_installed.patch +Patch0486: 0486-tree-wide-port-various-bits-over-to-locale_is_instal.patch +Patch0487: 0487-install-allow-instantiated-units-to-be-enabled-via-p.patch +Patch0488: 0488-install-small-refactor-to-combine-two-function-calls.patch +Patch0489: 0489-test-fix-a-memleak.patch +Patch0490: 0490-docs-Add-syntax-for-templated-units-to-systemd.prese.patch +Patch0491: 0491-shared-install-fix-preset-operations-for-non-service.patch +Patch0492: 0492-introduce-setsockopt_int-helper.patch +Patch0493: 0493-socket-util-add-generic-socket_pass_pktinfo-helper.patch +Patch0494: 0494-core-add-new-PassPacketInfo-socket-unit-property.patch +Patch0495: 0495-resolved-tweak-cmsg-calculation.patch %ifarch %{ix86} x86_64 aarch64 @@ -1152,6 +1173,29 @@ fi %files tests -f .file-list-tests %changelog +* Thu Nov 26 2020 systemd maintenance team - 239-43 +- man: mention System Administrator's Guide in systemctl manpage (#1623116) +- udev: introduce udev net_id "naming schemes" (#1827462) +- meson: make net.naming-scheme= default configurable (#1827462) +- man: describe naming schemes in a new man page (#1827462) +- udev/net_id: parse _SUN ACPI index as a signed integer (#1827462) +- udev/net_id: don't generate slot based names if multiple devices might claim the same slot (#1827462) +- fix typo in ProtectSystem= option (#1871139) +- remove references of non-existent man pages (#1876807) +- log: Prefer logging to CLI unless JOURNAL_STREAM is set (#1865840) +- locale-util: add new helper locale_is_installed() (#1755287) +- test: add test case for locale_is_installed() (#1755287) +- tree-wide: port various bits over to locale_is_installed() (#1755287) +- install: allow instantiated units to be enabled via presets (#1812972) +- install: small refactor to combine two function calls into one function (#1812972) +- test: fix a memleak (#1812972) +- docs: Add syntax for templated units to systemd.preset man page (#1812972) +- shared/install: fix preset operations for non-service instantiated units (#1812972) +- introduce setsockopt_int() helper (#1887181) +- socket-util: add generic socket_pass_pktinfo() helper (#1887181) +- core: add new PassPacketInfo= socket unit property (#1887181) +- resolved: tweak cmsg calculation (#1887181) + * Tue Nov 03 2020 systemd maintenance team - 239-42 - logind: don't print warning when user@.service template is masked (#1880270) - build: use simple project version in pkgconfig files (#1862714)