import systemd-239-51.el8

This commit is contained in:
CentOS Sources 2021-11-09 05:11:36 -05:00 committed by Stepan Oksanichenko
parent a26ecff55e
commit b59a7e755d
97 changed files with 112411 additions and 102 deletions

View File

@ -1,4 +1,4 @@
From 43c0bcb8b24edb83bc265cdde264e6d2a36d1cea Mon Sep 17 00:00:00 2001
From 1afb38f39a9b4508533cc1c7262e5fff418cb317 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 17 May 2021 15:49:08 +0200
Subject: [PATCH] Revert "udev: run link_update() with increased retry count in
@ -6,7 +6,7 @@ Subject: [PATCH] Revert "udev: run link_update() with increased retry count in
This reverts commit 1f3165bda13c8572c8c31d23c998835c4e2ad8f3.
Related: #1963980
Related: #1942299
---
src/udev/udev-event.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

View File

@ -1,4 +1,4 @@
From 612773fa8b6333dcdac382849e81fa5a473dd1f9 Mon Sep 17 00:00:00 2001
From 897b4d1e19c706d9198b9308125df57a5d469a6b Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 17 May 2021 15:50:31 +0200
Subject: [PATCH] Revert "udev: make algorithm that selects highest priority
@ -6,7 +6,7 @@ Subject: [PATCH] Revert "udev: make algorithm that selects highest priority
This reverts commit 1d5f966c1758eb620755fcae54abd07a1ac36d3d.
Related: #1963980
Related: #1942299
---
src/udev/udev-event.c | 71 +++++-------
src/udev/udev-node.c | 244 ++++++++++++------------------------------

View File

@ -1,4 +1,4 @@
From bc21daeb780911d586de7ff0004ed2bc515b8826 Mon Sep 17 00:00:00 2001
From 94ad224240140a7287f9e2be5905b9c506350193 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 17 May 2021 15:54:10 +0200
Subject: [PATCH] test/udev-test.pl: drop test cases that add mutliple devices
@ -7,7 +7,7 @@ Subject: [PATCH] test/udev-test.pl: drop test cases that add mutliple devices
udev test fail. Once we reintroduce the fix for link_update()
we will revert this commit.]
Related: #1963980
Related: #1942299
---
test/udev-test.pl | 179 ----------------------------------------------
1 file changed, 179 deletions(-)

View File

@ -0,0 +1,41 @@
From 4e589237979fdf90af38d466abd7fcd852356f02 Mon Sep 17 00:00:00 2001
From: Kai Krakow <kai@kaishome.de>
Date: Sat, 17 Aug 2019 02:33:43 +0200
Subject: [PATCH] cgroup: Also set io.bfq.weight
Current kernels with BFQ scheduler do not yet set their IO weight
through "io.weight" but through "io.bfq.weight" (using a slightly
different interface supporting only default weights, not per-device
weights). This commit enables "IOWeight=" to just to that.
This patch may be dropped at some time later.
Github-Link: https://github.com/systemd/systemd/issues/7057
Signed-off-by: Kai Krakow <kai@kaishome.de>
(cherry picked from commit 21221ce1ce9a572e82d46d80692afd65c224fc50)
Related: #1927290
---
src/core/cgroup.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 71e30fd4db..f02cc31c6e 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -984,6 +984,14 @@ static void cgroup_context_apply(
log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
"Failed to set io.weight: %m");
+ /* FIXME: drop this when distro kernels properly support BFQ through "io.weight"
+ * See also: https://github.com/systemd/systemd/pull/13335 */
+ xsprintf(buf, "%" PRIu64 "\n", weight);
+ r = cg_set_attribute("io", path, "io.bfq.weight", buf);
+ if (r < 0)
+ log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to set io.bfq.weight: %m");
+
if (has_io) {
CGroupIODeviceWeight *w;

View File

@ -0,0 +1,82 @@
From e706f5df66b7189a7df526aeeb45c86b8c4b057a Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 2 Nov 2020 14:51:10 +0100
Subject: [PATCH] seccomp: allow turning off of seccomp filtering via env var
Fixes: #17504
(While we are it, also move $SYSTEMD_SECCOMP_LOG= env var description
into the right document section)
Also suggested in: https://github.com/systemd/systemd/issues/17245#issuecomment-704773603
(cherry picked from commit ce8f6d478e3f6c6a313fb19615aa5029bb18f86d)
Resolves: #1916835
---
doc/ENVIRONMENT.md | 3 +++
src/nspawn/nspawn-seccomp.c | 2 +-
src/shared/seccomp-util.c | 19 +++++++++++++++----
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md
index 0e763b6302..36b649afe1 100644
--- a/doc/ENVIRONMENT.md
+++ b/doc/ENVIRONMENT.md
@@ -117,3 +117,6 @@ systemd-sulogin-shell:
* `$SYSTEMD_SULOGIN_FORCE=1` — This skips asking for the root password if the
root password is not available (such as when the root account is locked).
See `sulogin(8)` for more details.
+
+* `$SYSTEMD_SECCOMP=0` if set, seccomp filters will not be enforced, even if
+ support for it is compiled in and available in the kernel.
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
index b56c5b04a8..fba22644da 100644
--- a/src/nspawn/nspawn-seccomp.c
+++ b/src/nspawn/nspawn-seccomp.c
@@ -172,7 +172,7 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **sys
int r;
if (!is_seccomp_available()) {
- log_debug("SECCOMP features not detected in the kernel, disabling SECCOMP filterering");
+ log_debug("SECCOMP features not detected in the kernel or disabled at runtime, disabling SECCOMP filtering");
return 0;
}
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index d91fb4e269..e903512d45 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -12,6 +12,7 @@
#include "af-list.h"
#include "alloc-util.h"
+#include "env-util.h"
#include "macro.h"
#include "nsflags.h"
#include "process-util.h"
@@ -244,10 +245,20 @@ static bool is_seccomp_filter_available(void) {
bool is_seccomp_available(void) {
static int cached_enabled = -1;
- if (cached_enabled < 0)
- cached_enabled =
- is_basic_seccomp_available() &&
- is_seccomp_filter_available();
+ if (cached_enabled < 0) {
+ int b;
+
+ b = getenv_bool("SYSTEMD_SECCOMP");
+ if (b != 0) {
+ if (b < 0 && b != -ENXIO) /* ENXIO: env var unset */
+ log_debug_errno(b, "Failed to parse $SYSTEMD_SECCOMP value, ignoring.");
+
+ cached_enabled =
+ is_basic_seccomp_available() &&
+ is_seccomp_filter_available();
+ } else
+ cached_enabled = false;
+ }
return cached_enabled;
}

View File

@ -1,4 +1,4 @@
From 2991ba196d034aef170acbf0d73533f79c66b94e Mon Sep 17 00:00:00 2001
From 7fb2d86b58201341a582b739a5445821bec66eea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 6 Nov 2019 12:44:39 +0100
Subject: [PATCH] meson: remove strange dep that causes meson to enter infinite
@ -15,11 +15,9 @@ Fixes #13742.
Tested with meson-0.52.0-1.module_f31+6771+f5d842eb.noarch,
meson-0.51.1-1.fc29.noarch.
Based on: af336643a01d0b210b18312c253a50594ba54b0a
(cherry picked from commit af336643a01d0b210b18312c253a50594ba54b0a)
Related: #1984406
(cherry picked from commit 7fb2d86b58201341a582b739a5445821bec66eea)
Resolves: #1970860
---
man/meson.build | 1 -
1 file changed, 1 deletion(-)

View File

@ -1,4 +1,4 @@
From f13a7eab34e675a88634c053682ecb2af43a432c Mon Sep 17 00:00:00 2001
From 8df650c7c5adc2bb24a0077d8332f5ee342e7fd8 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 26 Feb 2021 10:25:24 +0100
Subject: [PATCH] copy: handle copy_file_range() weirdness on procfs/sysfs
@ -8,10 +8,7 @@ and makes sure we will be able to stream bytes from procfs/sysfs via
copy_bytes() if people ask us to.
Based on: ee1aa61c4710ae567a2b844e0f0bb8cb0456ab8c
Related: ##1984406
(cherry picked from commit 8df650c7c5adc2bb24a0077d8332f5ee342e7fd8)
Related: #1970860
---
src/basic/copy.c | 75 +++++++++++++++++++++++++++++---------------
src/test/test-copy.c | 17 ++++++++++

View File

@ -0,0 +1,33 @@
From 4dc498258bd0cce1bc8ad2311c5f12de5678e0af Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
Date: Thu, 27 May 2021 12:25:51 +0200
Subject: [PATCH] core: Hide "Deactivated successfully" message
Show message "Deactivated successfully" in debug mode (when manager is
user) rather than in info mode. This message has low information value
for regular users and it might be a bit overwhelming on a system with
a lot of devices.
(cherry picked from commit edf2ee22f54005d76b2fb8fdcc9c60974feb88bc)
Resolves: #1954802
---
src/core/unit.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/core/unit.c b/src/core/unit.c
index cd3e7c806d..93c13e58d9 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -5525,7 +5525,10 @@ int unit_pid_attachable(Unit *u, pid_t pid, sd_bus_error *error) {
void unit_log_success(Unit *u) {
assert(u);
- log_struct(LOG_INFO,
+ /* Let's show message "Deactivated successfully" in debug mode (when manager is user) rather than in info mode.
+ * This message has low information value for regular users and it might be a bit overwhelming on a system with
+ * a lot of devices. */
+ log_struct(MANAGER_IS_USER(u->manager) ? LOG_DEBUG : LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_UNIT_SUCCESS_STR,
LOG_UNIT_ID(u),
LOG_UNIT_INVOCATION_ID(u),

View File

@ -0,0 +1,35 @@
From 42f639d3689b7cbc9ce6b9578a2790c254508384 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Fri, 8 Jan 2021 14:52:26 +0800
Subject: [PATCH] util: rework in_initrd() to make use of
path_is_temporary_fs()
(cherry picked from commit 96cceb35e7985f5ee6c9b17e129a76259273cdde)
Related: #1959339
---
src/basic/util.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/basic/util.c b/src/basic/util.c
index 82cb937314..b443e639f3 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -130,7 +130,6 @@ int prot_from_flags(int flags) {
}
bool in_initrd(void) {
- struct statfs s;
if (saved_in_initrd >= 0)
return saved_in_initrd;
@@ -146,8 +145,7 @@ bool in_initrd(void) {
*/
saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 &&
- statfs("/", &s) >= 0 &&
- is_temporary_fs(&s);
+ path_is_temporary_fs("/") > 0;
return saved_in_initrd;
}

View File

@ -0,0 +1,99 @@
From 99ca5b681fceedd010b2616b1248a483f4bfbd97 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Wed, 13 Jan 2021 00:04:53 +0800
Subject: [PATCH] initrd: extend SYSTEMD_IN_INITRD to accept non-ramfs rootfs
Sometimes, non-ramfs initrd root are useful. Eg, for kdump, because
initramfs is memory consuming, so mount a compressed image in earlier
initrd, chroot into it then let systemd do the rest of job is a good
solution.
But systemd doesn't recognize the initrd environment if rootfs is not a
temporary fs. This is a reasonable check, because switch-root in initrd
will wipe the whole rootfs, will be a disaster if there are any
misdetect.
So extend SYSTEMD_IN_INITRD environment variable, now it accepts boolean
value and two extra keyword, "auto" and "lenient". "auto" is same as
before, and it's the default value. "lenient" will let systemd bypass
the rootfs check.
(cherry picked from commit db4c45cf4f10ca094b9e9570b758abd445d65381)
Related: #1959339
---
doc/ENVIRONMENT.md | 8 ++++++++
src/basic/util.c | 28 +++++++++++++++++++++++++---
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md
index 36b649afe1..8d7ce6ae2c 100644
--- a/doc/ENVIRONMENT.md
+++ b/doc/ENVIRONMENT.md
@@ -37,6 +37,14 @@ All tools:
useful for debugging, in order to test generators and other code against
specific kernel command lines.
+* `$SYSTEMD_IN_INITRD=[auto|lenient|0|1]` — if set, specifies initrd detection
+ method. Defaults to `auto`. Behavior is defined as follows:
+ `auto`: Checks if `/etc/initrd-release` exists, and a temporary fs is mounted
+ on `/`. If both conditions meet, then it's in initrd.
+ `lenient`: Similiar to `auto`, but the rootfs check is skipped.
+ `0|1`: Simply overrides initrd detection. This is useful for debugging and
+ testing initrd-only programs in the main system.
+
* `$SYSTEMD_EMOJI=0` — if set, tools such as "systemd-analyze security" will
not output graphical smiley emojis, but ASCII alternatives instead. Note that
this only controls use of Unicode emoji glyphs, and has no effect on other
diff --git a/src/basic/util.c b/src/basic/util.c
index b443e639f3..59bcf7b00c 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -130,11 +130,14 @@ int prot_from_flags(int flags) {
}
bool in_initrd(void) {
+ int r;
+ const char *e;
+ bool lenient = false;
if (saved_in_initrd >= 0)
return saved_in_initrd;
- /* We make two checks here:
+ /* We have two checks here:
*
* 1. the flag file /etc/initrd-release must exist
* 2. the root file system must be a memory file system
@@ -142,10 +145,29 @@ bool in_initrd(void) {
* The second check is extra paranoia, since misdetecting an
* initrd can have bad consequences due the initrd
* emptying when transititioning to the main systemd.
+ *
+ * If env var $SYSTEMD_IN_INITRD is not set or set to "auto",
+ * both checks are used. If it's set to "lenient", only check
+ * 1 is used. If set to a booleen value, then the boolean
+ * value is returned.
*/
- saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 &&
- path_is_temporary_fs("/") > 0;
+ e = secure_getenv("SYSTEMD_IN_INITRD");
+ if (e) {
+ if (streq(e, "lenient"))
+ lenient = true;
+ else if (!streq(e, "auto")) {
+ r = parse_boolean(e);
+ if (r >= 0) {
+ saved_in_initrd = r > 0;
+ return saved_in_initrd;
+ }
+ log_debug_errno(r, "Failed to parse $SYSTEMD_IN_INITRD, ignoring: %m");
+ }
+ }
+
+ saved_in_initrd = (lenient || path_is_temporary_fs("/") > 0) &&
+ access("/etc/initrd-release", F_OK) >= 0;
return saved_in_initrd;
}

View File

@ -0,0 +1,35 @@
From 3299c855c6e65596ff9d8635dcbd45ff6818499a Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Thu, 14 Jan 2021 00:39:10 +0800
Subject: [PATCH] initrd: do a debug log if failed to detect rootfs type
(cherry picked from commit 3377c740d9121f38385e70d6a380b5e4bd8c672a)
Related: #1959339
---
src/basic/util.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/basic/util.c b/src/basic/util.c
index 59bcf7b00c..fef52ad5ff 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -166,8 +166,16 @@ bool in_initrd(void) {
}
}
- saved_in_initrd = (lenient || path_is_temporary_fs("/") > 0) &&
- access("/etc/initrd-release", F_OK) >= 0;
+ if (!lenient) {
+ r = path_is_temporary_fs("/");
+ if (r < 0)
+ log_debug_errno(r, "Couldn't determine if / is a temporary file system: %m");
+
+ saved_in_initrd = r > 0;
+ }
+
+ if (saved_in_initrd != 0)
+ saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0;
return saved_in_initrd;
}

View File

@ -0,0 +1,39 @@
From a1417c121d19272b1389098648132106a5ffc661 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
Date: Thu, 14 Jan 2021 01:25:20 +0800
Subject: [PATCH] initrd: do a debug log if /etc/initrd-release doesn't take
effect
Signed-off-by: Kairui Song <kasong@redhat.com>
(cherry picked from commit 4a60d8cbcae574896a28f9f1f6204a1bddca8e99)
Related: #1959339
---
src/basic/util.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/basic/util.c b/src/basic/util.c
index fef52ad5ff..609f8c2f33 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -174,8 +174,17 @@ bool in_initrd(void) {
saved_in_initrd = r > 0;
}
- if (saved_in_initrd != 0)
- saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0;
+ r = access("/etc/initrd-release", F_OK);
+ if (r >= 0) {
+ if (saved_in_initrd == 0)
+ log_debug("/etc/initrd-release exists, but it's not an initrd.");
+ else
+ saved_in_initrd = 1;
+ } else {
+ if (errno != ENOENT)
+ log_debug_errno(errno, "Failed to test if /etc/initrd-release exists: %m");
+ saved_in_initrd = 0;
+ }
return saved_in_initrd;
}

View File

@ -0,0 +1,25 @@
From 64975b046d5a0877690aa6de9389b8234ee1cfab Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 10:45:31 +0200
Subject: [PATCH] units: assign user-runtime-dir@.service to user-%i.slice
This service won't use much resources, but it's certainly nicer to see
it attached th the user's slice along with user@.service, so that
everything we run for a specific user is properly bound into one unit.
(cherry picked from commit 1193c11a04b3ecc29925904fbeb5d64834bce73e)
Related: #1946453
---
units/user-runtime-dir@.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in
index 8c02beda3b..13b3ed52f8 100644
--- a/units/user-runtime-dir@.service.in
+++ b/units/user-runtime-dir@.service.in
@@ -15,3 +15,4 @@ StopWhenUnneeded=yes
ExecStart=@rootlibexecdir@/systemd-user-runtime-dir start %i
ExecStop=@rootlibexecdir@/systemd-user-runtime-dir stop %i
RemainAfterExit=true
+Slice=user-%i.slice

View File

@ -0,0 +1,30 @@
From 1fa9a6bf51a1a1d0fa2ccc23283739d16e9179b4 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 10:42:09 +0200
Subject: [PATCH] units: order user-runtime-dir@.service after
systemd-user-sessions.service
We use systemd-user-sessions.service as barrier when to allow login
sessions. With this patch user@.service is ordered after that too, so
that any login related code (which user-runtime-dir@.service is) is
guaranteed to run after the barrier, and never before.
(cherry picked from commit eb748aef4fbfd03b64938aa471bb8ceda1bc89a8)
Related: #1946453
---
units/user-runtime-dir@.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in
index 13b3ed52f8..31354c9bf2 100644
--- a/units/user-runtime-dir@.service.in
+++ b/units/user-runtime-dir@.service.in
@@ -9,6 +9,7 @@
[Unit]
Description=/run/user/%i mount wrapper
+After=systemd-user-sessions.service
StopWhenUnneeded=yes
[Service]

View File

@ -0,0 +1,26 @@
From 780d1d9fa7ccc036e6e237221ac51ed69453c8c6 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 2 Aug 2018 20:57:56 +0200
Subject: [PATCH] units: make sure user-runtime-dir@.service is Type=oneshot
We order user@.service after it, hence we need to properly know when it
finished starting up.
(cherry picked from commit d06e8fbce35c2b52ee1d09af4888876d5f2d7ae4)
Related: #1946453
---
units/user-runtime-dir@.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in
index 31354c9bf2..bfd6488d61 100644
--- a/units/user-runtime-dir@.service.in
+++ b/units/user-runtime-dir@.service.in
@@ -15,5 +15,6 @@ StopWhenUnneeded=yes
[Service]
ExecStart=@rootlibexecdir@/systemd-user-runtime-dir start %i
ExecStop=@rootlibexecdir@/systemd-user-runtime-dir stop %i
+Type=oneshot
RemainAfterExit=true
Slice=user-%i.slice

View File

@ -0,0 +1,52 @@
From 354b894aa3e79f54ab75bf6fae76ce28ca80db38 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 2 Aug 2018 20:56:34 +0200
Subject: [PATCH] user-runtime-dir: downgrade a few log messages to LOG_DEBUG
that we ignore
As the comments already say it might be quite likely that
$XDG_RUNTIME_DIR is not set up as mount, and we shouldn't complain about
that.
Moreover, let's make this idempotent, so that a runtime dir that is
already gone and is removed again doesn't cause failure.
(cherry picked from commit 3a13442bbf72e7ebdd0b4d60c2922ea7c5cc9496)
Related: #1946453
---
src/login/user-runtime-dir.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c
index 1bb26c99e4..9693821990 100644
--- a/src/login/user-runtime-dir.c
+++ b/src/login/user-runtime-dir.c
@@ -95,20 +95,19 @@ static int user_remove_runtime_path(const char *runtime_path) {
r = rm_rf(runtime_path, 0);
if (r < 0)
- log_error_errno(r, "Failed to remove runtime directory %s (before unmounting): %m", runtime_path);
+ log_debug_errno(r, "Failed to remove runtime directory %s (before unmounting), ignoring: %m", runtime_path);
- /* Ignore cases where the directory isn't mounted, as that's
- * quite possible, if we lacked the permissions to mount
- * something */
+ /* Ignore cases where the directory isn't mounted, as that's quite possible, if we lacked the permissions to
+ * mount something */
r = umount2(runtime_path, MNT_DETACH);
if (r < 0 && !IN_SET(errno, EINVAL, ENOENT))
- log_error_errno(errno, "Failed to unmount user runtime directory %s: %m", runtime_path);
+ log_debug_errno(errno, "Failed to unmount user runtime directory %s, ignoring: %m", runtime_path);
r = rm_rf(runtime_path, REMOVE_ROOT);
- if (r < 0)
- log_error_errno(r, "Failed to remove runtime directory %s (after unmounting): %m", runtime_path);
+ if (r < 0 && r != -ENOENT)
+ return log_error_errno(r, "Failed to remove runtime directory %s (after unmounting): %m", runtime_path);
- return r;
+ return 0;
}
static int do_mount(const char *runtime_path, uid_t uid, gid_t gid) {

View File

@ -0,0 +1,33 @@
From 91ed691ff73d4d71fae8f6896a1bba73e6a76bba Mon Sep 17 00:00:00 2001
From: David Michael <dm0@redhat.com>
Date: Wed, 20 Mar 2019 15:14:32 +0000
Subject: [PATCH] shared/install: Preserve escape characters for escaped unit
names
Since switching to extract_first_word with no flags for parsing
unit names in 4c9565eea534cd233a913c8c21f7920dba229743, escape
characters will be stripped from escaped unit names such as
"mnt-persistent\x2dvolume.mount" resulting in the unit not being
configured as defined. Preserve escape characters again for
compatibility with existing preset definitions.
(cherry picked from commit 82bd4da71e9cdd5a2e9266332f5a7399845e31f6)
Resolves: #1952686
---
src/shared/install.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/install.c b/src/shared/install.c
index c2847df3f8..c9fef6bde2 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -2774,7 +2774,7 @@ static int split_pattern_into_name_and_instances(const char *pattern, char **out
assert(out_instances);
assert(out_unit_name);
- r = extract_first_word(&pattern, &unit_name, NULL, 0);
+ r = extract_first_word(&pattern, &unit_name, NULL, EXTRACT_RETAIN_ESCAPE);
if (r < 0)
return r;

View File

@ -0,0 +1,80 @@
From 48dacf8d30cd61b72939e9c3419acced4b2fde74 Mon Sep 17 00:00:00 2001
From: Michal Suchanek <msuchanek@suse.de>
Date: Fri, 2 Oct 2020 11:05:23 +0200
Subject: [PATCH] basic/virt: Detect PowerVM hypervisor
Currently systemd-detect-virt fails to detect running under PowerVM.
Add code to detect PowerVM based on code in util-linux.
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
(cherry picked from commit 3224e38bb6b3287ca253cbafb460a150544d5818)
Resolves: #1937989
---
man/systemd-detect-virt.xml | 7 ++++++-
src/basic/virt.c | 6 ++++++
src/basic/virt.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
index c4763fd561..6beb2c2aa1 100644
--- a/man/systemd-detect-virt.xml
+++ b/man/systemd-detect-virt.xml
@@ -65,7 +65,7 @@
</thead>
<tbody>
<row>
- <entry valign="top" morerows="11">VM</entry>
+ <entry valign="top" morerows="12">VM</entry>
<entry><varname>qemu</varname></entry>
<entry>QEMU software virtualization, without KVM</entry>
</row>
@@ -95,6 +95,11 @@
<entry>Oracle VM VirtualBox (historically marketed by innotek and Sun Microsystems), for legacy and KVM hypervisor</entry>
</row>
+ <row>
+ <entry><varname>powervm</varname></entry>
+ <entry>IBM PowerVM hypervisor - comes as firmware with some IBM POWER servers</entry>
+ </row>
+
<row>
<entry><varname>xen</varname></entry>
<entry>Xen hypervisor (only domU, not dom0)</entry>
diff --git a/src/basic/virt.c b/src/basic/virt.c
index dfa1525219..0b88005ed6 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -92,6 +92,11 @@ static int detect_vm_device_tree(void) {
_cleanup_closedir_ DIR *dir = NULL;
struct dirent *dent;
+ if (access("/proc/device-tree/ibm,partition-name", F_OK) == 0 &&
+ access("/proc/device-tree/hmc-managed?", F_OK) == 0 &&
+ access("/proc/device-tree/chosen/qemu,graphic-width", F_OK) != 0)
+ return VIRTUALIZATION_POWERVM;
+
dir = opendir("/proc/device-tree");
if (!dir) {
if (errno == ENOENT) {
@@ -635,6 +640,7 @@ static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {
[VIRTUALIZATION_PARALLELS] = "parallels",
[VIRTUALIZATION_BHYVE] = "bhyve",
[VIRTUALIZATION_QNX] = "qnx",
+ [VIRTUALIZATION_POWERVM] = "powervm",
[VIRTUALIZATION_VM_OTHER] = "vm-other",
[VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn",
diff --git a/src/basic/virt.h b/src/basic/virt.h
index c4cf4bfeab..640b3ed779 100644
--- a/src/basic/virt.h
+++ b/src/basic/virt.h
@@ -21,6 +21,7 @@ enum {
VIRTUALIZATION_PARALLELS,
VIRTUALIZATION_BHYVE,
VIRTUALIZATION_QNX,
+ VIRTUALIZATION_POWERVM,
VIRTUALIZATION_VM_OTHER,
VIRTUALIZATION_VM_LAST = VIRTUALIZATION_VM_OTHER,

View File

@ -0,0 +1,57 @@
From 102f4ff97a24c2ddaf6e569c678a0a713f972863 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 19 Mar 2021 10:05:47 +0100
Subject: [PATCH] man: document differences in clean exit status for
Type=oneshot
See commit 1f0958f640b87175cd547c1e69084cfe54a22e9d .
(cherry picked from commit f055cf77862bc580f3afbfaac161d1c060f39411)
Resolves: #1940078
---
man/systemd.service.xml | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 54586d1948..1e30a564df 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -669,14 +669,19 @@
If set to <option>no</option> (the default), the service will
not be restarted. If set to <option>on-success</option>, it
will be restarted only when the service process exits cleanly.
- In this context, a clean exit means an exit code of 0, or one
- of the signals
- <constant>SIGHUP</constant>,
- <constant>SIGINT</constant>,
- <constant>SIGTERM</constant> or
- <constant>SIGPIPE</constant>, and
- additionally, exit statuses and signals specified in
- <varname>SuccessExitStatus=</varname>. If set to
+ In this context, a clean exit means any of the following:
+ <itemizedlist>
+ <listitem><simpara>exit code of 0;</simpara></listitem>
+ <listitem><simpara>for types other than
+ <varname>Type=oneshot</varname>, one of the signals
+ <constant>SIGHUP</constant>,
+ <constant>SIGINT</constant>,
+ <constant>SIGTERM</constant>, or
+ <constant>SIGPIPE</constant>;</simpara></listitem>
+ <listitem><simpara>exit statuses and signals specified in
+ <varname>SuccessExitStatus=</varname>.</simpara></listitem>
+ </itemizedlist>
+ If set to
<option>on-failure</option>, the service will be restarted
when the process exits with a non-zero exit code, is
terminated by a signal (including on core dump, but excluding
@@ -798,7 +803,8 @@
<listitem><para>Takes a list of exit status definitions that,
when returned by the main service process, will be considered
successful termination, in addition to the normal successful
- exit code 0 and the signals <constant>SIGHUP</constant>,
+ exit code 0 and, except for <varname>Type=oneshot</varname>,
+ the signals <constant>SIGHUP</constant>,
<constant>SIGINT</constant>, <constant>SIGTERM</constant>, and
<constant>SIGPIPE</constant>. Exit status definitions can
either be numeric exit codes or termination signal names,

View File

@ -0,0 +1,42 @@
From 53673326ea78039b27e1dbd5328a8fe9a1a17445 Mon Sep 17 00:00:00 2001
From: d032747 <michael.trapp@sap.com>
Date: Tue, 15 Dec 2020 10:40:06 +0100
Subject: [PATCH] busctl: add a timestamp to the output of the busctl monitor
command
(cherry picked from commit 6fe2a70b9160e35fdeed9d37bd31727c2d46a8b2)
Resolves: #1909214
---
src/libsystemd/sd-bus/bus-dump.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c
index 2bd06053a6..36f592e0ba 100644
--- a/src/libsystemd/sd-bus/bus-dump.c
+++ b/src/libsystemd/sd-bus/bus-dump.c
@@ -55,6 +55,15 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
f = stdout;
if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
+ char buf[FORMAT_TIMESTAMP_MAX];
+ const char *p;
+ usec_t ts = m->realtime;
+
+ if (ts == 0)
+ ts = now(CLOCK_REALTIME);
+
+ p = format_timestamp_us_utc(buf, sizeof(buf), ts);
+
fprintf(f,
"%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
@@ -82,6 +91,8 @@ int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
if (m->reply_cookie != 0)
fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
+ fprintf(f, " Timestamp=\"%s\"", strna(p));
+
fputs("\n", f);
if (m->sender)

View File

@ -0,0 +1,90 @@
From 240c55f1526300daac640ef2c1f4941de4579493 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 9 Jul 2020 23:15:47 +0200
Subject: [PATCH] basic/cap-list: parse/print numerical capabilities
We would refuse to print capabilities which were didn't have a name
for. The kernel adds new capabilities from time to time, most recently
cap_bpf. 'systmectl show -p CapabilityBoundingSet ...' would fail with
"Failed to parse bus message: Invalid argument" because
capability_set_to_string_alloc() would fail with -EINVAL. So let's
print such capabilities in hexadecimal:
CapabilityBoundingSet=cap_chown cap_dac_override cap_dac_read_search
cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap
cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin
cap_net_raw cap_ipc_lock cap_ipc_owner 0x10 0x11 0x12 0x13 0x14 0x15 0x16
0x17 0x18 0x19 0x1a ...
For symmetry, also allow capabilities that we don't know to be specified.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1853736.
(cherry picked from commit 417770f3033c426ca848b158d0bf057cd8ad1329)
Resolves: #1946943
---
src/basic/cap-list.c | 10 +++++++---
src/test/test-cap-list.c | 4 +++-
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c
index bfcda33520..56a81c7dfc 100644
--- a/src/basic/cap-list.c
+++ b/src/basic/cap-list.c
@@ -10,6 +10,7 @@
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
+#include "stdio-util.h"
#include "util.h"
static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len);
@@ -37,7 +38,7 @@ int capability_from_name(const char *name) {
/* Try to parse numeric capability */
r = safe_atoi(name, &i);
if (r >= 0) {
- if (i >= 0 && i < (int) ELEMENTSOF(capability_names))
+ if (i >= 0 && i < 64)
return i;
else
return -EINVAL;
@@ -65,11 +66,14 @@ int capability_set_to_string_alloc(uint64_t set, char **s) {
for (i = 0; i < cap_last_cap(); i++)
if (set & (UINT64_C(1) << i)) {
const char *p;
+ char buf[2 + 16 + 1];
size_t add;
p = capability_to_name(i);
- if (!p)
- return -EINVAL;
+ if (!p) {
+ xsprintf(buf, "0x%lx", i);
+ p = buf;
+ }
add = strlen(p);
diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c
index de5fa729cc..84bbb7b7e7 100644
--- a/src/test/test-cap-list.c
+++ b/src/test/test-cap-list.c
@@ -30,6 +30,8 @@ static void test_cap_list(void) {
assert_se(capability_from_name("cAp_aUdIt_rEAd") == CAP_AUDIT_READ);
assert_se(capability_from_name("0") == 0);
assert_se(capability_from_name("15") == 15);
+ assert_se(capability_from_name("63") == 63);
+ assert_se(capability_from_name("64") == -EINVAL);
assert_se(capability_from_name("-1") == -EINVAL);
for (i = 0; i < capability_list_length(); i++) {
@@ -64,7 +66,7 @@ static void test_capability_set_one(uint64_t c, const char *t) {
free(t1);
assert_se(t1 = strjoin("'cap_chown cap_dac_override' \"cap_setgid cap_setuid\"", t,
- " hogehoge foobar 12345 3.14 -3 ", t));
+ " hogehoge foobar 18446744073709551616 3.14 -3 ", t));
assert_se(capability_set_from_string(t1, &c1) == 0);
assert_se(c1 == c_masked);
}

View File

@ -0,0 +1,318 @@
From ca634baa10e2249d4a706d59b67be764867e5f32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 30 Nov 2020 10:37:06 +0100
Subject: [PATCH] shared/mount-util: convert to libmount
It seems better to use just a single parsing algorithm for /proc/self/mountinfo.
Also, unify the naming of variables in all places that use mnt_table_next_fs().
It makes it easier to compare the different call sites.
(cherry picked from commit 13dcfe4661b467131c943620d0f44711798bfd54)
Related: #1885143
---
src/basic/mount-util.c | 133 ++++++++++++++++++-----------------------
src/core/mount.c | 22 +++----
src/core/umount.c | 14 ++---
3 files changed, 76 insertions(+), 93 deletions(-)
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 5b04e21f34..bac1a25cc8 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -13,7 +13,6 @@
#include <libmount.h>
#include "alloc-util.h"
-#include "escape.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
@@ -27,6 +26,9 @@
#include "string-util.h"
#include "strv.h"
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
+
/* This is the original MAX_HANDLE_SZ definition from the kernel, when the API was introduced. We use that in place of
* any more currently defined value to future-proof things: if the size is increased in the API headers, and our code
* is recompiled then it would cease working on old kernels, as those refuse any sizes larger than this value with
@@ -313,55 +315,43 @@ int umount_recursive(const char *prefix, int flags) {
* unmounting them until they are gone. */
do {
- _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
again = false;
- r = 0;
- proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
- if (!proc_self_mountinfo)
- return -errno;
+ table = mnt_new_table();
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!table || !iter)
+ return -ENOMEM;
- (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER);
+ r = mnt_table_parse_mtab(table, NULL);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
for (;;) {
- _cleanup_free_ char *path = NULL, *p = NULL;
- int k;
-
- k = fscanf(proc_self_mountinfo,
- "%*s " /* (1) mount id */
- "%*s " /* (2) parent id */
- "%*s " /* (3) major:minor */
- "%*s " /* (4) root */
- "%ms " /* (5) mount point */
- "%*s" /* (6) mount options */
- "%*[^-]" /* (7) optional fields */
- "- " /* (8) separator */
- "%*s " /* (9) file system type */
- "%*s" /* (10) mount source */
- "%*s" /* (11) mount options 2 */
- "%*[^\n]", /* some rubbish at the end */
- &path);
- if (k != 1) {
- if (k == EOF)
- break;
+ struct libmnt_fs *fs;
+ const char *path;
- continue;
- }
-
- r = cunescape(path, UNESCAPE_RELAX, &p);
+ r = mnt_table_next_fs(table, iter, &fs);
+ if (r == 1)
+ break;
if (r < 0)
- return r;
+ return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
- if (!path_startswith(p, prefix))
+ path = mnt_fs_get_target(fs);
+ if (!path)
continue;
- if (umount2(p, flags) < 0) {
- r = log_debug_errno(errno, "Failed to umount %s: %m", p);
+ if (!path_startswith(path, prefix))
+ continue;
+
+ if (umount2(path, flags) < 0) {
+ r = log_debug_errno(errno, "Failed to umount %s: %m", path);
continue;
}
- log_debug("Successfully unmounted %s", p);
+ log_debug("Successfully unmounted %s", path);
again = true;
n++;
@@ -416,6 +406,8 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
for (;;) {
_cleanup_set_free_free_ Set *todo = NULL;
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
bool top_autofs = false;
char *x;
unsigned long orig_flags;
@@ -424,58 +416,52 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
if (!todo)
return -ENOMEM;
+ table = mnt_new_table();
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!table || !iter)
+ return -ENOMEM;
+
rewind(proc_self_mountinfo);
- for (;;) {
- _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
- int k;
-
- k = fscanf(proc_self_mountinfo,
- "%*s " /* (1) mount id */
- "%*s " /* (2) parent id */
- "%*s " /* (3) major:minor */
- "%*s " /* (4) root */
- "%ms " /* (5) mount point */
- "%*s" /* (6) mount options (superblock) */
- "%*[^-]" /* (7) optional fields */
- "- " /* (8) separator */
- "%ms " /* (9) file system type */
- "%*s" /* (10) mount source */
- "%*s" /* (11) mount options (bind mount) */
- "%*[^\n]", /* some rubbish at the end */
- &path,
- &type);
- if (k != 2) {
- if (k == EOF)
- break;
+ r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
+ if (r < 0)
+ return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
- continue;
- }
+ for (;;) {
+ struct libmnt_fs *fs;
+ const char *path, *type;
- r = cunescape(path, UNESCAPE_RELAX, &p);
+ r = mnt_table_next_fs(table, iter, &fs);
+ if (r == 1)
+ break;
if (r < 0)
- return r;
+ return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
+
+ path = mnt_fs_get_target(fs);
+ type = mnt_fs_get_fstype(fs);
+ if (!path || !type)
+ continue;
- if (!path_startswith(p, cleaned))
+ if (!path_startswith(path, cleaned))
continue;
- /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall
- * operate on. */
- if (!path_equal(cleaned, p)) {
+ /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount
+ * we shall operate on. */
+ if (!path_equal(path, cleaned)) {
bool blacklisted = false;
char **i;
STRV_FOREACH(i, blacklist) {
-
if (path_equal(*i, cleaned))
continue;
if (!path_startswith(*i, cleaned))
continue;
- if (path_startswith(p, *i)) {
+ if (path_startswith(path, *i)) {
blacklisted = true;
- log_debug("Not remounting %s, because blacklisted by %s, called for %s", p, *i, cleaned);
+ log_debug("Not remounting %s blacklisted by %s, called for %s",
+ path, *i, cleaned);
break;
}
}
@@ -490,15 +476,12 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
* already triggered, then we will find
* another entry for this. */
if (streq(type, "autofs")) {
- top_autofs = top_autofs || path_equal(cleaned, p);
+ top_autofs = top_autofs || path_equal(path, cleaned);
continue;
}
- if (!set_contains(done, p)) {
- r = set_consume(todo, p);
- p = NULL;
- if (r == -EEXIST)
- continue;
+ if (!set_contains(done, path)) {
+ r = set_put_strdup(todo, path);
if (r < 0)
return r;
}
diff --git a/src/core/mount.c b/src/core/mount.c
index 076dfd06a3..7e80a0c974 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1606,18 +1606,18 @@ fail:
}
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
- _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
- _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
- int r = 0;
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
+ int r;
assert(m);
- t = mnt_new_table();
- i = mnt_new_iter(MNT_ITER_FORWARD);
- if (!t || !i)
+ table = mnt_new_table();
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!table || !iter)
return log_oom();
- r = mnt_table_parse_mtab(t, NULL);
+ r = mnt_table_parse_mtab(table, NULL);
if (r < 0)
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
@@ -1628,11 +1628,11 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
_cleanup_free_ char *d = NULL, *p = NULL;
int k;
- k = mnt_table_next_fs(t, i, &fs);
- if (k == 1)
+ r = mnt_table_next_fs(table, iter, &fs);
+ if (r == 1)
break;
- if (k < 0)
- return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
+ if (r < 0)
+ return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
device = mnt_fs_get_source(fs);
path = mnt_fs_get_target(fs);
diff --git a/src/core/umount.c b/src/core/umount.c
index 241fe6fc62..3f02bf141a 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -55,18 +55,18 @@ void mount_points_list_free(MountPoint **head) {
}
int mount_points_list_get(const char *mountinfo, MountPoint **head) {
- _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
- _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
assert(head);
- t = mnt_new_table();
- i = mnt_new_iter(MNT_ITER_FORWARD);
- if (!t || !i)
+ table = mnt_new_table();
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!table || !iter)
return log_oom();
- r = mnt_table_parse_mtab(t, mountinfo);
+ r = mnt_table_parse_mtab(table, mountinfo);
if (r < 0)
return log_error_errno(r, "Failed to parse %s: %m", mountinfo);
@@ -79,7 +79,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
bool try_remount_ro;
MountPoint *m;
- r = mnt_table_next_fs(t, i, &fs);
+ r = mnt_table_next_fs(table, iter, &fs);
if (r == 1)
break;
if (r < 0)

View File

@ -0,0 +1,92 @@
From 996f88461c45e8620c5a8a0c958dc133bd02c50e Mon Sep 17 00:00:00 2001
From: Jakob Unterwurzacher <jakobunt@gmail.com>
Date: Mon, 30 Nov 2020 10:27:48 +0100
Subject: [PATCH] mount-util: bind_remount: avoid calling statvfs
The commit
"util: Do not clear parent mount flags when setting up namespaces"
introduced a statvfs call read the flags of the original mount
and have them applied to the bind mount.
This has two problems:
(1) The mount flags returned by statvfs(2) do not match the flags
accepted by mount(2). For example, the value 4096 means ST_RELATIME
when returned by statvfs(2), but means MS_BIND when passed to mount(2).
(2) A call to statvfs blocks indefinitely when ran against a disconnected
network drive ( https://github.com/systemd/systemd/issues/12667 ).
We already use libmount to parse `/proc/self/mountinfo` but did not use the
mount flag information from there. This patch changes that to use the mount
flags parsed by libmount instead of calling statvfs. Only if getting the
flags through libmount fails we call statvfs.
Fixes https://github.com/systemd/systemd/issues/12667
(cherry picked from commit d34a40082db3ffca8de66bfa4df50951101bdae5)
Resolves: #1885143
---
src/basic/mount-util.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index bac1a25cc8..2cf98eaa84 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -364,11 +364,34 @@ int umount_recursive(const char *prefix, int flags) {
return r ? r : n;
}
-static int get_mount_flags(const char *path, unsigned long *flags) {
- struct statvfs buf;
+/* Get the mount flags for the mountpoint at "path" from "table" */
+static int get_mount_flags(const char *path, unsigned long *flags, struct libmnt_table *table) {
+ struct statvfs buf = {};
+ struct libmnt_fs *fs = NULL;
+ const char *opts = NULL;
+ int r = 0;
+
+ fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD);
+ if (fs == NULL) {
+ log_warning("Could not find '%s' in mount table", path);
+ goto fallback;
+ }
+
+ opts = mnt_fs_get_vfs_options(fs);
+ r = mnt_optstr_get_flags(opts, flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
+ if (r != 0) {
+ log_warning_errno(r, "Could not get flags for '%s': %m", path);
+ goto fallback;
+ }
+ /* relatime is default and trying to set it in an unprivileged container causes EPERM */
+ *flags &= ~MS_RELATIME;
+ return 0;
+
+fallback:
if (statvfs(path, &buf) < 0)
return -errno;
+
*flags = buf.f_flag;
return 0;
}
@@ -501,7 +524,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
return -errno;
orig_flags = 0;
- (void) get_mount_flags(cleaned, &orig_flags);
+ (void) get_mount_flags(cleaned, &orig_flags, table);
orig_flags &= ~MS_RDONLY;
if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
@@ -535,7 +558,7 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
/* Try to reuse the original flag set */
orig_flags = 0;
- (void) get_mount_flags(x, &orig_flags);
+ (void) get_mount_flags(x, &orig_flags, table);
orig_flags &= ~MS_RDONLY;
if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)

View File

@ -0,0 +1,30 @@
From b6ffe7ec63d86c5ac66171d6731068b87e3e7b50 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Sat, 27 Jun 2020 11:13:01 +0200
Subject: [PATCH] mount-util: use UMOUNT_NOFOLLOW in recursive umounter
When we only want to unmount mount points below some path then it is
against our interest to follow symlinks. Hence don't.
(cherry picked from commit 827ea5212507c3833b6ae14cdf65e446b36b5e05)
Related: #1885143
---
src/basic/mount-util.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 2cf98eaa84..be26bb5ec1 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -346,8 +346,8 @@ int umount_recursive(const char *prefix, int flags) {
if (!path_startswith(path, prefix))
continue;
- if (umount2(path, flags) < 0) {
- r = log_debug_errno(errno, "Failed to umount %s: %m", path);
+ if (umount2(path, flags | UMOUNT_NOFOLLOW) < 0) {
+ log_debug_errno(errno, "Failed to umount %s: %m", path);
continue;
}

View File

@ -0,0 +1,29 @@
From 55cde82204724df756a198da691471f2f3f83d5a Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 31 Mar 2021 10:08:31 +0200
Subject: [PATCH] test-install-root: create referenced targets
(cherry picked from commit cd228002ccedb927b4531a4b7dd9ea7015fdb657)
Related: #1835351
---
src/test/test-install-root.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index fe1ca5b16f..f8b41b04db 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -1061,6 +1061,12 @@ int main(int argc, char *argv[]) {
p = strjoina(root, "/usr/lib/systemd/system-preset/");
assert_se(mkdir_p(p, 0755) >= 0);
+ p = strjoina(root, "/usr/lib/systemd/system/multi-user.target");
+ assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0);
+
+ p = strjoina(root, "/usr/lib/systemd/system/graphical.target");
+ assert_se(write_string_file(p, "# pretty much empty", WRITE_STRING_FILE_CREATE) >= 0);
+
test_basic_mask_and_enable(root);
test_linked_units(root);
test_default(root);

View File

@ -0,0 +1,113 @@
From dfb4e03e0865d189a5c171072d6d7b31f49e1088 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Wed, 3 Jun 2020 10:33:21 +0200
Subject: [PATCH] install: warn if WantedBy targets don't exist
Currently, if [Install] section contains WantedBy=target that doesn't exist,
systemd creates the symlinks anyway. That is just user-unfriendly.
Let's be nice and warn about installing non-existent targets.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1835351.
Replaces: #15834
(cherry picked from commit 8ae27441c2dcf585f58242991302b09778d4d710)
Resolves: #1835351
---
src/shared/install.c | 25 ++++++++++++++++++-------
src/shared/install.h | 1 +
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/shared/install.c b/src/shared/install.c
index c9fef6bde2..055b09f98c 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -362,6 +362,11 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
log_info("Unit %s is an alias to a unit that is not present, ignoring.",
changes[i].path);
break;
+ case UNIT_FILE_DESTINATION_NOT_PRESENT:
+ if (!quiet)
+ log_warning("Unit %s is added as a dependency to a non-existent unit %s.",
+ changes[i].source, changes[i].path);
+ break;
case -EEXIST:
if (changes[i].source)
log_error_errno(changes[i].type,
@@ -1730,6 +1735,7 @@ static int install_info_symlink_alias(
}
static int install_info_symlink_wants(
+ UnitFileScope scope,
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
@@ -1795,6 +1801,9 @@ static int install_info_symlink_wants(
q = create_symlink(paths, i->path, path, true, changes, n_changes);
if (r == 0)
r = q;
+
+ if (unit_file_exists(scope, paths, dst) == 0)
+ unit_file_changes_add(changes, n_changes, UNIT_FILE_DESTINATION_NOT_PRESENT, dst, i->path);
}
return r;
@@ -1830,6 +1839,7 @@ static int install_info_symlink_link(
}
static int install_info_apply(
+ UnitFileScope scope,
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
@@ -1848,11 +1858,11 @@ static int install_info_apply(
r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes);
- q = install_info_symlink_wants(i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
+ q = install_info_symlink_wants(scope, i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
if (r == 0)
r = q;
- q = install_info_symlink_wants(i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
+ q = install_info_symlink_wants(scope, i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
if (r == 0)
r = q;
@@ -1916,7 +1926,7 @@ static int install_context_apply(
if (i->type != UNIT_FILE_TYPE_REGULAR)
continue;
- q = install_info_apply(i, paths, config_path, force, changes, n_changes);
+ q = install_info_apply(scope, i, paths, config_path, force, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
@@ -3324,10 +3334,11 @@ static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
- [UNIT_FILE_SYMLINK] = "symlink",
- [UNIT_FILE_UNLINK] = "unlink",
- [UNIT_FILE_IS_MASKED] = "masked",
- [UNIT_FILE_IS_DANGLING] = "dangling",
+ [UNIT_FILE_SYMLINK] = "symlink",
+ [UNIT_FILE_UNLINK] = "unlink",
+ [UNIT_FILE_IS_MASKED] = "masked",
+ [UNIT_FILE_IS_DANGLING] = "dangling",
+ [UNIT_FILE_DESTINATION_NOT_PRESENT] = "destination not present",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
diff --git a/src/shared/install.h b/src/shared/install.h
index e452940991..f07bebb415 100644
--- a/src/shared/install.h
+++ b/src/shared/install.h
@@ -57,6 +57,7 @@ enum UnitFileChangeType {
UNIT_FILE_UNLINK,
UNIT_FILE_IS_MASKED,
UNIT_FILE_IS_DANGLING,
+ UNIT_FILE_DESTINATION_NOT_PRESENT,
_UNIT_FILE_CHANGE_TYPE_MAX,
_UNIT_FILE_CHANGE_TYPE_INVALID = INT_MIN
};

View File

@ -0,0 +1,56 @@
From 430445a936cdb4c32c55affdfdd94b7eb910d5e6 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 31 Mar 2021 10:38:00 +0200
Subject: [PATCH] test-install-root: add test for unknown WantedBy= target
(cherry picked from commit 8adbad370f522831dd9246fe272caf37ce748d4a)
Related: #1835351
---
src/test/test-install-root.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c
index f8b41b04db..73e1e0ae03 100644
--- a/src/test/test-install-root.c
+++ b/src/test/test-install-root.c
@@ -20,6 +20,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) == -ENOENT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) == -ENOENT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) == -ENOENT);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", NULL) == -ENOENT);
p = strjoina(root, "/usr/lib/systemd/system/a.service");
assert_se(write_string_file(p,
@@ -147,6 +148,31 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
+
+ /* Test enabling with unknown dependency target */
+
+ p = strjoina(root, "/usr/lib/systemd/system/f.service");
+ assert_se(write_string_file(p,
+ "[Install]\n"
+ "WantedBy=x.target\n", WRITE_STRING_FILE_CREATE) >= 0);
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", NULL) >= 0);
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
+
+ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("f.service"), &changes, &n_changes) == 1);
+ assert_se(n_changes == 2);
+ assert_se(changes[0].type == UNIT_FILE_SYMLINK);
+ assert_se(streq(changes[0].source, "/usr/lib/systemd/system/f.service"));
+ p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/x.target.wants/f.service");
+ assert_se(streq(changes[0].path, p));
+ assert_se(changes[1].type == UNIT_FILE_DESTINATION_NOT_PRESENT);
+ p = strjoina(root, "/usr/lib/systemd/system/f.service");
+ assert_se(streq(changes[1].source, p));
+ assert_se(streq(changes[1].path, "x.target"));
+ unit_file_changes_free(changes, n_changes);
+ changes = NULL; n_changes = 0;
+
+ assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "f.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
}
static void test_linked_units(const char *root) {

View File

@ -0,0 +1,24 @@
From d284fd2b036ed874f9f38da63f1ab4e9fd9e96a3 Mon Sep 17 00:00:00 2001
From: Jonas Jelten <jj@sft.mx>
Date: Thu, 17 Oct 2019 12:10:13 +0200
Subject: [PATCH] ceph is a network filesystem
(cherry picked from commit c4742de6d801b125abf3c4d1c710280f51d7c701)
Resolves: #1952013
---
src/basic/mount-util.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index be26bb5ec1..45348bf878 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -608,6 +608,7 @@ bool fstype_is_network(const char *fstype) {
return STR_IN_SET(fstype,
"afs",
+ "ceph",
"cifs",
"smb3",
"smbfs",

View File

@ -0,0 +1,49 @@
From 8bdc512d2651b4600f7e744b06633a7524b64346 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 12 Oct 2020 16:31:42 +0200
Subject: [PATCH] sysctl: set kernel.core_pipe_limit=16
We need to make sure that our coredump pattern handler manages to read
process metadata from /proc/$PID/ before the kernel reaps the crashed
process. By default the kernel will reap the process as soon as it can.
By setting kernel.core_pipe_limit to a non-zero the kernel will wait for
userspace to finish before reaping.
We'll set the value to 16, which allows 16 crashes to be
processed in parallel. This matches the MaxConnections= setting in
systemd-coredump.socket.
See: #17301
(This doesn't close 17301, since we probably should also gracefully
handle if /proc/$PID/ vanished already while our coredump handler runs,
just in case people loclly set the sysctl back to zero. i.e. we should
collect what we can and rather issue an incomplete log record than
none.)
(cherry picked from commit 2a9b9323cd844baae3229e9dba67e478bee70654)
Resolves: #1949729
---
sysctl.d/50-coredump.conf.in | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in
index ccd5c2cc56..8d6fbb718c 100644
--- a/sysctl.d/50-coredump.conf.in
+++ b/sysctl.d/50-coredump.conf.in
@@ -10,3 +10,14 @@
# setting below.
kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t %c %h %e
+
+# Allow that 16 coredumps are dispatched in parallel by the kernel. We want to
+# be able to collect process metadata from /proc/%P/ while processing
+# coredumps, and thus need to make sure the crashed processes are not reaped
+# until we finished collecting what we need. The kernel default for this sysctl
+# is "0" which means the kernel doesn't wait for userspace processes to finish
+# processing before reaping the crashed processes — by setting this higher the
+# kernel will delay reaping until we are done, but only for the specified
+# number of crashes in parallel. The value of 16 is chosen to match
+# systemd-coredump.socket's MaxConnections= value.
+kernel.core_pipe_limit=16

View File

@ -0,0 +1,116 @@
From 73bf41a783edbff1b367e645956ed602de1889e2 Mon Sep 17 00:00:00 2001
From: Insun <iplayinsun@gmail.com>
Date: Sun, 28 Oct 2018 21:26:13 +0900
Subject: [PATCH] core: don't drop timer expired but not yet processed when
system date is changed
There is difference between time set by the user and real elapsed time because of accuracy feature.
If you change the system date(or time) between these times, the timer drops.
You can easily reproduce it with the following command.
-----------------------------------------------------------
$ systemd-run --on-active=3s ls; sleep 3; date -s "`date`"
-----------------------------------------------------------
In the following command, the problem is rarely reproduced. But it exists.
---------------------------------------------------------------------------------------------
$ systemd-run --on-active=3s --timer-property=AccuracySec=1us ls ; sleep 1; date -s "`date`"
---------------------------------------------------------------------------------------------
Note : Global AccuracySec value.
----------------------------------------------------------------------
$ cat /etc/systemd/system.conf
DefaultTimerAccuracySec=1min
----------------------------------------------------------------------
(cherry picked from commit fee04d7f3ab810e99b97535ca5fda2f9517acda9)
Related: #1899402
---
src/core/timer.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index 281ac7f97f..ef240a6f19 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -262,7 +262,7 @@ static void timer_set_state(Timer *t, TimerState state) {
unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
}
-static void timer_enter_waiting(Timer *t, bool initial);
+static void timer_enter_waiting(Timer *t, bool initial, bool time_change);
static int timer_coldplug(Unit *u) {
Timer *t = TIMER(u);
@@ -274,7 +274,7 @@ static int timer_coldplug(Unit *u) {
return 0;
if (t->deserialized_state == TIMER_WAITING)
- timer_enter_waiting(t, false);
+ timer_enter_waiting(t, false, false);
else
timer_set_state(t, t->deserialized_state);
@@ -334,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) {
log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
}
-static void timer_enter_waiting(Timer *t, bool initial) {
+static void timer_enter_waiting(Timer *t, bool initial, bool time_change) {
bool found_monotonic = false, found_realtime = false;
bool leave_around = false;
triple_timestamp ts;
@@ -444,7 +444,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value);
- if (!initial &&
+ if (!initial && !time_change &&
v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) &&
IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
/* This is a one time trigger, disable it now */
@@ -642,7 +642,7 @@ static int timer_start(Unit *u) {
}
t->result = TIMER_SUCCESS;
- timer_enter_waiting(t, true);
+ timer_enter_waiting(t, true, false);
return 1;
}
@@ -764,14 +764,14 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
case TIMER_ELAPSED:
/* Recalculate sleep time */
- timer_enter_waiting(t, false);
+ timer_enter_waiting(t, false, false);
break;
case TIMER_RUNNING:
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
log_unit_debug(UNIT(t), "Got notified about unit deactivation.");
- timer_enter_waiting(t, false);
+ timer_enter_waiting(t, false, false);
}
break;
@@ -813,7 +813,7 @@ static void timer_time_change(Unit *u) {
t->last_trigger.realtime = ts;
log_unit_debug(u, "Time change, recalculating next elapse.");
- timer_enter_waiting(t, false);
+ timer_enter_waiting(t, false, true);
}
static void timer_timezone_change(Unit *u) {
@@ -825,7 +825,7 @@ static void timer_timezone_change(Unit *u) {
return;
log_unit_debug(u, "Timezone change, recalculating next elapse.");
- timer_enter_waiting(t, false);
+ timer_enter_waiting(t, false, false);
}
static const char* const timer_base_table[_TIMER_BASE_MAX] = {

View File

@ -0,0 +1,152 @@
From 3d4280d0a487109f8f648147083baf573e4418a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20Koutn=C3=BD?= <mkoutny@suse.com>
Date: Fri, 2 Nov 2018 20:56:08 +0100
Subject: [PATCH] core: Detect initial timer state from serialized data
We keep a mark whether a single-shot timer was triggered in the caller's
variable initial. When such a timer elapses while we are
serializing/deserializing the inner state, we consider the timer
incorrectly as elapsed and don't trigger it later.
This patch exploits last_trigger timestamp that we already serialize,
hence we can eliminate the argument initial completely.
A reproducer for OnBootSec= timers:
cat >repro.c <<EOD
/*
* Compile: gcc repro.c -o repro
* Run: ./repro
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char command[1024];
int pause;
struct timespec now;
while (1) {
usleep(rand() % 200000); // prevent periodic repeats
clock_gettime(CLOCK_MONOTONIC, &now);
printf("%i\n", now.tv_sec);
system("rm -f $PWD/mark");
snprintf(command, 1024, "systemd-run --user --on-boot=%i --timer-property=AccuracySec=100ms "
"touch $PWD/mark", now.tv_sec + 1);
system(command);
system("systemctl --user list-timers");
pause = (1000000000 - now.tv_nsec)/1000 - 70000; // fiddle to hit the middle of reloading
usleep(pause > 0 ? pause : 0);
system("systemctl --user daemon-reload");
sync();
sleep(2);
if (open("./mark", 0) < 0)
if (errno == ENOENT) {
printf("mark file does not exist\n");
break;
}
}
return 0;
}
EOD
(cherry picked from commit aa1f95d2647197eca84c33a0f10adaeada08467d)
Resolves: #1899402
---
src/core/timer.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/core/timer.c b/src/core/timer.c
index ef240a6f19..1718ffc5a5 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -262,7 +262,7 @@ static void timer_set_state(Timer *t, TimerState state) {
unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
}
-static void timer_enter_waiting(Timer *t, bool initial, bool time_change);
+static void timer_enter_waiting(Timer *t, bool time_change);
static int timer_coldplug(Unit *u) {
Timer *t = TIMER(u);
@@ -274,7 +274,7 @@ static int timer_coldplug(Unit *u) {
return 0;
if (t->deserialized_state == TIMER_WAITING)
- timer_enter_waiting(t, false, false);
+ timer_enter_waiting(t, false);
else
timer_set_state(t, t->deserialized_state);
@@ -334,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) {
log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
}
-static void timer_enter_waiting(Timer *t, bool initial, bool time_change) {
+static void timer_enter_waiting(Timer *t, bool time_change) {
bool found_monotonic = false, found_realtime = false;
bool leave_around = false;
triple_timestamp ts;
@@ -444,7 +444,8 @@ static void timer_enter_waiting(Timer *t, bool initial, bool time_change) {
v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value);
- if (!initial && !time_change &&
+ if (dual_timestamp_is_set(&t->last_trigger) &&
+ !time_change &&
v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) &&
IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
/* This is a one time trigger, disable it now */
@@ -642,7 +643,7 @@ static int timer_start(Unit *u) {
}
t->result = TIMER_SUCCESS;
- timer_enter_waiting(t, true, false);
+ timer_enter_waiting(t, false);
return 1;
}
@@ -764,14 +765,14 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
case TIMER_ELAPSED:
/* Recalculate sleep time */
- timer_enter_waiting(t, false, false);
+ timer_enter_waiting(t, false);
break;
case TIMER_RUNNING:
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
log_unit_debug(UNIT(t), "Got notified about unit deactivation.");
- timer_enter_waiting(t, false, false);
+ timer_enter_waiting(t, false);
}
break;
@@ -813,7 +814,7 @@ static void timer_time_change(Unit *u) {
t->last_trigger.realtime = ts;
log_unit_debug(u, "Time change, recalculating next elapse.");
- timer_enter_waiting(t, false, true);
+ timer_enter_waiting(t, true);
}
static void timer_timezone_change(Unit *u) {
@@ -825,7 +826,7 @@ static void timer_timezone_change(Unit *u) {
return;
log_unit_debug(u, "Timezone change, recalculating next elapse.");
- timer_enter_waiting(t, false, false);
+ timer_enter_waiting(t, false);
}
static const char* const timer_base_table[_TIMER_BASE_MAX] = {

View File

@ -0,0 +1,29 @@
From 8cd99937562cde7533519303a7a0ad1df749e075 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Thu, 11 Mar 2021 15:48:23 +0100
Subject: [PATCH] rc-local: order after network-online.target
I think this was the intent of commit 91b684c7300879a8d2006038f7d9185d92c3c3bf,
just network-online.target didn't exist back then.
RHEL-only
Resolves: #1934028
---
units/rc-local.service.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/units/rc-local.service.in b/units/rc-local.service.in
index 78ce69e0ae..74e83d8c07 100644
--- a/units/rc-local.service.in
+++ b/units/rc-local.service.in
@@ -13,7 +13,8 @@
Description=@RC_LOCAL_SCRIPT_PATH_START@ Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=@RC_LOCAL_SCRIPT_PATH_START@
-After=network.target
+After=network-online.target
+Wants=network-online.target
[Service]
Type=forking

View File

@ -0,0 +1,25 @@
From 830bd662276ee117e65a4b3d541f77e8b172eafd Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Mon, 25 Jan 2021 16:19:56 +0100
Subject: [PATCH] set core ulimit to 0 like on RHEL-7
RHEL-only
Resolves: #1905582
---
src/core/system.conf.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index 0d93fbf147..b4d6dfa15a 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -52,7 +52,7 @@
#DefaultLimitFSIZE=
#DefaultLimitDATA=
#DefaultLimitSTACK=
-#DefaultLimitCORE=
+DefaultLimitCORE=0
#DefaultLimitRSS=
#DefaultLimitNOFILE=
#DefaultLimitAS=

View File

@ -0,0 +1,129 @@
From 4ad39b0531f550cde6e01df0801f177c08514c8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 14 Sep 2020 17:58:03 +0200
Subject: [PATCH] test-mountpointutil-util: do not assert in test_mnt_id()
https://bugzilla.redhat.com/show_bug.cgi?id=1803070
I *think* this a kernel bug: the mnt_id as listed in /proc/self/mountinfo is different
than the one we get from /proc/self/fdinfo/. This only matters when both statx and
name_to_handle_at are unavailable and we hit the fallback path that goes through fdinfo:
(gdb) !uname -r
5.6.19-200.fc31.ppc64le
(gdb) !cat /proc/self/mountinfo
697 664 253:0 /var/lib/mock/fedora-31-ppc64le/root / rw,relatime shared:298 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
698 697 253:0 /var/cache/mock/fedora-31-ppc64le/yum_cache /var/cache/yum rw,relatime shared:299 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
699 697 253:0 /var/cache/mock/fedora-31-ppc64le/dnf_cache /var/cache/dnf rw,relatime shared:300 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
700 697 0:32 /mock-selinux-plugin.7me9bfpi /proc/filesystems rw,nosuid,nodev shared:301 master:18 - tmpfs tmpfs rw,seclabel <==========================================================
701 697 0:41 / /sys ro,nosuid,nodev,noexec,relatime shared:302 - sysfs sysfs ro,seclabel
702 701 0:21 / /sys/fs/selinux ro,nosuid,nodev,noexec,relatime shared:306 master:8 - selinuxfs selinuxfs rw
703 697 0:42 / /dev rw,nosuid shared:303 - tmpfs tmpfs rw,seclabel,mode=755
704 703 0:43 / /dev/shm rw,nosuid,nodev shared:304 - tmpfs tmpfs rw,seclabel
705 703 0:45 / /dev/pts rw,nosuid,noexec,relatime shared:307 - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=666
706 703 0:6 /btrfs-control /dev/btrfs-control rw,nosuid shared:308 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
707 703 0:6 /loop-control /dev/loop-control rw,nosuid shared:309 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
708 703 0:6 /loop0 /dev/loop0 rw,nosuid shared:310 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
709 703 0:6 /loop1 /dev/loop1 rw,nosuid shared:311 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
710 703 0:6 /loop10 /dev/loop10 rw,nosuid shared:312 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
711 703 0:6 /loop11 /dev/loop11 rw,nosuid shared:313 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
712 703 0:6 /loop2 /dev/loop2 rw,nosuid shared:314 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
713 703 0:6 /loop3 /dev/loop3 rw,nosuid shared:315 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
714 703 0:6 /loop4 /dev/loop4 rw,nosuid shared:316 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
715 703 0:6 /loop5 /dev/loop5 rw,nosuid shared:317 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
716 703 0:6 /loop6 /dev/loop6 rw,nosuid shared:318 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
717 703 0:6 /loop7 /dev/loop7 rw,nosuid shared:319 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
718 703 0:6 /loop8 /dev/loop8 rw,nosuid shared:320 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
719 703 0:6 /loop9 /dev/loop9 rw,nosuid shared:321 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
720 697 0:44 / /run rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755
721 720 0:25 /systemd/nspawn/propagate/9cc8a155d0244558b273f773d2b92142 /run/systemd/nspawn/incoming ro master:12 - tmpfs tmpfs rw,seclabel,mode=755
722 697 0:32 /mock-resolv.dvml91hp /etc/resolv.conf rw,nosuid,nodev shared:322 master:18 - tmpfs tmpfs rw,seclabel
725 697 0:47 / /proc rw,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
603 725 0:47 /sys /proc/sys ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
604 725 0:44 /systemd/inaccessible/reg /proc/kallsyms ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
605 725 0:44 /systemd/inaccessible/reg /proc/kcore ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
606 725 0:44 /systemd/inaccessible/reg /proc/keys ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
607 725 0:44 /systemd/inaccessible/reg /proc/sysrq-trigger ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
608 725 0:44 /systemd/inaccessible/reg /proc/timer_list ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
609 725 0:47 /bus /proc/bus ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
610 725 0:47 /fs /proc/fs ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
611 725 0:47 /irq /proc/irq ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
612 725 0:47 /scsi /proc/scsi ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
613 703 0:46 / /dev/mqueue rw,nosuid,nodev,noexec,relatime shared:324 - mqueue mqueue rw,seclabel
614 701 0:26 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:325 - cgroup2 cgroup rw,seclabel,nsdelegate
615 603 0:44 /.#proc-sys-kernel-random-boot-id4fbdce67af46d1c2//deleted /proc/sys/kernel/random/boot_id ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
616 725 0:44 /.#proc-sys-kernel-random-boot-id4fbdce67af46d1c2//deleted /proc/sys/kernel/random/boot_id rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755
617 725 0:44 /.#proc-kmsg5b7a8bcfe6717139//deleted /proc/kmsg rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755
The test process does
name_to_handle_at("/proc/filesystems") which returns -EOPNOTSUPP, and then
openat(AT_FDCWD, "/proc/filesystems") which returns 4, and then
read(open("/proc/self/fdinfo/4", ...)) which gives
"pos:\t0\nflags:\t012100000\nmnt_id:\t725\n"
and the "725" is clearly inconsistent with "700" in /proc/self/mountinfo.
We could either drop the fallback path (and fail name_to_handle_at() is not
avaliable) or ignore the error in the test. Not sure what is better. I think
this issue only occurs sometimes and with older kernels, so probably continuing
with the current flaky implementation is better than ripping out the fallback.
Another strace:
writev(2</dev/pts/0>, [{iov_base="mnt ids of /proc/sys is 603", iov_len=27}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/sys is 603
) = 28
name_to_handle_at(AT_FDCWD, "/", {handle_bytes=128 => 12, handle_type=129, f_handle=0x52748401000000008b93e20d}, [697], 0) = 0
writev(2</dev/pts/0>, [{iov_base="mnt ids of / is 697", iov_len=19}, {iov_base="\n", iov_len=1}], 2mnt ids of / is 697
) = 20
name_to_handle_at(AT_FDCWD, "/proc/kcore", {handle_bytes=128 => 12, handle_type=1, f_handle=0x92ddcfcd2e802d0100000000}, [605], 0) = 0
writev(2</dev/pts/0>, [{iov_base="mnt ids of /proc/kcore is 605", iov_len=29}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/kcore is 605
) = 30
name_to_handle_at(AT_FDCWD, "/dev", {handle_bytes=128 => 12, handle_type=1, f_handle=0x8ae269160c802d0100000000}, [703], 0) = 0
writev(2</dev/pts/0>, [{iov_base="mnt ids of /dev is 703", iov_len=22}, {iov_base="\n", iov_len=1}], 2mnt ids of /dev is 703
) = 23
name_to_handle_at(AT_FDCWD, "/proc/filesystems", {handle_bytes=128}, 0x7fffe36ddb84, 0) = -1 EOPNOTSUPP (Operation not supported)
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4</proc/filesystems>
openat(AT_FDCWD, "/proc/self/fdinfo/4", O_RDONLY|O_CLOEXEC) = 5</proc/20/fdinfo/4>
fstat(5</proc/20/fdinfo/4>, {st_mode=S_IFREG|0400, st_size=0, ...}) = 0
fstat(5</proc/20/fdinfo/4>, {st_mode=S_IFREG|0400, st_size=0, ...}) = 0
read(5</proc/20/fdinfo/4>, "pos:\t0\nflags:\t012100000\nmnt_id:\t725\n", 2048) = 36
read(5</proc/20/fdinfo/4>, "", 1024) = 0
close(5</proc/20/fdinfo/4>) = 0
close(4</proc/filesystems>) = 0
writev(2</dev/pts/0>, [{iov_base="mnt ids of /proc/filesystems are 700, 725", iov_len=41}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/filesystems are 700, 725
) = 42
writev(2</dev/pts/0>, [{iov_base="the other path for mnt id 725 is /proc", iov_len=38}, {iov_base="\n", iov_len=1}], 2the other path for mnt id 725 is /proc
) = 39
writev(2</dev/pts/0>, [{iov_base="Assertion 'path_equal(p, t)' failed at src/test/test-mountpoint-util.c:94, function test_mnt_id(). Aborting.", iov_len=108}, {iov_base="\n", iov_len=1}], 2Assertion 'path_equal(p, t)' failed at src/test/test-mountpoint-util.c:94, function test_mnt_id(). Aborting.
) = 109
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
getpid() = 20
gettid() = 20
tgkill(20, 20, SIGABRT) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
Resolves: #1910425
---
src/test/test-mount-util.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c
index c10e1681fb..991d165fc3 100644
--- a/src/test/test-mount-util.c
+++ b/src/test/test-mount-util.c
@@ -74,7 +74,13 @@ static void test_mnt_id(void) {
/* The ids don't match? If so, then there are two mounts on the same path, let's check if that's really
* the case */
- assert_se(path_equal_ptr(hashmap_get(h, INT_TO_PTR(mnt_id2)), p));
+ char *t = hashmap_get(h, INT_TO_PTR(mnt_id2));
+ log_debug("Path for mnt id %i from /proc/self/mountinfo is %s\n", mnt_id2, t);
+
+ if (!path_equal(p, t))
+ /* Apparent kernel bug in /proc/self/fdinfo */
+ log_warning("Bad mount id given for %s: %d, should be %d",
+ p, mnt_id2, mnt_id);
}
hashmap_free_free(h);

View File

@ -1,4 +1,4 @@
From 1745f135c7b26fef0223848efc06e62cf86c1b34 Mon Sep 17 00:00:00 2001
From 5944138a54017fc8f1f4c878a1eea96ea18736c4 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 25 Jun 2021 10:42:53 +0200
Subject: [PATCH] remove a left-over break
@ -8,11 +8,9 @@ but the break prohibits that.
This is a follow-up for ee1aa61c4710ae567a2b844e0f0bb8cb0456ab8c .
Based on: 99df1cb6f50875db513a5b45f18191460a150f3d)
(cherry picked from commit 99df1cb6f50875db513a5b45f18191460a150f3d)
Related: #1984406
(cherry picked from commit 5944138a54017fc8f1f4c878a1eea96ea18736c4)
Related: #1970860
---
src/basic/copy.c | 1 -
1 file changed, 1 deletion(-)

View File

@ -1,4 +1,4 @@
From 25e2006bff1b82c4cee3d3899ed2874815e81e4a Mon Sep 17 00:00:00 2001
From c5d2964d498da0ac06799e5f040de74a0f5d2deb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 23 Jun 2021 11:46:41 +0200
Subject: [PATCH] basic/unit-name: do not use strdupa() on a path
@ -20,6 +20,8 @@ So we can't reject paths that are too long before doing the duplication.
Hence the most obvious solution is to switch back to strdup(), as before
7410616cd9dbbec97cf98d75324da5cda2b2f7a2.
Resolves: #1974700
(cherry picked from commit 441e0115646d54f080e5c3bb0ba477c892861ab9)
---
src/basic/unit-name.c | 13 +++++--------

View File

@ -1,4 +1,4 @@
From 93de7820843c175f4c9661dbfcb312e8ee09fbd3 Mon Sep 17 00:00:00 2001
From f863f89d8a5cbb47676d5114e349918c4e009fe5 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 8 Jun 2021 00:07:51 -0700
Subject: [PATCH] sd-event: change ordering of pending/ratelimited events
@ -11,7 +11,7 @@ time.
(cherry picked from commit 81107b8419c39f726fd2805517a5b9faab204e59)
Related: #1984406
Related: #1968528
---
src/libsystemd/sd-event/sd-event.c | 48 +++++++++++++-----------------
1 file changed, 20 insertions(+), 28 deletions(-)

View File

@ -1,11 +1,11 @@
From 3e7e54c63236c65aa01bb332fd5135a13e51b992 Mon Sep 17 00:00:00 2001
From 9faf4d1a39b7fc8c9f986a808e1c0d3ed9b44357 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 15 Jun 2021 00:44:04 +0900
Subject: [PATCH] sd-event: drop unnecessary "else"
(cherry picked from commit 7e2bf71ca3638e36ee33215ceee386ba8013da6d)
Related: #1984406
Related: #1968528
---
src/libsystemd/sd-event/sd-event.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

View File

@ -1,11 +1,11 @@
From eaab8d57d9db0d98d7e618ba634983c34cdb9c06 Mon Sep 17 00:00:00 2001
From 7419222d3811d60c0a8f5ea27778108a1ca8ee71 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 15 Jun 2021 00:51:33 +0900
Subject: [PATCH] sd-event: use CMP() macro
(cherry picked from commit 06e131477d82b83c5d516e66d6e413affd7c774a)
Related: #1984406
Related: #1968528
---
src/libsystemd/sd-event/sd-event.c | 37 ++++++++++++++----------------
1 file changed, 17 insertions(+), 20 deletions(-)

View File

@ -1,11 +1,11 @@
From b8732d647162b50ce9b34de2ad7ae11a53f6e7ba Mon Sep 17 00:00:00 2001
From b79e00d8f97b8c959c5b17f0547c680f86dd9132 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 15 Jun 2021 01:01:48 +0900
Subject: [PATCH] sd-event: use usec_add()
(cherry picked from commit a595fb5ca9c69c589e758e9ebe3b70ac90450ba3)
Related: #1984406
Related: #1968528
---
src/libsystemd/sd-event/sd-event.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

View File

@ -1,4 +1,4 @@
From 9f044118dbc6a0f04b3820ffaa9d4c7807ae48a7 Mon Sep 17 00:00:00 2001
From bf370d05bbc8c4d91c8c2b455116e59a24e48911 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 15 Jun 2021 02:03:02 +0900
Subject: [PATCH] sd-event: make event_source_time_prioq_reshuffle() accept all
@ -9,7 +9,7 @@ ratelimited.
(cherry picked from commit 5c08c7ab23dbf02aaf4e4bbae8e08a195da230a4)
Related: #1984406
Related: #1968528
---
src/libsystemd/sd-event/sd-event.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

View File

@ -1,4 +1,4 @@
From f5611a22d4a65ef440352792085774ce898adb0f Mon Sep 17 00:00:00 2001
From 1ce5187fb47bec57de4d8d3fd0068072228ec5e3 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 15 Jun 2021 02:13:59 +0900
Subject: [PATCH] sd-event: always reshuffle time prioq on changing
@ -16,7 +16,7 @@ Hopefully fixes #19903.
(cherry picked from commit 2115b9b6629eeba7bc9f42f757f38205febb1cb7)
Related: #1984406
Related: #1968528
---
src/libsystemd/sd-event/sd-event.c | 33 ++++++++++--------------------
1 file changed, 11 insertions(+), 22 deletions(-)

View File

@ -1,13 +1,10 @@
From b36d6b397ad43e081574663a65b0db72cdcaaf28 Mon Sep 17 00:00:00 2001
From 68cedfd41f1ea3eda34b0023e951649b92953709 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Thu, 15 Jul 2021 12:27:33 +0200
Subject: [PATCH] ci: run unit tests on z-stream branches as well
Resolves: #1970860
rhel-only
Related: #1984406
(cherry picked from commit 68cedfd41f1ea3eda34b0023e951649b92953709)
---
.github/workflows/unit_tests.yml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

View File

@ -0,0 +1,32 @@
From 9bb57b7bed93e79f578e7c5b0c95f1f454e5d829 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 3 Mar 2021 12:33:38 +0100
Subject: [PATCH] ci: drop forgotten Travis references
rhel-only
Related: #1934504
---
.github/workflows/unit_tests.sh | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh
index ea4f7e7592..43882b27da 100755
--- a/.github/workflows/unit_tests.sh
+++ b/.github/workflows/unit_tests.sh
@@ -68,7 +68,7 @@ for phase in "${PHASES[@]}"; do
case $phase in
SETUP)
info "Setup phase"
- info "Using Travis $CENTOS_RELEASE"
+ info "Using $CENTOS_RELEASE image"
# Pull a Docker image and start a new container
docker pull quay.io/centos/centos:$CENTOS_RELEASE
info "Starting container $CONT_NAME"
@@ -110,7 +110,6 @@ for phase in "${PHASES[@]}"; do
docker exec --interactive=false \
-e UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 \
-e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \
- -e "TRAVIS=$TRAVIS" \
-t $CONT_NAME \
meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
;;

View File

@ -0,0 +1,113 @@
From ccde55a339d211af488b1f1c148597d7977a9bb8 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 3 Mar 2021 12:49:20 +0100
Subject: [PATCH] ci: run unit tests on CentOS 8 Stream as well
rhel-only
Related: #1934504
---
.github/workflows/unit_tests.sh | 52 +++++++++++++++++++++++++++++++-
.github/workflows/unit_tests.yml | 13 ++++----
2 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh
index 43882b27da..8648e7149e 100755
--- a/.github/workflows/unit_tests.sh
+++ b/.github/workflows/unit_tests.sh
@@ -58,6 +58,53 @@ CONFIGURE_OPTS=(
-Ddefault-hierarchy=legacy
)
+# CentOS 8 Stream still doesn't provide SRPMs, so we can't use dnf's builddep
+# command to fetch this list for us. Hopefully, we'll be able to get rid
+# of this in the future.
+# See: https://bugs.centos.org/view.php?id=16715
+SYSTEMD_BUILD_DEPS=(
+ audit-libs-devel
+ bzip2-devel
+ cryptsetup-devel
+ dbus-devel
+ docbook-style-xsl
+ elfutils-devel
+ firewalld-filesystem
+ gcc
+ gcc-c++
+ gettext
+ git
+ gnu-efi
+ gnu-efi-devel
+ gnutls-devel
+ gobject-introspection-devel
+ gperf
+ iptables-devel
+ kmod-devel
+ libacl-devel
+ libblkid-devel
+ libcap-devel
+ libcurl-devel
+ libgcrypt-devel
+ libgpg-error-devel
+ libidn2-devel
+ libmicrohttpd-devel
+ libmount-devel
+ libseccomp-devel
+ libselinux-devel
+ libxkbcommon-devel
+ libxslt
+ lz4
+ lz4-devel
+ meson
+ pam-devel
+ pkgconf-pkg-config
+ python3-lxml
+ python36-devel
+ tree
+ xz-devel
+)
+
function info() {
echo -e "\033[33;1m$1\033[0m"
}
@@ -85,7 +132,10 @@ for phase in "${PHASES[@]}"; do
# Upgrade the container to get the most recent environment
$DOCKER_EXEC dnf -y upgrade
# Install systemd's build dependencies
- $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd
+ if ! $DOCKER_EXEC dnf -q -y --enablerepo "powertools" builddep systemd; then
+ # See the $SYSTEMD_BUILD_DEPS above for reasoning
+ $DOCKER_EXEC dnf -q -y --enablerepo "powertools" install "${SYSTEMD_BUILD_DEPS[@]}"
+ fi
;;
RUN|RUN_GCC)
info "Run phase"
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
index 428bde4ed8..b363118be8 100644
--- a/.github/workflows/unit_tests.yml
+++ b/.github/workflows/unit_tests.yml
@@ -7,19 +7,20 @@ on: [pull_request]
jobs:
build:
runs-on: ubuntu-20.04
- env:
- CENTOS_RELEASE: "centos8"
- CONT_NAME: "systemd-centos8-ci"
strategy:
fail-fast: false
matrix:
- run_phase: [GCC, GCC_ASAN]
+ image: [centos8, stream8]
+ phase: [GCC, GCC_ASAN]
+ env:
+ CONT_NAME: "systemd-centos8-ci"
+ CENTOS_RELEASE: ${{ matrix.image }}
steps:
- name: Repository checkout
uses: actions/checkout@v1
- name: Install build dependencies
run: sudo -E .github/workflows/unit_tests.sh SETUP
- - name: Build & test (${{ matrix.run_phase }})
- run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.run_phase }}
+ - name: Build & test (${{ env.CENTOS_RELEASE }} / ${{ matrix.phase }})
+ run: sudo -E .github/workflows/unit_tests.sh RUN_${{ matrix.phase }}
- name: Cleanup
run: sudo -E .github/workflows/unit_tests.sh CLEANUP

View File

@ -0,0 +1,37 @@
From 68555d26da9e46efbd70703b39a81cee601d265a Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Wed, 3 Mar 2021 13:14:02 +0100
Subject: [PATCH] ci: add missing test dependencies
rhel-only
Related: #1934504
---
.github/workflows/unit_tests.sh | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh
index 8648e7149e..ad4584ec1d 100755
--- a/.github/workflows/unit_tests.sh
+++ b/.github/workflows/unit_tests.sh
@@ -6,7 +6,20 @@ CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}"
DOCKER_EXEC="${DOCKER_EXEC:-docker exec $CONT_NAME}"
DOCKER_RUN="${DOCKER_RUN:-docker run}"
REPO_ROOT="${REPO_ROOT:-$PWD}"
-ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq diffutils)
+ADDITIONAL_DEPS=(
+ diffutils
+ dnsmasq
+ e2fsprogs
+ hostname
+ libasan
+ libubsan
+ nc
+ net-tools
+ perl-IPC-SysV
+ perl-Time-HiRes
+ quota
+ strace
+)
# RHEL8 options
CONFIGURE_OPTS=(
-Dsysvinit-path=/etc/rc.d/init.d

View File

@ -0,0 +1,30 @@
From 998041fbb2b4114f2f1df604cdebc4afbf682d63 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <frantisek@sumsal.cz>
Date: Fri, 18 Jan 2019 22:32:42 +0100
Subject: [PATCH] meson: bump timeout for test-udev to 180s
On some (mainly virtual) machines the last test takes more than 30
seconds, which causes unnecessary fails, as the test itself is working
properly.
(cherry picked from commit bb0e960448fce037f5b82b1829863da8ccbe636b)
Related: #1934504
---
test/meson.build | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/test/meson.build b/test/meson.build
index 52e4fa2e3c..535354f3ab 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -246,7 +246,8 @@ custom_target(
if perl.found()
udev_test_pl = find_program('udev-test.pl')
test('udev-test',
- udev_test_pl)
+ udev_test_pl,
+ timeout : 180)
else
message('Skipping udev-test because perl is not available')
endif

View File

@ -0,0 +1,222 @@
From f875436b93c6c5e83f46ab32429c977db4f0b10c Mon Sep 17 00:00:00 2001
From: Felix Stupp <felix.stupp@outlook.com>
Date: Thu, 29 Oct 2020 12:48:48 +0100
Subject: [PATCH] Added option --check-inhibitors for non-tty usage
As described in #2680, systemctl did ignore inhibitors if it is not
attached to a tty to allow scripts to ignore inhibitors automatically.
This pull request preserves this behavior but allows scripts to
explicit check inhibitors if required.
The new parameter '--check-inhibitors=yes' enables this feature.
The old parameter '-i'/'--ignore-inhibitors' was deprecated in favor
of '--check-inhibitors=no', the default behaviour can be specified
with '--check-inhibitors=auto'.
The new parameter is also described in the documentations and shell
completions found here.
(cherry picked from commit b8ebe378b49a31549b8531d4b3177095ef385d55)
Related: #1269726
---
man/systemctl.xml | 38 ++++++++++++++++++++----------
shell-completion/bash/systemctl.in | 7 ++++--
shell-completion/zsh/_systemctl.in | 9 ++++++-
src/systemctl/systemctl.c | 37 +++++++++++++++++++++--------
4 files changed, 65 insertions(+), 26 deletions(-)
diff --git a/man/systemctl.xml b/man/systemctl.xml
index ed60a0739f..9f0f4d46ea 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -323,23 +323,35 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--check-inhibitors=</option></term>
+
+ <listitem>
+ <para>When system shutdown or sleep state is request, this option controls how to deal with
+ inhibitor locks. It takes one of <literal>auto</literal>, <literal>yes</literal> or
+ <literal>no</literal>. Defaults to <literal>auto</literal>, which will behave like
+ <literal>yes</literal> for interactive invocations (i.e. from a TTY) and <literal>no</literal>
+ for non-interactive invocations.
+ <literal>yes</literal> will let the request respect inhibitor locks.
+ <literal>no</literal> will let the request ignore inhibitor locks.
+ </para>
+ <para>Applications can establish inhibitor locks to avoid that certain important operations
+ (such as CD burning or suchlike) are interrupted by system shutdown or a sleep state. Any user may
+ take these locks and privileged users may override these locks.
+ If any locks are taken, shutdown and sleep state requests will normally fail (unless privileged)
+ and a list of active locks is printed.
+ However, if <literal>no</literal> is specified or <literal>auto</literal> is specified on a
+ non-interactive requests, the established locks are ignored and not shown, and the operation
+ attempted anyway, possibly requiring additional privileges.
+ May be overriden by <option>--force</option>.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>-i</option></term>
- <term><option>--ignore-inhibitors</option></term>
<listitem>
- <para>When system shutdown or a sleep state is requested,
- ignore inhibitor locks. Applications can establish inhibitor
- locks to avoid that certain important operations (such as CD
- burning or suchlike) are interrupted by system shutdown or a
- sleep state. Any user may take these locks and privileged
- users may override these locks. If any locks are taken,
- shutdown and sleep state requests will normally fail
- (regardless of whether privileged or not) and a list of active locks
- is printed. However, if <option>--ignore-inhibitors</option>
- is specified, the locks are ignored and not printed, and the
- operation attempted anyway, possibly requiring additional
- privileges.</para>
+ <para>Shortcut for <option>--check-inhibitors=no</option>.</para>
</listitem>
</varlistentry>
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index ba51ae0d34..0c7afea57d 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -111,9 +111,9 @@ _systemctl () {
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
--help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now
--quiet -q --system --user --version --runtime --recursive -r --firmware-setup
- --show-types -i --ignore-inhibitors --plain --failed --value --fail --dry-run --wait'
+ --show-types --plain --failed --value --fail --dry-run --wait'
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root
- --preset-mode -n --lines -o --output -M --machine --message'
+ --preset-mode -n --lines -o --output -M --machine --message --check-inhibitors'
)
if __contains_word "--user" ${COMP_WORDS[*]}; then
@@ -163,6 +163,9 @@ _systemctl () {
--machine|-M)
comps=$( __get_machines )
;;
+ --check-inhibitors)
+ comps='auto yes no'
+ ;;
esac
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
return 0
diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in
index 9f576ed77d..b3c51cc843 100644
--- a/shell-completion/zsh/_systemctl.in
+++ b/shell-completion/zsh/_systemctl.in
@@ -363,6 +363,13 @@ _job_modes() {
_values -s , "${_modes[@]}"
}
+(( $+functions[_systemctl_check_inhibitors] )) ||
+ _systemctl_check_inhibitors() {
+ local -a _modes
+ _modes=(auto yes no)
+ _values -s , "${_modes[@]}"
+ }
+
# Build arguments for "systemctl" to be used in completion.
local -a _modes; _modes=("--user" "--system")
# Use the last mode (they are exclusive and the last one is used).
@@ -380,7 +387,7 @@ _arguments -s \
'--before[Show units ordered before]' \
{-l,--full}"[Don't ellipsize unit names on output]" \
'--show-types[When showing sockets, show socket type]' \
- {-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \
+ '--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \
{-q,--quiet}'[Suppress output]' \
'--no-block[Do not wait until operation finished]' \
'--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 8bec798373..8bcbf6bf4b 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -121,7 +121,7 @@ static bool arg_no_wall = false;
static bool arg_no_reload = false;
static bool arg_value = false;
static bool arg_show_types = false;
-static bool arg_ignore_inhibitors = false;
+static int arg_check_inhibitors = -1;
static bool arg_dry_run = false;
static bool arg_quiet = false;
static bool arg_full = false;
@@ -3313,17 +3313,19 @@ static int logind_check_inhibitors(enum action a) {
char **s;
int r;
- if (arg_ignore_inhibitors || arg_force > 0)
+ if (arg_check_inhibitors == 0 || arg_force > 0)
return 0;
if (arg_when > 0)
return 0;
- if (geteuid() == 0)
- return 0;
+ if (arg_check_inhibitors < 0) {
+ if (geteuid() == 0)
+ return 0;
- if (!on_tty())
- return 0;
+ if (!on_tty())
+ return 0;
+ }
if (arg_transport != BUS_TRANSPORT_LOCAL)
return 0;
@@ -7237,8 +7239,10 @@ static void systemctl_help(void) {
" When enqueuing a unit job, show full transaction\n"
" --show-types When showing sockets, explicitly show their type\n"
" --value When showing properties, only print the value\n"
- " -i --ignore-inhibitors\n"
- " When shutting down or sleeping, ignore inhibitors\n"
+ " --check-inhibitors=MODE\n"
+ " Specify if checking inhibitors before shutting down,\n"
+ " sleeping or hibernating\n"
+ " -i Shortcut for --check-inhibitors=no\n"
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
" --now Start or stop unit in addition to enabling or disabling it\n"
@@ -7475,6 +7479,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
ARG_REVERSE,
ARG_AFTER,
ARG_BEFORE,
+ ARG_CHECK_INHIBITORS,
ARG_DRY_RUN,
ARG_SHOW_TYPES,
ARG_IRREVERSIBLE,
@@ -7520,7 +7525,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
{ "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
{ "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
- { "ignore-inhibitors", no_argument, NULL, 'i' },
+ { "ignore-inhibitors", no_argument, NULL, 'i' }, /* compatibility only */
+ { "check-inhibitors", required_argument, NULL, ARG_CHECK_INHIBITORS },
{ "value", no_argument, NULL, ARG_VALUE },
{ "user", no_argument, NULL, ARG_USER },
{ "system", no_argument, NULL, ARG_SYSTEM },
@@ -7813,7 +7819,18 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case 'i':
- arg_ignore_inhibitors = true;
+ arg_check_inhibitors = 0;
+ break;
+
+ case ARG_CHECK_INHIBITORS:
+ if (streq(optarg, "auto"))
+ arg_check_inhibitors = -1;
+ else {
+ r = parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --check-inhibitors= argument: %s", optarg);
+ arg_check_inhibitors = r;
+ }
break;
case ARG_PLAIN:

View File

@ -0,0 +1,769 @@
From d375206fe822903b16f3b9006ea47ffd938d88cb Mon Sep 17 00:00:00 2001
From: Deepak Rawat <drawat.floss@gmail.com>
Date: Mon, 25 Jan 2021 09:14:08 -0800
Subject: [PATCH] logind: Introduce RebootWithFlags and others
Add new systemd-logind WithFlags version for Reboot and others. These
methods add a unit64 parameter, with which can send additional control flags.
(cherry picked from commit 00971ea5164e2e7a5f2d7ffe12a566b62d282556)
Related: #1269726
---
src/basic/login-util.h | 8 +
src/login/logind-dbus.c | 498 +++++++++++++++++++++++++++++++-----
src/systemctl/systemctl.c | 26 ++
src/systemd/sd-bus-vtable.h | 19 +-
4 files changed, 480 insertions(+), 71 deletions(-)
diff --git a/src/basic/login-util.h b/src/basic/login-util.h
index e1e62e12b7..9832207458 100644
--- a/src/basic/login-util.h
+++ b/src/basic/login-util.h
@@ -4,6 +4,14 @@
#include <stdbool.h>
#include <unistd.h>
+#define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0)
+
+/* For internal use only */
+#define SD_LOGIND_INTERACTIVE (UINT64_C(1) << 63)
+
+#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS)
+#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_INTERACTIVE)
+
bool session_id_valid(const char *id);
static inline bool logind_running(void) {
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 3f122fcbd9..0c43fbb3e0 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1698,14 +1698,14 @@ static int verify_shutdown_creds(
Manager *m,
sd_bus_message *message,
InhibitWhat w,
- bool interactive,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
+ uint64_t flags,
sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- bool multiple_sessions, blocked;
+ bool multiple_sessions, blocked, interactive;
uid_t uid;
int r;
@@ -1728,6 +1728,7 @@ static int verify_shutdown_creds(
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
+ interactive = flags & SD_LOGIND_INTERACTIVE;
if (multiple_sessions && action_multiple_sessions) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
@@ -1737,12 +1738,19 @@ static int verify_shutdown_creds(
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
- if (blocked && action_ignore_inhibit) {
- r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+ if (blocked) {
+ /* We don't check polkit for root here, because you can't be more privileged than root */
+ if (uid == 0 && (flags & SD_LOGIND_ROOT_CHECK_INHIBITORS))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED,
+ "Access denied to root due to active block inhibitor");
+
+ if (action_ignore_inhibit) {
+ r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+ }
}
if (!multiple_sessions && !blocked && action) {
@@ -1765,9 +1773,11 @@ static int method_do_shutdown_or_sleep(
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
const char *sleep_verb,
+ bool with_flags,
sd_bus_error *error) {
- int interactive, r;
+ int interactive = false, r;
+ uint64_t flags = 0;
assert(m);
assert(message);
@@ -1775,10 +1785,20 @@ static int method_do_shutdown_or_sleep(
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
- r = sd_bus_message_read(message, "b", &interactive);
+ if (with_flags)
+ r = sd_bus_message_read(message, "t", &flags);
+ else
+ r = sd_bus_message_read(message, "b", &interactive);
+
if (r < 0)
return r;
+ if (with_flags && (flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
+ "Invalid flags parameter");
+
+ SET_FLAG(flags, SD_LOGIND_INTERACTIVE, interactive);
+
/* Don't allow multiple jobs being executed at the same time */
if (m->action_what)
return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS, "There's already a shutdown or sleep operation in progress");
@@ -1795,8 +1815,8 @@ static int method_do_shutdown_or_sleep(
return r;
}
- r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
- action_ignore_inhibit, error);
+ r = verify_shutdown_creds(m, message, w, action, action_multiple_sessions,
+ action_ignore_inhibit, flags, error);
if (r != 0)
return r;
@@ -1818,6 +1838,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error
"org.freedesktop.login1.power-off-multiple-sessions",
"org.freedesktop.login1.power-off-ignore-inhibit",
NULL,
+ sd_bus_message_is_method_call(message, NULL, "PowerOffWithFlags"),
error);
}
@@ -1832,6 +1853,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
NULL,
+ sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"),
error);
}
@@ -1846,6 +1868,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er
"org.freedesktop.login1.halt-multiple-sessions",
"org.freedesktop.login1.halt-ignore-inhibit",
NULL,
+ sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"),
error);
}
@@ -1860,6 +1883,7 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
"suspend",
+ sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"),
error);
}
@@ -1874,6 +1898,7 @@ static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_erro
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hibernate",
+ sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"),
error);
}
@@ -1888,6 +1913,7 @@ static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_e
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hybrid-sleep",
+ sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"),
error);
}
@@ -1902,6 +1928,7 @@ static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hybrid-sleep",
+ sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"),
error);
}
@@ -2089,8 +2116,8 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
} else
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
- r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
- action, action_multiple_sessions, action_ignore_inhibit, error);
+ r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, action, action_multiple_sessions,
+ action_ignore_inhibit, 0, error);
if (r != 0)
return r;
@@ -2683,60 +2710,395 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_hashmap_size, offsetof(Manager, sessions), 0),
SD_BUS_PROPERTY("UserTasksMax", "t", property_get_compat_user_tasks_max, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetSessionByPID", "u", "o", method_get_session_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetUser", "u", "o", method_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetUserByPID", "u", "o", method_get_user_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("GetSeat", "s", "o", method_get_seat, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListSessions", NULL, "a(susso)", method_list_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListUsers", NULL, "a(uso)", method_list_users, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListSeats", NULL, "a(so)", method_list_seats, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ListInhibitors", NULL, "a(ssssuu)", method_list_inhibitors, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CreateSession", "uusssssussbssa(sv)", "soshusub", method_create_session, 0),
- SD_BUS_METHOD("ReleaseSession", "s", NULL, method_release_session, 0),
- SD_BUS_METHOD("ActivateSession", "s", NULL, method_activate_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ActivateSessionOnSeat", "ss", NULL, method_activate_session_on_seat, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("LockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("UnlockSession", "s", NULL, method_lock_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("LockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("UnlockSessions", NULL, NULL, method_lock_sessions, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("KillSession", "ssi", NULL, method_kill_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("KillUser", "ui", NULL, method_kill_user, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("TerminateSession", "s", NULL, method_terminate_session, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("TerminateUser", "u", NULL, method_terminate_user, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("TerminateSeat", "s", NULL, method_terminate_seat, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetUserLinger", "ubb", NULL, method_set_user_linger, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("AttachDevice", "ssb", NULL, method_attach_device, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("FlushDevices", "b", NULL, method_flush_devices, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("PowerOff", "b", NULL, method_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Reboot", "b", NULL, method_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Halt", "b", NULL, method_halt, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Suspend", "b", NULL, method_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Hibernate", "b", NULL, method_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("HybridSleep", "b", NULL, method_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SuspendThenHibernate", "b", NULL, method_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanPowerOff", NULL, "s", method_can_poweroff, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanReboot", NULL, "s", method_can_reboot, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanHalt", NULL, "s", method_can_halt, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanSuspend", NULL, "s", method_can_suspend, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanSuspendThenHibernate", NULL, "s", method_can_suspend_then_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("ScheduleShutdown", "st", NULL, method_schedule_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CancelScheduledShutdown", NULL, "b", method_cancel_scheduled_shutdown, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("CanRebootToFirmwareSetup", NULL, "s", method_can_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetRebootToFirmwareSetup", "b", NULL, method_set_reboot_to_firmware_setup, SD_BUS_VTABLE_UNPRIVILEGED),
- SD_BUS_METHOD("SetWallMessage", "sb", NULL, method_set_wall_message, SD_BUS_VTABLE_UNPRIVILEGED),
-
- SD_BUS_SIGNAL("SessionNew", "so", 0),
- SD_BUS_SIGNAL("SessionRemoved", "so", 0),
- SD_BUS_SIGNAL("UserNew", "uo", 0),
- SD_BUS_SIGNAL("UserRemoved", "uo", 0),
- SD_BUS_SIGNAL("SeatNew", "so", 0),
- SD_BUS_SIGNAL("SeatRemoved", "so", 0),
- SD_BUS_SIGNAL("PrepareForShutdown", "b", 0),
- SD_BUS_SIGNAL("PrepareForSleep", "b", 0),
+ SD_BUS_METHOD_WITH_NAMES("GetSession",
+ "s",
+ SD_BUS_PARAM(session_id),
+ "o",
+ SD_BUS_PARAM(object_path),
+ method_get_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("GetSessionByPID",
+ "u",
+ SD_BUS_PARAM(pid),
+ "o",
+ SD_BUS_PARAM(object_path),
+ method_get_session_by_pid,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("GetUser",
+ "u",
+ SD_BUS_PARAM(uid),
+ "o",
+ SD_BUS_PARAM(object_path),
+ method_get_user,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("GetUserByPID",
+ "u",
+ SD_BUS_PARAM(pid),
+ "o",
+ SD_BUS_PARAM(object_path),
+ method_get_user_by_pid,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("GetSeat",
+ "s",
+ SD_BUS_PARAM(seat_id),
+ "o",
+ SD_BUS_PARAM(object_path),
+ method_get_seat,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("ListSessions",
+ NULL,,
+ "a(susso)",
+ SD_BUS_PARAM(sessions),
+ method_list_sessions,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("ListUsers",
+ NULL,,
+ "a(uso)",
+ SD_BUS_PARAM(users),
+ method_list_users,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("ListSeats",
+ NULL,,
+ "a(so)",
+ SD_BUS_PARAM(seats),
+ method_list_seats,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("ListInhibitors",
+ NULL,,
+ "a(ssssuu)",
+ SD_BUS_PARAM(inhibitors),
+ method_list_inhibitors,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CreateSession",
+ "uusssssussbssa(sv)",
+ SD_BUS_PARAM(uid)
+ SD_BUS_PARAM(pid)
+ SD_BUS_PARAM(service)
+ SD_BUS_PARAM(type)
+ SD_BUS_PARAM(class)
+ SD_BUS_PARAM(desktop)
+ SD_BUS_PARAM(seat_id)
+ SD_BUS_PARAM(vtnr)
+ SD_BUS_PARAM(tty)
+ SD_BUS_PARAM(display)
+ SD_BUS_PARAM(remote)
+ SD_BUS_PARAM(remote_user)
+ SD_BUS_PARAM(remote_host)
+ SD_BUS_PARAM(properties),
+ "soshusub",
+ SD_BUS_PARAM(session_id)
+ SD_BUS_PARAM(object_path)
+ SD_BUS_PARAM(runtime_path)
+ SD_BUS_PARAM(fifo_fd)
+ SD_BUS_PARAM(uid)
+ SD_BUS_PARAM(seat_id)
+ SD_BUS_PARAM(vtnr)
+ SD_BUS_PARAM(existing),
+ method_create_session,
+ 0),
+ SD_BUS_METHOD_WITH_NAMES("ReleaseSession",
+ "s",
+ SD_BUS_PARAM(session_id),
+ NULL,,
+ method_release_session,
+ 0),
+ SD_BUS_METHOD_WITH_NAMES("ActivateSession",
+ "s",
+ SD_BUS_PARAM(session_id),
+ NULL,,
+ method_activate_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("ActivateSessionOnSeat",
+ "ss",
+ SD_BUS_PARAM(session_id)
+ SD_BUS_PARAM(seat_id),
+ NULL,,
+ method_activate_session_on_seat,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("LockSession",
+ "s",
+ SD_BUS_PARAM(session_id),
+ NULL,,
+ method_lock_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("UnlockSession",
+ "s",
+ SD_BUS_PARAM(session_id),
+ NULL,,
+ method_lock_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("LockSessions",
+ NULL,
+ NULL,
+ method_lock_sessions,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("UnlockSessions",
+ NULL,
+ NULL,
+ method_lock_sessions,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("KillSession",
+ "ssi",
+ SD_BUS_PARAM(session_id)
+ SD_BUS_PARAM(who)
+ SD_BUS_PARAM(signal_number),
+ NULL,,
+ method_kill_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("KillUser",
+ "ui",
+ SD_BUS_PARAM(uid)
+ SD_BUS_PARAM(signal_number),
+ NULL,,
+ method_kill_user,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("TerminateSession",
+ "s",
+ SD_BUS_PARAM(session_id),
+ NULL,,
+ method_terminate_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("TerminateUser",
+ "u",
+ SD_BUS_PARAM(uid),
+ NULL,,
+ method_terminate_user,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("TerminateSeat",
+ "s",
+ SD_BUS_PARAM(seat_id),
+ NULL,,
+ method_terminate_seat,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SetUserLinger",
+ "ubb",
+ SD_BUS_PARAM(uid)
+ SD_BUS_PARAM(enable)
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_set_user_linger,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("AttachDevice",
+ "ssb",
+ SD_BUS_PARAM(seat_id)
+ SD_BUS_PARAM(sysfs_path)
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_attach_device,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("FlushDevices",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_flush_devices,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("PowerOff",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_poweroff,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("PowerOffWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_poweroff,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("Reboot",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_reboot,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("RebootWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_reboot,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("Halt",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_halt,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HaltWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_halt,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("Suspend",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_suspend,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SuspendWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_suspend,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("Hibernate",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HibernateWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HybridSleep",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_hybrid_sleep,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HybridSleepWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_hybrid_sleep,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernate",
+ "b",
+ SD_BUS_PARAM(interactive),
+ NULL,,
+ method_suspend_then_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernateWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_suspend_then_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanPowerOff",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_poweroff,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanReboot",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_reboot,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanHalt",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_halt,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanSuspend",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_suspend,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanHibernate",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanHybridSleep",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_hybrid_sleep,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanSuspendThenHibernate",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_suspend_then_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("ScheduleShutdown",
+ "st",
+ SD_BUS_PARAM(type)
+ SD_BUS_PARAM(usec),
+ NULL,,
+ method_schedule_shutdown,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CancelScheduledShutdown",
+ NULL,,
+ "b",
+ SD_BUS_PARAM(cancelled),
+ method_cancel_scheduled_shutdown,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("Inhibit",
+ "ssss",
+ SD_BUS_PARAM(what)
+ SD_BUS_PARAM(who)
+ SD_BUS_PARAM(why)
+ SD_BUS_PARAM(mode),
+ "h",
+ SD_BUS_PARAM(pipe_fd),
+ method_inhibit,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("CanRebootToFirmwareSetup",
+ NULL,,
+ "s",
+ SD_BUS_PARAM(result),
+ method_can_reboot_to_firmware_setup,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SetRebootToFirmwareSetup",
+ "b",
+ SD_BUS_PARAM(enable),
+ NULL,,
+ method_set_reboot_to_firmware_setup,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SetWallMessage",
+ "sb",
+ SD_BUS_PARAM(wall_message)
+ SD_BUS_PARAM(enable),
+ NULL,,
+ method_set_wall_message,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+
+ SD_BUS_SIGNAL_WITH_NAMES("SessionNew",
+ "so",
+ SD_BUS_PARAM(session_id)
+ SD_BUS_PARAM(object_path),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("SessionRemoved",
+ "so",
+ SD_BUS_PARAM(session_id)
+ SD_BUS_PARAM(object_path),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("UserNew",
+ "uo",
+ SD_BUS_PARAM(uid)
+ SD_BUS_PARAM(object_path),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("UserRemoved",
+ "uo",
+ SD_BUS_PARAM(uid)
+ SD_BUS_PARAM(object_path),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("SeatNew",
+ "so",
+ SD_BUS_PARAM(seat_id)
+ SD_BUS_PARAM(object_path),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("SeatRemoved",
+ "so",
+ SD_BUS_PARAM(seat_id)
+ SD_BUS_PARAM(object_path),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("PrepareForShutdown",
+ "b",
+ SD_BUS_PARAM(start),
+ 0),
+ SD_BUS_SIGNAL_WITH_NAMES("PrepareForSleep",
+ "b",
+ SD_BUS_PARAM(start),
+ 0),
SD_BUS_VTABLE_END
};
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 8bcbf6bf4b..3dd7c1522f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -50,6 +50,7 @@
#include "list.h"
#include "locale-util.h"
#include "log.h"
+#include "login-util.h"
#include "logs-show.h"
#include "macro.h"
#include "mkdir.h"
@@ -3266,6 +3267,8 @@ static int logind_reboot(enum action a) {
};
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ const char *method_with_flags;
+ uint64_t flags = 0;
sd_bus *bus;
int r;
@@ -3284,6 +3287,29 @@ static int logind_reboot(enum action a) {
if (arg_dry_run)
return 0;
+ SET_FLAG(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS, arg_check_inhibitors > 0);
+
+ method_with_flags = strjoina(actions[a].method, "WithFlags");
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ method_with_flags,
+ &error,
+ NULL,
+ "t", flags);
+ if (r >= 0)
+ return 0;
+
+ if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
+ return log_error_errno(r, "Failed to %s via logind: %s", actions[a].description, bus_error_message(&error, r));
+
+ /* Fallback to original methods in case there is older version of systemd-logind */
+ log_debug("Method %s not available: %s. Falling back to %s", method_with_flags, bus_error_message(&error, r), actions[a].method);
+ sd_bus_error_free(&error);
+
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h
index 1268085498..8805e19477 100644
--- a/src/systemd/sd-bus-vtable.h
+++ b/src/systemd/sd-bus-vtable.h
@@ -65,10 +65,12 @@ struct sd_bus_vtable {
const char *result;
sd_bus_message_handler_t handler;
size_t offset;
+ const char *names;
} method;
struct {
const char *member;
const char *signature;
+ const char *names;
} signal;
struct {
const char *member;
@@ -91,7 +93,10 @@ struct sd_bus_vtable {
}, \
}
-#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \
+/* helper macro to format method and signal parameters, one at a time */
+#define SD_BUS_PARAM(x) #x "\0"
+
+#define SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_METHOD, \
.flags = _flags, \
@@ -102,13 +107,18 @@ struct sd_bus_vtable {
.result = _result, \
.handler = _handler, \
.offset = _offset, \
+ .names = _in_names _out_names, \
}, \
}, \
}
+#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \
+ SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, _offset, _flags)
+#define SD_BUS_METHOD_WITH_NAMES(_member, _signature, _in_names, _result, _out_names, _handler, _flags) \
+ SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, 0, _flags)
#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \
- SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, 0, _flags)
+ SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, 0, _flags)
-#define SD_BUS_SIGNAL(_member, _signature, _flags) \
+#define SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, _out_names, _flags) \
{ \
.type = _SD_BUS_VTABLE_SIGNAL, \
.flags = _flags, \
@@ -116,9 +126,12 @@ struct sd_bus_vtable {
.signal = { \
.member = _member, \
.signature = _signature, \
+ .names = _out_names, \
}, \
}, \
}
+#define SD_BUS_SIGNAL(_member, _signature, _flags) \
+ SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, "", _flags)
#define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags) \
{ \

View File

@ -0,0 +1,85 @@
From e1b18ab36b2457a4896e531f03713b198725c919 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 9 Mar 2021 09:03:58 +0100
Subject: [PATCH] =?UTF-8?q?logind:=20add=20=E2=80=A6WithFlags=20methods=20?=
=?UTF-8?q?to=20policy?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Without this, privilege escalation through polkit does not work, because all
methods fail with permission errors.
Forgotten in 8885fed4e3a52cf1bf105e42043203c485ed9d92.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1933335.
(cherry picked from commit 2280db756eaff795091871feee8e47d4f6989a58)
Related: #1269726
---
src/login/org.freedesktop.login1.conf | 28 +++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf
index f880f3e2da..dcde0c22c6 100644
--- a/src/login/org.freedesktop.login1.conf
+++ b/src/login/org.freedesktop.login1.conf
@@ -130,30 +130,58 @@
send_interface="org.freedesktop.login1.Manager"
send_member="PowerOff"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="PowerOffWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="Reboot"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="RebootWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="Halt"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="HaltWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="Suspend"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="SuspendWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="Hibernate"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="HibernateWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="HybridSleep"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="HybridSleepWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="SuspendThenHibernate"/>
+ <allow send_destination="org.freedesktop.login1"
+ send_interface="org.freedesktop.login1.Manager"
+ send_member="SuspendThenHibernateWithFlags"/>
+
<allow send_destination="org.freedesktop.login1"
send_interface="org.freedesktop.login1.Manager"
send_member="CanPowerOff"/>

View File

@ -0,0 +1,72 @@
From 6751217a032dd1a8e8ee324332f29786265f0ebe Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 2 Feb 2021 15:27:30 +0100
Subject: [PATCH] logind: simplify flags handling a bit
Let's split out the two codepaths a bit, and emphasize which ones it the
new-style and which the old-style codepath, and let's clearly convert
the params of the old-stye into the new style for further processing, so
that the old style path is brief and isolated.
No change in behaviour.
Follow-up for: 8885fed4e3a52cf1bf105e42043203c485ed9d92
(cherry picked from commit d3e99bc0c7f785dcf4e73cfed12f74002e73be5f)
Related: #1269726
---
src/login/logind-dbus.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 0c43fbb3e0..ae9abc9bce 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1776,8 +1776,8 @@ static int method_do_shutdown_or_sleep(
bool with_flags,
sd_bus_error *error) {
- int interactive = false, r;
- uint64_t flags = 0;
+ uint64_t flags;
+ int r;
assert(m);
assert(message);
@@ -1785,19 +1785,25 @@ static int method_do_shutdown_or_sleep(
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
- if (with_flags)
+ if (with_flags) {
+ /* New style method: with flags parameter (and interactive bool in the bus message header) */
r = sd_bus_message_read(message, "t", &flags);
- else
- r = sd_bus_message_read(message, "b", &interactive);
-
- if (r < 0)
- return r;
+ if (r < 0)
+ return r;
+ if ((flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC) != 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
+ } else {
+ /* Old style method: no flags parameter, but interactive bool passed as boolean in
+ * payload. Let's convert this argument to the new-style flags parameter for our internal
+ * use. */
+ int interactive;
- if (with_flags && (flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC))
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
- "Invalid flags parameter");
+ r = sd_bus_message_read(message, "b", &interactive);
+ if (r < 0)
+ return r;
- SET_FLAG(flags, SD_LOGIND_INTERACTIVE, interactive);
+ flags = interactive ? SD_LOGIND_INTERACTIVE : 0;
+ }
/* Don't allow multiple jobs being executed at the same time */
if (m->action_what)

View File

@ -0,0 +1,25 @@
From 48b893c770aed3214586d529ddaba14267818c33 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Thu, 15 Jul 2021 10:35:08 +0200
Subject: [PATCH] Update link to RHEL documentation
RHEL-only
Resolves: #1982584
---
man/systemctl.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 9f0f4d46ea..a71e6c7c4f 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -2017,7 +2017,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>
For examples how to use systemctl in comparsion
with old service and chkconfig command please see:
- <ulink url="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-services-with-systemd_configuring-basic-system-settings">
+ <ulink url="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-system-services-with-systemctl_configuring-basic-system-settings">
Managing System Services
</ulink>
</para>

View File

@ -0,0 +1,29 @@
From e2f5e8ccb27f48717b50339f58582d70ad5f59b1 Mon Sep 17 00:00:00 2001
From: Frantisek Sumsal <fsumsal@redhat.com>
Date: Tue, 3 Aug 2021 11:52:36 +0200
Subject: [PATCH] Set default core ulimit to 0, but keep the hard limit
ulimited
so users can change it later.
Follow-up to 830bd662276ee117e65a4b3d541f77e8b172eafd.
rhel-only
Resolves: #1905582
---
src/core/system.conf.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index b4d6dfa15a..84246c0e36 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -52,7 +52,7 @@
#DefaultLimitFSIZE=
#DefaultLimitDATA=
#DefaultLimitSTACK=
-DefaultLimitCORE=0
+DefaultLimitCORE=0:infinity
#DefaultLimitRSS=
#DefaultLimitNOFILE=
#DefaultLimitAS=

View File

@ -0,0 +1,76 @@
From 3cf73fa4599116da350a0100378e749bbcbcad37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 26 Nov 2020 11:23:54 +0100
Subject: [PATCH] shared/seccomp-util: address family filtering is broken on
ppc
This reverts the gist of da1921a5c396547261c8c7fcd94173346eb3b718 and
0d9fca76bb69e162265b2d25cb79f1890c0da31b (for ppc).
Quoting #17559:
> libseccomp 2.5 added socket syscall multiplexing on ppc64(el):
> https://github.com/seccomp/libseccomp/pull/229
>
> Like with i386, s390 and s390x this breaks socket argument filtering, so
> RestrictAddressFamilies doesn't work.
>
> This causes the unit test to fail:
> /* test_restrict_address_families */
> Operating on architecture: ppc
> Failed to install socket family rules for architecture ppc, skipping: Operation canceled
> Operating on architecture: ppc64
> Failed to add socket() rule for architecture ppc64, skipping: Invalid argument
> Operating on architecture: ppc64-le
> Failed to add socket() rule for architecture ppc64-le, skipping: Invalid argument
> Assertion 'fd < 0' failed at src/test/test-seccomp.c:424, function test_restrict_address_families(). Aborting.
>
> The socket filters can't be added so `socket(AF_UNIX, SOCK_DGRAM, 0);` still
> works, triggering the assertion.
Fixes #17559.
(cherry picked from commit d5923e38bc0e6cf9d7620ed5f1f8606fe7fe1168)
Resolves: #1982650
---
src/shared/seccomp-util.c | 6 +++---
src/test/test-seccomp.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index e903512d45..c57c409433 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -1251,9 +1251,6 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) {
case SCMP_ARCH_X32:
case SCMP_ARCH_ARM:
case SCMP_ARCH_AARCH64:
- case SCMP_ARCH_PPC:
- case SCMP_ARCH_PPC64:
- case SCMP_ARCH_PPC64LE:
case SCMP_ARCH_MIPSEL64N32:
case SCMP_ARCH_MIPS64N32:
case SCMP_ARCH_MIPSEL64:
@@ -1267,6 +1264,9 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) {
case SCMP_ARCH_X86:
case SCMP_ARCH_MIPSEL:
case SCMP_ARCH_MIPS:
+ case SCMP_ARCH_PPC:
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
default:
/* These we either know we don't support (i.e. are the ones that do use socketcall()), or we
* don't know */
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
index 009a2e1922..5eb1c78b8b 100644
--- a/src/test/test-seccomp.c
+++ b/src/test/test-seccomp.c
@@ -25,7 +25,7 @@
#include "util.h"
#include "virt.h"
-#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__)
+#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__)
/* On these archs, socket() is implemented via the socketcall() syscall multiplexer,
* and we can't restrict it hence via seccomp. */
# define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1

View File

@ -0,0 +1,341 @@
From 019b3a5d7530c51aa8f7f1e5f5cb5eb81113d4db Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 18:53:09 +0200
Subject: [PATCH] logind: rework Seat/Session/User object allocation and
freeing a bit
Let's update things a bit to follow current practices:
- User structure initialization rather than zero-initialized allocation
- Always propagate proper errors from allocation functions
- Use _cleanup_ for freeing objects when allocation fails half-way
- Make destructors return NULL
(cherry picked from commit 8c29a4570993105fecc12288596d2ee77c7f82b8)
Related: #1642460
---
src/login/logind-core.c | 14 ++++++----
src/login/logind-seat.c | 38 +++++++++++++++----------
src/login/logind-seat.h | 6 ++--
src/login/logind-session.c | 57 +++++++++++++++++++++-----------------
src/login/logind-session.h | 7 +++--
src/login/logind-user.c | 21 +++++++-------
6 files changed, 83 insertions(+), 60 deletions(-)
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index cff5536ac0..f598bbaa1c 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -88,15 +88,16 @@ int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_dev
int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
Seat *s;
+ int r;
assert(m);
assert(id);
s = hashmap_get(m->seats, id);
if (!s) {
- s = seat_new(m, id);
- if (!s)
- return -ENOMEM;
+ r = seat_new(&s, m, id);
+ if (r < 0)
+ return r;
}
if (_seat)
@@ -107,15 +108,16 @@ int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
int manager_add_session(Manager *m, const char *id, Session **_session) {
Session *s;
+ int r;
assert(m);
assert(id);
s = hashmap_get(m->sessions, id);
if (!s) {
- s = session_new(m, id);
- if (!s)
- return -ENOMEM;
+ r = session_new(&s, m, id);
+ if (r < 0)
+ return r;
}
if (_session)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 63253db5bf..f68fc0ceaa 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -21,33 +21,42 @@
#include "terminal-util.h"
#include "util.h"
-Seat *seat_new(Manager *m, const char *id) {
- Seat *s;
+int seat_new(Seat** ret, Manager *m, const char *id) {
+ _cleanup_(seat_freep) Seat *s = NULL;
+ int r;
+ assert(ret);
assert(m);
assert(id);
- s = new0(Seat, 1);
+ if (!seat_name_is_valid(id))
+ return -EINVAL;
+
+ s = new(Seat, 1);
if (!s)
- return NULL;
+ return -ENOMEM;
+
+ *s = (Seat) {
+ .manager = m,
+ };
s->state_file = strappend("/run/systemd/seats/", id);
if (!s->state_file)
- return mfree(s);
+ return -ENOMEM;
s->id = basename(s->state_file);
- s->manager = m;
- if (hashmap_put(m->seats, s->id, s) < 0) {
- free(s->state_file);
- return mfree(s);
- }
+ r = hashmap_put(m->seats, s->id, s);
+ if (r < 0)
+ return r;
- return s;
+ *ret = TAKE_PTR(s);
+ return 0;
}
-void seat_free(Seat *s) {
- assert(s);
+Seat* seat_free(Seat *s) {
+ if (!s)
+ return NULL;
if (s->in_gc_queue)
LIST_REMOVE(gc_queue, s->manager->seat_gc_queue, s);
@@ -64,7 +73,8 @@ void seat_free(Seat *s) {
free(s->positions);
free(s->state_file);
- free(s);
+
+ return mfree(s);
}
int seat_save(Seat *s) {
diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h
index 70878bbe52..51cd468e26 100644
--- a/src/login/logind-seat.h
+++ b/src/login/logind-seat.h
@@ -27,8 +27,10 @@ struct Seat {
LIST_FIELDS(Seat, gc_queue);
};
-Seat *seat_new(Manager *m, const char *id);
-void seat_free(Seat *s);
+int seat_new(Seat **ret, Manager *m, const char *id);
+Seat* seat_free(Seat *s);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Seat *, seat_free);
int seat_save(Seat *s);
int seat_load(Seat *s);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 69d5a10319..5621d59a41 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -24,57 +24,61 @@
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
+#include "process-util.h"
#include "string-table.h"
#include "terminal-util.h"
#include "user-util.h"
#include "util.h"
-#include "process-util.h"
#define RELEASE_USEC (20*USEC_PER_SEC)
static void session_remove_fifo(Session *s);
-Session* session_new(Manager *m, const char *id) {
- Session *s;
+int session_new(Session **ret, Manager *m, const char *id) {
+ _cleanup_(session_freep) Session *s = NULL;
+ int r;
+ assert(ret);
assert(m);
assert(id);
- assert(session_id_valid(id));
- s = new0(Session, 1);
+ if (!session_id_valid(id))
+ return -EINVAL;
+
+ s = new(Session, 1);
if (!s)
- return NULL;
+ return -ENOMEM;
+
+ *s = (Session) {
+ .manager = m,
+ .fifo_fd = -1,
+ .vtfd = -1,
+ .audit_id = AUDIT_SESSION_INVALID,
+ };
s->state_file = strappend("/run/systemd/sessions/", id);
if (!s->state_file)
- return mfree(s);
-
- s->devices = hashmap_new(&devt_hash_ops);
- if (!s->devices) {
- free(s->state_file);
- return mfree(s);
- }
+ return -ENOMEM;
s->id = basename(s->state_file);
- if (hashmap_put(m->sessions, s->id, s) < 0) {
- hashmap_free(s->devices);
- free(s->state_file);
- return mfree(s);
- }
+ s->devices = hashmap_new(&devt_hash_ops);
+ if (!s->devices)
+ return -ENOMEM;
- s->manager = m;
- s->fifo_fd = -1;
- s->vtfd = -1;
- s->audit_id = AUDIT_SESSION_INVALID;
+ r = hashmap_put(m->sessions, s->id, s);
+ if (r < 0)
+ return r;
- return s;
+ *ret = TAKE_PTR(s);
+ return 0;
}
-void session_free(Session *s) {
+Session* session_free(Session *s) {
SessionDevice *sd;
- assert(s);
+ if (!s)
+ return NULL;
if (s->in_gc_queue)
LIST_REMOVE(gc_queue, s->manager->session_gc_queue, s);
@@ -126,7 +130,8 @@ void session_free(Session *s) {
hashmap_remove(s->manager->sessions, s->id);
free(s->state_file);
- free(s);
+
+ return mfree(s);
}
void session_set_user(Session *s, User *u) {
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 29ca399daf..572f2545c1 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -109,8 +109,11 @@ struct Session {
LIST_FIELDS(Session, gc_queue);
};
-Session *session_new(Manager *m, const char *id);
-void session_free(Session *s);
+int session_new(Session **ret, Manager *m, const char *id);
+Session* session_free(Session *s);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free);
+
void session_set_user(Session *s, User *u);
bool session_may_gc(Session *s, bool drop_not_started);
void session_add_to_gc_queue(Session *s);
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 56b8066f12..60ccd62abb 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -30,23 +30,24 @@
#include "user-util.h"
#include "util.h"
-int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) {
+int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
_cleanup_(user_freep) User *u = NULL;
char lu[DECIMAL_STR_MAX(uid_t) + 1];
int r;
- assert(out);
+ assert(ret);
assert(m);
assert(name);
- u = new0(User, 1);
+ u = new(User, 1);
if (!u)
return -ENOMEM;
- u->manager = m;
- u->uid = uid;
- u->gid = gid;
- xsprintf(lu, UID_FMT, uid);
+ *u = (User) {
+ .manager = m,
+ .uid = uid,
+ .gid = gid,
+ };
u->name = strdup(name);
if (!u->name)
@@ -58,6 +59,7 @@ int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) {
if (asprintf(&u->runtime_path, "/run/user/"UID_FMT, uid) < 0)
return -ENOMEM;
+ xsprintf(lu, UID_FMT, uid);
r = slice_build_subslice(SPECIAL_USER_SLICE, lu, &u->slice);
if (r < 0)
return r;
@@ -78,8 +80,7 @@ int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) {
if (r < 0)
return r;
- *out = TAKE_PTR(u);
-
+ *ret = TAKE_PTR(u);
return 0;
}
@@ -272,7 +273,7 @@ int user_save(User *u) {
if (!u->started)
return 0;
- return user_save_internal (u);
+ return user_save_internal(u);
}
int user_load(User *u) {

View File

@ -0,0 +1,116 @@
From 0314e68fe961cec941b1b0eb1cbcca4546cfdfdb Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 19:04:35 +0200
Subject: [PATCH] logind: fix serialization/deserialization of user's "display
session"
Previously this was serialized as part of the user object. This didn't
work however, as we load users first, and sessions seconds and hence
referencing a session from the user load logic cannot work.
Fix this by storing an IS_DISPLAY property along with each session, and
make the session with this set display session when it is loaded.
(cherry picked from commit 1c8280fd47b6561d35b15b3b6d49bdeacf891bfd)
Related: #1642460
---
src/login/logind-session.c | 18 +++++++++++++++++-
src/login/logind-user.c | 18 ++++--------------
2 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 5621d59a41..0afb065b2b 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -184,11 +184,13 @@ int session_save(Session *s) {
"UID="UID_FMT"\n"
"USER=%s\n"
"ACTIVE=%i\n"
+ "IS_DISPLAY=%i\n"
"STATE=%s\n"
"REMOTE=%i\n",
s->user->uid,
s->user->name,
session_is_active(s),
+ s->user->display == s,
session_state_to_string(session_get_state(s)),
s->remote);
@@ -359,7 +361,8 @@ int session_load(Session *s) {
*monotonic = NULL,
*controller = NULL,
*active = NULL,
- *devices = NULL;
+ *devices = NULL,
+ *is_display = NULL;
int k, r;
@@ -389,6 +392,7 @@ int session_load(Session *s) {
"CONTROLLER", &controller,
"ACTIVE", &active,
"DEVICES", &devices,
+ "IS_DISPLAY", &is_display,
NULL);
if (r < 0)
@@ -496,6 +500,18 @@ int session_load(Session *s) {
s->was_active = k;
}
+ if (is_display) {
+ /* Note that when enumerating users are loaded before sessions, hence the display session to use is
+ * something we have to store along with the session and not the user, as in that case we couldn't
+ * apply it at the time we load the user. */
+
+ k = parse_boolean(is_display);
+ if (k < 0)
+ log_warning_errno(k, "Failed to parse IS_DISPLAY session property: %m");
+ else if (k > 0)
+ s->user->display = s;
+ }
+
if (controller) {
if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
session_set_controller(s, controller, false, false);
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 60ccd62abb..17ed361411 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -277,8 +277,7 @@ int user_save(User *u) {
}
int user_load(User *u) {
- _cleanup_free_ char *display = NULL, *realtime = NULL, *monotonic = NULL;
- Session *s = NULL;
+ _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
int r;
assert(u);
@@ -286,22 +285,13 @@ int user_load(User *u) {
r = parse_env_file(NULL, u->state_file, NEWLINE,
"SERVICE_JOB", &u->service_job,
"SLICE_JOB", &u->slice_job,
- "DISPLAY", &display,
"REALTIME", &realtime,
"MONOTONIC", &monotonic,
NULL);
- if (r < 0) {
- if (r == -ENOENT)
- return 0;
-
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
return log_error_errno(r, "Failed to read %s: %m", u->state_file);
- }
-
- if (display)
- s = hashmap_get(u->manager->sessions, display);
-
- if (s && s->display && display_is_local(s->display))
- u->display = s;
if (realtime)
timestamp_deserialize(realtime, &u->timestamp.realtime);

View File

@ -0,0 +1,39 @@
From 3eab0f1b64477792bd01ca52c3eb26ce64c5c7ba Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 20:18:55 +0200
Subject: [PATCH] logind: turn of stdio locking when writing session files too
This just copies what we already do for user and seat files to session
files.
(cherry picked from commit 44176400138e18d9087e0864ca97041416a90d47)
Related: #1642460
---
src/login/logind-session.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 0afb065b2b..960a24d1a7 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -5,6 +5,7 @@
#include <linux/kd.h>
#include <linux/vt.h>
#include <signal.h>
+#include <stdio_ext.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
@@ -175,9 +176,8 @@ int session_save(Session *s) {
if (r < 0)
goto fail;
- assert(s->user);
-
- fchmod(fileno(f), 0644);
+ (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+ (void) fchmod(fileno(f), 0644);
fprintf(f,
"# This is private data. Do not parse.\n"

View File

@ -0,0 +1,27 @@
From f94c1bbec9e2c3efcbafd61ea1fdf8dbc3245d1b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 20:19:38 +0200
Subject: [PATCH] units: set StopWhenUnneeded= for the user slice units too
We'd like them to go away, just like the user-runtime-dir@.service when
they aren't needed anymore.
(cherry picked from commit 1007473b49b5aaeef0e53cd4a15f4ed8cf721926)
Related: #1642460
---
units/user-.slice.d/10-defaults.conf | 1 +
1 file changed, 1 insertion(+)
diff --git a/units/user-.slice.d/10-defaults.conf b/units/user-.slice.d/10-defaults.conf
index efc9d37c8e..1147e7aed9 100644
--- a/units/user-.slice.d/10-defaults.conf
+++ b/units/user-.slice.d/10-defaults.conf
@@ -10,6 +10,7 @@
[Unit]
Description=User Slice of UID %j
After=systemd-user-sessions.service
+StopWhenUnneeded=yes
[Slice]
TasksMax=80%

View File

@ -0,0 +1,29 @@
From 50a4e03d2da89df32f2f63eb56051d789508ae75 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 18:15:07 +0200
Subject: [PATCH] units: improve Description= string a bit
Let's not use the word "wrapper", as it's not clear what that is, and in
some way any unit file is a "wrapper"... let's simply say that it's
about the runtime directory.
(cherry picked from commit 14df094a51e87013d96ac697ae4f14593cbcad39)
Related: #1642460
---
units/user-runtime-dir@.service.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/units/user-runtime-dir@.service.in b/units/user-runtime-dir@.service.in
index bfd6488d61..63db1cca6a 100644
--- a/units/user-runtime-dir@.service.in
+++ b/units/user-runtime-dir@.service.in
@@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
-Description=/run/user/%i mount wrapper
+Description=User runtime directory /run/user/%i
After=systemd-user-sessions.service
StopWhenUnneeded=yes

View File

@ -0,0 +1,77 @@
From 9e9c6cbbdd60f4538cee041ffe3f9cd831c5de17 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 3 Aug 2018 20:21:27 +0200
Subject: [PATCH] logind: improve logging in manager_connect_console()
let's make sure we log about every failure
Also, complain about systems where /dev/tty0 exists but
/sys/class/tty/tty0/active does not. Such systems (usually container
environments) are pretty broken as they mount something that is not a VC
to /dev/tty0 and they really shouldn't.
Systems should either have a VC or not, but not badly fake one by
mounting things wildly.
This just adds a warning message, as before we'll simply turn off VC
handling in this case.
(cherry picked from commit 0b6d55cae9b8adc507fbea95d1b2874729a77386)
Related: #1642460
---
src/login/logind.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/login/logind.c b/src/login/logind.c
index 52fcee933c..1b366cd55f 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -815,28 +815,28 @@ static int manager_connect_console(Manager *m) {
assert(m);
assert(m->console_active_fd < 0);
- /* On certain architectures (S390 and Xen, and containers),
- /dev/tty0 does not exist, so don't fail if we can't open
- it. */
+ /* On certain systems (such as S390, Xen, and containers) /dev/tty0 does not exist (as there is no VC), so
+ * don't fail if we can't open it. */
+
if (access("/dev/tty0", F_OK) < 0)
return 0;
m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (m->console_active_fd < 0) {
- /* On some systems the device node /dev/tty0 may exist
- * even though /sys/class/tty/tty0 does not. */
- if (errno == ENOENT)
+ /* On some systems /dev/tty0 may exist even though /sys/class/tty/tty0 does not. These are broken, but
+ * common. Let's complain but continue anyway. */
+ if (errno == ENOENT) {
+ log_warning_errno(errno, "System has /dev/tty0 but not /sys/class/tty/tty0/active which is broken, ignoring: %m");
return 0;
+ }
return log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
}
r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
- if (r < 0) {
- log_error("Failed to watch foreground console");
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to watch foreground console: %m");
/*
* SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
@@ -855,7 +855,7 @@ static int manager_connect_console(Manager *m) {
r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to subscribe to signal: %m");
return 0;
}

View File

@ -0,0 +1,90 @@
From 4703c08fe3a8bfa1bc9b893e8bde365b1cbeffd9 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 18:14:11 +0200
Subject: [PATCH] logind: save/restore User object's "stopping" field during
restarts
Whether we are stopping or not is highly relevant, hence don't forget it
across restarts.
(cherry picked from commit d865bc024bf28c17120d7322a81e9a99997a59f6)
Related: #1642460
---
src/login/logind-user.c | 20 +++++++++++++++-----
src/login/logind-user.h | 5 +++--
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 17ed361411..35b2ca5489 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -136,9 +136,11 @@ static int user_save_internal(User *u) {
fprintf(f,
"# This is private data. Do not parse.\n"
"NAME=%s\n"
- "STATE=%s\n",
+ "STATE=%s\n" /* friendly user-facing state */
+ "STOPPING=%s\n", /* low-level state */
u->name,
- user_state_to_string(user_get_state(u)));
+ user_state_to_string(user_get_state(u)),
+ yes_no(u->stopping));
/* LEGACY: no-one reads RUNTIME= anymore, drop it at some point */
if (u->runtime_path)
@@ -277,14 +279,14 @@ int user_save(User *u) {
}
int user_load(User *u) {
- _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
+ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL;
int r;
assert(u);
r = parse_env_file(NULL, u->state_file, NEWLINE,
"SERVICE_JOB", &u->service_job,
- "SLICE_JOB", &u->slice_job,
+ "STOPPING", &stopping,
"REALTIME", &realtime,
"MONOTONIC", &monotonic,
NULL);
@@ -293,12 +295,20 @@ int user_load(User *u) {
if (r < 0)
return log_error_errno(r, "Failed to read %s: %m", u->state_file);
+ if (stopping) {
+ r = parse_boolean(stopping);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse 'STOPPING' boolean: %s", stopping);
+ else
+ u->stopping = r;
+ }
+
if (realtime)
timestamp_deserialize(realtime, &u->timestamp.realtime);
if (monotonic)
timestamp_deserialize(monotonic, &u->timestamp.monotonic);
- return r;
+ return 0;
}
static int user_start_service(User *u) {
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index eba2325284..03e020b870 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -36,8 +36,9 @@ struct User {
dual_timestamp timestamp;
bool in_gc_queue:1;
- bool started:1;
- bool stopping:1;
+
+ bool started:1; /* Whenever the user being started, has been started or is being stopped again. */
+ bool stopping:1; /* Whenever the user is being stopped or has been stopped. */
LIST_HEAD(Session, sessions);
LIST_FIELDS(User, gc_queue);

View File

@ -0,0 +1,25 @@
From eebbeada76b0fa4e252ecf4e25b088733636fe89 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 18:19:45 +0200
Subject: [PATCH] logind: correct bad clean-up path
(cherry picked from commit d88ffeeeefda4c3447223fd36f8e30f23c931e48)
Related: #1642460
---
src/login/logind-dbus.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index ae9abc9bce..4b2c418453 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -845,7 +845,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
r = sd_bus_message_enter_container(message, 'a', "(sv)");
if (r < 0)
- return r;
+ goto fail;
r = session_start(session, message);
if (r < 0)

View File

@ -0,0 +1,25 @@
From 7662d7c86d1fbb01693d4eb008fa27bf1e0030a9 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 18:21:37 +0200
Subject: [PATCH] logind: fix bad error propagation
(cherry picked from commit cce08496e7353e3e9903b42695aba3f9d259b90a)
Related: #1642460
---
src/login/logind-seat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index f68fc0ceaa..9e4f009643 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -175,7 +175,7 @@ static int vt_allocate(unsigned int vtnr) {
xsprintf(p, "/dev/tty%u", vtnr);
fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
- return -errno;
+ return fd;
return 0;
}

View File

@ -0,0 +1,42 @@
From 35f9a7f8f4e8917725349fe764706658c02537ca Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 19:02:29 +0200
Subject: [PATCH] logind: never elect a session that is stopping as display
(cherry picked from commit 04857cd801022d9f9933efb484c6253572f09870)
Related: #1642460
---
src/login/logind-user.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 35b2ca5489..3e4c99bdbd 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -613,11 +613,10 @@ int user_kill(User *u, int signo) {
}
static bool elect_display_filter(Session *s) {
- /* Return true if the session is a candidate for the users primary
- * session or display. */
+ /* Return true if the session is a candidate for the users primary session or display. */
assert(s);
- return (s->class == SESSION_USER && !s->stopping);
+ return s->class == SESSION_USER && s->started && !s->stopping;
}
static int elect_display_compare(Session *s1, Session *s2) {
@@ -663,9 +662,8 @@ void user_elect_display(User *u) {
assert(u);
- /* This elects a primary session for each user, which we call
- * the "display". We try to keep the assignment stable, but we
- * "upgrade" to better choices. */
+ /* This elects a primary session for each user, which we call the "display". We try to keep the assignment
+ * stable, but we "upgrade" to better choices. */
log_debug("Electing new display for user %s", u->name);
LIST_FOREACH(sessions_by_user, s, u->sessions) {

View File

@ -0,0 +1,60 @@
From 83c49a5e54dffc3dfa85b79f6375cd0a42a4ff76 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 19:34:39 +0200
Subject: [PATCH] logind: introduce little helper that checks whether a session
is ready
(cherry picked from commit b1951bc83ffbbb92ba4de7b9cba845421c2f35b1)
Related: #1642460
---
src/login/logind-session-dbus.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
index 88a2d33dc8..03585b7f8e 100644
--- a/src/login/logind-session-dbus.c
+++ b/src/login/logind-session-dbus.c
@@ -704,6 +704,15 @@ int session_send_lock_all(Manager *m, bool lock) {
return r;
}
+static bool session_ready(Session *s) {
+ assert(s);
+
+ /* Returns true when the session is ready, i.e. all jobs we enqueued for it are done (regardless if successful or not) */
+
+ return !s->scope_job &&
+ !s->user->service_job;
+}
+
int session_send_create_reply(Session *s, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *c = NULL;
_cleanup_close_ int fifo_fd = -1;
@@ -711,14 +720,13 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
assert(s);
- /* This is called after the session scope and the user service
- * were successfully created, and finishes where
+ /* This is called after the session scope and the user service were successfully created, and finishes where
* bus_manager_create_session() left off. */
if (!s->create_message)
return 0;
- if (!sd_bus_error_is_set(error) && (s->scope_job || s->user->service_job))
+ if (!sd_bus_error_is_set(error) && !session_ready(s))
return 0;
c = s->create_message;
@@ -731,8 +739,7 @@ int session_send_create_reply(Session *s, sd_bus_error *error) {
if (fifo_fd < 0)
return fifo_fd;
- /* Update the session state file before we notify the client
- * about the result. */
+ /* Update the session state file before we notify the client about the result. */
session_save(s);
p = session_bus_path(s);

View File

@ -0,0 +1,40 @@
From 31aa21a13f9b91486b1a95c5b73fa088af77fcb4 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 19:35:44 +0200
Subject: [PATCH] logind: propagate session stop errors
Let's propagate errors from stopping sessions via seat_stop(). This is
similar to how we propagate such errors in user_stop() for all sessions
associated with a user.
Note that we propagate these errors, but we don't abort the function.
(cherry picked from commit e6958b7ea33813b085966ac25817a957c0dad7f9)
Related: #1642460
---
src/login/logind-seat.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index 9e4f009643..96c34a6c9e 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -431,7 +431,7 @@ int seat_start(Seat *s) {
}
int seat_stop(Seat *s, bool force) {
- int r = 0;
+ int r;
assert(s);
@@ -441,7 +441,7 @@ int seat_stop(Seat *s, bool force) {
"SEAT_ID=%s", s->id,
LOG_MESSAGE("Removed seat %s.", s->id));
- seat_stop_sessions(s, force);
+ r = seat_stop_sessions(s, force);
unlink(s->state_file);
seat_add_to_gc_queue(s);

View File

@ -0,0 +1,618 @@
From a05c1077911652954c8b9e82cfdc0fc643eca782 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 6 Aug 2018 21:44:45 +0200
Subject: [PATCH] logind: rework how we manage the slice and
user-runtime-dir@.service unit for each user
Instead of managing it explicitly, let's simplify things and rely on
regular Wants=/Requires= dependencies to pull in these units from
user@.service and the session scope, and StopWhenUneeded= to stop these
auxiliary units again. This way, they can be pulled in easily by
unrelated units too.
This simplifies things quite a bit: for each session we now only need to
manage the session scope, and for each user the user@.service, the other
units are not something we need to manage anymore.
This patch also makes sure that if user@.service of a user is masked we
will continue to work, and user-runtime-dir@.service will still be
correctly pulled in, as it is now a dependency of the scope unit.
Fixes: #9461
Replaces: #5546
(cherry picked from commit 25a1ab4ed48b72e974f77a68dcbe3521014787bb)
Related: #1642460
---
src/login/logind-dbus.c | 58 ++++++++--------
src/login/logind-session.c | 64 ++++++++++--------
src/login/logind-session.h | 2 +-
src/login/logind-user.c | 134 ++++++++++++++-----------------------
src/login/logind-user.h | 7 +-
src/login/logind.c | 2 +-
src/login/logind.h | 2 +-
7 files changed, 123 insertions(+), 146 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 4b2c418453..7eba617fff 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -847,7 +847,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus
if (r < 0)
goto fail;
- r = session_start(session, message);
+ r = session_start(session, message, error);
if (r < 0)
goto fail;
@@ -3110,24 +3110,20 @@ const sd_bus_vtable manager_vtable[] = {
};
static int session_jobs_reply(Session *s, const char *unit, const char *result) {
- int r = 0;
-
assert(s);
assert(unit);
if (!s->started)
- return r;
+ return 0;
- if (streq(result, "done"))
- r = session_send_create_reply(s, NULL);
- else {
+ if (result && !streq(result, "done")) {
_cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
- sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
- r = session_send_create_reply(s, &e);
+ sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit '%s' failed with '%s'", unit, result);
+ return session_send_create_reply(s, &e);
}
- return r;
+ return session_send_create_reply(s, NULL);
}
int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
@@ -3160,30 +3156,29 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err
}
session = hashmap_get(m->session_units, unit);
- if (session && streq_ptr(path, session->scope_job)) {
- session->scope_job = mfree(session->scope_job);
- session_jobs_reply(session, unit, result);
+ if (session) {
+ if (streq_ptr(path, session->scope_job)) {
+ session->scope_job = mfree(session->scope_job);
+ (void) session_jobs_reply(session, unit, result);
+
+ session_save(session);
+ user_save(session->user);
+ }
- session_save(session);
- user_save(session->user);
session_add_to_gc_queue(session);
}
user = hashmap_get(m->user_units, unit);
- if (user &&
- (streq_ptr(path, user->service_job) ||
- streq_ptr(path, user->slice_job))) {
-
- if (streq_ptr(path, user->service_job))
+ if (user) {
+ if (streq_ptr(path, user->service_job)) {
user->service_job = mfree(user->service_job);
- if (streq_ptr(path, user->slice_job))
- user->slice_job = mfree(user->slice_job);
+ LIST_FOREACH(sessions_by_user, session, user->sessions)
+ (void) session_jobs_reply(session, unit, NULL /* don't propagate user service failures to the client */);
- LIST_FOREACH(sessions_by_user, session, user->sessions)
- session_jobs_reply(session, unit, result);
+ user_save(user);
+ }
- user_save(user);
user_add_to_gc_queue(user);
}
@@ -3315,13 +3310,14 @@ int manager_start_scope(
pid_t pid,
const char *slice,
const char *description,
- const char *after,
- const char *after2,
+ char **wants,
+ char **after,
sd_bus_message *more_properties,
sd_bus_error *error,
char **job) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
+ char **i;
int r;
assert(manager);
@@ -3359,14 +3355,14 @@ int manager_start_scope(
return r;
}
- if (!isempty(after)) {
- r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
+ STRV_FOREACH(i, wants) {
+ r = sd_bus_message_append(m, "(sv)", "Wants", "as", 1, *i);
if (r < 0)
return r;
}
- if (!isempty(after2)) {
- r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
+ STRV_FOREACH(i, after) {
+ r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i);
if (r < 0)
return r;
}
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 960a24d1a7..d56b48a732 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -27,6 +27,7 @@
#include "path-util.h"
#include "process-util.h"
#include "string-table.h"
+#include "strv.h"
#include "terminal-util.h"
#include "user-util.h"
#include "util.h"
@@ -560,17 +561,18 @@ int session_activate(Session *s) {
return 0;
}
-static int session_start_scope(Session *s, sd_bus_message *properties) {
+static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_error *error) {
int r;
assert(s);
assert(s->user);
if (!s->scope) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *scope, *job = NULL;
+ _cleanup_free_ char *scope = NULL;
const char *description;
+ s->scope_job = mfree(s->scope_job);
+
scope = strjoin("session-", s->id, ".scope");
if (!scope)
return log_oom();
@@ -583,21 +585,15 @@ static int session_start_scope(Session *s, sd_bus_message *properties) {
s->leader,
s->user->slice,
description,
- "systemd-logind.service",
- "systemd-user-sessions.service",
+ STRV_MAKE(s->user->runtime_dir_service, s->user->service), /* These two have StopWhenUnneeded= set, hence add a dep towards them */
+ STRV_MAKE("systemd-logind.service", "systemd-user-sessions.service", s->user->runtime_dir_service, s->user->service), /* And order us after some more */
properties,
- &error,
- &job);
- if (r < 0) {
- log_error_errno(r, "Failed to start session scope %s: %s", scope, bus_error_message(&error, r));
- free(scope);
- return r;
- } else {
- s->scope = scope;
+ error,
+ &s->scope_job);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start session scope %s: %s", scope, bus_error_message(error, r));
- free(s->scope_job);
- s->scope_job = job;
- }
+ s->scope = TAKE_PTR(scope);
}
if (s->scope)
@@ -606,7 +602,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties) {
return 0;
}
-int session_start(Session *s, sd_bus_message *properties) {
+int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error) {
int r;
assert(s);
@@ -614,6 +610,9 @@ int session_start(Session *s, sd_bus_message *properties) {
if (!s->user)
return -ESTALE;
+ if (s->stopping)
+ return -EINVAL;
+
if (s->started)
return 0;
@@ -621,8 +620,7 @@ int session_start(Session *s, sd_bus_message *properties) {
if (r < 0)
return r;
- /* Create cgroup */
- r = session_start_scope(s, properties);
+ r = session_start_scope(s, properties, error);
if (r < 0)
return r;
@@ -673,21 +671,24 @@ static int session_stop_scope(Session *s, bool force) {
* that is left in the scope is "left-over". Informing systemd about this has the benefit that it will log
* when killing any processes left after this point. */
r = manager_abandon_scope(s->manager, s->scope, &error);
- if (r < 0)
+ if (r < 0) {
log_warning_errno(r, "Failed to abandon session scope, ignoring: %s", bus_error_message(&error, r));
+ sd_bus_error_free(&error);
+ }
+
+ s->scope_job = mfree(s->scope_job);
/* Optionally, let's kill everything that's left now. */
if (force || manager_shall_kill(s->manager, s->user->name)) {
- char *job = NULL;
- r = manager_stop_unit(s->manager, s->scope, &error, &job);
- if (r < 0)
- return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r));
+ r = manager_stop_unit(s->manager, s->scope, &error, &s->scope_job);
+ if (r < 0) {
+ if (force)
+ return log_error_errno(r, "Failed to stop session scope: %s", bus_error_message(&error, r));
- free(s->scope_job);
- s->scope_job = job;
+ log_warning_errno(r, "Failed to stop session scope, ignoring: %s", bus_error_message(&error, r));
+ }
} else {
- s->scope_job = mfree(s->scope_job);
/* With no killing, this session is allowed to persist in "closing" state indefinitely.
* Therefore session stop and session removal may be two distinct events.
@@ -707,8 +708,17 @@ int session_stop(Session *s, bool force) {
assert(s);
+ /* This is called whenever we begin with tearing down a session record. It's called in four cases: explicit API
+ * request via the bus (either directly for the session object or for the seat or user object this session
+ * belongs to; 'force' is true), or due to automatic GC (i.e. scope vanished; 'force' is false), or because the
+ * session FIFO saw an EOF ('force' is false), or because the release timer hit ('force' is false). */
+
if (!s->user)
return -ESTALE;
+ if (!s->started)
+ return 0;
+ if (s->stopping)
+ return 0;
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
index 572f2545c1..7d17d9a25f 100644
--- a/src/login/logind-session.h
+++ b/src/login/logind-session.h
@@ -124,7 +124,7 @@ void session_set_idle_hint(Session *s, bool b);
int session_get_locked_hint(Session *s);
void session_set_locked_hint(Session *s, bool b);
int session_create_fifo(Session *s);
-int session_start(Session *s, sd_bus_message *properties);
+int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error);
int session_stop(Session *s, bool force);
int session_finalize(Session *s);
int session_release(Session *s);
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 3e4c99bdbd..39fc76f4dc 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -68,6 +68,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
if (r < 0)
return r;
+ r = unit_name_build("user-runtime-dir", lu, ".service", &u->runtime_dir_service);
+ if (r < 0)
+ return r;
+
r = hashmap_put(m->users, UID_TO_PTR(uid), u);
if (r < 0)
return r;
@@ -80,6 +84,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
if (r < 0)
return r;
+ r = hashmap_put(m->user_units, u->runtime_dir_service, u);
+ if (r < 0)
+ return r;
+
*ret = TAKE_PTR(u);
return 0;
}
@@ -97,15 +105,18 @@ User *user_free(User *u) {
if (u->service)
hashmap_remove_value(u->manager->user_units, u->service, u);
+ if (u->runtime_dir_service)
+ hashmap_remove_value(u->manager->user_units, u->runtime_dir_service, u);
+
if (u->slice)
hashmap_remove_value(u->manager->user_units, u->slice, u);
hashmap_remove_value(u->manager->users, UID_TO_PTR(u->uid), u);
- u->slice_job = mfree(u->slice_job);
u->service_job = mfree(u->service_job);
u->service = mfree(u->service);
+ u->runtime_dir_service = mfree(u->runtime_dir_service);
u->slice = mfree(u->slice);
u->runtime_path = mfree(u->runtime_path);
u->state_file = mfree(u->state_file);
@@ -149,9 +160,6 @@ static int user_save_internal(User *u) {
if (u->service_job)
fprintf(f, "SERVICE_JOB=%s\n", u->service_job);
- if (u->slice_job)
- fprintf(f, "SLICE_JOB=%s\n", u->slice_job);
-
if (u->display)
fprintf(f, "DISPLAY=%s\n", u->display->id);
@@ -311,66 +319,46 @@ int user_load(User *u) {
return 0;
}
-static int user_start_service(User *u) {
+static void user_start_service(User *u) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *job;
int r;
assert(u);
+ /* Start the service containing the "systemd --user" instance (user@.service). Note that we don't explicitly
+ * start the per-user slice or the systemd-runtime-dir@.service instance, as those are pulled in both by
+ * user@.service and the session scopes as dependencies. */
+
u->service_job = mfree(u->service_job);
- r = manager_start_unit(
- u->manager,
- u->service,
- &error,
- &job);
+ r = manager_start_unit(u->manager, u->service, &error, &u->service_job);
if (r < 0)
/* we don't fail due to this, let's try to continue */
log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_UNIT_MASKED) ? LOG_DEBUG : LOG_WARNING, r,
"Failed to start user service '%s', ignoring: %s", u->service, bus_error_message(&error, r));
- else
- u->service_job = job;
-
- return 0;
}
int user_start(User *u) {
- int r;
-
assert(u);
if (u->started && !u->stopping)
return 0;
- /*
- * If u->stopping is set, the user is marked for removal and the slice
- * and service stop-jobs are queued. We have to clear that flag before
- * queing the start-jobs again. If they succeed, the user object can be
- * re-used just fine (pid1 takes care of job-ordering and proper
- * restart), but if they fail, we want to force another user_stop() so
- * possibly pending units are stopped.
- * Note that we don't clear u->started, as we have no clue what state
- * the user is in on failure here. Hence, we pretend the user is
- * running so it will be properly taken down by GC. However, we clearly
- * return an error from user_start() in that case, so no further
- * reference to the user is taken.
- */
+ /* If u->stopping is set, the user is marked for removal and service stop-jobs are queued. We have to clear
+ * that flag before queing the start-jobs again. If they succeed, the user object can be re-used just fine
+ * (pid1 takes care of job-ordering and proper restart), but if they fail, we want to force another user_stop()
+ * so possibly pending units are stopped. */
u->stopping = false;
if (!u->started)
log_debug("Starting services for new user %s.", u->name);
- /* Save the user data so far, because pam_systemd will read the
- * XDG_RUNTIME_DIR out of it while starting up systemd --user.
- * We need to do user_save_internal() because we have not
- * "officially" started yet. */
+ /* Save the user data so far, because pam_systemd will read the XDG_RUNTIME_DIR out of it while starting up
+ * systemd --user. We need to do user_save_internal() because we have not "officially" started yet. */
user_save_internal(u);
- /* Spawn user systemd */
- r = user_start_service(u);
- if (r < 0)
- return r;
+ /* Start user@UID.service */
+ user_start_service(u);
if (!u->started) {
if (!dual_timestamp_is_set(&u->timestamp))
@@ -385,68 +373,50 @@ int user_start(User *u) {
return 0;
}
-static int user_stop_slice(User *u) {
+static void user_stop_service(User *u) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *job;
int r;
assert(u);
+ assert(u->service);
- r = manager_stop_unit(u->manager, u->slice, &error, &job);
- if (r < 0) {
- log_error("Failed to stop user slice: %s", bus_error_message(&error, r));
- return r;
- }
+ /* The reverse of user_start_service(). Note that we only stop user@UID.service here, and let StopWhenUnneeded=
+ * deal with the slice and the user-runtime-dir@.service instance. */
- free(u->slice_job);
- u->slice_job = job;
-
- return r;
-}
-
-static int user_stop_service(User *u) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *job;
- int r;
-
- assert(u);
-
- r = manager_stop_unit(u->manager, u->service, &error, &job);
- if (r < 0) {
- log_error("Failed to stop user service: %s", bus_error_message(&error, r));
- return r;
- }
+ u->service_job = mfree(u->service_job);
- free_and_replace(u->service_job, job);
- return r;
+ r = manager_stop_unit(u->manager, u->service, &error, &u->service_job);
+ if (r < 0)
+ log_warning_errno(r, "Failed to stop user service '%s', ignoring: %s", u->service, bus_error_message(&error, r));
}
int user_stop(User *u, bool force) {
Session *s;
- int r = 0, k;
+ int r = 0;
assert(u);
- /* Stop jobs have already been queued */
- if (u->stopping) {
+ /* This is called whenever we begin with tearing down a user record. It's called in two cases: explicit API
+ * request to do so via the bus (in which case 'force' is true) and automatically due to GC, if there's no
+ * session left pinning it (in which case 'force' is false). Note that this just initiates tearing down of the
+ * user, the User object will remain in memory until user_finalize() is called, see below. */
+
+ if (!u->started)
+ return 0;
+
+ if (u->stopping) { /* Stop jobs have already been queued */
user_save(u);
- return r;
+ return 0;
}
LIST_FOREACH(sessions_by_user, s, u->sessions) {
+ int k;
+
k = session_stop(s, force);
if (k < 0)
r = k;
}
- /* Kill systemd */
- k = user_stop_service(u);
- if (k < 0)
- r = k;
-
- /* Kill cgroup */
- k = user_stop_slice(u);
- if (k < 0)
- r = k;
+ user_stop_service(u);
u->stopping = true;
@@ -461,6 +431,9 @@ int user_finalize(User *u) {
assert(u);
+ /* Called when the user is really ready to be freed, i.e. when all unit stop jobs and suchlike for it are
+ * done. This is called as a result of an earlier user_done() when all jobs are completed. */
+
if (u->started)
log_debug("User %s logged out.", u->name);
@@ -554,9 +527,6 @@ bool user_may_gc(User *u, bool drop_not_started) {
if (user_check_linger_file(u) > 0)
return false;
- if (u->slice_job && manager_job_is_active(u->manager, u->slice_job))
- return false;
-
if (u->service_job && manager_job_is_active(u->manager, u->service_job))
return false;
@@ -581,7 +551,7 @@ UserState user_get_state(User *u) {
if (u->stopping)
return USER_CLOSING;
- if (!u->started || u->slice_job || u->service_job)
+ if (!u->started || u->service_job)
return USER_OPENING;
if (u->sessions) {
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index 03e020b870..5e1f7b813a 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -25,11 +25,12 @@ struct User {
char *name;
char *state_file;
char *runtime_path;
- char *slice;
- char *service;
+
+ char *slice; /* user-UID.slice */
+ char *service; /* user@UID.service */
+ char *runtime_dir_service; /* user-runtime-dir@UID.service */
char *service_job;
- char *slice_job;
Session *display;
diff --git a/src/login/logind.c b/src/login/logind.c
index 1b366cd55f..6c208c8e89 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -1158,7 +1158,7 @@ static int manager_startup(Manager *m) {
user_start(user);
HASHMAP_FOREACH(session, m->sessions, i)
- session_start(session, NULL);
+ (void) session_start(session, NULL, NULL);
HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
inhibitor_start(inhibitor);
diff --git a/src/login/logind.h b/src/login/logind.h
index a6ebc9e152..ae4d74076b 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -161,7 +161,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name
int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *after2, sd_bus_message *more_properties, sd_bus_error *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);

View File

@ -0,0 +1,291 @@
From 35455408393cb29a5e49fd769c4823b6a6f886b4 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 7 Aug 2018 11:02:00 +0200
Subject: [PATCH] logind: optionally, keep the user@.service instance for
eached logged in user around for a while
This should speed up rapid logout/login cycles a bit.
By default this timeout is now set to 10s.
Fixes: #8410
Replaces: #4434
(cherry picked from commit 9afe9efb9340588db553950727a2a9672dc3db24)
Resolves: #1642460
---
man/logind.conf.xml | 11 +++++
src/login/logind-core.c | 2 +
src/login/logind-dbus.c | 1 +
src/login/logind-gperf.gperf | 1 +
src/login/logind-session.c | 4 ++
src/login/logind-user.c | 88 +++++++++++++++++++++++++++++++++---
src/login/logind-user.h | 7 ++-
src/login/logind.h | 1 +
8 files changed, 107 insertions(+), 8 deletions(-)
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index 7d7e869a26..0cf8a7d1f2 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -184,6 +184,17 @@
5.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>UserStopDelaySec=</varname></term>
+
+ <listitem><para>Specifies how long to keep the user record and per-user service
+ <filename>user@.service</filename> around for a user after they logged out fully. If set to zero, the per-user
+ service is terminated immediately when the last session of the user has ended. If this option is configured to
+ non-zero rapid logout/login cycles are sped up, as the user's service manager is not constantly restarted. If
+ set to <literal>infinity</literal> the per-user service for a user is never terminated again after first login,
+ and continues to run until system shutdown. Defaults to 10s.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>HandlePowerKey=</varname></term>
<term><varname>HandleSuspendKey=</varname></term>
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index f598bbaa1c..678c708df1 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -27,6 +27,8 @@ void manager_reset_config(Manager *m) {
m->reserve_vt = 6;
m->remove_ipc = false;
m->inhibit_delay_max = 5 * USEC_PER_SEC;
+ m->user_stop_delay = 10 * USEC_PER_SEC;
+
m->handle_power_key = HANDLE_POWEROFF;
m->handle_suspend_key = HANDLE_SUSPEND;
m->handle_hibernate_key = HANDLE_HIBERNATE;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 7eba617fff..6586280269 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2695,6 +2695,7 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_PROPERTY("BlockInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("DelayInhibited", "s", property_get_inhibited, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("InhibitDelayMaxUSec", "t", NULL, offsetof(Manager, inhibit_delay_max), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("UserStopDelayUSec", "t", NULL, offsetof(Manager, user_stop_delay), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandlePowerKey", "s", property_get_handle_action, offsetof(Manager, handle_power_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleSuspendKey", "s", property_get_handle_action, offsetof(Manager, handle_suspend_key), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("HandleHibernateKey", "s", property_get_handle_action, offsetof(Manager, handle_hibernate_key), SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
index c85339dcd3..8829ce7d85 100644
--- a/src/login/logind-gperf.gperf
+++ b/src/login/logind-gperf.gperf
@@ -23,6 +23,7 @@ Login.KillUserProcesses, config_parse_bool, 0, offse
Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users)
Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users)
Login.InhibitDelayMaxSec, config_parse_sec, 0, offsetof(Manager, inhibit_delay_max)
+Login.UserStopDelaySec, config_parse_sec, 0, offsetof(Manager, user_stop_delay)
Login.HandlePowerKey, config_parse_handle_action, 0, offsetof(Manager, handle_power_key)
Login.HandleSuspendKey, config_parse_handle_action, 0, offsetof(Manager, handle_suspend_key)
Login.HandleHibernateKey, config_parse_handle_action, 0, offsetof(Manager, handle_hibernate_key)
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index d56b48a732..dd4ac9482a 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -101,6 +101,8 @@ Session* session_free(Session *s) {
if (s->user->display == s)
s->user->display = NULL;
+
+ user_update_last_session_timer(s->user);
}
if (s->seat) {
@@ -142,6 +144,8 @@ void session_set_user(Session *s, User *u) {
s->user = u;
LIST_PREPEND(sessions_by_user, u->sessions, s);
+
+ user_update_last_session_timer(u);
}
static void session_save_devices(Session *s, FILE *f) {
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 39fc76f4dc..f23fcbe674 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -47,6 +47,7 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
.manager = m,
.uid = uid,
.gid = gid,
+ .last_session_timestamp = USEC_INFINITY,
};
u->name = strdup(name);
@@ -113,6 +114,8 @@ User *user_free(User *u) {
hashmap_remove_value(u->manager->users, UID_TO_PTR(u->uid), u);
+ (void) sd_event_source_unref(u->timer_event_source);
+
u->service_job = mfree(u->service_job);
u->service = mfree(u->service);
@@ -170,6 +173,10 @@ static int user_save_internal(User *u) {
u->timestamp.realtime,
u->timestamp.monotonic);
+ if (u->last_session_timestamp != USEC_INFINITY)
+ fprintf(f, "LAST_SESSION_TIMESTAMP=" USEC_FMT "\n",
+ u->last_session_timestamp);
+
if (u->sessions) {
Session *i;
bool first;
@@ -287,16 +294,17 @@ int user_save(User *u) {
}
int user_load(User *u) {
- _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL;
+ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL, *last_session_timestamp = NULL;
int r;
assert(u);
r = parse_env_file(NULL, u->state_file, NEWLINE,
- "SERVICE_JOB", &u->service_job,
- "STOPPING", &stopping,
- "REALTIME", &realtime,
- "MONOTONIC", &monotonic,
+ "SERVICE_JOB", &u->service_job,
+ "STOPPING", &stopping,
+ "REALTIME", &realtime,
+ "MONOTONIC", &monotonic,
+ "LAST_SESSION_TIMESTAMP", &last_session_timestamp,
NULL);
if (r == -ENOENT)
return 0;
@@ -312,9 +320,11 @@ int user_load(User *u) {
}
if (realtime)
- timestamp_deserialize(realtime, &u->timestamp.realtime);
+ (void) timestamp_deserialize(realtime, &u->timestamp.realtime);
if (monotonic)
- timestamp_deserialize(monotonic, &u->timestamp.monotonic);
+ (void) timestamp_deserialize(monotonic, &u->timestamp.monotonic);
+ if (last_session_timestamp)
+ (void) timestamp_deserialize(last_session_timestamp, &u->last_session_timestamp);
return 0;
}
@@ -524,6 +534,17 @@ bool user_may_gc(User *u, bool drop_not_started) {
if (u->sessions)
return false;
+ if (u->last_session_timestamp != USEC_INFINITY) {
+ /* All sessions have been closed. Let's see if we shall leave the user record around for a bit */
+
+ if (u->manager->user_stop_delay == USEC_INFINITY)
+ return false; /* Leave it around forever! */
+ if (u->manager->user_stop_delay > 0 &&
+ now(CLOCK_MONOTONIC) < usec_add(u->last_session_timestamp, u->manager->user_stop_delay))
+ return false; /* Leave it around for a bit longer. */
+ }
+
+ /* Is this a user that shall stay around forever? */
if (user_check_linger_file(u) > 0)
return false;
@@ -649,6 +670,59 @@ void user_elect_display(User *u) {
}
}
+static int user_stop_timeout_callback(sd_event_source *es, uint64_t usec, void *userdata) {
+ User *u = userdata;
+
+ assert(u);
+ user_add_to_gc_queue(u);
+
+ return 0;
+}
+
+void user_update_last_session_timer(User *u) {
+ int r;
+
+ assert(u);
+
+ if (u->sessions) {
+ /* There are sessions, turn off the timer */
+ u->last_session_timestamp = USEC_INFINITY;
+ u->timer_event_source = sd_event_source_unref(u->timer_event_source);
+ return;
+ }
+
+ if (u->last_session_timestamp != USEC_INFINITY)
+ return; /* Timer already started */
+
+ u->last_session_timestamp = now(CLOCK_MONOTONIC);
+
+ assert(!u->timer_event_source);
+
+ if (u->manager->user_stop_delay == 0 || u->manager->user_stop_delay == USEC_INFINITY)
+ return;
+
+ if (sd_event_get_state(u->manager->event) == SD_EVENT_FINISHED) {
+ log_debug("Not allocating user stop timeout, since we are already exiting.");
+ return;
+ }
+
+ r = sd_event_add_time(u->manager->event,
+ &u->timer_event_source,
+ CLOCK_MONOTONIC,
+ usec_add(u->last_session_timestamp, u->manager->user_stop_delay), 0,
+ user_stop_timeout_callback, u);
+ if (r < 0)
+ log_warning_errno(r, "Failed to enqueue user stop event source, ignoring: %m");
+
+ if (DEBUG_LOGGING) {
+ char s[FORMAT_TIMESPAN_MAX];
+
+ log_debug("Last session of user '%s' logged out, terminating user context in %s.",
+ u->name,
+ format_timespan(s, sizeof(s), u->manager->user_stop_delay, USEC_PER_MSEC));
+ }
+}
+
static const char* const user_state_table[_USER_STATE_MAX] = {
[USER_OFFLINE] = "offline",
[USER_OPENING] = "opening",
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index 5e1f7b813a..e05646adc9 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -34,7 +34,11 @@ struct User {
Session *display;
- dual_timestamp timestamp;
+ dual_timestamp timestamp; /* When this User object was 'started' the first time */
+ usec_t last_session_timestamp; /* When the number of sessions of this user went from 1 to 0 the last time */
+
+ /* Set up when the last session of the user logs out */
+ sd_event_source *timer_event_source;
bool in_gc_queue:1;
@@ -62,6 +66,7 @@ int user_load(User *u);
int user_kill(User *u, int signo);
int user_check_linger_file(User *u);
void user_elect_display(User *u);
+void user_update_last_session_timer(User *u);
extern const sd_bus_vtable user_vtable[];
int user_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error);
diff --git a/src/login/logind.h b/src/login/logind.h
index ae4d74076b..7288dd7445 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -62,6 +62,7 @@ struct Manager {
Hashmap *user_units;
usec_t inhibit_delay_max;
+ usec_t user_stop_delay;
/* If an action is currently being executed or is delayed,
* this is != 0 and encodes what is being done */

View File

@ -0,0 +1,210 @@
From e9a187ea6abf1e7034ee3113355b282743a98f39 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 8 Aug 2018 15:27:49 +0200
Subject: [PATCH] logind: add a RequiresMountsFor= dependency from the session
scope unit to the home directory of the user
This is useful so that during shutdown scope units are always terminated
before the mounts necessary for the home directory.
(Ideally we'd also add a similar dependency from the user@.service
instance to the home directory, but this isn't as easy as that service
is defined statically and not dynamically, and hence not easy to modify
dynamically, in particular when it comes to deps)
(cherry picked from commit d5ac9d060267820aabdf9af509a54a1830b27b7d)
Related: #1642460
---
src/login/logind-core.c | 24 ++++++++++++++++++------
src/login/logind-dbus.c | 7 +++++++
src/login/logind-session.c | 1 +
src/login/logind-user.c | 13 ++++++++++++-
src/login/logind-user.h | 3 ++-
src/login/logind.h | 4 ++--
6 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 678c708df1..0ed812a2c8 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -128,7 +128,14 @@ int manager_add_session(Manager *m, const char *id, Session **_session) {
return 0;
}
-int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
+int manager_add_user(
+ Manager *m,
+ uid_t uid,
+ gid_t gid,
+ const char *name,
+ const char *home,
+ User **_user) {
+
User *u;
int r;
@@ -137,7 +144,7 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **
u = hashmap_get(m->users, UID_TO_PTR(uid));
if (!u) {
- r = user_new(&u, m, uid, gid, name);
+ r = user_new(&u, m, uid, gid, name, home);
if (r < 0)
return r;
}
@@ -148,7 +155,12 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **
return 0;
}
-int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
+int manager_add_user_by_name(
+ Manager *m,
+ const char *name,
+ User **_user) {
+
+ const char *home = NULL;
uid_t uid;
gid_t gid;
int r;
@@ -156,11 +168,11 @@ int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
assert(m);
assert(name);
- r = get_user_creds(&name, &uid, &gid, NULL, NULL);
+ r = get_user_creds(&name, &uid, &gid, &home, NULL);
if (r < 0)
return r;
- return manager_add_user(m, uid, gid, name, _user);
+ return manager_add_user(m, uid, gid, name, home, _user);
}
int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
@@ -173,7 +185,7 @@ int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
if (!p)
return errno > 0 ? -errno : -ENOENT;
- return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
+ return manager_add_user(m, uid, p->pw_gid, p->pw_name, p->pw_dir, _user);
}
int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 6586280269..1bb152bc20 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -3313,6 +3313,7 @@ int manager_start_scope(
const char *description,
char **wants,
char **after,
+ const char *requires_mounts_for,
sd_bus_message *more_properties,
sd_bus_error *error,
char **job) {
@@ -3368,6 +3369,12 @@ int manager_start_scope(
return r;
}
+ if (!empty_or_root(requires_mounts_for)) {
+ r = sd_bus_message_append(m, "(sv)", "RequiresMountsFor", "as", 1, requires_mounts_for);
+ if (r < 0)
+ return r;
+ }
+
/* Make sure that the session shells are terminated with SIGHUP since bash and friends tend to ignore
* SIGTERM */
r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index dd4ac9482a..e4c8bb36f6 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -591,6 +591,7 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
description,
STRV_MAKE(s->user->runtime_dir_service, s->user->service), /* These two have StopWhenUnneeded= set, hence add a dep towards them */
STRV_MAKE("systemd-logind.service", "systemd-user-sessions.service", s->user->runtime_dir_service, s->user->service), /* And order us after some more */
+ s->user->home,
properties,
error,
&s->scope_job);
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index f23fcbe674..70f5eb9d59 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -30,7 +30,13 @@
#include "user-util.h"
#include "util.h"
-int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
+int user_new(User **ret,
+ Manager *m,
+ uid_t uid,
+ gid_t gid,
+ const char *name,
+ const char *home) {
+
_cleanup_(user_freep) User *u = NULL;
char lu[DECIMAL_STR_MAX(uid_t) + 1];
int r;
@@ -54,6 +60,10 @@ int user_new(User **ret, Manager *m, uid_t uid, gid_t gid, const char *name) {
if (!u->name)
return -ENOMEM;
+ u->home = strdup(home);
+ if (!u->home)
+ return -ENOMEM;
+
if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT, uid) < 0)
return -ENOMEM;
@@ -124,6 +134,7 @@ User *user_free(User *u) {
u->runtime_path = mfree(u->runtime_path);
u->state_file = mfree(u->state_file);
u->name = mfree(u->name);
+ u->home = mfree(u->home);
return mfree(u);
}
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index e05646adc9..c41973e27d 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -23,6 +23,7 @@ struct User {
uid_t uid;
gid_t gid;
char *name;
+ char *home;
char *state_file;
char *runtime_path;
@@ -49,7 +50,7 @@ struct User {
LIST_FIELDS(User, gc_queue);
};
-int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name);
+int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name, const char *home);
User *user_free(User *u);
DEFINE_TRIVIAL_CLEANUP_FUNC(User *, user_free);
diff --git a/src/login/logind.h b/src/login/logind.h
index 7288dd7445..d29b01c75b 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -129,7 +129,7 @@ int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_dev
int manager_add_button(Manager *m, const char *name, Button **_button);
int manager_add_seat(Manager *m, const char *id, Seat **_seat);
int manager_add_session(Manager *m, const char *id, Session **_session);
-int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user);
+int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, const char *home, User **_user);
int manager_add_user_by_name(Manager *m, const char *name, User **_user);
int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user);
int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor);
@@ -162,7 +162,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(Manager *m, const char *unit_name
int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_;
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, sd_bus_message *more_properties, sd_bus_error *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);

View File

@ -0,0 +1,39 @@
From 117ed6bd7aa71fc79599e1d37bdb4a94b3505a38 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 8 Aug 2018 16:03:11 +0200
Subject: [PATCH] logind: improve error propagation of user_check_linger_file()
Let's make this a bit prettier, and propagate unexpected access() errors
correctly.
(The callers of this function will suppress them, but it's nicer of they
do that, rather than us doing that twice in both the callers and the
callees)
(cherry picked from commit 6996df9b864981980f5b713dc5c7d506a7a4b9bf)
Related: #1642460
---
src/login/logind-user.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 70f5eb9d59..3fd28fc66c 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -532,8 +532,14 @@ int user_check_linger_file(User *u) {
return -ENOMEM;
p = strjoina("/var/lib/systemd/linger/", cc);
+ if (access(p, F_OK) < 0) {
+ if (errno != ENOENT)
+ return -errno;
- return access(p, F_OK) >= 0;
+ return false;
+ }
+
+ return true;
}
bool user_may_gc(User *u, bool drop_not_started) {

View File

@ -0,0 +1,82 @@
From 89dd5e016a50da082e51129eecb3c5e04b8f0cf5 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 8 Aug 2018 16:04:40 +0200
Subject: [PATCH] logind: automatically GC lingering users for who now
user@.service (nor slice, not runtime dir service) is running anymore
This heavily borrows from @intelfx' PR #5546, but watches all three
units that are associated with a user now: the slice, the user@.service
and user-runtime-dir@.service.
The logic and reasoning behind it is the same though: there's no value
in keeping lingering users around if all their three services are gone.
Replaces: #5546
Fixes: #4162
(cherry picked from commit 4e5b605af202c770dfc8e3562d0f8d0440b2fe14)
Related: #1642460
---
src/login/logind-user.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 3fd28fc66c..bba3158d1a 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -26,6 +26,7 @@
#include "special.h"
#include "stdio-util.h"
#include "string-table.h"
+#include "strv.h"
#include "unit-name.h"
#include "user-util.h"
#include "util.h"
@@ -542,6 +543,25 @@ int user_check_linger_file(User *u) {
return true;
}
+static bool user_unit_active(User *u) {
+ const char *i;
+ int r;
+
+ assert(u->service);
+ assert(u->runtime_dir_service);
+ assert(u->slice);
+
+ FOREACH_STRING(i, u->service, u->runtime_dir_service, u->slice) {
+ r = manager_unit_is_active(u->manager, i);
+ if (r < 0)
+ log_debug_errno(r, "Failed to determine whether unit '%s' is active, ignoring", u->service);
+ if (r != 0)
+ return true;
+ }
+
+ return false;
+}
+
bool user_may_gc(User *u, bool drop_not_started) {
assert(u);
@@ -561,8 +581,10 @@ bool user_may_gc(User *u, bool drop_not_started) {
return false; /* Leave it around for a bit longer. */
}
- /* Is this a user that shall stay around forever? */
- if (user_check_linger_file(u) > 0)
+ /* Is this a user that shall stay around forever ("linger")? Before we say "no" to GC'ing for lingering users, let's check
+ * if any of the three units that we maintain for this user is still around. If none of them is,
+ * there's no need to keep this user around even if lingering is enabled. */
+ if (user_check_linger_file(u) > 0 && user_unit_active(u))
return false;
if (u->service_job && manager_job_is_active(u->manager, u->service_job))
@@ -608,7 +630,7 @@ UserState user_get_state(User *u) {
return all_closing ? USER_CLOSING : USER_ONLINE;
}
- if (user_check_linger_file(u) > 0)
+ if (user_check_linger_file(u) > 0 && user_unit_active(u))
return USER_LINGERING;
return USER_CLOSING;

View File

@ -0,0 +1,101 @@
From 96887ddecd1e4c36d8a32411ed515ddaf0f3a0e3 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 20 Jul 2018 11:27:55 +0200
Subject: [PATCH] pam_systemd: simplify code which with we set environment
variables
Let's shorten things a bit by splitting out common code in a new
function.
(cherry picked from commit d6baaa6978d3eb5b8e8497021c4ba576aee936a3)
Related: #1642460
---
src/login/pam_systemd.c | 46 ++++++++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 78ddb7d398..b2b62540bb 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -301,6 +301,24 @@ static const char* getenv_harder(pam_handle_t *handle, const char *key, const ch
return fallback;
}
+static int update_environment(pam_handle_t *handle, const char *key, const char *value) {
+ int r;
+
+ assert(handle);
+ assert(key);
+
+ /* Updates the environment, but only if there's actually a value set. Also, log about errors */
+
+ if (isempty(value))
+ return PAM_SUCCESS;
+
+ r = pam_misc_setenv(handle, key, value, 0);
+ if (r != PAM_SUCCESS)
+ pam_syslog(handle, LOG_ERR, "Failed to set environment variable %s.", key);
+
+ return r;
+}
+
_public_ PAM_EXTERN int pam_sm_open_session(
pam_handle_t *handle,
int flags,
@@ -555,11 +573,9 @@ _public_ PAM_EXTERN int pam_sm_open_session(
"id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u original_uid=%u",
id, object_path, runtime_path, session_fd, seat, vtnr, original_uid);
- r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0);
- if (r != PAM_SUCCESS) {
- pam_syslog(handle, LOG_ERR, "Failed to set session id.");
+ r = update_environment(handle, "XDG_SESSION_ID", id);
+ if (r != PAM_SUCCESS)
return r;
- }
if (original_uid == pw->pw_uid) {
/* Don't set $XDG_RUNTIME_DIR if the user we now
@@ -568,34 +584,26 @@ _public_ PAM_EXTERN int pam_sm_open_session(
* in privileged apps clobbering the runtime directory
* unnecessarily. */
- r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0);
- if (r != PAM_SUCCESS) {
- pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
+ r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path);
+ if (r != PAM_SUCCESS)
return r;
- }
r = export_legacy_dbus_address(handle, pw->pw_uid, runtime_path);
if (r != PAM_SUCCESS)
return r;
}
- if (!isempty(seat)) {
- r = pam_misc_setenv(handle, "XDG_SEAT", seat, 0);
- if (r != PAM_SUCCESS) {
- pam_syslog(handle, LOG_ERR, "Failed to set seat.");
- return r;
- }
- }
+ r = update_environment(handle, "XDG_SEAT", seat);
+ if (r != PAM_SUCCESS)
+ return r;
if (vtnr > 0) {
char buf[DECIMAL_STR_MAX(vtnr)];
sprintf(buf, "%u", vtnr);
- r = pam_misc_setenv(handle, "XDG_VTNR", buf, 0);
- if (r != PAM_SUCCESS) {
- pam_syslog(handle, LOG_ERR, "Failed to set virtual terminal number.");
+ r = update_environment(handle, "XDG_VTNR", buf);
+ if (r != PAM_SUCCESS)
return r;
- }
}
r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL);

View File

@ -0,0 +1,89 @@
From c8b74ac5cf508c7bcec92d197880043af1d2bad7 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 9 Oct 2018 22:23:41 +0200
Subject: [PATCH] logind: validate /run/user/1000 before we set it
Let's be safe than sorry, in particular as logind doesn't set it up
anymore, but user-runtime-dir@.service does, and logind doesn't really
track success of that.
(cherry picked from commit b92171124819305985ed292cc472f6668a027425)
Related: #1642460
---
src/login/pam_systemd.c | 48 +++++++++++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index b2b62540bb..64e1b4d1bf 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -319,6 +319,36 @@ static int update_environment(pam_handle_t *handle, const char *key, const char
return r;
}
+static bool validate_runtime_directory(pam_handle_t *handle, const char *path, uid_t uid) {
+ struct stat st;
+
+ assert(path);
+
+ /* Just some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually set
+ * up properly for us. */
+
+ if (lstat(path, &st) < 0) {
+ pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror(errno));
+ goto fail;
+ }
+
+ if (!S_ISDIR(st.st_mode)) {
+ pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
+ goto fail;
+ }
+
+ if (st.st_uid != uid) {
+ pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
+ goto fail;
+ }
+
+ return true;
+
+fail:
+ pam_syslog(handle, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
+ return false;
+}
+
_public_ PAM_EXTERN int pam_sm_open_session(
pam_handle_t *handle,
int flags,
@@ -377,10 +407,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
if (asprintf(&rt, "/run/user/"UID_FMT, pw->pw_uid) < 0)
return PAM_BUF_ERR;
- r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0);
- if (r != PAM_SUCCESS) {
- pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
- return r;
+ if (validate_runtime_directory(handle, rt, pw->pw_uid)) {
+ r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0);
+ if (r != PAM_SUCCESS) {
+ pam_syslog(handle, LOG_ERR, "Failed to set runtime dir.");
+ return r;
+ }
}
r = export_legacy_dbus_address(handle, pw->pw_uid, rt);
@@ -584,9 +616,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
* in privileged apps clobbering the runtime directory
* unnecessarily. */
- r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path);
- if (r != PAM_SUCCESS)
- return r;
+ if (validate_runtime_directory(handle, runtime_path, pw->pw_uid)) {
+ r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path);
+ if (r != PAM_SUCCESS)
+ return r;
+ }
r = export_legacy_dbus_address(handle, pw->pw_uid, runtime_path);
if (r != PAM_SUCCESS)

View File

@ -0,0 +1,60 @@
From 81b23f487eeffbc0e217c4e57567cfb70842f668 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Thu, 26 Nov 2020 16:29:10 +0100
Subject: [PATCH] define newly needed constants
Related: #1850986
---
src/basic/missing.h | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 14ad3d4914..b9376617fc 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -747,10 +747,13 @@ struct input_mask {
#define IFLA_NUM_RX_QUEUES 32
#define IFLA_CARRIER 33
#define IFLA_PHYS_PORT_ID 34
-#define __IFLA_MAX 35
+#endif
+
+#define IFLA_PROP_LIST 52
+#define IFLA_ALT_IFNAME 53
+#define __IFLA_MAX 53
#define IFLA_MAX (__IFLA_MAX - 1)
-#endif
#if !HAVE_IFLA_BOND_AD_INFO
#define IFLA_BOND_UNSPEC 0
@@ -1045,6 +1048,18 @@ struct input_mask {
#define RTA_EXPIRES 23
#endif
+#ifndef RTM_NEWLINKPROP
+#define RTM_NEWLINKPROP 108
+#endif
+
+#ifndef RTM_DELLINKPROP
+#define RTM_DELLINKPROP 109
+#endif
+
+#ifndef RTM_GETLINKPROP
+#define RTM_GETLINKPROP 110
+#endif
+
#ifndef IPV6_UNICAST_IF
#define IPV6_UNICAST_IF 76
#endif
@@ -1057,6 +1072,10 @@ struct input_mask {
#define IPV4_MIN_MTU 68
#endif
+#ifndef ALTIFNAMSIZ
+#define ALTIFNAMSIZ 128
+#endif
+
#ifndef IFF_MULTI_QUEUE
#define IFF_MULTI_QUEUE 0x100
#endif

View File

@ -0,0 +1,95 @@
From b0b98085bb0b95395b686efca43980d463749f3d Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 20:57:51 +0900
Subject: [PATCH] sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME
attributes
(cherry picked from commit ffeb16f5d832b1c65b8c8a1dd9bdd028bd76fc72)
Related: #1850986
---
src/libsystemd/sd-netlink/netlink-message.c | 2 +-
src/libsystemd/sd-netlink/netlink-types.c | 13 +++++++++++++
src/libsystemd/sd-netlink/netlink-util.h | 4 +++-
src/libsystemd/sd-netlink/rtnl-message.c | 2 ++
4 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index 23907c8224..db9101c163 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -89,7 +89,7 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL);
- assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL), -EINVAL);
+ assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETLINKPROP, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL), -EINVAL);
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index c93fe9cb4c..47d9c7f1c4 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -451,6 +451,15 @@ static const NLTypeSystem rtnl_af_spec_type_system = {
.types = rtnl_af_spec_types,
};
+static const NLType rtnl_prop_list_types[] = {
+ [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 },
+};
+
+static const NLTypeSystem rtnl_prop_list_type_system = {
+ .count = ELEMENTSOF(rtnl_prop_list_types),
+ .types = rtnl_prop_list_types,
+};
+
static const NLType rtnl_link_types[] = {
[IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR },
[IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR },
@@ -501,6 +510,7 @@ static const NLType rtnl_link_types[] = {
/*
[IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
*/
+ [IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system },
};
static const NLTypeSystem rtnl_link_type_system = {
@@ -643,6 +653,9 @@ static const NLType rtnl_types[] = {
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
[RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
[RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
index 7c35a2cfa7..882a616310 100644
--- a/src/libsystemd/sd-netlink/netlink-util.h
+++ b/src/libsystemd/sd-netlink/netlink-util.h
@@ -19,7 +19,9 @@ static inline bool rtnl_message_type_is_route(uint16_t type) {
}
static inline bool rtnl_message_type_is_link(uint16_t type) {
- return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
+ return IN_SET(type,
+ RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK,
+ RTM_NEWLINKPROP, RTM_DELLINKPROP, RTM_GETLINKPROP);
}
static inline bool rtnl_message_type_is_addr(uint16_t type) {
diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c
index 4416e1720c..369c402986 100644
--- a/src/libsystemd/sd-netlink/rtnl-message.c
+++ b/src/libsystemd/sd-netlink/rtnl-message.c
@@ -449,6 +449,8 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
if (nlmsg_type == RTM_NEWLINK)
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
+ else if (nlmsg_type == RTM_NEWLINK)
+ (*ret)->hdr->nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND;
ifi = NLMSG_DATA((*ret)->hdr);

View File

@ -0,0 +1,106 @@
From 3c31ef05ba732e3ab5d23761c5f84768ca8de68e Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 21:32:25 +0900
Subject: [PATCH] sd-netlink: introduce sd_netlink_message_read_strv()
The combination of sd_netlink_message_enter_container() and
sd_netlink_message_read_string() only reads the last element if the attribute is
duplicated, such a situation easily happens for IFLA_ALT_IFNAME.
The function introduced here reads all matched attributes.
(cherry picked from commit 8f3c1859669230c2c8458675f41de13e369b47e7)
Related: #1850986
---
src/libsystemd/sd-netlink/netlink-message.c | 58 +++++++++++++++++++++
src/systemd/sd-netlink.h | 1 +
2 files changed, 59 insertions(+)
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index db9101c163..5723e1d21c 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -14,6 +14,7 @@
#include "netlink-util.h"
#include "refcnt.h"
#include "socket-util.h"
+#include "strv.h"
#include "util.h"
#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
@@ -754,6 +755,63 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type,
return 0;
}
+int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret) {
+ _cleanup_strv_free_ char **s = NULL;
+ const NLTypeSystem *type_system;
+ const NLType *nl_type;
+ struct rtattr *rta;
+ void *container;
+ unsigned short rt_len;
+ int r;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
+
+ r = type_system_get_type(m->containers[m->n_containers].type_system,
+ &nl_type,
+ container_type);
+ if (r < 0)
+ return r;
+
+ if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
+ return -EINVAL;
+
+ r = type_system_get_type_system(m->containers[m->n_containers].type_system,
+ &type_system,
+ container_type);
+ if (r < 0)
+ return r;
+
+ r = type_system_get_type(type_system, &nl_type, type_id);
+ if (r < 0)
+ return r;
+
+ if (type_get_type(nl_type) != NETLINK_TYPE_STRING)
+ return -EINVAL;
+
+ r = netlink_message_read_internal(m, container_type, &container, NULL);
+ if (r < 0)
+ return r;
+
+ rt_len = (unsigned short) r;
+ rta = container;
+
+ for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
+ unsigned short type;
+
+ type = RTA_TYPE(rta);
+ if (type != type_id)
+ continue;
+
+ r = strv_extend(&s, RTA_DATA(rta));
+ if (r < 0)
+ return r;
+ }
+
+ *ret = TAKE_PTR(s);
+ return 0;
+}
+
static int netlink_container_parse(sd_netlink_message *m,
struct netlink_container *container,
int count,
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index 51f0fa16b4..1f5c093f11 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -82,6 +82,7 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor
int sd_netlink_message_close_container(sd_netlink_message *m);
int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, const char **data);
+int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret);
int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8_t *data);
int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data);
int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data);

View File

@ -0,0 +1,65 @@
From 7888c8796197357f0214ea5fe17b11a8814fc313 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 21:47:21 +0900
Subject: [PATCH] sd-netlink: introduce sd_netlink_message_append_strv()
(cherry picked from commit 6d725977c4f98a8f5effc33f44aa646cc2b6a0b7)
Related: #1850986
---
src/libsystemd/sd-netlink/netlink-message.c | 29 +++++++++++++++++++++
src/systemd/sd-netlink.h | 1 +
2 files changed, 30 insertions(+)
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index 5723e1d21c..55d6510b63 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -259,6 +259,35 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type,
return 0;
}
+int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data) {
+ size_t length, size;
+ char * const *p;
+ int r;
+
+ assert_return(m, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(data, -EINVAL);
+
+ r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(p, data) {
+ if (size) {
+ length = strnlen(*p, size+1);
+ if (length > size)
+ return -EINVAL;
+ } else
+ length = strlen(*p);
+
+ r = add_rtattr(m, type, *p, length + 1);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type) {
size_t size;
int r;
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index 1f5c093f11..5a05cd4485 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -67,6 +67,7 @@ int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
int sd_netlink_detach_event(sd_netlink *nl);
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
+int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data);
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type);
int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uint8_t data);
int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data);

View File

@ -0,0 +1,71 @@
From aff5197c5f06617b1ca0291614a0fb02c0c2e948 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 21:48:12 +0900
Subject: [PATCH] test: add a test for sd_netlink_message_{append,read}_strv()
(cherry picked from commit d08d92d5ee508a80e35d6b95b962bd09527fb5f2)
Related: #1850986
---
src/libsystemd/sd-netlink/test-netlink.c | 33 ++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
index 03773fb936..8ee6551385 100644
--- a/src/libsystemd/sd-netlink/test-netlink.c
+++ b/src/libsystemd/sd-netlink/test-netlink.c
@@ -10,7 +10,9 @@
#include "missing.h"
#include "netlink-util.h"
#include "socket-util.h"
+#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
#include "util.h"
static void test_message_link_bridge(sd_netlink *rtnl) {
@@ -357,6 +359,36 @@ static void test_message(sd_netlink *rtnl) {
assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT);
}
+static void test_strv(sd_netlink *rtnl) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+ _cleanup_strv_free_ char **names_in = NULL, **names_out;
+ const char *p;
+
+ assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0);
+
+ for (unsigned i = 0; i < 10; i++) {
+ char name[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)];
+
+ xsprintf(name, "hoge%" PRIu32, i + 1000);
+ assert_se(strv_extend(&names_in, name) >= 0);
+ }
+
+ assert_se(sd_netlink_message_open_container(m, IFLA_PROP_LIST) >= 0);
+ assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, names_in) >= 0);
+ assert_se(sd_netlink_message_close_container(m) >= 0);
+
+ rtnl_message_seal(m);
+ assert_se(sd_netlink_message_rewind(m) >= 0);
+
+ assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0);
+ assert_se(strv_equal(names_in, names_out));
+
+ assert_se(sd_netlink_message_enter_container(m, IFLA_PROP_LIST) >= 0);
+ assert_se(sd_netlink_message_read_string(m, IFLA_ALT_IFNAME, &p) >= 0);
+ assert_se(streq(p, "hoge1009"));
+ assert_se(sd_netlink_message_exit_container(m) >= 0);
+}
+
int main(void) {
sd_netlink *rtnl;
sd_netlink_message *m;
@@ -377,6 +409,7 @@ int main(void) {
test_message(rtnl);
test_container(rtnl);
+ test_strv(rtnl);
if_loopback = (int) if_nametoindex("lo");
assert_se(if_loopback > 0);

View File

@ -0,0 +1,79 @@
From c50aab5f23535ea7f3ef004910465e7054931199 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 23:01:54 +0900
Subject: [PATCH] util: introduce ifname_valid_full()
(cherry picked from commit 4252696aec9ec038ff312a164e25f039da25126f)
Related: #1850986
---
src/basic/socket-util.c | 12 +++++++++---
src/basic/socket-util.h | 5 ++++-
src/test/test-socket-util.c | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 053bcba670..7f8066123b 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <linux/if.h>
#include "alloc-util.h"
#include "fd-util.h"
@@ -868,7 +869,7 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
-bool ifname_valid(const char *p) {
+bool ifname_valid_full(const char *p, bool alternative) {
bool numeric = true;
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
@@ -878,8 +879,13 @@ bool ifname_valid(const char *p) {
if (isempty(p))
return false;
- if (strlen(p) >= IFNAMSIZ)
- return false;
+ if (alternative) {
+ if (strlen(p) >= ALTIFNAMSIZ)
+ return false;
+ } else {
+ if (strlen(p) >= IFNAMSIZ)
+ return false;
+ }
if (dot_or_dot_dot(p))
return false;
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index c7c9ad34d6..30baba6c03 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -123,7 +123,10 @@ int fd_inc_rcvbuf(int fd, size_t n);
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
-bool ifname_valid(const char *p);
+bool ifname_valid_full(const char *p, bool alternative);
+static inline bool ifname_valid(const char *p) {
+ return ifname_valid_full(p, false);
+}
bool address_label_valid(const char *p);
int getpeercred(int fd, struct ucred *ucred);
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 19c5395b92..c545622c09 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -39,6 +39,7 @@ static void test_ifname_valid(void) {
assert(ifname_valid("xxxxxxxxxxxxxxx"));
assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
+ assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true));
}
static void test_socket_address_parse(void) {

View File

@ -0,0 +1,69 @@
From 7fc7c2774e0836ace524215ced5c60db405a154a Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 27 Nov 2020 10:25:12 +0100
Subject: [PATCH] rename function
This happened upstream in commit
54a8423788ec3cc6240959ab9f5cdac40baf047a, but I don't want to backport
the whole commit...
Related: #1850986
---
src/libsystemd-network/network-internal.c | 2 +-
src/libsystemd-network/network-internal.h | 2 +-
src/network/networkd-network-gperf.gperf | 2 +-
src/udev/net/link-config-gperf.gperf | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 0849b44ee2..629e858def 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -183,7 +183,7 @@ int config_parse_net_condition(const char *unit,
return 0;
}
-int config_parse_ifnames(
+int config_parse_match_ifnames(
const char *unit,
const char *filename,
unsigned line,
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 883f34b95c..9074758bbb 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -34,7 +34,7 @@ bool net_match_config(Set *match_mac,
CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
-CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 6ad5257f79..c4a2eccdc2 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -24,7 +24,7 @@ Match.MACAddress, config_parse_hwaddrs,
Match.Path, config_parse_strv, 0, offsetof(Network, match_path)
Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver)
Match.Type, config_parse_strv, 0, offsetof(Network, match_type)
-Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name)
+Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel_cmdline)
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 5640fa0513..b37836d852 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -20,7 +20,7 @@ struct ConfigPerfItem;
%includes
%%
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_mac)
-Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name)
+Match.OriginalName, config_parse_match_ifnames, 0, offsetof(link_config, match_name)
Match.Path, config_parse_strv, 0, offsetof(link_config, match_path)
Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver)
Match.Type, config_parse_strv, 0, offsetof(link_config, match_type)

View File

@ -0,0 +1,238 @@
From b99b055ba975c1663beaf94dbfe8f5c5c7398996 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 23:21:18 +0900
Subject: [PATCH] udev: support AlternativeName= setting in .link file
(cherry picked from commit a5053a158b43c5ddee90f4915b9fc603e0191d6d)
Related: #1850986
---
man/systemd.link.xml | 8 ++++
src/libsystemd/sd-netlink/netlink-util.c | 40 ++++++++++++++++
src/libsystemd/sd-netlink/netlink-util.h | 1 +
src/shared/conf-parser.c | 60 ++++++++++++++++++++++++
src/shared/conf-parser.h | 1 +
src/udev/net/link-config-gperf.gperf | 1 +
src/udev/net/link-config.c | 5 ++
src/udev/net/link-config.h | 1 +
8 files changed, 117 insertions(+)
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 32657308d0..0b0d83349d 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -343,6 +343,14 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>AlternativeName=</varname></term>
+ <listitem>
+ <para>The alternative interface name to use. This option can be specified multiple times.
+ If the empty string is assigned to this option, the list is reset, and all prior assignments
+ have no effect.</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>MTUBytes=</varname></term>
<listitem>
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
index 3928dfbabf..c1c306f121 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -4,6 +4,7 @@
#include "netlink-internal.h"
#include "netlink-util.h"
+#include "strv.h"
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
@@ -80,6 +81,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias,
return 0;
}
+int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(ifindex > 0);
+
+ if (strv_isempty(alternative_names))
+ return 0;
+
+ if (!*rtnl) {
+ r = sd_netlink_open(rtnl);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_close_container(message);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(*rtnl, message, 0, NULL);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
struct nlmsgerr *err;
int r;
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
index 882a616310..92de19c092 100644
--- a/src/libsystemd/sd-netlink/netlink-util.h
+++ b/src/libsystemd/sd-netlink/netlink-util.h
@@ -38,6 +38,7 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) {
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
+int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
int rtnl_log_parse_error(int r);
int rtnl_log_create_error(int r);
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 246b7431e4..1f40f00c72 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -970,6 +970,66 @@ int config_parse_ifname(
return 0;
}
+int config_parse_ifnames(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ _cleanup_strv_free_ char **names = NULL;
+ char ***s = data;
+ const char *p;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *s = strv_free(*s);
+ return 0;
+ }
+
+ p = rvalue;
+ for (;;) {
+ _cleanup_free_ char *word = NULL;
+
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to extract interface name, ignoring assignment: %s",
+ rvalue);
+ return 0;
+ }
+ if (r == 0)
+ break;
+
+ if (!ifname_valid_full(word, ltype)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Interface name is not valid or too long, ignoring assignment: %s",
+ word);
+ continue;
+ }
+
+ r = strv_consume(&names, TAKE_PTR(word));
+ if (r < 0)
+ return log_oom();
+ }
+
+ r = strv_extend_strv(s, names, true);
+ if (r < 0)
+ return log_oom();
+
+ return 0;
+}
+
int config_parse_ip_port(
const char *unit,
const char *filename,
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index a0a5c89c27..375b2e5a74 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -137,6 +137,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_signal);
CONFIG_PARSER_PROTOTYPE(config_parse_personality);
CONFIG_PARSER_PROTOTYPE(config_parse_permille);
CONFIG_PARSER_PROTOTYPE(config_parse_ifname);
+CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
CONFIG_PARSER_PROTOTYPE(config_parse_join_controllers);
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index b37836d852..913c754145 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -34,6 +34,7 @@ Link.MACAddressPolicy, config_parse_mac_policy, 0,
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
+Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 5113586457..d07a1a1874 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -67,6 +67,7 @@ static void link_config_free(link_config *link) {
free(link->mac);
free(link->name_policy);
free(link->name);
+ strv_free(link->alternative_names);
free(link->alias);
free(link);
@@ -468,6 +469,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (r < 0)
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
+ r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
+ if (r < 0)
+ return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
+
*name = new_name;
return 0;
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 4798bb101c..93d5fdce59 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -50,6 +50,7 @@ struct link_config {
MACPolicy mac_policy;
NamePolicy *name_policy;
char *name;
+ char **alternative_names;
char *alias;
uint32_t mtu;
size_t speed;

View File

@ -0,0 +1,115 @@
From c76d050d8d61b4a63d4407bd03bd3f49cd9915ce Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Sun, 15 Dec 2019 22:46:19 +0900
Subject: [PATCH] network: make Name= in [Match] support alternative names of
interfaces
(cherry picked from commit 572b21d96cabd5860b0670e98440b6cb99a4b749
src/network bits have been left out.)
Related: #1850986
---
man/systemd.network.xml | 7 +++----
src/libsystemd-network/network-internal.c | 20 ++++++++++++++++++--
src/libsystemd-network/network-internal.h | 3 ++-
src/udev/net/link-config.c | 3 ++-
4 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index fc8e0aea68..8300540096 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -133,10 +133,9 @@
<varlistentry>
<term><varname>Name=</varname></term>
<listitem>
- <para>A whitespace-separated list of shell-style globs
- matching the device name, as exposed by the udev property
- <literal>INTERFACE</literal>. If the list is prefixed
- with a "!", the test is inverted.</para>
+ <para>A whitespace-separated list of shell-style globs matching the device name, as exposed
+ by the udev property <literal>INTERFACE</literal>, or device's alternative names. If the
+ list is prefixed with a "!", the test is inverted.</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 629e858def..a935709cd0 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -92,6 +92,18 @@ static bool net_condition_test_strv(char * const *raw_patterns,
return string && strv_fnmatch(raw_patterns, string, 0);
}
+static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) {
+ if (net_condition_test_strv(patterns, ifname))
+ return true;
+
+ char * const *p;
+ STRV_FOREACH(p, alternative_names)
+ if (net_condition_test_strv(patterns, *p))
+ return true;
+
+ return false;
+}
+
bool net_match_config(Set *match_mac,
char * const *match_paths,
char * const *match_drivers,
@@ -107,7 +119,8 @@ bool net_match_config(Set *match_mac,
const char *dev_parent_driver,
const char *dev_driver,
const char *dev_type,
- const char *dev_name) {
+ const char *dev_name,
+ char * const *alternative_names) {
if (match_host && condition_test(match_host) <= 0)
return false;
@@ -124,6 +137,9 @@ bool net_match_config(Set *match_mac,
if (match_arch && condition_test(match_arch) <= 0)
return false;
+ if (!net_condition_test_ifname(match_names, dev_name, alternative_names))
+ return false;
+
if (match_mac && dev_mac && !set_contains(match_mac, dev_mac))
return false;
@@ -214,7 +230,7 @@ int config_parse_match_ifnames(
if (r == 0)
break;
- if (!ifname_valid(word)) {
+ if (!ifname_valid_full(word, ltype)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
return 0;
}
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 9074758bbb..e1d098f3fe 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -29,7 +29,8 @@ bool net_match_config(Set *match_mac,
const char *dev_parent_driver,
const char *dev_driver,
const char *dev_type,
- const char *dev_name);
+ const char *dev_name,
+ char * const *alternative_names);
CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index d07a1a1874..e5052f8f29 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -238,7 +238,8 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device,
udev_device_get_driver(udev_device_get_parent(device)),
udev_device_get_property_value(device, "ID_NET_DRIVER"),
udev_device_get_devtype(device),
- udev_device_get_sysname(device))) {
+ udev_device_get_sysname(device),
+ NULL)) {
if (link->match_name) {
unsigned char name_assign_type = NET_NAME_UNKNOWN;

View File

@ -0,0 +1,170 @@
From 22dd44ae3cfd66e622e0b672af96728b6f505ad1 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 17 Dec 2019 11:01:35 +0900
Subject: [PATCH] udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ
(cherry picked from commit 78f8849f84ca0939796edb840e878a9d2e124a4d)
Related: #1850986
---
src/udev/net/link-config.c | 5 ++++-
src/udev/udev-builtin-net_id.c | 33 +++++++++++++++++----------------
src/udev/udev-event.c | 4 ++--
3 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index e5052f8f29..4de8ee7d7e 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -19,6 +19,7 @@
#include "path-util.h"
#include "proc-cmdline.h"
#include "random-util.h"
+#include "socket-util.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
@@ -405,7 +406,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
NamePolicy *policy;
for (policy = config->name_policy;
- !new_name && *policy != _NAMEPOLICY_INVALID; policy++) {
+ *policy != _NAMEPOLICY_INVALID; policy++) {
switch (*policy) {
case NAMEPOLICY_KERNEL:
respect_predictable = true;
@@ -428,6 +429,8 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
default:
break;
}
+ if (ifname_valid(new_name))
+ break;
}
}
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 7c153f0aef..0611c08234 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -90,6 +90,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <linux/if.h>
#include <linux/pci_regs.h>
#include "dirent-util.h"
@@ -172,21 +173,21 @@ struct netnames {
bool mac_valid;
struct udev_device *pcidev;
- char pci_slot[IFNAMSIZ];
- char pci_path[IFNAMSIZ];
- char pci_onboard[IFNAMSIZ];
+ char pci_slot[ALTIFNAMSIZ];
+ char pci_path[ALTIFNAMSIZ];
+ char pci_onboard[ALTIFNAMSIZ];
const char *pci_onboard_label;
- char usb_ports[IFNAMSIZ];
- char bcma_core[IFNAMSIZ];
- char ccw_busid[IFNAMSIZ];
- char vio_slot[IFNAMSIZ];
- char platform_path[IFNAMSIZ];
+ char usb_ports[ALTIFNAMSIZ];
+ char bcma_core[ALTIFNAMSIZ];
+ char ccw_busid[ALTIFNAMSIZ];
+ char vio_slot[ALTIFNAMSIZ];
+ char platform_path[ALTIFNAMSIZ];
};
struct virtfn_info {
struct udev_device *physfn_pcidev;
- char suffix[IFNAMSIZ];
+ char suffix[ALTIFNAMSIZ];
};
static const NamingScheme* naming_scheme_from_name(const char *name) {
@@ -883,7 +884,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
err = names_mac(dev, &names);
if (err >= 0 && names.mac_valid) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix,
names.mac[0], names.mac[1], names.mac[2],
@@ -896,7 +897,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* get path names for Linux on System z network devices */
err = names_ccw(dev, &names);
if (err >= 0 && names.type == NET_CCW) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.ccw_busid))
udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
@@ -906,7 +907,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* get ibmveth/ibmvnic slot-based names. */
err = names_vio(dev, &names);
if (err >= 0 && names.type == NET_VIO) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.vio_slot))
udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
@@ -916,7 +917,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* get ACPI path names for ARM64 platform devices */
err = names_platform(dev, &names, test);
if (err >= 0 && names.type == NET_PLATFORM) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.platform_path))
udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
@@ -930,7 +931,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* plain PCI device */
if (names.type == NET_PCI) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
if (names.pci_onboard[0] &&
snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_onboard))
@@ -953,7 +954,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* USB device */
err = names_usb(dev, &names);
if (err >= 0 && names.type == NET_USB) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
if (names.pci_path[0] &&
snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.usb_ports))
@@ -968,7 +969,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* Broadcom bus */
err = names_bcma(dev, &names);
if (err >= 0 && names.type == NET_BCMA) {
- char str[IFNAMSIZ];
+ char str[ALTIFNAMSIZ];
if (names.pci_path[0] &&
snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.bcma_core))
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index fd8406d959..19b100d4f8 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -816,13 +816,13 @@ out:
static int rename_netif(struct udev_event *event) {
struct udev_device *dev = event->dev;
- char name[IFNAMSIZ];
+ char name[ALTIFNAMSIZ];
const char *oldname;
int r;
oldname = udev_device_get_sysname(dev);
- strscpy(name, IFNAMSIZ, event->name);
+ strscpy(name, ALTIFNAMSIZ, event->name);
r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name);
if (r < 0)

View File

@ -0,0 +1,43 @@
From 42894fc33ae88f3be49aa01ac24dd1c3e96770f6 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 17 Dec 2019 15:32:22 +0900
Subject: [PATCH] udev: do not fail if kernel does not support alternative
names
(cherry picked from commit bb181dd4a664ca8e82a8f7194261fd6531e861d8)
Related: #1850986
---
man/systemd.link.xml | 3 ++-
src/udev/net/link-config.c | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 0b0d83349d..c8ebb751ee 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -348,7 +348,8 @@
<listitem>
<para>The alternative interface name to use. This option can be specified multiple times.
If the empty string is assigned to this option, the list is reset, and all prior assignments
- have no effect.</para>
+ have no effect. If the kernel does not support the alternative names, then this setting will
+ be ignored.</para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 4de8ee7d7e..8e88c8e5c4 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -474,7 +474,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
- if (r < 0)
+ if (r == -EOPNOTSUPP)
+ log_debug_errno(r, "Could not set AlternativeName= on %s, ignoring: %m", old_name);
+ else if (r < 0)
return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
*name = new_name;

View File

@ -0,0 +1,169 @@
From 4f47e35ee4026f24ee99a0bfa7ba5b2f24a92a02 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 16 Dec 2019 23:44:42 +0900
Subject: [PATCH] udev: introduce AlternativeNamesPolicy= setting
(cherry picked from commit ef1d2c07f9567dfea8a4e012d8779a4ded2d9ae6)
Resolves: #1850986
---
man/systemd.link.xml | 11 +++++
src/udev/net/link-config-gperf.gperf | 1 +
src/udev/net/link-config.c | 62 ++++++++++++++++++++++++++--
src/udev/net/link-config.h | 5 +++
4 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index c8ebb751ee..13dcce0879 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -343,6 +343,17 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>AlternativeNamesPolicy=</varname></term>
+ <listitem>
+ <para>A space-separated list of policies by which the interface's alternative names
+ should be set. Each of the policies may fail, and all successful policies are used. The
+ available policies are <literal>database</literal>, <literal>onboard</literal>,
+ <literal>slot</literal>, <literal>path</literal>, and <literal>mac</literal>. If the
+ kernel does not support the alternative names, then this setting will be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>AlternativeName=</varname></term>
<listitem>
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 913c754145..df8404e7b8 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -35,6 +35,7 @@ Link.MACAddress, config_parse_hwaddr, 0,
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
+Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(link_config, alternative_names_policy)
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 8e88c8e5c4..6ceb4c698e 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -69,6 +69,7 @@ static void link_config_free(link_config *link) {
free(link->name_policy);
free(link->name);
strv_free(link->alternative_names);
+ free(link->alternative_names_policy);
free(link->alias);
free(link);
@@ -349,6 +350,7 @@ static int get_mac(struct udev_device *device, bool want_random,
int link_config_apply(link_config_ctx *ctx, link_config *config,
struct udev_device *device, const char **name) {
+ _cleanup_strv_free_ char **altnames = NULL;
bool respect_predictable = false;
struct ether_addr generated_mac;
struct ether_addr *mac = NULL;
@@ -473,11 +475,52 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (r < 0)
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
- r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
+ if (config->alternative_names) {
+ altnames = strv_copy(config->alternative_names);
+ if (!altnames)
+ return log_oom();
+ }
+
+ if (config->alternative_names_policy)
+ for (NamePolicy *p = config->alternative_names_policy; *p != _NAMEPOLICY_INVALID; p++) {
+ const char *n;
+
+ switch (*p) {
+ case NAMEPOLICY_DATABASE:
+ n = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE");
+ break;
+ case NAMEPOLICY_ONBOARD:
+ n = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
+ break;
+ case NAMEPOLICY_SLOT:
+ n = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
+ break;
+ case NAMEPOLICY_PATH:
+ n = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
+ break;
+ case NAMEPOLICY_MAC:
+ n = udev_device_get_property_value(device, "ID_NET_NAME_MAC");
+ break;
+ default:
+ assert_not_reached("invalid policy");
+ }
+ if (!isempty(n)) {
+ r = strv_extend(&altnames, n);
+ if (r < 0)
+ return log_oom();
+ }
+ }
+
+ if (new_name)
+ strv_remove(altnames, new_name);
+ strv_remove(altnames, old_name);
+ strv_uniq(altnames);
+
+ r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames);
if (r == -EOPNOTSUPP)
- log_debug_errno(r, "Could not set AlternativeName= on %s, ignoring: %m", old_name);
+ log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name);
else if (r < 0)
- return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
+ return log_warning_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name);
*name = new_name;
@@ -524,3 +567,16 @@ DEFINE_STRING_TABLE_LOOKUP(name_policy, NamePolicy);
DEFINE_CONFIG_PARSE_ENUMV(config_parse_name_policy, name_policy, NamePolicy,
_NAMEPOLICY_INVALID,
"Failed to parse interface name policy");
+
+static const char* const alternative_names_policy_table[_NAMEPOLICY_MAX] = {
+ [NAMEPOLICY_DATABASE] = "database",
+ [NAMEPOLICY_ONBOARD] = "onboard",
+ [NAMEPOLICY_SLOT] = "slot",
+ [NAMEPOLICY_PATH] = "path",
+ [NAMEPOLICY_MAC] = "mac",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(alternative_names_policy, NamePolicy);
+DEFINE_CONFIG_PARSE_ENUMV(config_parse_alternative_names_policy, alternative_names_policy, NamePolicy,
+ _NAMEPOLICY_INVALID,
+ "Failed to parse alternative names policy");
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 93d5fdce59..634bd2ec54 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -49,6 +49,7 @@ struct link_config {
struct ether_addr *mac;
MACPolicy mac_policy;
NamePolicy *name_policy;
+ NamePolicy *alternative_names_policy;
char *name;
char **alternative_names;
char *alias;
@@ -78,6 +79,9 @@ int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret
const char *name_policy_to_string(NamePolicy p) _const_;
NamePolicy name_policy_from_string(const char *p) _pure_;
+const char *alternative_names_policy_to_string(NamePolicy p) _const_;
+NamePolicy alternative_names_policy_from_string(const char *p) _pure_;
+
const char *mac_policy_to_string(MACPolicy p) _const_;
MACPolicy mac_policy_from_string(const char *p) _pure_;
@@ -86,3 +90,4 @@ const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN
int config_parse_mac_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_name_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_alternative_names_policy(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);

View File

@ -0,0 +1,22 @@
From 433d85ac89baa0683290cf8b5a913e7c6d666ef1 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 17 Dec 2019 00:30:38 +0900
Subject: [PATCH] network: set AlternativeNamesPolicy= in 99-default.link
(cherry picked from commit 49f5cbe92484a6661bccc0ae6c547bc5767c83bf)
Related: #1850986
---
network/99-default.link | 1 +
1 file changed, 1 insertion(+)
diff --git a/network/99-default.link b/network/99-default.link
index 561bf329e4..58c0b74a7c 100644
--- a/network/99-default.link
+++ b/network/99-default.link
@@ -9,4 +9,5 @@
[Link]
NamePolicy=kernel database onboard slot path
+AlternativeNamesPolicy=database onboard slot path
MACAddressPolicy=persistent

View File

@ -0,0 +1,59 @@
From c4c771f2dc5c590990d1f9105886b833afa59852 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Mon, 16 Dec 2019 19:47:48 +0900
Subject: [PATCH] random-util: call initialize_srand() after fork()
(cherry picked from commit a0f11d1d11a546f791855ec9c47c2ff830e6a5aa)
Related: #1850986
---
src/basic/random-util.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index 91481559db..801f6ad131 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -4,6 +4,7 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/random.h>
+#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -26,6 +27,8 @@
#include "random-util.h"
#include "time-util.h"
+static bool srand_called = false;
+
int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
static int have_syscall = -1;
@@ -81,8 +84,12 @@ int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true);
}
+static void clear_srand_initialization(void) {
+ srand_called = false;
+}
+
void initialize_srand(void) {
- static bool srand_called = false;
+ static bool pthread_atfork_registered = false;
unsigned x;
#if HAVE_SYS_AUXV_H
void *auxv;
@@ -109,6 +116,11 @@ void initialize_srand(void) {
srand(x);
srand_called = true;
+
+ if (!pthread_atfork_registered) {
+ (void) pthread_atfork(NULL, NULL, clear_srand_initialization);
+ pthread_atfork_registered = true;
+ }
}
/* INT_MAX gives us only 31 bits, so use 24 out of that. */

View File

@ -0,0 +1,78 @@
From 8db22aec9bfd140855b64f2879b7ca6d1cba69c6 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 17 Dec 2019 18:28:36 +0900
Subject: [PATCH] sd-netlink: introduce rtnl_resolve_link_alternative_names()
(cherry picked from commit b04c5e51da7a61d41d564e73a1e92bd8b29b0223)
Related: #1850986
---
src/libsystemd/sd-netlink/netlink-types.c | 1 +
src/libsystemd/sd-netlink/netlink-util.c | 29 +++++++++++++++++++++++
src/libsystemd/sd-netlink/netlink-util.h | 1 +
3 files changed, 31 insertions(+)
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 47d9c7f1c4..e118a0aa30 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -511,6 +511,7 @@ static const NLType rtnl_link_types[] = {
[IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
*/
[IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system },
+ [IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 },
};
static const NLTypeSystem rtnl_link_type_system = {
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
index c1c306f121..62fc71a3d8 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -120,6 +120,35 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const
return 0;
}
+int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(name);
+ assert(ret);
+
+ if (!*rtnl) {
+ r = sd_netlink_open(rtnl);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, 0);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_string(message, IFLA_ALT_IFNAME, name);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(*rtnl, message, 0, &reply);
+ if (r < 0)
+ return r;
+
+ return sd_rtnl_message_link_get_ifindex(reply, ret);
+}
+
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
struct nlmsgerr *err;
int r;
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
index 92de19c092..ea98439fad 100644
--- a/src/libsystemd/sd-netlink/netlink-util.h
+++ b/src/libsystemd/sd-netlink/netlink-util.h
@@ -39,6 +39,7 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) {
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
+int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret);
int rtnl_log_parse_error(int r);
int rtnl_log_create_error(int r);

View File

@ -0,0 +1,27 @@
From eeea9a2f94b5defb97c20c62a23345a367a734aa Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Tue, 17 Dec 2019 20:41:21 +0900
Subject: [PATCH] udev: sort alternative names
Kernel preserves the order of alternative names. So, for user
visibility, let's sort the alternative names.
(cherry picked from commit 4d016e965b13883cccc963a34a1299a0c4f900ca)
Related: #1850986
---
src/udev/net/link-config.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 6ceb4c698e..8bd374d352 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -515,6 +515,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
strv_remove(altnames, new_name);
strv_remove(altnames, old_name);
strv_uniq(altnames);
+ strv_sort(altnames);
r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames);
if (r == -EOPNOTSUPP)

View File

@ -0,0 +1,102 @@
From 8f946da7ee9bbb6e52e99b452c1f4f6f76e7b3c2 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 17 Jul 2020 21:29:13 +0900
Subject: [PATCH] netlink: introduce rtnl_get/delete_link_alternative_names()
(cherry picked from commit 14982526145de84201c7e3b4fc6be6aa5e9a08f7)
Related: #1850986
---
src/libsystemd/sd-netlink/netlink-util.c | 45 ++++++++++++++++++++++--
src/libsystemd/sd-netlink/netlink-util.h | 2 ++
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
index 62fc71a3d8..7f09261981 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -81,12 +81,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias,
return 0;
}
-int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
+int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
+ _cleanup_strv_free_ char **names = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(ifindex > 0);
+ assert(ret);
+
+ if (!*rtnl) {
+ r = sd_netlink_open(rtnl);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(*rtnl, message, 0, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_read_strv(reply, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names);
+ if (r < 0 && r != -ENODATA)
+ return r;
+
+ *ret = TAKE_PTR(names);
+
+ return 0;
+}
+
+static int rtnl_update_link_alternative_names(sd_netlink **rtnl, uint16_t nlmsg_type, int ifindex, char * const *alternative_names) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
int r;
assert(rtnl);
assert(ifindex > 0);
+ assert(IN_SET(nlmsg_type, RTM_NEWLINKPROP, RTM_DELLINKPROP));
if (strv_isempty(alternative_names))
return 0;
@@ -97,7 +130,7 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const
return r;
}
- r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex);
+ r = sd_rtnl_message_new_link(*rtnl, &message, nlmsg_type, ifindex);
if (r < 0)
return r;
@@ -120,6 +153,14 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const
return 0;
}
+int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
+ return rtnl_update_link_alternative_names(rtnl, RTM_NEWLINKPROP, ifindex, alternative_names);
+}
+
+int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
+ return rtnl_update_link_alternative_names(rtnl, RTM_DELLINKPROP, ifindex, alternative_names);
+}
+
int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
int r;
diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h
index ea98439fad..4fc31aa274 100644
--- a/src/libsystemd/sd-netlink/netlink-util.h
+++ b/src/libsystemd/sd-netlink/netlink-util.h
@@ -38,7 +38,9 @@ static inline bool rtnl_message_type_is_routing_policy_rule(uint16_t type) {
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
+int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret);
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
+int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret);
int rtnl_log_parse_error(int r);

View File

@ -0,0 +1,81 @@
From 6db267672de69d6bf4809f433cde106e11145ca8 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 17 Jul 2020 21:31:24 +0900
Subject: [PATCH] netlink: do not fail when new interface name is already used
as an alternative name
When renaming a network interface, the new name may be used as an
alternative name. In that case, let's swap the current name and the
alternative name. That is, first drop the new name from the list of
alternative names, then rename the interface, finally set the old name
as an alternative name.
(cherry picked from commit 434a34838034347f45fb9a47df55b1a36e5addfd)
Related: #1850986
---
src/libsystemd/sd-netlink/netlink-util.c | 30 +++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c
index 7f09261981..4e42ef9e26 100644
--- a/src/libsystemd/sd-netlink/netlink-util.c
+++ b/src/libsystemd/sd-netlink/netlink-util.c
@@ -1,23 +1,40 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include <net/if.h>
+
#include "sd-netlink.h"
#include "netlink-internal.h"
#include "netlink-util.h"
+#include "socket-util.h"
+#include "string-util.h"
#include "strv.h"
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
+ _cleanup_strv_free_ char **alternative_names = NULL;
+ char old_name[IF_NAMESIZE + 1] = {};
int r;
assert(rtnl);
assert(ifindex > 0);
assert(name);
- if (!*rtnl) {
- r = sd_netlink_open(rtnl);
+ if (!ifname_valid(name))
+ return -EINVAL;
+
+ r = rtnl_get_link_alternative_names(rtnl, ifindex, &alternative_names);
+ if (r < 0)
+ log_debug_errno(r, "Failed to get alternative names on network interface %i, ignoring: %m",
+ ifindex);
+
+ if (strv_contains(alternative_names, name)) {
+ r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
if (r < 0)
- return r;
+ return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
+ name, ifindex);
+
+ if_indextoname(ifindex, old_name);
}
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
@@ -32,6 +49,13 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
if (r < 0)
return r;
+ if (!isempty(old_name)) {
+ r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name));
+ if (r < 0)
+ log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m",
+ old_name, ifindex);
+ }
+
return 0;
}

View File

@ -0,0 +1,46 @@
From 817a707daf1e9fa4f20eba04ce1c52af7518e355 Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Date: Fri, 17 Jul 2020 21:36:05 +0900
Subject: [PATCH] udev: do not try to reassign alternative names
Setting alternative names may fail if some of them are already assigned.
(cherry picked from commit 97fdae33dfe8e7e0a4e5230564f6cdebc4450eec)
Related: #1850986
---
src/udev/net/link-config.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 8bd374d352..5220f247f0 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -350,7 +350,7 @@ static int get_mac(struct udev_device *device, bool want_random,
int link_config_apply(link_config_ctx *ctx, link_config *config,
struct udev_device *device, const char **name) {
- _cleanup_strv_free_ char **altnames = NULL;
+ _cleanup_strv_free_ char **altnames = NULL, **current_altnames = NULL;
bool respect_predictable = false;
struct ether_addr generated_mac;
struct ether_addr *mac = NULL;
@@ -514,9 +514,17 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (new_name)
strv_remove(altnames, new_name);
strv_remove(altnames, old_name);
+
+ r = rtnl_get_link_alternative_names(&ctx->rtnl, ifindex, &current_altnames);
+ if (r < 0)
+ log_debug_errno(r, "Failed to get alternative names on %s, ignoring: %m", old_name);
+
+ char **p;
+ STRV_FOREACH(p, current_altnames)
+ strv_remove(altnames, *p);
+
strv_uniq(altnames);
strv_sort(altnames);
-
r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames);
if (r == -EOPNOTSUPP)
log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name);

View File

@ -0,0 +1,37 @@
From 93c42f4da4563d225e3a2b9e72e8f9bb50d86bb1 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Fri, 17 Sep 2021 15:10:03 +0200
Subject: [PATCH] Fix LGTM build
Related: #1850986
---
src/network/netdev/netdev.c | 2 +-
src/network/networkd-network.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index 82ce88402f..e97cc07028 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -640,7 +640,7 @@ static int netdev_load_one(Manager *manager, const char *filename) {
netdev_raw->match_host, netdev_raw->match_virt,
netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version,
netdev_raw->match_arch,
- NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;
if (netdev_raw->kind == _NETDEV_KIND_INVALID) {
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 429aac5e6c..7637d135a4 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -479,7 +479,7 @@ int network_get(Manager *manager, struct udev_device *device,
network->match_virt, network->match_kernel_cmdline,
network->match_kernel_version, network->match_arch,
address, path, parent_driver, driver,
- devtype, ifname)) {
+ devtype, ifname, NULL)) {
if (network->match_name && device) {
const char *attr;
uint8_t name_assign_type = NET_NAME_UNKNOWN;

View File

@ -0,0 +1,33 @@
From cd407514366a2ec2c32ebc7a5b405d37005456fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Tue, 20 Oct 2020 17:12:42 +0200
Subject: [PATCH] sd-hwdb: allow empty properties
So far we didn't allow empty properties, but it makes sense to do so, for
example to distinguish empty data from lack of data. It also makes it easy to
override properties (back to the empty) value for specific cases.
(cherry picked from commit afe87974dd57741f74dd87165b251886f24c859f)
Related: #1930568
---
src/hwdb/hwdb.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index 317cad8a67..af085cdb75 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -462,10 +462,9 @@ static int insert_data(struct trie *trie, char **match_list, char *line,
while (isblank(line[0]) && isblank(line[1]))
line++;
- if (isempty(line + 1) || isempty(value))
+ if (isempty(line + 1))
return log_syntax(NULL, LOG_WARNING, filename, line_number, EINVAL,
- "Empty %s in \"%s=%s\", ignoring",
- isempty(line + 1) ? "key" : "value",
+ "Empty key in \"%s=%s\", ignoring",
line, value);
STRV_FOREACH(entry, match_list)

104589
SOURCES/0658-Update-hwdb.patch Normal file

File diff suppressed because it is too large Load Diff

View File

@ -105,5 +105,7 @@ fi
# This script will automatically apply binfmt rules if files have been
# installed or updated in /usr/lib/binfmt.d.
if test -d /run/systemd/system; then
/usr/lib/systemd/systemd-binfmt
# systemd-binfmt might fail if binfmt_misc kernel module is not loaded
# during install
/usr/lib/systemd/systemd-binfmt || :
fi

View File

@ -13,7 +13,7 @@
Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 239
Release: 45%{?dist}.3
Release: 51%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -616,21 +616,100 @@ Patch0563: 0563-pam-systemd-use-secure_getenv-rather-than-getenv.patch
Patch0564: 0564-Revert-udev-run-link_update-with-increased-retry-cou.patch
Patch0565: 0565-Revert-udev-make-algorithm-that-selects-highest-prio.patch
Patch0566: 0566-test-udev-test.pl-drop-test-cases-that-add-mutliple-.patch
Patch0567: 0567-basic-unit-name-do-not-use-strdupa-on-a-path.patch
Patch0568: 0568-sd-event-change-ordering-of-pending-ratelimited-even.patch
Patch0569: 0569-sd-event-drop-unnecessary-else.patch
Patch0570: 0570-sd-event-use-CMP-macro.patch
Patch0571: 0571-sd-event-use-usec_add.patch
Patch0572: 0572-sd-event-make-event_source_time_prioq_reshuffle-acce.patch
Patch0573: 0573-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch
Patch0574: 0574-meson-remove-strange-dep-that-causes-meson-to-enter-.patch
Patch0575: 0575-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch
Patch0576: 0576-ci-run-unit-tests-on-z-stream-branches-as-well.patch
Patch0577: 0577-remove-a-left-over-break.patch
Patch0567: 0567-cgroup-Also-set-io.bfq.weight.patch
Patch0568: 0568-seccomp-allow-turning-off-of-seccomp-filtering-via-e.patch
Patch0569: 0569-meson-remove-strange-dep-that-causes-meson-to-enter-.patch
Patch0570: 0570-copy-handle-copy_file_range-weirdness-on-procfs-sysf.patch
Patch0571: 0571-core-Hide-Deactivated-successfully-message.patch
Patch0572: 0572-util-rework-in_initrd-to-make-use-of-path_is_tempora.patch
Patch0573: 0573-initrd-extend-SYSTEMD_IN_INITRD-to-accept-non-ramfs-.patch
Patch0574: 0574-initrd-do-a-debug-log-if-failed-to-detect-rootfs-typ.patch
Patch0575: 0575-initrd-do-a-debug-log-if-etc-initrd-release-doesn-t-.patch
Patch0576: 0576-units-assign-user-runtime-dir-.service-to-user-i.sli.patch
Patch0577: 0577-units-order-user-runtime-dir-.service-after-systemd-.patch
Patch0578: 0578-units-make-sure-user-runtime-dir-.service-is-Type-on.patch
Patch0579: 0579-user-runtime-dir-downgrade-a-few-log-messages-to-LOG.patch
Patch0580: 0580-shared-install-Preserve-escape-characters-for-escape.patch
Patch0581: 0581-basic-virt-Detect-PowerVM-hypervisor.patch
Patch0582: 0582-man-document-differences-in-clean-exit-status-for-Ty.patch
Patch0583: 0583-busctl-add-a-timestamp-to-the-output-of-the-busctl-m.patch
Patch0584: 0584-basic-cap-list-parse-print-numerical-capabilities.patch
Patch0585: 0585-shared-mount-util-convert-to-libmount.patch
Patch0586: 0586-mount-util-bind_remount-avoid-calling-statvfs.patch
Patch0587: 0587-mount-util-use-UMOUNT_NOFOLLOW-in-recursive-umounter.patch
Patch0588: 0588-test-install-root-create-referenced-targets.patch
Patch0589: 0589-install-warn-if-WantedBy-targets-don-t-exist.patch
Patch0590: 0590-test-install-root-add-test-for-unknown-WantedBy-targ.patch
Patch0591: 0591-ceph-is-a-network-filesystem.patch
Patch0592: 0592-sysctl-set-kernel.core_pipe_limit-16.patch
Patch0593: 0593-core-don-t-drop-timer-expired-but-not-yet-processed-.patch
Patch0594: 0594-core-Detect-initial-timer-state-from-serialized-data.patch
Patch0595: 0595-rc-local-order-after-network-online.target.patch
Patch0596: 0596-set-core-ulimit-to-0-like-on-RHEL-7.patch
Patch0597: 0597-test-mountpointutil-util-do-not-assert-in-test_mnt_i.patch
Patch0598: 0598-remove-a-left-over-break.patch
Patch0599: 0599-basic-unit-name-do-not-use-strdupa-on-a-path.patch
Patch0600: 0600-sd-event-change-ordering-of-pending-ratelimited-even.patch
Patch0601: 0601-sd-event-drop-unnecessary-else.patch
Patch0602: 0602-sd-event-use-CMP-macro.patch
Patch0603: 0603-sd-event-use-usec_add.patch
Patch0604: 0604-sd-event-make-event_source_time_prioq_reshuffle-acce.patch
Patch0605: 0605-sd-event-always-reshuffle-time-prioq-on-changing-onl.patch
Patch0606: 0606-ci-run-unit-tests-on-z-stream-branches-as-well.patch
Patch0607: 0607-ci-drop-forgotten-Travis-references.patch
Patch0608: 0608-ci-run-unit-tests-on-CentOS-8-Stream-as-well.patch
Patch0609: 0609-ci-add-missing-test-dependencies.patch
Patch0610: 0610-meson-bump-timeout-for-test-udev-to-180s.patch
Patch0611: 0611-Added-option-check-inhibitors-for-non-tty-usage.patch
Patch0612: 0612-logind-Introduce-RebootWithFlags-and-others.patch
Patch0613: 0613-logind-add-WithFlags-methods-to-policy.patch
Patch0614: 0614-logind-simplify-flags-handling-a-bit.patch
Patch0615: 0615-Update-link-to-RHEL-documentation.patch
Patch0616: 0616-Set-default-core-ulimit-to-0-but-keep-the-hard-limit.patch
Patch0617: 0617-shared-seccomp-util-address-family-filtering-is-brok.patch
Patch0618: 0618-logind-rework-Seat-Session-User-object-allocation-an.patch
Patch0619: 0619-logind-fix-serialization-deserialization-of-user-s-d.patch
Patch0620: 0620-logind-turn-of-stdio-locking-when-writing-session-fi.patch
Patch0621: 0621-units-set-StopWhenUnneeded-for-the-user-slice-units-.patch
Patch0622: 0622-units-improve-Description-string-a-bit.patch
Patch0623: 0623-logind-improve-logging-in-manager_connect_console.patch
Patch0624: 0624-logind-save-restore-User-object-s-stopping-field-dur.patch
Patch0625: 0625-logind-correct-bad-clean-up-path.patch
Patch0626: 0626-logind-fix-bad-error-propagation.patch
Patch0627: 0627-logind-never-elect-a-session-that-is-stopping-as-dis.patch
Patch0628: 0628-logind-introduce-little-helper-that-checks-whether-a.patch
Patch0629: 0629-logind-propagate-session-stop-errors.patch
Patch0630: 0630-logind-rework-how-we-manage-the-slice-and-user-runti.patch
Patch0631: 0631-logind-optionally-keep-the-user-.service-instance-fo.patch
Patch0632: 0632-logind-add-a-RequiresMountsFor-dependency-from-the-s.patch
Patch0633: 0633-logind-improve-error-propagation-of-user_check_linge.patch
Patch0634: 0634-logind-automatically-GC-lingering-users-for-who-now-.patch
Patch0635: 0635-pam_systemd-simplify-code-which-with-we-set-environm.patch
Patch0636: 0636-logind-validate-run-user-1000-before-we-set-it.patch
Patch0637: 0637-define-newly-needed-constants.patch
Patch0638: 0638-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch
Patch0639: 0639-sd-netlink-introduce-sd_netlink_message_read_strv.patch
Patch0640: 0640-sd-netlink-introduce-sd_netlink_message_append_strv.patch
Patch0641: 0641-test-add-a-test-for-sd_netlink_message_-append-read-.patch
Patch0642: 0642-util-introduce-ifname_valid_full.patch
Patch0643: 0643-rename-function.patch
Patch0644: 0644-udev-support-AlternativeName-setting-in-.link-file.patch
Patch0645: 0645-network-make-Name-in-Match-support-alternative-names.patch
Patch0646: 0646-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch
Patch0647: 0647-udev-do-not-fail-if-kernel-does-not-support-alternat.patch
Patch0648: 0648-udev-introduce-AlternativeNamesPolicy-setting.patch
Patch0649: 0649-network-set-AlternativeNamesPolicy-in-99-default.lin.patch
Patch0650: 0650-random-util-call-initialize_srand-after-fork.patch
Patch0651: 0651-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch
Patch0652: 0652-udev-sort-alternative-names.patch
Patch0653: 0653-netlink-introduce-rtnl_get-delete_link_alternative_n.patch
Patch0654: 0654-netlink-do-not-fail-when-new-interface-name-is-alrea.patch
Patch0655: 0655-udev-do-not-try-to-reassign-alternative-names.patch
Patch0656: 0656-Fix-LGTM-build.patch
Patch0657: 0657-sd-hwdb-allow-empty-properties.patch
Patch0658: 0658-Update-hwdb.patch
# Security patches
%ifarch %{ix86} x86_64 aarch64
%global have_gnu_efi 1
%endif
@ -661,7 +740,6 @@ BuildRequires: libgpg-error-devel
BuildRequires: gnutls-devel
BuildRequires: libmicrohttpd-devel
BuildRequires: libxkbcommon-devel
BuildRequires: iptables-devel
BuildRequires: libxslt
BuildRequires: docbook-style-xsl
BuildRequires: pkgconfig
@ -683,6 +761,8 @@ Requires(post): coreutils
Requires(post): sed
Requires(post): acl
Requires(post): grep
# systemd-machine-id-setup requires libssl
Requires(post): openssl-libs
Requires(pre): coreutils
Requires(pre): /usr/bin/getent
Requires(pre): /usr/sbin/groupadd
@ -869,7 +949,7 @@ CONFIGURE_OPTS=(
-Dgnutls=true
-Dmicrohttpd=true
-Dlibidn2=true
-Dlibiptc=true
-Dlibiptc=false
-Dlibcurl=true
-Defi=true
-Dgnu-efi=%{?have_gnu_efi:true}%{?!have_gnu_efi:false}
@ -1089,16 +1169,14 @@ if [ -e /etc/fstab ]; then
sed -i.rpm.bak -r '/^devpts\s+\/dev\/pts\s+devpts\s+defaults\s+/d; /^tmpfs\s+\/dev\/shm\s+tmpfs\s+defaults\s+/d; /^sysfs\s+\/sys\s+sysfs\s+defaults\s+/d; /^proc\s+\/proc\s+proc\s+defaults\s+/d' /etc/fstab || :
fi
# Services we install by default, and which are controlled by presets.
# We reset the enablement of all services upon initial installation
# https://bugzilla.redhat.com/show_bug.cgi?id=1118740#c23
# This will fix up enablement of any preset services that got installed
# before systemd due to rpm ordering problems:
# Fedora: https://bugzilla.redhat.com/show_bug.cgi?id=1647172
# RHEL: https://bugzilla.redhat.com/show_bug.cgi?id=1783263
if [ $1 -eq 1 ] ; then
systemctl preset --quiet \
remote-fs.target \
getty@.service \
serial-getty@.service \
console-getty.service \
debug-shell.service \
systemd-resolved.service \
>/dev/null || :
systemctl preset-all &>/dev/null || :
fi
# remove obsolete systemd-readahead file
@ -1257,47 +1335,138 @@ fi
%files tests -f .file-list-tests
%changelog
* Wed Jul 28 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-45.3
- sd-event: change ordering of pending/ratelimited events (#1984406)
- sd-event: drop unnecessary "else" (#1984406)
- sd-event: use CMP() macro (#1984406)
- sd-event: use usec_add() (#1984406)
- sd-event: make event_source_time_prioq_reshuffle() accept all event source type (#1984406)
- sd-event: always reshuffle time prioq on changing online/offline state (#1984406)
- meson: remove strange dep that causes meson to enter infinite loop (#1984406)
- copy: handle copy_file_range() weirdness on procfs/sysfs (#1984406)
- ci: run unit tests on z-stream branches as well (#1984406)
- remove a left-over break (#1984406)
* Thu Sep 23 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-51
- define newly needed constants (#1850986)
- sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME attributes (#1850986)
- sd-netlink: introduce sd_netlink_message_read_strv() (#1850986)
- sd-netlink: introduce sd_netlink_message_append_strv() (#1850986)
- test: add a test for sd_netlink_message_{append,read}_strv() (#1850986)
- util: introduce ifname_valid_full() (#1850986)
- rename function (#1850986)
- udev: support AlternativeName= setting in .link file (#1850986)
- network: make Name= in [Match] support alternative names of interfaces (#1850986)
- udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ (#1850986)
- udev: do not fail if kernel does not support alternative names (#1850986)
- udev: introduce AlternativeNamesPolicy= setting (#1850986)
- network: set AlternativeNamesPolicy= in 99-default.link (#1850986)
- random-util: call initialize_srand() after fork() (#1850986)
- sd-netlink: introduce rtnl_resolve_link_alternative_names() (#1850986)
- udev: sort alternative names (#1850986)
- netlink: introduce rtnl_get/delete_link_alternative_names() (#1850986)
- netlink: do not fail when new interface name is already used as an alternative name (#1850986)
- udev: do not try to reassign alternative names (#1850986)
- Fix LGTM build (#1850986)
- sd-hwdb: allow empty properties (#1930568)
- Update hwdb (#1930568)
* Mon Jun 28 2021 Jan Macku <jamacku@redhat.com> - 239-45.2
- basic/unit-name: do not use strdupa() on a path (CVE-2021-33910, #1974699)
* Fri Aug 27 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-50
- Added option --check-inhibitors for non-tty usage (#1269726)
- logind: Introduce RebootWithFlags and others (#1269726)
- logind: add …WithFlags methods to policy (#1269726)
- logind: simplify flags handling a bit (#1269726)
- Update link to RHEL documentation (#1982584)
- Set default core ulimit to 0, but keep the hard limit ulimited (#1905582)
- shared/seccomp-util: address family filtering is broken on ppc (#1982650)
- logind: rework Seat/Session/User object allocation and freeing a bit (#1642460)
- logind: fix serialization/deserialization of user's "display session" (#1642460)
- logind: turn of stdio locking when writing session files too (#1642460)
- units: set StopWhenUnneeded= for the user slice units too (#1642460)
- units: improve Description= string a bit (#1642460)
- logind: improve logging in manager_connect_console() (#1642460)
- logind: save/restore User object's "stopping" field during restarts (#1642460)
- logind: correct bad clean-up path (#1642460)
- logind: fix bad error propagation (#1642460)
- logind: never elect a session that is stopping as display (#1642460)
- logind: introduce little helper that checks whether a session is ready (#1642460)
- logind: propagate session stop errors (#1642460)
- logind: rework how we manage the slice and user-runtime-dir@.service unit for each user (#1642460)
- logind: optionally, keep the user@.service instance for eached logged in user around for a while (#1642460)
- logind: add a RequiresMountsFor= dependency from the session scope unit to the home directory of the user (#1642460)
- logind: improve error propagation of user_check_linger_file() (#1642460)
- logind: automatically GC lingering users for who now user@.service (nor slice, not runtime dir service) is running anymore (#1642460)
- pam_systemd: simplify code which with we set environment variables (#1642460)
- logind: validate /run/user/1000 before we set it (#1642460)
* Tue May 25 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-45.1
- Revert "udev: run link_update() with increased retry count in second invocation" (#1963980)
- Revert "udev: make algorithm that selects highest priority devlink less susceptible to race conditions" (#1963980)
- test/udev-test.pl: drop test cases that add mutliple devices (#1963980)
* Fri Jul 23 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-49
- remove a left-over break (#1970860)
- basic/unit-name: do not use strdupa() on a path (#1974700)
- sd-event: change ordering of pending/ratelimited events (#1968528)
- sd-event: drop unnecessary "else" (#1968528)
- sd-event: use CMP() macro (#1968528)
- sd-event: use usec_add() (#1968528)
- sd-event: make event_source_time_prioq_reshuffle() accept all event source type (#1968528)
- sd-event: always reshuffle time prioq on changing online/offline state (#1968528)
- ci: run unit tests on z-stream branches as well (#1970860)
- ci: drop forgotten Travis references (#1934504)
- ci: run unit tests on CentOS 8 Stream as well (#1934504)
- ci: add missing test dependencies (#1934504)
- meson: bump timeout for test-udev to 180s (#1934504)
* Thu Jun 24 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-48
- cgroup: Also set io.bfq.weight (#1927290)
- seccomp: allow turning off of seccomp filtering via env var (#1916835)
- meson: remove strange dep that causes meson to enter infinite loop (#1970860)
- copy: handle copy_file_range() weirdness on procfs/sysfs (#1970860)
- core: Hide "Deactivated successfully" message (#1954802)
- util: rework in_initrd() to make use of path_is_temporary_fs() (#1959339)
- initrd: extend SYSTEMD_IN_INITRD to accept non-ramfs rootfs (#1959339)
- initrd: do a debug log if failed to detect rootfs type (#1959339)
- initrd: do a debug log if /etc/initrd-release doesn't take effect (#1959339)
- units: assign user-runtime-dir@.service to user-%i.slice (#1946453)
- units: order user-runtime-dir@.service after systemd-user-sessions.service (#1946453)
- units: make sure user-runtime-dir@.service is Type=oneshot (#1946453)
- user-runtime-dir: downgrade a few log messages to LOG_DEBUG that we ignore (#1946453)
- shared/install: Preserve escape characters for escaped unit names (#1952686)
- basic/virt: Detect PowerVM hypervisor (#1937989)
- man: document differences in clean exit status for Type=oneshot (#1940078)
- busctl: add a timestamp to the output of the busctl monitor command (#1909214)
- basic/cap-list: parse/print numerical capabilities (#1946943)
- shared/mount-util: convert to libmount (#1885143)
- mount-util: bind_remount: avoid calling statvfs (#1885143)
- mount-util: use UMOUNT_NOFOLLOW in recursive umounter (#1885143)
- test-install-root: create referenced targets (#1835351)
- install: warn if WantedBy targets don't exist (#1835351)
- test-install-root: add test for unknown WantedBy= target (#1835351)
- ceph is a network filesystem (#1952013)
- sysctl: set kernel.core_pipe_limit=16 (#1949729)
- core: don't drop timer expired but not yet processed when system date is changed (#1899402)
- core: Detect initial timer state from serialized data (#1899402)
- rc-local: order after network-online.target (#1934028)
- set core ulimit to 0 like on RHEL-7 (#1905582)
- test-mountpointutil-util: do not assert in test_mnt_id() (#1910425)
* Fri Jun 04 2021 Jan Macku <jamacku@redhat.com> - 239-47
- systemd-binfmt: Add safeguard in triggers (#1787144)
- spec: Requires(post) openssl-libs to fix missing /etc/machine-id (#1947438)
- spec: Go back to using systemctl preset-all in post (#1783263, #1647172, #1118740)
- spec: Disable libiptc support (#1817265)
* Wed May 19 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-46
- Revert "udev: run link_update() with increased retry count in second invocation" (#1942299)
- Revert "udev: make algorithm that selects highest priority devlink less susceptible to race conditions" (#1942299)
- test/udev-test.pl: drop test cases that add mutliple devices (#1942299)
* Thu Mar 11 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-45
- Revert "test: add test cases for empty string match" and "test: add test case for multi matches when use ||" (#1931947)
- test/sys-script.py: add missing DEVNAME entries to uevents (#1931947)
- sd-event: split out helper functions for reshuffling prioqs (#1819868)
- sd-event: split out enable and disable codepaths from sd_event_source_set_enabled() (#1819868)
- sd-event: mention that two debug logged events are ignored (#1819868)
- sd-event: split clock data allocation out of sd_event_add_time() (#1819868)
- sd-event: split out code to add/remove timer event sources to earliest/latest prioq (#1819868)
- sd-event: fix delays assert brain-o (#17790) (#1819868)
- sd-event: let's suffix last_run/last_log with "_usec" (#1819868)
- sd-event: refuse running default event loops in any other thread than the one they are default for (#1819868)
- sd-event: ref event loop while in sd_event_prepare() ot sd_event_run() (#1819868)
- sd-event: follow coding style with naming return parameter (#1819868)
- sd-event: remove earliest_index/latest_index into common part of event source objects (#1819868)
- sd-event: update state at the end in event_source_enable (#1819868)
- sd-event: increase n_enabled_child_sources just once (#1819868)
- sd-event: add ability to ratelimit event sources (#1819868)
- test: add ratelimiting test (#1819868)
- core: prevent excessive /proc/self/mountinfo parsing (#1819868)
- udev: run link_update() with increased retry count in second invocation (#1931947)
- pam-systemd: use secure_getenv() rather than getenv() (#1687514)
- Revert "test: add test cases for empty string match" and "test: add test case for multi matches when use ||" (#1935124)
- test/sys-script.py: add missing DEVNAME entries to uevents (#1935124)
- sd-event: split out helper functions for reshuffling prioqs (#1937315)
- sd-event: split out enable and disable codepaths from sd_event_source_set_enabled() (#1937315)
- sd-event: mention that two debug logged events are ignored (#1937315)
- sd-event: split clock data allocation out of sd_event_add_time() (#1937315)
- sd-event: split out code to add/remove timer event sources to earliest/latest prioq (#1937315)
- sd-event: fix delays assert brain-o (#17790) (#1937315)
- sd-event: let's suffix last_run/last_log with "_usec" (#1937315)
- sd-event: refuse running default event loops in any other thread than the one they are default for (#1937315)
- sd-event: ref event loop while in sd_event_prepare() ot sd_event_run() (#1937315)
- sd-event: follow coding style with naming return parameter (#1937315)
- sd-event: remove earliest_index/latest_index into common part of event source objects (#1937315)
- sd-event: update state at the end in event_source_enable (#1937315)
- sd-event: increase n_enabled_child_sources just once (#1937315)
- sd-event: add ability to ratelimit event sources (#1937315)
- test: add ratelimiting test (#1937315)
- core: prevent excessive /proc/self/mountinfo parsing (#1937315)
- udev: run link_update() with increased retry count in second invocation (#1935124)
- pam-systemd: use secure_getenv() rather than getenv() (#1936866)
* Thu Jan 28 2021 systemd maintenance team <systemd-maint@redhat.com> - 239-44
- ci: PowerTools repo was renamed to powertools in RHEL 8.3 (#1871827)