Browse Source

systemd package update

Signed-off-by: basebuilder_pel7x64builder0 <basebuilder@powerel.org>
master
basebuilder_pel7x64builder0 6 years ago
parent
commit
5bd09e28fb
  1. 41
      SOURCES/0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch
  2. 28
      SOURCES/0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch
  3. 79
      SOURCES/0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch
  4. 27
      SOURCES/0617-man-udevadm-remove-superfluous-version-from-subcomma.patch
  5. 23
      SOURCES/0618-man-udevadm-correctly-show-the-short-version-of-exit.patch
  6. 30
      SOURCES/0619-core-timer-downgrade-message-about-random-time-addit.patch
  7. 277
      SOURCES/0620-fd-util-add-new-acquire_data_fd-API-helper.patch
  8. 189
      SOURCES/0621-systemd-analyze-make-dump-work-for-large-of-units.patch
  9. 27
      SOURCES/0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch
  10. 77
      SOURCES/0623-cryptsetup-support-LUKS2-on-disk-format.patch
  11. 56
      SOURCES/0624-core-scope-fix-missing-fragment_path.patch
  12. 27
      SOURCES/0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch
  13. 37
      SOURCES/0626-rules-disable-support-for-Lenovo-IR-cameras.patch
  14. 92
      SOURCES/0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch
  15. 247
      SOURCES/0628-core-fix-confusing-logging-of-instantaneous-jobs.patch
  16. 43
      SOURCES/0629-core-correct-return-value-from-reload-methods.patch
  17. 91
      SOURCES/0630-core-always-try-harder-to-get-unit-status-message-fo.patch
  18. 63
      SOURCES/0631-core-unit_get_status_message_format-never-returns-NU.patch
  19. 254
      SOURCES/0632-core-try-harder-to-get-job-completion-messages-too.patch
  20. 132
      SOURCES/0633-core-remove-generic-job-completion-messages-from-uni.patch
  21. 67
      SOURCES/0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch
  22. 42
      SOURCES/0635-core-log-completion-of-remaining-job-types.patch
  23. 75
      SOURCES/0636-core-adjust-job-completion-message-log-levels.patch
  24. 111
      SOURCES/0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch
  25. 42
      SOURCES/0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch
  26. 72
      SOURCES/0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
  27. 305
      SOURCES/0640-core-Implement-timeout-based-umount-remount-limit.patch
  28. 169
      SOURCES/0641-core-Implement-sync_with_progress.patch
  29. 48
      SOURCES/0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch
  30. 135
      SOURCES/0643-journal-forward-messages-from-dev-log-unmodified-to-.patch
  31. 158
      SOURCES/0644-tmpfiles-use-safe_glob.patch
  32. 52
      SOURCES/0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch
  33. 91
      SOURCES/0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch
  34. 188
      SOURCES/0647-fix-race-between-daemon-reload-and-other-commands.patch
  35. 223
      SOURCES/0648-core-delay-adding-target-dependencies-until-all-unit.patch
  36. 35
      SOURCES/0649-man-correct-the-meaning-of-TimeoutStopSec.patch
  37. 32
      SOURCES/0650-rules-mark-hotplugged-memory-as-movable.patch
  38. 27
      SOURCES/0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch
  39. 32
      SOURCES/0652-rules-disable-support-for-Dell-IR-cameras.patch
  40. 36
      SOURCES/0653-rpm-fix-systemd_user_post-macro.patch
  41. 35
      SOURCES/0654-rpm-remove-confusing-user-before-global.patch
  42. 58
      SOURCES/0655-automount-handle-state-changes-of-the-corresponding-.patch
  43. 32
      SOURCES/0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch
  44. 46
      SOURCES/0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch
  45. 25
      SOURCES/0658-Revert-rules-mark-hotplugged-memory-as-movable.patch
  46. 49
      SOURCES/0659-rules-implement-new-memory-hotplug-policy.patch
  47. 48
      SOURCES/0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch
  48. 258
      SOURCES/0661-cryptsetup-generator-introduce-basic-keydev-support.patch
  49. 38
      SOURCES/0662-cryptsetup-generator-don-t-return-error-if-target-di.patch
  50. 62
      SOURCES/0663-cryptsetup-generator-allow-whitespace-characters-in-.patch
  51. 50
      SOURCES/0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch
  52. 122
      SPECS/systemd.spec

41
SOURCES/0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch

@ -0,0 +1,41 @@
From 38c68c3b13e278a77a4bd02d97f6b3f81db46288 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 27 Mar 2018 10:34:06 +0200
Subject: [PATCH] tmpfiles: don't skip cleanup of read-only root owned files if
TMPFILES_AGE_ALL is set

Resolves: #1533638
---
src/tmpfiles/tmpfiles.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index ddb274fce..5212d72f5 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -367,6 +367,7 @@ static int dir_cleanup(
struct stat s;
usec_t age;
_cleanup_free_ char *sub_path = NULL;
+ const char *e;
if (STR_IN_SET(dent->d_name, ".", ".."))
continue;
@@ -399,10 +400,13 @@ static int dir_cleanup(
continue;
}
- /* Do not delete read-only files owned by root */
- if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) {
- log_debug("Ignoring \"%s/%s\": read-only and owner by root.", p, dent->d_name);
- continue;
+ e = getenv("TMPFILES_AGE_ALL");
+ if (!e) {
+ /* Do not delete read-only files owned by root */
+ if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) {
+ log_debug("Ignoring \"%s/%s\": read-only and owner by root.", p, dent->d_name);
+ continue;
+ }
}
sub_path = strjoin(p, "/", dent->d_name, NULL);

28
SOURCES/0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch

@ -0,0 +1,28 @@
From cfa30c21a4e5324a43695fcf43fe984aed2a8a8e Mon Sep 17 00:00:00 2001
From: Lukas Nykryn <lnykryn@redhat.com>
Date: Mon, 26 Feb 2018 13:56:52 +0100
Subject: [PATCH] timer: we already got the trigger before, no need to call
UNIT_TRIGGER again

In d7b2f6ef we forgot to replace this occurence.

rhel-only

Resolves: #1549119
---
src/core/timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/timer.c b/src/core/timer.c
index 91d8db67e..0a264f60d 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -421,7 +421,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
case TIMER_UNIT_INACTIVE:
- base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
+ base = trigger->inactive_enter_timestamp.monotonic;
if (base <= 0)
base = t->last_trigger.monotonic;

79
SOURCES/0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch

@ -0,0 +1,79 @@
From fdc7b6b2af0b80e13bebae8d2f461f54cb71c9d2 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Fri, 27 Apr 2018 08:57:08 +0200
Subject: [PATCH] doc: fix links to binfmt_misc kernel documentation

Resolves: #1572244
---
man/binfmt.d.xml | 2 +-
src/test/test-util.c | 2 +-
units/proc-sys-fs-binfmt_misc.automount | 2 +-
units/proc-sys-fs-binfmt_misc.mount | 2 +-
units/systemd-binfmt.service.in | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml
index 5b63cfb4c..1a57517d0 100644
--- a/man/binfmt.d.xml
+++ b/man/binfmt.d.xml
@@ -67,7 +67,7 @@
<para>Each file contains a list of binfmt_misc kernel binary
format rules. Consult <ulink
- url="https://www.kernel.org/doc/Documentation/binfmt_misc.txt">binfmt_misc.txt</ulink>
+ url="https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst">binfmt_misc.rst</ulink>
for more information on registration of additional binary formats
and how to write rules.</para>
diff --git a/src/test/test-util.c b/src/test/test-util.c
index fcf5416c0..f2c52edce 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -1213,7 +1213,7 @@ static void test_files_same(void) {
static void test_is_valid_documentation_url(void) {
assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
- assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
+ assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst"));
assert_se(documentation_url_is_valid("file:/foo/foo"));
assert_se(documentation_url_is_valid("man:systemd.special(7)"));
assert_se(documentation_url_is_valid("info:bar"));
diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
index 6be38937b..b28bf9bb8 100644
--- a/units/proc-sys-fs-binfmt_misc.automount
+++ b/units/proc-sys-fs-binfmt_misc.automount
@@ -7,7 +7,7 @@
[Unit]
Description=Arbitrary Executable File Formats File System Automount Point
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+Documentation=https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
index 8c7c38631..8d22dc908 100644
--- a/units/proc-sys-fs-binfmt_misc.mount
+++ b/units/proc-sys-fs-binfmt_misc.mount
@@ -7,7 +7,7 @@
[Unit]
Description=Arbitrary Executable File Formats File System
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+Documentation=https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in
index 02dfe774d..e066f7fec 100644
--- a/units/systemd-binfmt.service.in
+++ b/units/systemd-binfmt.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Set Up Additional Binary Formats
Documentation=man:systemd-binfmt.service(8) man:binfmt.d(5)
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+Documentation=https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount

27
SOURCES/0617-man-udevadm-remove-superfluous-version-from-subcomma.patch

@ -0,0 +1,27 @@
From 5fa3a659c5d106734b3fa76270f048b8b2ea0194 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Fri, 23 Mar 2018 11:20:31 +0100
Subject: [PATCH] man/udevadm: remove superfluous --version from subcommand

Resolves: #1553076
---
man/udevadm.xml | 6 ------
1 file changed, 6 deletions(-)

diff --git a/man/udevadm.xml b/man/udevadm.xml
index 8ef9e23aa..99eae387f 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -187,12 +187,6 @@
<para>Cleanup the udev database.</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term><option>--version</option></term>
- <listitem>
- <para>Print version.</para>
- </listitem>
- </varlistentry>
<varlistentry>
<term><option>-h</option></term>
<term><option>--help</option></term>

23
SOURCES/0618-man-udevadm-correctly-show-the-short-version-of-exit.patch

@ -0,0 +1,23 @@
From 81725f613bebedc27f7ff763097bcb393f9c4bd9 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Wed, 7 Mar 2018 18:45:29 +0100
Subject: [PATCH] man/udevadm: correctly show the short version of --exit

Resolves: #1552712
---
man/udevadm.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/man/udevadm.xml b/man/udevadm.xml
index 99eae387f..e11c2cb2e 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -374,7 +374,7 @@
<para>Modify the internal state of the running udev daemon.</para>
<variablelist>
<varlistentry>
- <term><option>-x</option></term>
+ <term><option>-e</option></term>
<term><option>--exit</option></term>
<listitem>
<para>Signal and wait for systemd-udevd to exit.</para>

30
SOURCES/0619-core-timer-downgrade-message-about-random-time-addit.patch

@ -0,0 +1,30 @@
From 7adabea503fb86b3b33da17fe65a2b5a246fcac7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 5 Feb 2017 03:37:46 -0500
Subject: [PATCH] core/timer: downgrade message about random time addition
(#5229)

This seems like something that shouldn't be higher then debug level, even
if it does not get emitted too often.

Fixes #5228.

(cherry picked from commit 382852fd581efe3cc0ae11154102ab9f435adea1)
Resolves: #1587906
---
src/core/timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/timer.c b/src/core/timer.c
index 0a264f60d..d32b007c7 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -335,7 +335,7 @@ static void add_random(Timer *t, usec_t *v) {
else
*v += add;
- log_unit_info(UNIT(t)->id, "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
+ log_unit_debug(UNIT(t)->id, "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
}
static void timer_enter_waiting(Timer *t, bool initial) {

277
SOURCES/0620-fd-util-add-new-acquire_data_fd-API-helper.patch

@ -0,0 +1,277 @@
From 581edd240f8dd68b1dbb4070353ddb2059eb8a67 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 27 Oct 2017 10:56:42 +0200
Subject: [PATCH] fd-util: add new acquire_data_fd() API helper

All this function does is place some data in an in-memory read-only fd,
that may be read back to get the original data back.

Doing this in a way that works everywhere, given the different kernels
we support as well as different privilege levels is surprisingly
complex.

(cherry picked from commit a548e14d690133dd8cca2d5ab8082bb23259fd5f)

Related: #1446095
---
src/shared/util.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/shared/util.h | 10 ++++
src/test/test-util.c | 49 ++++++++++++++++
3 files changed, 215 insertions(+)

diff --git a/src/shared/util.c b/src/shared/util.c
index af0953273..982f5e044 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -95,6 +95,7 @@
#include "sparse-endian.h"
#include "conf-parser.h"
#include "cgroup-util.h"
+#include "memfd-util.h"
int saved_argc = 0;
char **saved_argv = NULL;
@@ -8893,3 +8894,158 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
return m / max;
}
+
+int acquire_data_fd(const void *data, size_t size, unsigned flags) {
+
+ char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+ _cleanup_close_pair_ int pipefds[2] = { -1, -1 };
+ char pattern[] = "/dev/shm/data-fd-XXXXXX";
+ _cleanup_close_ int fd = -1;
+ int isz = 0, r;
+ ssize_t n;
+ off_t f;
+
+ assert(data || size == 0);
+
+ /* Acquire a read-only file descriptor that when read from returns the specified data. This is much more
+ * complex than I wish it was. But here's why:
+ *
+ * a) First we try to use memfds. They are the best option, as we can seal them nicely to make them
+ * read-only. Unfortunately they require kernel 3.17, and – at the time of writing – we still support 3.14.
+ *
+ * b) Then, we try classic pipes. They are the second best options, as we can close the writing side, retaining
+ * a nicely read-only fd in the reading side. However, they are by default quite small, and unprivileged
+ * clients can only bump their size to a system-wide limit, which might be quite low.
+ *
+ * c) Then, we try an O_TMPFILE file in /dev/shm (that dir is the only suitable one known to exist from
+ * earliest boot on). To make it read-only we open the fd a second time with O_RDONLY via
+ * /proc/self/<fd>. Unfortunately O_TMPFILE is not available on older kernels on tmpfs.
+ *
+ * d) Finally, we try creating a regular file in /dev/shm, which we then delete.
+ *
+ * It sucks a bit that depending on the situation we return very different objects here, but that's Linux I
+ * figure. */
+
+ if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) {
+ /* As a special case, return /dev/null if we have been called for an empty data block */
+ r = open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (r < 0)
+ return -errno;
+
+ return r;
+ }
+
+ if ((flags & ACQUIRE_NO_MEMFD) == 0) {
+ fd = memfd_new("data-fd");
+ if (fd < 0)
+ goto try_pipe;
+
+ n = write(fd, data, size);
+ if (n < 0)
+ return -errno;
+ if ((size_t) n != size)
+ return -EIO;
+
+ f = lseek(fd, 0, SEEK_SET);
+ if (f != 0)
+ return -errno;
+
+ r = memfd_set_sealed(fd);
+ if (r < 0)
+ return r;
+
+ r = fd;
+ fd = -1;
+
+ return r;
+ }
+
+try_pipe:
+ if ((flags & ACQUIRE_NO_PIPE) == 0) {
+ if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0)
+ return -errno;
+
+ isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
+ if (isz < 0)
+ return -errno;
+
+ if ((size_t) isz < size) {
+ isz = (int) size;
+ if (isz < 0 || (size_t) isz != size)
+ return -E2BIG;
+
+ /* Try to bump the pipe size */
+ (void) fcntl(pipefds[1], F_SETPIPE_SZ, isz);
+
+ /* See if that worked */
+ isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
+ if (isz < 0)
+ return -errno;
+
+ if ((size_t) isz < size)
+ goto try_dev_shm;
+ }
+
+ n = write(pipefds[1], data, size);
+ if (n < 0)
+ return -errno;
+ if ((size_t) n != size)
+ return -EIO;
+
+ (void) fd_nonblock(pipefds[0], false);
+
+ r = pipefds[0];
+ pipefds[0] = -1;
+
+ return r;
+ }
+
+try_dev_shm:
+ if ((flags & ACQUIRE_NO_TMPFILE) == 0) {
+ fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500);
+ if (fd < 0)
+ goto try_dev_shm_without_o_tmpfile;
+
+ n = write(fd, data, size);
+ if (n < 0)
+ return -errno;
+ if ((size_t) n != size)
+ return -EIO;
+
+ /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
+ xsprintf(procfs_path, "/proc/self/fd/%i", fd);
+ r = open(procfs_path, O_RDONLY|O_CLOEXEC);
+ if (r < 0)
+ return -errno;
+
+ return r;
+ }
+
+try_dev_shm_without_o_tmpfile:
+ if ((flags & ACQUIRE_NO_REGULAR) == 0) {
+ fd = mkostemp_safe(pattern, O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ n = write(fd, data, size);
+ if (n < 0) {
+ r = -errno;
+ goto unlink_and_return;
+ }
+ if ((size_t) n != size) {
+ r = -EIO;
+ goto unlink_and_return;
+ }
+
+ /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
+ r = open(pattern, O_RDONLY|O_CLOEXEC);
+ if (r < 0)
+ r = -errno;
+
+ unlink_and_return:
+ (void) unlink(pattern);
+ return r;
+ }
+
+ return -EOPNOTSUPP;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 526a6fe84..9c4be0256 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1112,3 +1112,13 @@ int parse_percent(const char *p);
uint64_t system_tasks_max(void);
uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
+
+enum {
+ ACQUIRE_NO_DEV_NULL = 1 << 0,
+ ACQUIRE_NO_MEMFD = 1 << 1,
+ ACQUIRE_NO_PIPE = 1 << 2,
+ ACQUIRE_NO_TMPFILE = 1 << 3,
+ ACQUIRE_NO_REGULAR = 1 << 4,
+};
+
+int acquire_data_fd(const void *data, size_t size, unsigned flags);
diff --git a/src/test/test-util.c b/src/test/test-util.c
index f2c52edce..efb02ff53 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -1861,6 +1861,54 @@ static void test_system_tasks_max_scale(void) {
assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
}
+static void test_acquire_data_fd_one(unsigned flags) {
+ char wbuffer[196*1024 - 7];
+ char rbuffer[sizeof(wbuffer)];
+ int fd;
+
+ fd = acquire_data_fd("foo", 3, flags);
+ assert_se(fd >= 0);
+
+ zero(rbuffer);
+ assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 3);
+ assert_se(streq(rbuffer, "foo"));
+
+ fd = safe_close(fd);
+
+ fd = acquire_data_fd("", 0, flags);
+ assert_se(fd >= 0);
+
+ zero(rbuffer);
+ assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 0);
+ assert_se(streq(rbuffer, ""));
+
+ fd = safe_close(fd);
+
+ random_bytes(wbuffer, sizeof(wbuffer));
+
+ fd = acquire_data_fd(wbuffer, sizeof(wbuffer), flags);
+ assert_se(fd >= 0);
+
+ zero(rbuffer);
+ assert_se(read(fd, rbuffer, sizeof(rbuffer)) == sizeof(rbuffer));
+ assert_se(memcmp(rbuffer, wbuffer, sizeof(rbuffer)) == 0);
+
+ fd = safe_close(fd);
+}
+
+static void test_acquire_data_fd(void) {
+
+ test_acquire_data_fd_one(0);
+ test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL);
+ test_acquire_data_fd_one(ACQUIRE_NO_MEMFD);
+ test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD);
+ test_acquire_data_fd_one(ACQUIRE_NO_PIPE);
+ test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_PIPE);
+ test_acquire_data_fd_one(ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
+ test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
+ test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE|ACQUIRE_NO_TMPFILE);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -1943,6 +1991,7 @@ int main(int argc, char *argv[]) {
test_shell_maybe_quote();
test_system_tasks_max();
test_system_tasks_max_scale();
+ test_acquire_data_fd();
return 0;
}

189
SOURCES/0621-systemd-analyze-make-dump-work-for-large-of-units.patch

@ -0,0 +1,189 @@
From 6772555b226a116bff07b7d8af28b16032273866 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 9 May 2018 09:35:52 +0200
Subject: [PATCH] systemd-analyze: make dump work for large # of units

If there is a large number of units, the size of the generated dump
string can overstep DBus message size limit. So let's pass that string
via a fd.

(cherry picked from commit c0a1bfacfea9c65ea79fd07682a5b60b5d711a33)

Resolves: #1446095
---
src/analyze/analyze.c | 57 ++++++++++++++++++++++++++++------
src/core/dbus-manager.c | 26 ++++++++++++++--
src/core/org.freedesktop.systemd1.conf | 4 +++
3 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index ff84f6894..7116aaa88 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -29,6 +29,7 @@
#include "sd-bus.h"
#include "bus-util.h"
#include "bus-error.h"
+#include "copy.h"
#include "install.h"
#include "log.h"
#include "build.h"
@@ -1096,12 +1097,42 @@ static int dot(sd_bus *bus, char* patterns[]) {
return 0;
}
-static int dump(sd_bus *bus, char **args) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+static int dump_fallback(sd_bus *bus) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
const char *text = NULL;
int r;
+ assert(bus);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "Dump",
+ &error,
+ &reply,
+ "");
+ if (r < 0) {
+ log_error("Failed to issue method call Dump: %s", bus_error_message(&error, -r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply, "s", &text);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ fputs(text, stdout);
+ return 0;
+}
+
+static int dump(sd_bus *bus, char **args) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ int fd = -1;
+ int r;
+
if (!strv_isempty(args)) {
log_error("Too many arguments.");
return -E2BIG;
@@ -1109,26 +1140,34 @@ static int dump(sd_bus *bus, char **args) {
pager_open_if_enabled();
+ if (!sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD))
+ return dump_fallback(bus);
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "Dump",
+ "DumpByFileDescriptor",
&error,
&reply,
"");
if (r < 0) {
- log_error("Failed issue method call: %s", bus_error_message(&error, -r));
- return r;
+ /* fall back to Dump if DumpByFileDescriptor is not supported */
+ if (!IN_SET(r, -EACCES, -EBADR)) {
+ log_error("Failed to issue method call DumpByFileDescriptor: %s", bus_error_message(&error, -r));
+ return r;
+ }
+
+ return dump_fallback(bus);
}
- r = sd_bus_message_read(reply, "s", &text);
+ r = sd_bus_message_read(reply, "h", &fd);
if (r < 0)
return bus_log_parse_error(r);
- fputs(text, stdout);
- return 0;
+ fflush(stdout);
+ return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
}
static int set_log_level(sd_bus *bus, char **args) {
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index d34ed042f..1766163b3 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1064,7 +1064,7 @@ static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userda
return sd_bus_reply_method_return(message, NULL);
}
-static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int dump_impl(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, int (*reply)(sd_bus_message *, char *)) {
_cleanup_free_ char *dump = NULL;
_cleanup_fclose_ FILE *f = NULL;
Manager *m = userdata;
@@ -1089,13 +1089,34 @@ static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
manager_dump_jobs(m, f, NULL);
fflush(f);
-
if (ferror(f))
return -ENOMEM;
+ return reply(message, dump);
+}
+
+static int reply_dump(sd_bus_message *message, char *dump) {
return sd_bus_reply_method_return(message, "s", dump);
}
+static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return dump_impl(bus, message, userdata, error, reply_dump);
+}
+
+static int reply_dump_by_fd(sd_bus_message *message, char *dump) {
+ _cleanup_close_ int fd = -1;
+
+ fd = acquire_data_fd(dump, strlen(dump), 0);
+ if (fd < 0)
+ return fd;
+
+ return sd_bus_reply_method_return(message, "h", fd);
+}
+
+static int method_dump_by_fd(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ return dump_impl(bus, message, userdata, error, reply_dump_by_fd);
+}
+
static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *path = NULL;
Manager *m = userdata;
@@ -2092,6 +2113,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("DumpByFileDescriptor", NULL, "h", method_dump_by_fd, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
index 3997dd0b4..8187cf173 100644
--- a/src/core/org.freedesktop.systemd1.conf
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -96,6 +96,10 @@
send_interface="org.freedesktop.systemd1.Manager"
send_member="Dump"/>
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
+ send_member="DumpByFileDescriptor"/>
+
<allow send_destination="org.freedesktop.systemd1"
send_interface="org.freedesktop.systemd1.Manager"
send_member="GetDefaultTarget"/>

27
SOURCES/0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch

@ -0,0 +1,27 @@
From 191e504e9847ba3f46fe579922bbee64f02a04c1 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Wed, 9 May 2018 10:33:28 +0200
Subject: [PATCH] use max. message size allowed by DBus spec (#8936)

C.f. https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages.

(cherry picked from commit 33d8fe60573dd3e88fe98e368437bb4d29534b5a)

Related: #1446095
---
src/libsystemd/sd-bus/bus-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 6a106862e..9c1e5a35b 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -329,7 +329,7 @@ struct sd_bus {
#define BUS_WQUEUE_MAX (192*1024)
#define BUS_RQUEUE_MAX (192*1024)
-#define BUS_MESSAGE_SIZE_MAX (64*1024*1024)
+#define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
#define BUS_AUTH_SIZE_MAX (64*1024)
#define BUS_CONTAINER_DEPTH 128

77
SOURCES/0623-cryptsetup-support-LUKS2-on-disk-format.patch

@ -0,0 +1,77 @@
From be973ab9f6585be762ea0888c81b011222eabb13 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Thu, 3 May 2018 11:21:27 +0200
Subject: [PATCH] cryptsetup: support LUKS2 on-disk format

Allow cryptsetup utility to activate LUKS2 devices (with appropriate
libcryptsetup)

The change itself doesn't enforce new libcryptsetup 2.x and is backward
compatible with versions 1.x

(cherry-picked from commit b3b4ebab02395933cde554b5a5d5c363dae3920d)

Resolves: #1573838
---
src/cryptsetup/cryptsetup.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 69a015614..528c36c48 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -36,7 +36,15 @@
#include "libudev.h"
#include "udev-util.h"
-static const char *arg_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */
+/* libcryptsetup define for any LUKS version, compatible with libcryptsetup 1.x */
+#ifndef CRYPT_LUKS
+#define CRYPT_LUKS NULL
+#endif
+
+/* internal helper */
+#define ANY_LUKS "LUKS"
+
+static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
static char *arg_cipher = NULL;
static unsigned arg_key_size = 0;
static int arg_key_slot = CRYPT_ANY_SLOT;
@@ -98,7 +106,7 @@ static int parse_one_option(const char *option) {
} else if (startswith(option, "key-slot=")) {
- arg_type = CRYPT_LUKS1;
+ arg_type = ANY_LUKS;
if (safe_atoi(option+9, &arg_key_slot) < 0) {
log_error("key-slot= parse failure, ignoring.");
return 0;
@@ -138,7 +146,7 @@ static int parse_one_option(const char *option) {
arg_hash = t;
} else if (startswith(option, "header=")) {
- arg_type = CRYPT_LUKS1;
+ arg_type = ANY_LUKS;
if (!path_is_absolute(option+7)) {
log_error("Header path '%s' is not absolute, refusing.", option+7);
@@ -168,7 +176,7 @@ static int parse_one_option(const char *option) {
else if (STR_IN_SET(option, "allow-discards", "discard"))
arg_discards = true;
else if (streq(option, "luks"))
- arg_type = CRYPT_LUKS1;
+ arg_type = ANY_LUKS;
else if (streq(option, "tcrypt"))
arg_type = CRYPT_TCRYPT;
else if (streq(option, "tcrypt-hidden")) {
@@ -430,8 +438,8 @@ static int attach_luks_or_plain(struct crypt_device *cd,
assert(name);
assert(key_file || passwords);
- if (!arg_type || streq(arg_type, CRYPT_LUKS1)) {
- r = crypt_load(cd, CRYPT_LUKS1, NULL);
+ if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
+ r = crypt_load(cd, CRYPT_LUKS, NULL);
if (r < 0) {
log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
return r;

56
SOURCES/0624-core-scope-fix-missing-fragment_path.patch

@ -0,0 +1,56 @@
From f838bf376249b68205641d1736da2622c0279ed2 Mon Sep 17 00:00:00 2001
From: chenglin130 <cheng.lin130@zte.com.cn>
Date: Sat, 20 Jan 2018 17:45:27 +0800
Subject: [PATCH] core:scope: fix missing fragment_path

fragment_path in struct unit is a record of unit file, which will
be deleted (unlink) in unit_free().

After a daemon-reload process, the u->fragment_path of scope unit
will be missing (NULL). Then, the discarded session scope unit file
will be redundant until reboot.

Steps to Reproduce problem:
1. ssh access and login
2. systemctl daemon-reload
3. ssh logout
4. discarded session-xxx.scope file will be found in /run/systemd/system/

So in a daemon-reload case, scope_load() need unit_load_fragment() to reload
u->fragment_path.
---
src/core/load-fragment.c | 5 +++++
src/core/scope.c | 4 ++++
2 files changed, 9 insertions(+)

diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index da58bcc5c..f3d0851fe 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -3950,6 +3950,11 @@ int unit_load_fragment(Unit *u) {
assert(u->load_state == UNIT_STUB);
assert(u->id);
+ if (u->transient && u->fragment_path) {
+ u->load_state = UNIT_LOADED;
+ return 0;
+ }
+
/* First, try to find the unit under its id. We always look
* for unit files in the default directories, to make it easy
* to override things by placing things in /etc/systemd/system */
diff --git a/src/core/scope.c b/src/core/scope.c
index ae6614fbf..29954ba28 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -150,6 +150,10 @@ static int scope_load(Unit *u) {
if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
return -ENOENT;
+ r = unit_load_fragment(u);
+ if (r < 0)
+ return r;
+
u->load_state = UNIT_LOADED;
r = unit_load_dropin(u);

27
SOURCES/0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch

@ -0,0 +1,27 @@
From 5c62e7afe2197c7b5bb00ed70bc6960b49a0317e Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 18 Jan 2018 19:23:56 +0100
Subject: [PATCH] units: don't put udev to its own mount namespace with slave
propagation

Change in upstream was done mostly for political reasons to discourage
people from doing mounts in udev rules. RHEL is very bad place for
such experiments. Revert to default we shipped with RHEL-7 GA.

RHEL-only

Resolves: #1432211
---
units/systemd-udevd.service.in | 1 -
1 file changed, 1 deletion(-)

diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index 32f04d901..46b079515 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -21,5 +21,4 @@ Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
Restart=always
RestartSec=0
ExecStart=@rootlibexecdir@/systemd-udevd
-MountFlags=slave
KillMode=mixed

37
SOURCES/0626-rules-disable-support-for-Lenovo-IR-cameras.patch

@ -0,0 +1,37 @@
From 647615bfa4015336eb88f6cb44dc111f1d713df7 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 13 Jun 2018 14:33:18 +0200
Subject: [PATCH] rules: disable support for Lenovo IR cameras

Resolves: #1540418
---
Makefile.am | 1 +
rules/40-redhat-disable-lenovo-ir-camera.rules | 6 ++++++
2 files changed, 7 insertions(+)
create mode 100644 rules/40-redhat-disable-lenovo-ir-camera.rules

diff --git a/Makefile.am b/Makefile.am
index 8c73326fa..cbc120dad 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3522,6 +3522,7 @@ dist_udevrules_DATA += \
rules/80-net-setup-link.rules \
rules/95-udev-late.rules \
rules/40-redhat.rules \
+ rules/40-redhat-disable-lenovo-ir-camera.rules \
rules/73-idrac.rules \
rules/80-net-name-slot.rules
diff --git a/rules/40-redhat-disable-lenovo-ir-camera.rules b/rules/40-redhat-disable-lenovo-ir-camera.rules
new file mode 100644
index 000000000..ea326d4ab
--- /dev/null
+++ b/rules/40-redhat-disable-lenovo-ir-camera.rules
@@ -0,0 +1,6 @@
+# Disable known IR cameras in Lenovo Notebooks
+SUBSYSTEM=="usb", ATTRS{idVendor}=="5986", ATTRS{idProduct}=="211a", ATTR{authorized}="0"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="5986", ATTRS{idProduct}=="1141", ATTR{authorized}="0"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b605", ATTR{authorized}="0"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b613", ATTR{authorized}="0"
+SUBSYSTEM=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b615", ATTR{authorized}="0"
\ No newline at end of file

92
SOURCES/0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch

@ -0,0 +1,92 @@
From f7507f4bb5385ed0303451d812d220f14f341629 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 28 Jan 2016 18:48:42 +0100
Subject: [PATCH] core: make sure "systemctl reload-or-try-restart is actually
a noop if a unit is not running

This makes sure we follow the same basic logic for try-restart if we have a try-reload.

Fixes #688

(cherry picked from commit 3282591dc30b2934a895c7403d2f0b0690260947)
Resolves: #1191920
---
src/core/dbus-unit.c | 2 +-
src/core/job.c | 8 ++++++++
src/core/job.h | 3 +++
src/core/unit.c | 2 ++
4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 1d0d6f67c..f0f75e01b 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -850,7 +850,7 @@ int bus_unit_queue_job(
if (type == JOB_RESTART)
type = JOB_RELOAD_OR_START;
else if (type == JOB_TRY_RESTART)
- type = JOB_RELOAD;
+ type = JOB_TRY_RELOAD;
}
r = mac_selinux_unit_access_check(
diff --git a/src/core/job.c b/src/core/job.c
index 1617e24c0..c9a43a4cb 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -404,6 +404,13 @@ JobType job_type_collapse(JobType t, Unit *u) {
return JOB_RESTART;
+ case JOB_TRY_RELOAD:
+ s = unit_active_state(u);
+ if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+ return JOB_NOP;
+
+ return JOB_RELOAD;
+
case JOB_RELOAD_OR_START:
s = unit_active_state(u);
if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
@@ -1212,6 +1219,7 @@ static const char* const job_type_table[_JOB_TYPE_MAX] = {
[JOB_RELOAD_OR_START] = "reload-or-start",
[JOB_RESTART] = "restart",
[JOB_TRY_RESTART] = "try-restart",
+ [JOB_TRY_RELOAD] = "try-reload",
[JOB_NOP] = "nop",
};
diff --git a/src/core/job.h b/src/core/job.h
index ce81607de..535052b48 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -63,6 +63,9 @@ enum JobType {
* Thus we never need to merge it with anything. */
JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
+ /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
+ JOB_TRY_RELOAD,
+
/* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
* from transaction merging (there's no way for JOB_RELOAD and
* JOB_START to meet in one transaction). It can result from a merge
diff --git a/src/core/unit.c b/src/core/unit.c
index 41d7b63d7..6d535ae12 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1868,6 +1868,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
case JOB_RELOAD:
case JOB_RELOAD_OR_START:
+ case JOB_TRY_RELOAD:
if (u->job->state == JOB_RUNNING) {
if (ns == UNIT_ACTIVE)
@@ -2144,6 +2145,7 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
return unit_can_start(u);
case JOB_RELOAD:
+ case JOB_TRY_RELOAD:
return unit_can_reload(u);
case JOB_RELOAD_OR_START:

247
SOURCES/0628-core-fix-confusing-logging-of-instantaneous-jobs.patch

@ -0,0 +1,247 @@
From 7bc07eb6c9a31f2c26d0fe3e6d7a26a13cbb2369 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 16 Jul 2015 20:08:30 +0200
Subject: [PATCH] core: fix confusing logging of instantaneous jobs

For instantaneous jobs (e.g. starting of targets, sockets, slices, or
Type=simple services) the log shows the job completion
before starting:

systemd[1]: Created slice -.slice.
systemd[1]: Starting -.slice.
systemd[1]: Created slice System Slice.
systemd[1]: Starting System Slice.
systemd[1]: Listening on Journal Audit Socket.
systemd[1]: Starting Journal Audit Socket.
systemd[1]: Reached target Timers.
systemd[1]: Starting Timers.
...

The reason is that the job completes before the ->start() method returns
and only then does unit_start() print the "Starting ..." message.
The same thing happens when stopping units.

Rather than fixing the order of the messages, let's just not emit the
Starting/Stopping message at all when the job completes instantaneously.
The job completion message is sufficient in this case.

(cherry picked from commit d1a34ae9c20f1c02aab17884919eccef572b1d21)

Resolves: #1506256
---
src/core/job.c | 65 +++++++++++++++++++++++++++++++++++++++------------------
src/core/unit.c | 36 +++++++++++---------------------
src/core/unit.h | 1 +
3 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/src/core/job.c b/src/core/job.c
index c9a43a4cb..612caa604 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -504,10 +504,48 @@ static void job_change_type(Job *j, JobType newtype) {
j->type = newtype;
}
+static int job_perform_on_unit(Job **j) {
+ /* While we execute this operation the job might go away (for
+ * example: because it finishes immediately or is replaced by a new,
+ * conflicting job.) To make sure we don't access a freed job later on
+ * we store the id here, so that we can verify the job is still
+ * valid. */
+ Manager *m = (*j)->manager;
+ Unit *u = (*j)->unit;
+ JobType t = (*j)->type;
+ uint32_t id = (*j)->id;
+ int r;
+
+ switch (t) {
+ case JOB_START:
+ r = unit_start(u);
+ break;
+
+ case JOB_RESTART:
+ t = JOB_STOP;
+ case JOB_STOP:
+ r = unit_stop(u);
+ break;
+
+ case JOB_RELOAD:
+ r = unit_reload(u);
+ break;
+
+ default:
+ assert_not_reached("Invalid job type");
+ }
+
+ /* Log if the job still exists and the start/stop/reload function
+ * actually did something. */
+ *j = manager_get_job(m, id);
+ if (*j && r > 0)
+ unit_status_emit_starting_stopping_reloading(u, t);
+
+ return r;
+}
+
int job_run_and_invalidate(Job *j) {
int r;
- uint32_t id;
- Manager *m = j->manager;
assert(j);
assert(j->installed);
@@ -526,23 +564,9 @@ int job_run_and_invalidate(Job *j) {
job_set_state(j, JOB_RUNNING);
job_add_to_dbus_queue(j);
- /* While we execute this operation the job might go away (for
- * example: because it is replaced by a new, conflicting
- * job.) To make sure we don't access a freed job later on we
- * store the id here, so that we can verify the job is still
- * valid. */
- id = j->id;
switch (j->type) {
- case JOB_START:
- r = unit_start(j->unit);
-
- /* If this unit cannot be started, then simply wait */
- if (r == -EBADR)
- r = 0;
- break;
-
case JOB_VERIFY_ACTIVE: {
UnitActiveState t = unit_active_state(j->unit);
if (UNIT_IS_ACTIVE_OR_RELOADING(t))
@@ -554,17 +578,19 @@ int job_run_and_invalidate(Job *j) {
break;
}
+ case JOB_START:
case JOB_STOP:
case JOB_RESTART:
- r = unit_stop(j->unit);
+ r = job_perform_on_unit(&j);
- /* If this unit cannot stopped, then simply wait. */
+ /* If the unit type does not support starting/stopping,
+ * then simply wait. */
if (r == -EBADR)
r = 0;
break;
case JOB_RELOAD:
- r = unit_reload(j->unit);
+ r = job_perform_on_unit(&j);
break;
case JOB_NOP:
@@ -575,7 +601,6 @@ int job_run_and_invalidate(Job *j) {
assert_not_reached("Unknown job type");
}
- j = manager_get_job(m, id);
if (j) {
if (r == -EALREADY)
r = job_finish_and_invalidate(j, JOB_DONE, true, true);
diff --git a/src/core/unit.c b/src/core/unit.c
index 6d535ae12..907a4bf7f 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1417,6 +1417,15 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
NULL);
}
+void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) {
+
+ unit_status_log_starting_stopping_reloading(u, t);
+
+ /* Reload status messages have traditionally not been printed to console. */
+ if (t != JOB_RELOAD)
+ unit_status_print_starting_stopping(u, t);
+}
+
/* Errors:
* -EBADR: This unit type does not support starting.
* -EALREADY: Unit is already started.
@@ -1427,7 +1436,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
int unit_start(Unit *u) {
UnitActiveState state;
Unit *following;
- int r;
assert(u);
@@ -1481,14 +1489,7 @@ int unit_start(Unit *u) {
unit_add_to_dbus_queue(u);
- r = UNIT_VTABLE(u)->start(u);
- if (r <= 0)
- return r;
-
- /* Log if the start function actually did something */
- unit_status_log_starting_stopping_reloading(u, JOB_START);
- unit_status_print_starting_stopping(u, JOB_START);
- return r;
+ return UNIT_VTABLE(u)->start(u);
}
bool unit_can_start(Unit *u) {
@@ -1512,7 +1513,6 @@ bool unit_can_isolate(Unit *u) {
int unit_stop(Unit *u) {
UnitActiveState state;
Unit *following;
- int r;
assert(u);
@@ -1531,13 +1531,7 @@ int unit_stop(Unit *u) {
unit_add_to_dbus_queue(u);
- r = UNIT_VTABLE(u)->stop(u);
- if (r <= 0)
- return r;
-
- unit_status_log_starting_stopping_reloading(u, JOB_STOP);
- unit_status_print_starting_stopping(u, JOB_STOP);
- return r;
+ return UNIT_VTABLE(u)->stop(u);
}
/* Errors:
@@ -1548,7 +1542,6 @@ int unit_stop(Unit *u) {
int unit_reload(Unit *u) {
UnitActiveState state;
Unit *following;
- int r;
assert(u);
@@ -1575,12 +1568,7 @@ int unit_reload(Unit *u) {
unit_add_to_dbus_queue(u);
- r = UNIT_VTABLE(u)->reload(u);
- if (r <= 0)
- return r;
-
- unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
- return r;
+ return UNIT_VTABLE(u)->reload(u);
}
bool unit_can_reload(Unit *u) {
diff --git a/src/core/unit.h b/src/core/unit.h
index 85f52df18..480e2e95f 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -562,6 +562,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency d);
int unit_coldplug(Unit *u, Hashmap *deferred_work);
void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0);
+void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t);
bool unit_need_daemon_reload(Unit *u);

43
SOURCES/0629-core-correct-return-value-from-reload-methods.patch

@ -0,0 +1,43 @@
From bc54eb811caf738ee54867359f798dc0f4be9e7e Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Thu, 16 Jul 2015 21:39:56 +0200
Subject: [PATCH] core: correct return value from reload methods

Return 1 from *_reload() methods to signify "we did something", just
like in *_start(). This causes "Reloading foo..." messages to be logged.
"Reloaded foo." messages are already logged.

(cherry picked from commit 2d018ae23b838f050516d06859f50ecb9733d44b)

Related: #1506256
---
src/core/mount.c | 2 +-
src/core/service.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/mount.c b/src/core/mount.c
index a6d93b869..f726d9659 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1081,7 +1081,7 @@ static int mount_reload(Unit *u) {
assert(m->state == MOUNT_MOUNTED);
mount_enter_remounting(m);
- return 0;
+ return 1;
}
static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
diff --git a/src/core/service.c b/src/core/service.c
index 71ec5e37c..9622ce11f 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1939,7 +1939,7 @@ static int service_reload(Unit *u) {
assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED);
service_enter_reload(s);
- return 0;
+ return 1;
}
_pure_ static bool service_can_reload(Unit *u) {

91
SOURCES/0630-core-always-try-harder-to-get-unit-status-message-fo.patch

@ -0,0 +1,91 @@
From c571dc5f7d593a4526da9e19b35ae3d1ed11bfaa Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Mon, 20 Jul 2015 17:18:13 +0200
Subject: [PATCH] core: always try harder to get unit status message format
string

The starting/stopping messages are printed to the console only if the
corresponding format string is defined in the unit's vtable. To avoid
excessive messages on the console, the unit types whose start/stop
jobs are instantaneous had the format strings intentionally undefined.
When logging the same event to the journal, a fallback to generic
Starting/Stopping/Reloading messages is used.

The problem of excessive console messages with instantaneous jobs
is already resolved in a nicer way ("core: fix confusing logging of
instantaneous jobs"), so there's no longer a need to have two ways of
getting the format strings. Let's fold them into one function with
the fallback to generic message strings.

(cherry picked from commit a85ca902c9f7f5aa8f2f3e3299147733802cf09d)

Related: #1506256
---
src/core/unit.c | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)

diff --git a/src/core/unit.c b/src/core/unit.c
index 907a4bf7f..a33cbdf73 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1328,32 +1328,21 @@ static bool unit_assert_test(Unit *u) {
}
_pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
- const UnitStatusMessageFormats *format_table;
-
- assert(u);
- assert(t >= 0);
- assert(t < _JOB_TYPE_MAX);
-
- if (t != JOB_START && t != JOB_STOP)
- return NULL;
-
- format_table = &UNIT_VTABLE(u)->status_message_formats;
- if (!format_table)
- return NULL;
-
- return format_table->starting_stopping[t == JOB_STOP];
-}
-
-_pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
const char *format;
+ const UnitStatusMessageFormats *format_table;
assert(u);
assert(t >= 0);
assert(t < _JOB_TYPE_MAX);
- format = unit_get_status_message_format(u, t);
- if (format)
- return format;
+ if (t == JOB_START || t == JOB_STOP) {
+ format_table = &UNIT_VTABLE(u)->status_message_formats;
+ if (format_table) {
+ format = format_table->starting_stopping[t == JOB_STOP];
+ if (format)
+ return format;
+ }
+ }
/* Return generic strings */
if (t == JOB_START)
@@ -1371,9 +1360,6 @@ static void unit_status_print_starting_stopping(Unit *u, JobType t) {
assert(u);
- /* We only print status messages for selected units on
- * selected operations. */
-
format = unit_get_status_message_format(u, t);
if (!format)
return;
@@ -1398,7 +1384,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
/* We log status messages for all units and all operations. */
- format = unit_get_status_message_format_try_harder(u, t);
+ format = unit_get_status_message_format(u, t);
if (!format)
return;

63
SOURCES/0631-core-unit_get_status_message_format-never-returns-NU.patch

@ -0,0 +1,63 @@
From 0204371780cbcae7635544abc61846d33d04c317 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Mon, 20 Jul 2015 18:36:12 +0200
Subject: [PATCH] core: unit_get_status_message_format() never returns NULL

unit_get_status_message_format() is used only with one of JOB_START,
JOB_STOP, JOB_RELOAD, all of which have fallback message strings
defined, so the function may never return NULL.

(cherry picked from commit b5bf308ba50ab0bac0f0caec2d8e4d5c75c107d0)

Related: #1506256
---
src/core/unit.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/src/core/unit.c b/src/core/unit.c
index a33cbdf73..22d9beed7 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1332,10 +1332,9 @@ _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
const UnitStatusMessageFormats *format_table;
assert(u);
- assert(t >= 0);
- assert(t < _JOB_TYPE_MAX);
+ assert(t == JOB_START || t == JOB_STOP || t == JOB_RELOAD);
- if (t == JOB_START || t == JOB_STOP) {
+ if (t != JOB_RELOAD) {
format_table = &UNIT_VTABLE(u)->status_message_formats;
if (format_table) {
format = format_table->starting_stopping[t == JOB_STOP];
@@ -1349,10 +1348,8 @@ _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
return "Starting %s.";
else if (t == JOB_STOP)
return "Stopping %s.";
- else if (t == JOB_RELOAD)
+ else
return "Reloading %s.";
-
- return NULL;
}
static void unit_status_print_starting_stopping(Unit *u, JobType t) {
@@ -1361,8 +1358,6 @@ static void unit_status_print_starting_stopping(Unit *u, JobType t) {
assert(u);
format = unit_get_status_message_format(u, t);
- if (!format)
- return;
DISABLE_WARNING_FORMAT_NONLITERAL;
unit_status_printf(u, "", format);
@@ -1385,8 +1380,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
/* We log status messages for all units and all operations. */
format = unit_get_status_message_format(u, t);
- if (!format)
- return;
DISABLE_WARNING_FORMAT_NONLITERAL;
snprintf(buf, sizeof(buf), format, unit_description(u));

254
SOURCES/0632-core-try-harder-to-get-job-completion-messages-too.patch

@ -0,0 +1,254 @@
From 50ce13182e07af7f240c61d03bf113e86a269917 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 21 Jul 2015 14:54:24 +0200
Subject: [PATCH] core: try harder to get job completion messages too

This is similar to "core: always try harder to get unit status
message format string", but for job completion status messages.
It makes generic status messages applicable for printing to the console.
And it rewrites the functions in a more table-based style.

(cherry picked from commit aa49ab5f22c0fdc7a5381d4e452f40705f3d7bf8)

Related: #1506256
---
src/core/job.c | 192 ++++++++++++++++++++-------------------------------------
1 file changed, 68 insertions(+), 124 deletions(-)

diff --git a/src/core/job.c b/src/core/job.c
index 612caa604..f371f914d 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -622,156 +622,100 @@ int job_run_and_invalidate(Job *j) {
}
_pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
+ const char *format;
const UnitStatusMessageFormats *format_table;
+ static const char *const generic_finished_start_job[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = "Started %s.",
+ [JOB_TIMEOUT] = "Timed out starting %s.",
+ [JOB_FAILED] = "Failed to start %s.",
+ [JOB_DEPENDENCY] = "Dependency failed for %s.",
+ [JOB_ASSERT] = "Assertion failed for %s.",
+ [JOB_UNSUPPORTED] = "Starting of %s not supported.",
+ };
+ static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = "Stopped %s.",
+ [JOB_FAILED] = "Stopped (with error) %s.",
+ [JOB_TIMEOUT] = "Timed out stoppping %s.",
+ };
+ static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = "Reloaded %s.",
+ [JOB_FAILED] = "Reload failed for %s.",
+ [JOB_TIMEOUT] = "Timed out reloading %s.",
+ };
+ /* When verify-active detects the unit is inactive, report it.
+ * Most likely a DEPEND warning from a requisiting unit will
+ * occur next and it's nice to see what was requisited. */
+ static const char *const generic_finished_verify_active_job[_JOB_RESULT_MAX] = {
+ [JOB_SKIPPED] = "%s is not active.",
+ };
assert(u);
assert(t >= 0);
assert(t < _JOB_TYPE_MAX);
- format_table = &UNIT_VTABLE(u)->status_message_formats;
- if (!format_table)
- return NULL;
+ if (t == JOB_START || t == JOB_STOP || t == JOB_RESTART) {
+ format_table = &UNIT_VTABLE(u)->status_message_formats;
+ if (format_table) {
+ format = t == JOB_START ? format_table->finished_start_job[result] :
+ format_table->finished_stop_job[result];
+ if (format)
+ return format;
+ }
+ }
+ /* Return generic strings */
if (t == JOB_START)
- return format_table->finished_start_job[result];
+ return generic_finished_start_job[result];
else if (t == JOB_STOP || t == JOB_RESTART)
- return format_table->finished_stop_job[result];
-
- return NULL;
-}
-
-_pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
- const char *format;
-
- assert(u);
- assert(t >= 0);
- assert(t < _JOB_TYPE_MAX);
-
- format = job_get_status_message_format(u, t, result);
- if (format)
- return format;
-
- /* Return generic strings */
- if (t == JOB_START) {
- if (result == JOB_DONE)
- return "Started %s.";
- else if (result == JOB_TIMEOUT)
- return "Timed out starting %s.";
- else if (result == JOB_FAILED)
- return "Failed to start %s.";
- else if (result == JOB_DEPENDENCY)
- return "Dependency failed for %s.";
- else if (result == JOB_ASSERT)
- return "Assertion failed for %s.";
- else if (result == JOB_UNSUPPORTED)
- return "Starting of %s not supported.";
- } else if (t == JOB_STOP || t == JOB_RESTART) {
- if (result == JOB_DONE)
- return "Stopped %s.";
- else if (result == JOB_FAILED)
- return "Stopped (with error) %s.";
- else if (result == JOB_TIMEOUT)
- return "Timed out stoppping %s.";
- } else if (t == JOB_RELOAD) {
- if (result == JOB_DONE)
- return "Reloaded %s.";
- else if (result == JOB_FAILED)
- return "Reload failed for %s.";
- else if (result == JOB_TIMEOUT)
- return "Timed out reloading %s.";
- }
+ return generic_finished_stop_job[result];
+ else if (t == JOB_RELOAD)
+ return generic_finished_reload_job[result];
+ else if (t == JOB_VERIFY_ACTIVE)
+ return generic_finished_verify_active_job[result];
return NULL;
}
static void job_print_status_message(Unit *u, JobType t, JobResult result) {
const char *format;
+ static const char* const job_result_status_table[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF,
+ [JOB_TIMEOUT] = ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF,
+ [JOB_FAILED] = ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF,
+ [JOB_DEPENDENCY] = ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF,
+ [JOB_SKIPPED] = ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF,
+ [JOB_ASSERT] = ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF,
+ [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF,
+ };
assert(u);
assert(t >= 0);
assert(t < _JOB_TYPE_MAX);
- DISABLE_WARNING_FORMAT_NONLITERAL;
-
- if (t == JOB_START) {
- format = job_get_status_message_format(u, t, result);
- if (!format)
- return;
-
- switch (result) {
-
- case JOB_DONE:
- if (u->condition_result)
- unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
- break;
-
- case JOB_TIMEOUT:
- manager_flip_auto_status(u->manager, true);
- unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
- break;
-
- case JOB_FAILED: {
- _cleanup_free_ char *quoted = NULL;
-
- quoted = shell_maybe_quote(u->id);
-
- manager_flip_auto_status(u->manager, true);
- unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
- manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, "See 'systemctl status %s' for details.", strna(quoted));
- break;
- }
-
- case JOB_DEPENDENCY:
- manager_flip_auto_status(u->manager, true);
- unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format);
- break;
-
- case JOB_ASSERT:
- manager_flip_auto_status(u->manager, true);
- unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF, format);
- break;
-
- case JOB_UNSUPPORTED:
- manager_flip_auto_status(u->manager, true);
- unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF, format);
- break;
-
- default:
- ;
- }
-
- } else if (t == JOB_STOP || t == JOB_RESTART) {
-
- format = job_get_status_message_format(u, t, result);
- if (!format)
- return;
+ /* Reload status messages have traditionally not been printed to console. */
+ if (t == JOB_RELOAD)
+ return;
- switch (result) {
+ if (t == JOB_START && result == JOB_DONE && !u->condition_result)
+ return;
- case JOB_TIMEOUT:
- manager_flip_auto_status(u->manager, true);
- unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
- break;
+ format = job_get_status_message_format(u, t, result);
+ if (!format)
+ return;
- case JOB_DONE:
- case JOB_FAILED:
- unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
- break;
+ if (result != JOB_DONE)
+ manager_flip_auto_status(u->manager, true);
- default:
- ;
- }
+ DISABLE_WARNING_FORMAT_NONLITERAL;
+ unit_status_printf(u, job_result_status_table[result], format);
+ REENABLE_WARNING;
- } else if (t == JOB_VERIFY_ACTIVE) {
+ if (t == JOB_START && result == JOB_FAILED) {
+ _cleanup_free_ char *quoted = shell_maybe_quote(u->id);
- /* When verify-active detects the unit is inactive, report it.
- * Most likely a DEPEND warning from a requisiting unit will
- * occur next and it's nice to see what was requisited. */
- if (result == JOB_SKIPPED)
- unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.");
+ manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
+ "See 'systemctl status %s' for details.", strna(quoted));
}
-
- REENABLE_WARNING;
}
static void job_log_status_message(Unit *u, JobType t, JobResult result) {
@@ -788,7 +732,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
if (log_on_console())
return;
- format = job_get_status_message_format_try_harder(u, t, result);
+ format = job_get_status_message_format(u, t, result);
if (!format)
return;

132
SOURCES/0633-core-remove-generic-job-completion-messages-from-uni.patch

@ -0,0 +1,132 @@
From 60545c63716ecc720728c221c61d575b267fbfc8 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 21 Jul 2015 15:51:16 +0200
Subject: [PATCH] core: remove generic job completion messages from unit
vtables

These units' message format strings are identical to the generic
strings. Since we can always rely on the fallback, these are now
redundant.

(cherry picked from commit c382d69e3d39daedebcedb2da882beeb147a3cda)

Related: #1506256
---
src/core/automount.c | 1 -
src/core/busname.c | 3 ---
src/core/mount.c | 1 -
src/core/service.c | 3 ---
src/core/slice.c | 1 -
src/core/socket.c | 1 -
src/core/swap.c | 1 -
src/core/target.c | 1 -
8 files changed, 12 deletions(-)

diff --git a/src/core/automount.c b/src/core/automount.c
index 679fe071e..08519e49c 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -1126,7 +1126,6 @@ const UnitVTable automount_vtable = {
.finished_start_job = {
[JOB_DONE] = "Set up automount %s.",
[JOB_FAILED] = "Failed to set up automount %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Unset automount %s.",
diff --git a/src/core/busname.c b/src/core/busname.c
index f626ba96d..a5e659049 100644
--- a/src/core/busname.c
+++ b/src/core/busname.c
@@ -1064,13 +1064,10 @@ const UnitVTable busname_vtable = {
.finished_start_job = {
[JOB_DONE] = "Listening on %s.",
[JOB_FAILED] = "Failed to listen on %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
- [JOB_TIMEOUT] = "Timed out starting %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Closed %s.",
[JOB_FAILED] = "Failed stopping %s.",
- [JOB_TIMEOUT] = "Timed out stopping %s.",
},
},
};
diff --git a/src/core/mount.c b/src/core/mount.c
index f726d9659..0dc67dde6 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1978,7 +1978,6 @@ const UnitVTable mount_vtable = {
.finished_start_job = {
[JOB_DONE] = "Mounted %s.",
[JOB_FAILED] = "Failed to mount %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
[JOB_TIMEOUT] = "Timed out mounting %s.",
},
.finished_stop_job = {
diff --git a/src/core/service.c b/src/core/service.c
index 9622ce11f..8303a1e7e 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -3398,13 +3398,10 @@ const UnitVTable service_vtable = {
.finished_start_job = {
[JOB_DONE] = "Started %s.",
[JOB_FAILED] = "Failed to start %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
- [JOB_TIMEOUT] = "Timed out starting %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Stopped %s.",
[JOB_FAILED] = "Stopped (with error) %s.",
- [JOB_TIMEOUT] = "Timed out stopping %s.",
},
},
};
diff --git a/src/core/slice.c b/src/core/slice.c
index 9154558b7..1cce3e121 100644
--- a/src/core/slice.c
+++ b/src/core/slice.c
@@ -299,7 +299,6 @@ const UnitVTable slice_vtable = {
.status_message_formats = {
.finished_start_job = {
[JOB_DONE] = "Created slice %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Removed slice %s.",
diff --git a/src/core/socket.c b/src/core/socket.c
index 771af0d24..efefe7ce5 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2736,7 +2736,6 @@ const UnitVTable socket_vtable = {
.finished_start_job = {
[JOB_DONE] = "Listening on %s.",
[JOB_FAILED] = "Failed to listen on %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
[JOB_TIMEOUT] = "Timed out starting %s.",
},
.finished_stop_job = {
diff --git a/src/core/swap.c b/src/core/swap.c
index 984be2d9a..e71de4e65 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -1525,7 +1525,6 @@ const UnitVTable swap_vtable = {
.finished_start_job = {
[JOB_DONE] = "Activated swap %s.",
[JOB_FAILED] = "Failed to activate swap %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
[JOB_TIMEOUT] = "Timed out activating swap %s.",
},
.finished_stop_job = {
diff --git a/src/core/target.c b/src/core/target.c
index 2411a8e75..45248ad02 100644
--- a/src/core/target.c
+++ b/src/core/target.c
@@ -231,7 +231,6 @@ const UnitVTable target_vtable = {
.status_message_formats = {
.finished_start_job = {
[JOB_DONE] = "Reached target %s.",
- [JOB_DEPENDENCY] = "Dependency failed for %s.",
},
.finished_stop_job = {
[JOB_DONE] = "Stopped target %s.",

67
SOURCES/0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch

@ -0,0 +1,67 @@
From 0fd062edc435d9cf39022e2e92c895bf8625ad0d Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 21 Jul 2015 16:15:19 +0200
Subject: [PATCH] core: do not log done failed-condition jobs as if unit
started

It is misleading to see "Started foo." in the log when the unit's
condition was false.

(cherry picked from commit 30961fa300cad21b50fe47baee523beeadb5d0bc)

Related: #1506256
---
src/core/job.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/core/job.c b/src/core/job.c
index f371f914d..5e582b3d3 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -692,13 +692,6 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
assert(t >= 0);
assert(t < _JOB_TYPE_MAX);
- /* Reload status messages have traditionally not been printed to console. */
- if (t == JOB_RELOAD)
- return;
-
- if (t == JOB_START && result == JOB_DONE && !u->condition_result)
- return;
-
format = job_get_status_message_format(u, t, result);
if (!format)
return;
@@ -768,6 +761,19 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
NULL);
}
+static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
+
+ /* No message if the job did not actually do anything due to failed condition. */
+ if (t == JOB_START && result == JOB_DONE && !u->condition_result)
+ return;
+
+ job_log_status_message(u, t, result);
+
+ /* Reload status messages have traditionally not been printed to console. */
+ if (t != JOB_RELOAD)
+ job_print_status_message(u, t, result);
+}
+
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
Unit *u;
Unit *other;
@@ -787,10 +793,8 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
u->id, job_type_to_string(t), job_result_to_string(result));
/* If this job did nothing to respective unit we don't log the status message */
- if (!already) {
- job_print_status_message(u, t, result);
- job_log_status_message(u, t, result);
- }
+ if (!already)
+ job_emit_status_message(u, t, result);
job_add_to_dbus_queue(j);

42
SOURCES/0635-core-log-completion-of-remaining-job-types.patch

@ -0,0 +1,42 @@
From 010b80c6215da7357114911f46742939772e18fc Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 21 Jul 2015 16:20:18 +0200
Subject: [PATCH] core: log completion of remaining job types

JOB_RESTART and failed JOB_VERIFY_ACTIVE completions were printed to
console but not to the log.

(cherry picked from commit 4f29c6fea6a6c5c2c9406ad091cd6f56da21e2cb)

Related: #1506256
---
src/core/job.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/core/job.c b/src/core/job.c
index 5e582b3d3..086050aa7 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -743,8 +743,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
NULL);
-
- } else if (t == JOB_STOP)
+ } else if (t == JOB_STOP || t == JOB_RESTART)
log_unit_struct(u->id,
result == JOB_DONE ? LOG_INFO : LOG_ERR,
LOG_MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
@@ -759,6 +758,12 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
NULL);
+ else
+ log_unit_struct(u->id,
+ result == JOB_DONE ? LOG_INFO : LOG_ERR,
+ LOG_MESSAGE("%s", buf),
+ "RESULT=%s", job_result_to_string(result),
+ NULL);
}
static void job_emit_status_message(Unit *u, JobType t, JobResult result) {

75
SOURCES/0636-core-adjust-job-completion-message-log-levels.patch

@ -0,0 +1,75 @@
From ea366cda56dc0550b9829e4d9e733cb8b70ffb30 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Tue, 21 Jul 2015 19:07:24 +0200
Subject: [PATCH] core: adjust job completion message log levels

We do not print all non-OK job completion status messages to the console
in red, because not all of them are plain errors. We do however log the
same messages as LOG_ERR.

Differentiate the log levels by deducing them from the job result in a
way that more or less matches the color of the console message.

(cherry picked from commit 64f575d2ab9a6743d3c7172b7591c88ba243cf1b)

Related: #1506256
---
src/core/job.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/core/job.c b/src/core/job.c
index 086050aa7..1861c8a63 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -714,6 +714,17 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
static void job_log_status_message(Unit *u, JobType t, JobResult result) {
const char *format;
char buf[LINE_MAX];
+ static const int job_result_log_level[_JOB_RESULT_MAX] = {
+ [JOB_DONE] = LOG_INFO,
+ [JOB_CANCELED] = LOG_INFO,
+ [JOB_TIMEOUT] = LOG_ERR,
+ [JOB_FAILED] = LOG_ERR,
+ [JOB_DEPENDENCY] = LOG_WARNING,
+ [JOB_SKIPPED] = LOG_NOTICE,
+ [JOB_INVALID] = LOG_INFO,
+ [JOB_ASSERT] = LOG_WARNING,
+ [JOB_UNSUPPORTED] = LOG_WARNING,
+ };
assert(u);
assert(t >= 0);
@@ -738,14 +749,14 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
log_unit_struct(u->id,
- result == JOB_DONE ? LOG_INFO : LOG_ERR,
+ job_result_log_level[result],
LOG_MESSAGE_ID(mid),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
NULL);
} else if (t == JOB_STOP || t == JOB_RESTART)
log_unit_struct(u->id,
- result == JOB_DONE ? LOG_INFO : LOG_ERR,
+ job_result_log_level[result],
LOG_MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
@@ -753,14 +764,14 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
else if (t == JOB_RELOAD)
log_unit_struct(u->id,
- result == JOB_DONE ? LOG_INFO : LOG_ERR,
+ job_result_log_level[result],
LOG_MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
NULL);
else
log_unit_struct(u->id,
- result == JOB_DONE ? LOG_INFO : LOG_ERR,
+ job_result_log_level[result],
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
NULL);

111
SOURCES/0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch

@ -0,0 +1,111 @@
From 048ed4b2fecef7003925772740bab651cb08b260 Mon Sep 17 00:00:00 2001
From: brulon <barron@lexmark.com>
Date: Fri, 26 Aug 2016 11:57:22 -0400
Subject: [PATCH] mount: add new LazyUnmount= setting for mount units, mapping
to umount(8)'s "-l" switch (#3827)

(cherry-picked commit from e520950a03419957875034bc27795b0b81d8e793)

Resolves: #1497264
---
man/systemd.mount.xml | 13 +++++++++++++
src/core/dbus-mount.c | 1 +
src/core/load-fragment-gperf.gperf.m4 | 1 +
src/core/mount.c | 8 ++++++--
src/core/mount.h | 2 ++
5 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index dfa437b5d..1590c44ce 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -329,6 +329,19 @@
off.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>LazyUnmount=</varname></term>
+
+ <listitem><para>Takes a boolean argument. If true, detach the
+ filesystem from the filesystem hierarchy at time of the unmount
+ operation, and clean up all references to the filesystem as
+ soon as they are not busy anymore.
+ This corresponds with
+ <citerefentry project='man-pages'><refentrytitle>umount</refentrytitle><manvolnum>8</manvolnum></citerefentry>'s
+ <parameter>-l</parameter> switch. Defaults to
+ off.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>DirectoryMode=</varname></term>
<listitem><para>Directories of mount points (and any parent
diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
index 04beba631..cbb842f70 100644
--- a/src/core/dbus-mount.c
+++ b/src/core/dbus-mount.c
@@ -110,6 +110,7 @@ const sd_bus_vtable bus_mount_vtable[] = {
SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("LazyUnmount", "b", bus_property_get_bool, offsetof(Mount, lazy_unmount), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index b2fe627af..664bba0ef 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -316,6 +316,7 @@ Mount.Type, config_parse_string, 0,
Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec)
Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
Mount.SloppyOptions, config_parse_bool, 0, offsetof(Mount, sloppy_options)
+Mount.LazyUnmount, config_parse_bool, 0, offsetof(Mount, lazy_unmount)
EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
diff --git a/src/core/mount.c b/src/core/mount.c
index 0dc67dde6..5fd7a86dd 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -690,7 +690,8 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
"%sOptions: %s\n"
"%sFrom /proc/self/mountinfo: %s\n"
"%sFrom fragment: %s\n"
- "%sDirectoryMode: %04o\n",
+ "%sDirectoryMode: %04o\n"
+ "%sLazyUnmount: %s\n",
prefix, mount_state_to_string(m->state),
prefix, mount_result_to_string(m->result),
prefix, m->where,
@@ -699,7 +700,8 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
prefix, p ? strna(p->options) : "n/a",
prefix, yes_no(m->from_proc_self_mountinfo),
prefix, yes_no(m->from_fragment),
- prefix, m->directory_mode);
+ prefix, m->directory_mode,
+ prefix, yes_no(m->lazy_unmount));
if (m->control_pid > 0)
fprintf(f,
@@ -891,6 +893,8 @@ static void mount_enter_unmounting(Mount *m) {
m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
r = exec_command_set(m->control_command, "/bin/umount", m->where, NULL);
+ if (r >= 0 && m->lazy_unmount)
+ r = exec_command_append(m->control_command, "-l", NULL);
if (r < 0)
goto fail;
diff --git a/src/core/mount.h b/src/core/mount.h
index 353222000..4e870299c 100644
--- a/src/core/mount.h
+++ b/src/core/mount.h
@@ -90,6 +90,8 @@ struct Mount {
bool sloppy_options;
+ bool lazy_unmount;
+
MountResult result;
MountResult reload_result;

42
SOURCES/0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch

@ -0,0 +1,42 @@
From 14ca846073e3b7accb71012a9612d0a7cb6b5ea6 Mon Sep 17 00:00:00 2001
From: gwendalcr <gwendal@chromium.org>
Date: Wed, 20 Jun 2018 16:54:05 +0200
Subject: [PATCH] rules: Add MODEL_ID for NVMe device (#7037)

To mimic MODEL_ID variable built for ATA and SCSI devices, add rules
to add MODEL_ID variable for NVMe devices.

TEST: Check on a system with NVMe device that MODEL_ID variable is
present:
udevadm info --query=all -n /dev/nvme0n1p1 | grep ID_MODEL
and
udevadm info --query=all -n /dev/nvme0n1p1 | grep ID_MODEL
return:
E: ID_MODEL=SAMSUNG...

(cherry picked from commit e2c2d70ba7cc7497b03c4a377bfb529035540aa7)

Resolves: #1397264
---
rules/60-persistent-storage.rules | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
index ba619633b..4aae97a9f 100644
--- a/rules/60-persistent-storage.rules
+++ b/rules/60-persistent-storage.rules
@@ -28,10 +28,12 @@ KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{wwid}=="?*"
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{wwid}=="?*", ENV{ID_WWN}="$attr{wwid}"
-KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}", OPTIONS="string_escape=replace"
+KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
+KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}", OPTIONS="string_escape=replace"
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
-KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n", OPTIONS="string_escape=replace"
+KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
+KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n", OPTIONS="string_escape=replace"
# virtio-blk
KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"

72
SOURCES/0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch

@ -0,0 +1,72 @@
From 5bace483dedc9098da8191f39c823649948a7a3c Mon Sep 17 00:00:00 2001
From: NeilBrown <neil@brown.name>
Date: Wed, 8 Nov 2017 19:29:32 +1100
Subject: [PATCH] umount: always use MNT_FORCE in umount_all() (#7213)

The linux umount2() systemcall accepts a MNT_FORCE flags
which some filesystems honor, particularly FUSE and various
network filesystems such as NFS.
These filesystems can sometimes wait for an indefinite period
for a response from an external service, and the wait if
sometimes "uninterruptible" meaning that the process cannot be
killed.
Using MNT_FORCE causes any such request that are outstanding to
be aborted. This normally allows the waiting process to
be killed. It will then realease and reference it has to the
filesytem, this allowing the filesystem to be unmounted.

If there remain active references to the filesystem, MNT_FORCE
is *not* forcefull enough to unmount the filesystem anyway.

By the time that umount_all() is run by systemd-shutdown, all
filesystems *should* be unmounted, and sync() will have been
called. Anything that remains cannot be unmounted in a
completely clean manner and just nees to be dealt with as firmly
as possible. So use MNT_FORCE and try to explain why in the
comment.

Also enhance an earlier comment to explain why umount2() is
safe even though mount(MNT_REMOUNT) isn't.

(cherry picked from commit c44cac7c6c43407d28bd8daebff39f6145a2a33e)

Resolves: #1571098
---
src/core/umount.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/core/umount.c b/src/core/umount.c
index 3eec0d459..91d67c06c 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -377,7 +377,9 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
the superblock here, not the bind mount.
If the filesystem is a network fs, also skip the
remount. It brings no value (we cannot leave
- a "dirty fs") and could hang if the network is down. */
+ a "dirty fs") and could hang if the network is down.
+ Note that umount2() is more careful and will not
+ hang because of the network being down. */
if (detect_container(NULL) <= 0 &&
!fstype_is_network(m->type)) {
_cleanup_free_ char *options = NULL;
@@ -418,11 +420,15 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
)
continue;
- /* Trying to umount. We don't force here since we rely
- * on busy NFS and FUSE file systems to return EBUSY
- * until we closed everything on top of them. */
+ /* Trying to umount. Using MNT_FORCE causes some
+ * filesystems (e.g. FUSE and NFS and other network
+ * filesystems) to abort any pending requests and
+ * return -EIO rather than blocking indefinitely.
+ * If the filesysten is "busy", this may allow processes
+ * to die, thus making the filesystem less busy so
+ * the unmount might succeed (rather then return EBUSY).*/
log_info("Unmounting %s.", m->path);
- if (umount2(m->path, 0) == 0) {
+ if (umount2(m->path, MNT_FORCE) == 0) {
if (changed)
*changed = true;

305
SOURCES/0640-core-Implement-timeout-based-umount-remount-limit.patch

@ -0,0 +1,305 @@
From 5ccae46f2a192a9347feb604901127c55ce1e039 Mon Sep 17 00:00:00 2001
From: Kyle Walker <kwalker@redhat.com>
Date: Wed, 13 Dec 2017 12:49:26 -0500
Subject: [PATCH] core: Implement timeout based umount/remount limit

Remount, and subsequent umount, attempts can hang for inaccessible network
based mount points. This can leave a system in a hard hang state that
requires a hard reset in order to recover. This change moves the remount,
and umount attempts into separate child processes. The remount and umount
operations will block for up to 90 seconds (DEFAULT_TIMEOUT_USEC). Should
those waits fail, the parent will issue a SIGKILL to the child and continue
with the shutdown efforts.

In addition, instead of only reporting some additional errors on the final
attempt, failures are reported as they occur.

(cherry picked from commit d5641e0d7e8f55937fbc3a7ecd667e42c5836d80)

Related: #1571098
---
src/core/umount.c | 112 +++++++++++++++++++++++++++++++++++++---------
src/shared/def.h | 2 -
src/shared/login-shared.c | 1 +
src/shared/util.c | 61 +++++++++++++++++++++++++
src/shared/util.h | 16 +++++++
5 files changed, 168 insertions(+), 24 deletions(-)

diff --git a/src/core/umount.c b/src/core/umount.c
index 91d67c06c..bd3896612 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -363,7 +363,84 @@ static int delete_dm(dev_t devnum) {
return r >= 0 ? 0 : -errno;
}
-static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
+static int remount_with_timeout(MountPoint *m, char *options, int *n_failed) {
+ pid_t pid;
+ int r;
+
+ BLOCK_SIGNALS(SIGCHLD);
+
+ /* Due to the possiblity of a remount operation hanging, we
+ * fork a child process and set a timeout. If the timeout
+ * lapses, the assumption is that that particular remount
+ * failed. */
+ pid = fork();
+ if (pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
+
+ if (pid == 0) {
+ log_info("Remounting '%s' read-only in with options '%s'.", m->path, options);
+
+ /* Start the mount operation here in the child */
+ r = mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
+ if (r < 0)
+ log_error_errno(errno, "Failed to remount '%s' read-only: %m", m->path);
+
+ _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+ }
+
+ r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
+ if (r == -ETIMEDOUT) {
+ log_error_errno(errno, "Remounting '%s' - timed out, issuing SIGKILL to PID "PID_FMT".", m->path, pid);
+ (void) kill(pid, SIGKILL);
+ } else if (r < 0)
+ log_error_errno(r, "Failed to wait for process: %m");
+
+ return r;
+}
+
+static int umount_with_timeout(MountPoint *m, bool *changed) {
+ pid_t pid;
+ int r;
+
+ BLOCK_SIGNALS(SIGCHLD);
+
+ /* Due to the possiblity of a umount operation hanging, we
+ * fork a child process and set a timeout. If the timeout
+ * lapses, the assumption is that that particular umount
+ * failed. */
+ pid = fork();
+ if (pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
+
+ if (pid == 0) {
+ log_info("Unmounting '%s'.", m->path);
+
+ /* Start the mount operation here in the child Using MNT_FORCE
+ * causes some filesystems (e.g. FUSE and NFS and other network
+ * filesystems) to abort any pending requests and return -EIO
+ * rather than blocking indefinitely. If the filesysten is
+ * "busy", this may allow processes to die, thus making the
+ * filesystem less busy so the unmount might succeed (rather
+ * then return EBUSY).*/
+ r = umount2(m->path, MNT_FORCE);
+ if (r < 0)
+ log_error_errno(errno, "Failed to unmount %s: %m", m->path);
+
+ _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+ }
+
+ r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
+ if (r == -ETIMEDOUT) {
+ log_error_errno(errno, "Unmounting '%s' - timed out, issuing SIGKILL to PID "PID_FMT".", m->path, pid);
+ (void) kill(pid, SIGKILL);
+ } else if (r < 0)
+ log_error_errno(r, "Failed to wait for process: %m");
+
+ return r;
+}
+
+
+static int mount_points_list_umount(MountPoint **head, bool *changed) {
MountPoint *m, *n;
int n_failed = 0;
@@ -405,9 +482,13 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
* explicitly remount the super block of that
* alias read-only we hence should be
* relatively safe regarding keeping the fs we
- * can otherwise not see dirty. */
- log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
- (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
+ * can otherwise not see dirty.
+ *
+ * Since the remount can hang in the instance of
+ * remote filesystems, we remount asynchronously
+ * and skip the subsequent umount if it fails */
+ if (remount_with_timeout(m, options, &n_failed) < 0)
+ continue;
}
/* Skip / and /usr since we cannot unmount that
@@ -420,22 +501,14 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
)
continue;
- /* Trying to umount. Using MNT_FORCE causes some
- * filesystems (e.g. FUSE and NFS and other network
- * filesystems) to abort any pending requests and
- * return -EIO rather than blocking indefinitely.
- * If the filesysten is "busy", this may allow processes
- * to die, thus making the filesystem less busy so
- * the unmount might succeed (rather then return EBUSY).*/
- log_info("Unmounting %s.", m->path);
- if (umount2(m->path, MNT_FORCE) == 0) {
+ /* Trying to umount */
+ if (umount_with_timeout(m, changed) < 0)
+ n_failed++;
+ else {
if (changed)
*changed = true;
mount_point_free(head, m);
- } else if (log_error) {
- log_warning_errno(errno, "Could not unmount %s: %m", m->path);
- n_failed++;
}
}
@@ -550,17 +623,12 @@ int umount_all(bool *changed) {
do {
umount_changed = false;
- mount_points_list_umount(&mp_list_head, &umount_changed, false);
+ mount_points_list_umount(&mp_list_head, &umount_changed);
if (umount_changed)
*changed = true;
} while (umount_changed);
- /* umount one more time with logging enabled */
- r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
- if (r <= 0)
- goto end;
-
end:
mount_points_list_free(&mp_list_head);
diff --git a/src/shared/def.h b/src/shared/def.h
index 9e008a6d2..f193ab1f9 100644
--- a/src/shared/def.h
+++ b/src/shared/def.h
@@ -21,8 +21,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "util.h"
-
#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC)
#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
#define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC)
diff --git a/src/shared/login-shared.c b/src/shared/login-shared.c
index 054c77503..5da0f0583 100644
--- a/src/shared/login-shared.c
+++ b/src/shared/login-shared.c
@@ -21,6 +21,7 @@
#include "login-shared.h"
#include "def.h"
+#include "util.h"
bool session_id_valid(const char *id) {
assert(id);
diff --git a/src/shared/util.c b/src/shared/util.c
index 982f5e044..3216f004a 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -9049,3 +9049,64 @@ try_dev_shm_without_o_tmpfile:
return -EOPNOTSUPP;
}
+
+/*
+ * Return values:
+ * < 0 : wait_for_terminate_with_timeout() failed to get the state of the
+ * process, the process timed out, the process was terminated by a
+ * signal, or failed for an unknown reason.
+ * >=0 : The process terminated normally with no failures.
+ *
+ * Success is indicated by a return value of zero, a timeout is indicated
+ * by ETIMEDOUT, and all other child failure states are indicated by error
+ * is indicated by a non-zero value.
+*/
+int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
+ sigset_t mask;
+ int r;
+ usec_t until;
+
+ assert_se(sigemptyset(&mask) == 0);
+ assert_se(sigaddset(&mask, SIGCHLD) == 0);
+
+ /* Drop into a sigtimewait-based timeout. Waiting for the
+ * pid to exit. */
+ until = now(CLOCK_MONOTONIC) + timeout;
+ for (;;) {
+ usec_t n;
+ siginfo_t status = {};
+ struct timespec ts;
+
+ n = now(CLOCK_MONOTONIC);
+ if (n >= until)
+ break;
+
+ r = sigtimedwait(&mask, NULL, timespec_store(&ts, until - n)) < 0 ? -errno : 0;
+ /* Assuming we woke due to the child exiting. */
+ if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) {
+ if (status.si_pid == pid) {
+ /* This is the correct child.*/
+ if (status.si_code == CLD_EXITED)
+ return (status.si_status == 0) ? 0 : -EPROTO;
+ else
+ return -EPROTO;
+ }
+ }
+ /* Not the child, check for errors and proceed appropriately */
+ if (r < 0) {
+ switch (r) {
+ case -EAGAIN:
+ /* Timed out, child is likely hung. */
+ return -ETIMEDOUT;
+ case -EINTR:
+ /* Received a different signal and should retry */
+ continue;
+ default:
+ /* Return any unexpected errors */
+ return r;
+ }
+ }
+ }
+
+ return -EPROTO;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 9c4be0256..998f882bb 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -22,6 +22,7 @@
***/
#include <alloca.h>
+#include <def.h>
#include <fcntl.h>
#include <inttypes.h>
#include <time.h>
@@ -1122,3 +1123,18 @@ enum {
};
int acquire_data_fd(const void *data, size_t size, unsigned flags);
+
+int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout);
+
+static inline void block_signals_reset(sigset_t *ss) {
+ assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
+}
+
+#define BLOCK_SIGNALS(...) \
+ _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
+ sigset_t _t; \
+ assert_se(sigprocmask(SIG_SETMASK, NULL, &_t) == 0); \
+ assert_se(sigprocmask_many(SIG_BLOCK, __VA_ARGS__, -1) >= 0); \
+ _t; \
+ })
+

169
SOURCES/0641-core-Implement-sync_with_progress.patch

@ -0,0 +1,169 @@
From db57bf73d3e5e650b261834a0c39c9d368f9eeea Mon Sep 17 00:00:00 2001
From: Kyle Walker <kwalker@redhat.com>
Date: Thu, 14 Dec 2017 11:46:03 -0500
Subject: [PATCH] core: Implement sync_with_progress()

In similar fashion to the previous change, sync() operations can stall
endlessly if cache is unable to be written out. In order to avoid an
unbounded hang, the sync takes place within a child process. Every 10
seconds (SYNC_TIMEOUT_USEC), the value of /proc/meminfo "Dirty" is checked
to verify it is smaller than the last iteration. If the sync is not making
progress for 3 successive iterations (SYNC_PROGRESS_ATTEMPTS), a SIGKILL is
sent to the sync process and the shutdown continues.

(cherry picked from commit 73ad712fcfea5d8ba475044698d31d2c15d4180d)

Related: #1571098
---
src/core/shutdown.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 111 insertions(+), 5 deletions(-)

diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index 71f001ac1..0b0a54a7d 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -53,6 +53,9 @@
#define FINALIZE_ATTEMPTS 50
+#define SYNC_PROGRESS_ATTEMPTS 3
+#define SYNC_TIMEOUT_USEC (10*USEC_PER_SEC)
+
static char* arg_verb;
static int parse_argv(int argc, char *argv[]) {
@@ -152,6 +155,102 @@ static int switch_root_initramfs(void) {
return switch_root("/run/initramfs", "/oldroot", false, MS_BIND);
}
+/* Read the following fields from /proc/meminfo:
+ *
+ * NFS_Unstable
+ * Writeback
+ * Dirty
+ *
+ * Return true if the sum of these fields is greater than the previous
+ * value input. For all other issues, report the failure and indicate that
+ * the sync is not making progress.
+ */
+static bool sync_making_progress(unsigned long long *prev_dirty) {
+ _cleanup_fclose_ FILE *f = NULL;
+ char line[LINE_MAX];
+ bool r = false;
+ unsigned long long val = 0;
+
+ f = fopen("/proc/meminfo", "re");
+ if (!f)
+ return log_warning_errno(errno, "Failed to open /proc/meminfo: %m");
+
+ FOREACH_LINE(line, f, log_warning_errno(errno, "Failed to parse /proc/meminfo: %m")) {
+ unsigned long long ull = 0;
+
+ if (!first_word(line, "NFS_Unstable:") && !first_word(line, "Writeback:") && !first_word(line, "Dirty:"))
+ continue;
+
+ errno = 0;
+ if (sscanf(line, "%*s %llu %*s", &ull) != 1) {
+ if (errno != 0)
+ log_warning_errno(errno, "Failed to parse /proc/meminfo: %m");
+ else
+ log_warning("Failed to parse /proc/meminfo");
+
+ return false;
+ }
+
+ val += ull;
+ }
+
+ r = *prev_dirty > val;
+
+ *prev_dirty = val;
+
+ return r;
+}
+
+static void sync_with_progress(void) {
+ unsigned checks;
+ pid_t pid;
+ int r;
+ unsigned long long dirty = ULONG_LONG_MAX;
+
+ BLOCK_SIGNALS(SIGCHLD);
+
+ /* Due to the possiblity of the sync operation hanging, we fork
+ * a child process and monitor the progress. If the timeout
+ * lapses, the assumption is that that particular sync stalled. */
+ pid = fork();
+ if (pid < 0) {
+ log_error_errno(errno, "Failed to fork: %m");
+ return;
+ }
+
+ if (pid == 0) {
+ /* Start the sync operation here in the child */
+ sync();
+ _exit(EXIT_SUCCESS);
+ }
+
+ log_info("Syncing filesystems and block devices.");
+
+ /* Start monitoring the sync operation. If more than
+ * SYNC_PROGRESS_ATTEMPTS lapse without progress being made,
+ * we assume that the sync is stalled */
+ for (checks = 0; checks < SYNC_PROGRESS_ATTEMPTS; checks++) {
+ r = wait_for_terminate_with_timeout(pid, SYNC_TIMEOUT_USEC);
+ if (r == 0)
+ /* Sync finished without error.
+ * (The sync itself does not return an error code) */
+ return;
+ else if (r == -ETIMEDOUT) {
+ /* Reset the check counter if the "Dirty" value is
+ * decreasing */
+ if (sync_making_progress(&dirty))
+ checks = 0;
+ } else {
+ log_error_errno(r, "Failed to sync filesystems and block devices: %m");
+ return;
+ }
+ }
+
+ /* Only reached in the event of a timeout. We should issue a kill
+ * to the stray process. */
+ log_error("Syncing filesystems and block devices - timed out, issuing SIGKILL to PID "PID_FMT".", pid);
+ (void) kill(pid, SIGKILL);
+}
int main(int argc, char *argv[]) {
bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
@@ -202,6 +301,13 @@ int main(int argc, char *argv[]) {
/* lock us into memory */
mlockall(MCL_CURRENT|MCL_FUTURE);
+ /* Synchronize everything that is not written to disk yet at this point already. This is a good idea so that
+ * slow IO is processed here already and the final process killing spree is not impacted by processes
+ * desperately trying to sync IO to disk within their timeout. Do not remove this sync, data corruption will
+ * result. */
+ if (!in_container)
+ sync_with_progress();
+
log_info("Sending SIGTERM to remaining processes...");
broadcast_signal(SIGTERM, true, true);
@@ -338,12 +444,12 @@ int main(int argc, char *argv[]) {
need_loop_detach ? " loop devices," : "",
need_dm_detach ? " DM devices," : "");
- /* The kernel will automaticall flush ATA disks and suchlike
- * on reboot(), but the file systems need to be synce'd
- * explicitly in advance. So let's do this here, but not
- * needlessly slow down containers. */
+ /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
+ * sync'ed explicitly in advance. So let's do this here, but not needlessly slow down containers. Note that we
+ * sync'ed things already once above, but we did some more work since then which might have caused IO, hence
+ * let's do it once more. Do not remove this sync, data corruption will result. */
if (!in_container)
- sync();
+ sync_with_progress();
switch (cmd) {

48
SOURCES/0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch

@ -0,0 +1,48 @@
From 4f36220ccfe40621cd7df3595568278d7bca4f87 Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Fri, 23 Sep 2016 13:33:01 +0200
Subject: [PATCH] journal: fix HMAC calculation when appending a data object

Since commit 5996c7c295e073ce21d41305169132c8aa993ad0 (v190 !), the
calculation of the HMAC is broken because the hash for a data object
including a field is done in the wrong order: the field object is
hashed before the data object is.

However during verification, the hash is done in the opposite order as
objects are scanned sequentially.

(cherry picked from commit 33685a5a3a98c6ded64d0cc25e37d0180ceb0a6a)
---
src/journal/journal-file.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 2bb3a9757..586f620e2 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1099,6 +1099,12 @@ static int journal_file_append_data(
if (r < 0)
return r;
+#ifdef HAVE_GCRYPT
+ r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p);
+ if (r < 0)
+ return r;
+#endif
+
/* The linking might have altered the window, so let's
* refresh our pointer */
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
@@ -1123,12 +1129,6 @@ static int journal_file_append_data(
fo->field.head_data_offset = le64toh(p);
}
-#ifdef HAVE_GCRYPT
- r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p);
- if (r < 0)
- return r;
-#endif
-
if (ret)
*ret = o;

135
SOURCES/0643-journal-forward-messages-from-dev-log-unmodified-to-.patch

@ -0,0 +1,135 @@
From d82c40a2377b487ef83aa1fb907ec275a1b3e86e Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 30 May 2018 16:27:22 +0200
Subject: [PATCH] journal: forward messages from /dev/log unmodified to
syslog.socket

(cherry picked from commit bb3ff70a86faff85fe482995c8ba5332b1a34f76)

Resolves: #1409659
---
src/journal/journald-server.c | 2 +-
src/journal/journald-syslog.c | 39 +++++++++++++++++++++++++--------------
src/journal/journald-syslog.h | 2 +-
3 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 7c69061f4..7e67e055e 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1294,7 +1294,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
if (fd == s->syslog_fd) {
if (n > 0 && n_fds == 0)
- server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
+ server_process_syslog_message(s, s->buffer, n, ucred, tv, label, label_len);
else if (n_fds > 0)
log_warning("Got file descriptors via syslog socket. Ignoring.");
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index b499a0d38..01d2bf69f 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -109,7 +109,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
log_debug_errno(errno, "Failed to forward syslog message: %m");
}
-static void forward_syslog_raw(Server *s, int priority, const char *buffer, const struct ucred *ucred, const struct timeval *tv) {
+static void forward_syslog_raw(Server *s, int priority, const char *buffer, size_t buffer_len, const struct ucred *ucred, const struct timeval *tv) {
struct iovec iovec;
assert(s);
@@ -118,7 +118,9 @@ static void forward_syslog_raw(Server *s, int priority, const char *buffer, cons
if (LOG_PRI(priority) > s->max_level_syslog)
return;
- IOVEC_SET_STRING(iovec, buffer);
+ iovec.iov_base = (char *) buffer;
+ iovec.iov_len = buffer_len;
+
forward_syslog_iovec(s, &iovec, 1, ucred, tv);
}
@@ -311,40 +313,49 @@ static void syslog_skip_date(char **buf) {
void server_process_syslog_message(
Server *s,
const char *buf,
+ size_t buf_len,
const struct ucred *ucred,
const struct timeval *tv,
const char *label,
size_t label_len) {
char syslog_priority[sizeof("PRIORITY=") + DECIMAL_STR_MAX(int)],
- syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
+ syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)], *msg;
const char *message = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
struct iovec iovec[N_IOVEC_META_FIELDS + 6];
- unsigned n = 0;
+ unsigned n = 0, i;
int priority = LOG_USER | LOG_INFO;
_cleanup_free_ char *identifier = NULL, *pid = NULL;
- const char *orig;
assert(s);
assert(buf);
- orig = buf;
- syslog_parse_priority(&buf, &priority, true);
+ /* We are creating copy of the message because we want to forward original message verbatim to the legacy
+ syslog implementation */
+ for (i = buf_len; i > 0; i--)
+ if (!strchr(WHITESPACE, buf[i-1]))
+ break;
+
+ msg = newa(char, i + 1);
+ *((char *) mempcpy(msg, buf, i)) = 0;
+ msg += strspn(msg, WHITESPACE);
+
+ syslog_parse_priority((const char **)&msg, &priority, true);
if (s->forward_to_syslog)
- forward_syslog_raw(s, priority, orig, ucred, tv);
+ forward_syslog_raw(s, priority, buf, buf_len, ucred, tv);
- syslog_skip_date((char**) &buf);
- syslog_parse_identifier(&buf, &identifier, &pid);
+ syslog_skip_date(&msg);
+ syslog_parse_identifier((const char**)&msg, &identifier, &pid);
if (s->forward_to_kmsg)
- server_forward_kmsg(s, priority, identifier, buf, ucred);
+ server_forward_kmsg(s, priority, identifier, msg, ucred);
if (s->forward_to_console)
- server_forward_console(s, priority, identifier, buf, ucred);
+ server_forward_console(s, priority, identifier, msg, ucred);
if (s->forward_to_wall)
- server_forward_wall(s, priority, identifier, buf, ucred);
+ server_forward_wall(s, priority, identifier, msg, ucred);
IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
@@ -368,7 +379,7 @@ void server_process_syslog_message(
IOVEC_SET_STRING(iovec[n++], syslog_pid);
}
- message = strjoina("MESSAGE=", buf);
+ message = strjoina("MESSAGE=", msg);
if (message)
IOVEC_SET_STRING(iovec[n++], message);
diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h
index 3774ebdf0..e593be99a 100644
--- a/src/journal/journald-syslog.h
+++ b/src/journal/journald-syslog.h
@@ -29,7 +29,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid);
void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv);
-void server_process_syslog_message(Server *s, const char *buf, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
+void server_process_syslog_message(Server *s, const char *buf, size_t buf_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
int server_open_syslog_socket(Server *s);
void server_maybe_warn_forward_syslog_missed(Server *s);

158
SOURCES/0644-tmpfiles-use-safe_glob.patch

@ -0,0 +1,158 @@
From 2f9ee3163c44a71c99fe104daf01d4d9ab51d2c9 Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Mon, 28 May 2018 10:52:52 +0200
Subject: [PATCH] tmpfiles: use safe_glob()

This filters out "." and ".." from glob results. Fixes #5655 and #5644.

Any judgements on whether the path is "safe" are removed. We will not remove
"/" under any name (including "/../" and such), but we will remove stuff that
is specified using paths that include "//", "/./" and "/../". Such paths can be
created when joining strings automatically, or for other reasons, and people
generally know what ".." and "." is.

Tests are added to make sure that the helper functions behave as expected.

Original commit: 84e72b5ef445ffb256bc4add4209c4c9c9855206
Resolves: #1436004
---
src/shared/util.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++--
src/shared/util.h | 2 ++
src/tmpfiles/tmpfiles.c | 11 +++------
3 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/src/shared/util.c b/src/shared/util.c
index 3216f004a..78967103a 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -49,7 +49,6 @@
#include <dlfcn.h>
#include <sys/wait.h>
#include <sys/time.h>
-#include <glob.h>
#include <grp.h>
#include <sys/mman.h>
#include <sys/vfs.h>
@@ -3370,7 +3369,7 @@ static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bo
/* We refuse to clean the root file system with this
* call. This is extra paranoia to never cause a really
* seriously broken system. */
- if (path_equal(path, "/")) {
+ if (path_equal_or_files_same(path, "/")) {
log_error("Attempted to remove entire root file system, and we can't allow that.");
return -EPERM;
}
@@ -5096,6 +5095,66 @@ int in_group(const char *name) {
return in_gid(gid);
}
+static void closedir_wrapper(void* v) {
+ (void) closedir(v);
+}
+
+static bool dot_or_dot_dot(const char *path) {
+ if (!path)
+ return false;
+ if (path[0] != '.')
+ return false;
+ if (path[1] == 0)
+ return true;
+ if (path[1] != '.')
+ return false;
+
+ return path[2] == 0;
+}
+
+static struct dirent* readdir_no_dot(DIR *dirp) {
+ struct dirent* d;
+
+ for (;;) {
+ d = readdir(dirp);
+ if (d && dot_or_dot_dot(d->d_name))
+ continue;
+ return d;
+ }
+}
+
+int safe_glob(const char *path, int flags, glob_t *pglob) {
+ int k;
+
+ /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
+ assert(!(flags & GLOB_ALTDIRFUNC));
+
+ if (!pglob->gl_closedir)
+ pglob->gl_closedir = closedir_wrapper;
+ if (!pglob->gl_readdir)
+ pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
+ if (!pglob->gl_opendir)
+ pglob->gl_opendir = (void *(*)(const char *)) opendir;
+ if (!pglob->gl_lstat)
+ pglob->gl_lstat = lstat;
+ if (!pglob->gl_stat)
+ pglob->gl_stat = stat;
+
+ errno = 0;
+ k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
+
+ if (k == GLOB_NOMATCH)
+ return -ENOENT;
+ if (k == GLOB_NOSPACE)
+ return -ENOMEM;
+ if (k != 0)
+ return errno > 0 ? -errno : -EIO;
+ if (strv_isempty(pglob->gl_pathv))
+ return -ENOENT;
+
+ return 0;
+}
+
int glob_exists(const char *path) {
_cleanup_globfree_ glob_t g = {};
int k;
diff --git a/src/shared/util.h b/src/shared/util.h
index 998f882bb..cf096aa07 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -44,6 +44,7 @@
#include <mntent.h>
#include <sys/socket.h>
#include <sys/inotify.h>
+#include <glob.h>
#if SIZEOF_PID_T == 4
# define PID_PRI PRIi32
@@ -595,6 +596,7 @@ char* gid_to_name(gid_t gid);
int glob_exists(const char *path);
int glob_extend(char ***strv, const char *path);
+int safe_glob(const char *path, int flags, glob_t *pglob);
int dirent_ensure_type(DIR *d, struct dirent *de);
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 5212d72f5..8a75efb22 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -1095,19 +1095,14 @@ static int item_do_children(Item *i, const char *path, action_t action) {
static int glob_item(Item *i, action_t action, bool recursive) {
_cleanup_globfree_ glob_t g = {
- .gl_closedir = (void (*)(void *)) closedir,
- .gl_readdir = (struct dirent *(*)(void *)) readdir,
.gl_opendir = (void *(*)(const char *)) opendir_nomod,
- .gl_lstat = lstat,
- .gl_stat = stat,
};
int r = 0, k;
char **fn;
- errno = 0;
- k = glob(i->path, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
- if (k != 0 && k != GLOB_NOMATCH)
- return log_error_errno(errno ?: EIO, "glob(%s) failed: %m", i->path);
+ k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k < 0 && k != -ENOENT)
+ return log_error_errno(k, "glob(%s) failed: %m", i->path);
STRV_FOREACH(fn, g.gl_pathv) {
k = action(i, *fn);

52
SOURCES/0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch

@ -0,0 +1,52 @@
From c043ae5b2ef2e1e437bf738bbf522799c6213230 Mon Sep 17 00:00:00 2001
From: Krzysztof Nowicki <krzysztof.a.nowicki+github@gmail.com>
Date: Thu, 30 Nov 2017 11:59:29 +0100
Subject: [PATCH] Fix SELinux labels in cgroup filesystem root directory
(#7496)

When using SELinux with legacy cgroups the tmpfs on /sys/fs/cgroup is by
default labelled as tmpfs_t. This label is also inherited by the "cpu"
and "cpuacct" symbolic links. Unfortunately the policy expects them to
be labelled as cgroup_t, which is used for all the actual cgroup
filesystems. Failure to do so results in a stream of denials.

This state cannot be fixed reliably when the cgroup filesystem structure
is set-up as the SELinux policy is not yet loaded at this
moment. It also cannot be fixed later as the root of the cgroup
filesystem is remounted read-only. In order to fix it the root of the
cgroup filesystem needs to be temporary remounted read-write, relabelled
and remounted back read-only.

(cherry picked from commit 8739f23e3c26bbf8b0296421578e56daa63cbf4b)
---
src/core/mount-setup.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index 521545e5c..7a2cae4a3 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -363,14 +363,22 @@ int mount_setup(bool loaded_policy) {
usec_t before_relabel, after_relabel;
char timespan[FORMAT_TIMESPAN_MAX];
+ mkdir_label("/run/systemd/policy-relabelling", 0755);
before_relabel = now(CLOCK_MONOTONIC);
nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+ /* Temporarily remount the root cgroup filesystem to give it a proper label. */
+ (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
+ label_fix("/sys/fs/cgroup", false, false);
+ nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+ (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
+
after_relabel = now(CLOCK_MONOTONIC);
- log_info("Relabelled /dev and /run in %s.",
+ mkdir_label("/run/systemd/policy-relabelled", 0755);
+ log_info("Relabelled /dev, /run and /sys/fs/cgroup in %s.",
format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel, 0));
}
#endif

91
SOURCES/0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch

@ -0,0 +1,91 @@
From 1707b9959e67e5e73987e1ff8a72189d24656fa0 Mon Sep 17 00:00:00 2001
From: Krzysztof Nowicki <krzysztof.a.nowicki+github@gmail.com>
Date: Wed, 28 Mar 2018 13:36:33 +0200
Subject: [PATCH] core: dont't remount /sys/fs/cgroup for relabel if not needed
(#8595)

The initial fix for relabelling the cgroup filesystem for
SELinux delivered in commit 8739f23e3 was based on the assumption that
the cgroup filesystem is already populated once mount_setup() is
executed, which was true for my system. What I wasn't aware is that this
is the case only when another instance of systemd was running before
this one, which can happen if systemd is used in the initrd (for ex. by
dracut).

In case of a clean systemd start-up the cgroup filesystem is actually
being populated after mount_setup() and does not need relabelling as at
that moment the SELinux policy is already loaded. Since however the root
cgroup filesystem was remounted read-only in the meantime this operation
will now fail.

To fix this check for the filesystem mount flags before relabelling and
only remount ro->rw->ro if necessary and leave the filesystem read-write
otherwise.

Fixes #7901.

(cherry picked from commit 6f7729c1767998110c4460c85c94435c5782a613)
---
src/core/mount-setup.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index 7a2cae4a3..ed493cbe3 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -25,6 +25,8 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <sys/statfs.h>
+#include <sys/statvfs.h>
#include <unistd.h>
#include <ftw.h>
@@ -337,6 +339,31 @@ static int nftw_cb(
return FTW_CONTINUE;
};
+
+static int relabel_cgroup_filesystems(void) {
+ int r;
+ struct statfs st;
+
+ /* Temporarily remount the root cgroup filesystem to give it a proper label. Do this
+ only when the filesystem has been already populated by a previous instance of systemd
+ running from initrd. Otherwise don't remount anything and leave the filesystem read-write
+ for the cgroup filesystems to be mounted inside. */
+ r = statfs("/sys/fs/cgroup", &st);
+ if (r < 0) {
+ return log_error_errno(errno, "Failed to determine mount flags for /sys/fs/cgroup: %m");
+ }
+
+ if (st.f_flags & ST_RDONLY)
+ (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
+
+ (void) label_fix("/sys/fs/cgroup", false, false);
+ nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+
+ if (st.f_flags & ST_RDONLY)
+ (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
+
+ return 0;
+}
#endif
int mount_setup(bool loaded_policy) {
@@ -369,11 +396,9 @@ int mount_setup(bool loaded_policy) {
nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
- /* Temporarily remount the root cgroup filesystem to give it a proper label. */
- (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
- label_fix("/sys/fs/cgroup", false, false);
- nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
- (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
+ r = relabel_cgroup_filesystems();
+ if (r < 0)
+ return r;
after_relabel = now(CLOCK_MONOTONIC);

188
SOURCES/0647-fix-race-between-daemon-reload-and-other-commands.patch

@ -0,0 +1,188 @@
From 13bcf85ffab4b4e67039599246604a3f5b503975 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Tue, 24 Apr 2018 15:19:38 +0200
Subject: [PATCH] fix race between daemon-reload and other commands

When "systemctl daemon-reload" is run at the same time as "systemctl
start foo", the latter might hang. That's because commands like start
wait for JobRemoved signal to know when the job is finished. But if the
job is finished during reloading, the signal is never sent.

The hang can be easily reproduced by running

# for ((N=1; N>0; N++)) ; do echo $N ; systemctl daemon-reload ; done
# for ((N=1; N>0; N++)) ; do echo $N ; systemctl start systemd-coredump.socket ; done

in two different terminals. The start command will hang after 1-2
iterations.

This keeps track of jobs that were started before reload and finished
during it and sends JobRemoved after the reload has finished.

(cherry picked from commit a7a7163df7fc8a9f794f6803b2f6c9c9b0745a1f)
---
src/core/job.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
src/core/job.h | 2 ++
src/core/manager.c | 15 +++++++++++++++
src/core/manager.h | 3 +++
4 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/src/core/job.c b/src/core/job.c
index 1861c8a63..275503169 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -53,6 +53,7 @@ Job* job_new_raw(Unit *unit) {
j->manager = unit->manager;
j->unit = unit;
j->type = _JOB_TYPE_INVALID;
+ j->reloaded = false;
return j;
}
@@ -74,7 +75,7 @@ Job* job_new(Unit *unit, JobType type) {
return j;
}
-void job_free(Job *j) {
+void job_unlink(Job *j) {
assert(j);
assert(!j->installed);
assert(!j->transaction_prev);
@@ -82,13 +83,28 @@ void job_free(Job *j) {
assert(!j->subject_list);
assert(!j->object_list);
- if (j->in_run_queue)
+ if (j->in_run_queue) {
LIST_REMOVE(run_queue, j->manager->run_queue, j);
+ j->in_run_queue = false;
+ }
- if (j->in_dbus_queue)
+ if (j->in_dbus_queue) {
LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
+ j->in_dbus_queue = false;
+ }
+
+ j->timer_event_source = sd_event_source_unref(j->timer_event_source);
+}
+
+void job_free(Job *j) {
+ assert(j);
+ assert(!j->installed);
+ assert(!j->transaction_prev);
+ assert(!j->transaction_next);
+ assert(!j->subject_list);
+ assert(!j->object_list);
- sd_event_source_unref(j->timer_event_source);
+ job_unlink(j);
sd_bus_track_unref(j->clients);
strv_free(j->deserialized_clients);
@@ -246,6 +262,7 @@ int job_install_deserialized(Job *j) {
*pj = j;
j->installed = true;
+ j->reloaded = true;
if (j->state == JOB_RUNNING)
j->unit->manager->n_running_jobs++;
@@ -790,6 +807,19 @@ static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
job_print_status_message(u, t, result);
}
+static int job_save_pending_finished_job(Job *j) {
+ int r;
+
+ assert(j);
+
+ r = set_ensure_allocated(&j->manager->pending_finished_jobs, NULL);
+ if (r < 0)
+ return r;
+
+ job_unlink(j);
+ return set_put(j->manager->pending_finished_jobs, j);
+}
+
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
Unit *u;
Unit *other;
@@ -829,7 +859,12 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
j->manager->n_failed_jobs ++;
job_uninstall(j);
- job_free(j);
+ /* Remember jobs started before the reload */
+ if (j->manager->n_reloading > 0 && j->reloaded) {
+ if (job_save_pending_finished_job(j) < 0)
+ job_free(j);
+ } else
+ job_free(j);
/* Fail depending jobs on failure */
if (result != JOB_DONE && recursive) {
diff --git a/src/core/job.h b/src/core/job.h
index 535052b48..4ae6f2802 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -172,10 +172,12 @@ struct Job {
bool sent_dbus_new_signal:1;
bool ignore_order:1;
bool irreversible:1;
+ bool reloaded:1;
};
Job* job_new(Unit *unit, JobType type);
Job* job_new_raw(Unit *unit);
+void job_unlink(Job *job);
void job_free(Job *job);
Job* job_install(Job *j);
int job_install_deserialized(Job *j);
diff --git a/src/core/manager.c b/src/core/manager.c
index 47b09e1e9..9c406bb5b 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -2702,6 +2702,18 @@ finish:
return r;
}
+static void manager_flush_finished_jobs(Manager *m) {
+ Job *j;
+
+ while ((j = set_steal_first(m->pending_finished_jobs))) {
+ bus_job_send_removed_signal(j);
+ job_free(j);
+ }
+
+ set_free(m->pending_finished_jobs);
+ m->pending_finished_jobs = NULL;
+}
+
int manager_reload(Manager *m) {
int r, q;
_cleanup_fclose_ FILE *f = NULL;
@@ -2784,6 +2796,9 @@ int manager_reload(Manager *m) {
assert(m->n_reloading > 0);
m->n_reloading--;
+ if (m->n_reloading <= 0)
+ manager_flush_finished_jobs(m);
+
m->send_reloading_done = true;
return r;
diff --git a/src/core/manager.h b/src/core/manager.h
index e91e7bd8b..90d2d982e 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -270,6 +270,9 @@ struct Manager {
/* non-zero if we are reloading or reexecuting, */
int n_reloading;
+ /* A set which contains all jobs that started before reload and finished
+ * during it */
+ Set *pending_finished_jobs;
unsigned n_installed_jobs;
unsigned n_failed_jobs;

223
SOURCES/0648-core-delay-adding-target-dependencies-until-all-unit.patch

@ -0,0 +1,223 @@
From 36226a9afe96bdffce9d0697be020f2ca9d7fe6f Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekletar@users.noreply.github.com>
Date: Fri, 23 Mar 2018 15:28:06 +0100
Subject: [PATCH] core: delay adding target dependencies until all units are
loaded and aliases resolved (#8381)

Currently we add target dependencies while we are loading units. This
can create ordering loops even if configuration doesn't contain any
loop. Take for example following configuration,

$ systemctl get-default
multi-user.target

$ cat /etc/systemd/system/test.service
[Unit]
After=default.target

[Service]
ExecStart=/bin/true

[Install]
WantedBy=multi-user.target

If we encounter such unit file early during manager start-up (e.g. load
queue is dispatched while enumerating devices due to SYSTEMD_WANTS in
udev rules) we would add stub unit default.target and we order it Before
test.service. At the same time we add implicit Before to
multi-user.target. Later we merge two units and we create ordering cycle
in the process.

To fix the issue we will now never add any target dependencies until we
loaded all the unit files and resolved all the aliases.

(cherry picked from commit 19496554e23ea4861ce780430052dcf86a2ffcba)

Resolves: #1368856
---
src/core/manager.c | 40 ++++++++++++++++++++++++++++++++++++++++
src/core/manager.h | 3 +++
src/core/unit.c | 46 ++++++++++++++++------------------------------
src/core/unit.h | 5 +++++
4 files changed, 64 insertions(+), 30 deletions(-)

diff --git a/src/core/manager.c b/src/core/manager.c
index 9c406bb5b..0466e4bb8 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1373,6 +1373,41 @@ Unit *manager_get_unit(Manager *m, const char *name) {
return hashmap_get(m->units, name);
}
+static int manager_dispatch_target_deps_queue(Manager *m) {
+ Unit *u;
+ unsigned k;
+ int r = 0;
+
+ static const UnitDependency deps[] = {
+ UNIT_REQUIRED_BY,
+ UNIT_REQUIRED_BY_OVERRIDABLE,
+ UNIT_WANTED_BY,
+ UNIT_BOUND_BY
+ };
+
+ assert(m);
+
+ while ((u = m->target_deps_queue)) {
+ assert(u->in_target_deps_queue);
+
+ LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
+ u->in_target_deps_queue = false;
+
+ for (k = 0; k < ELEMENTSOF(deps); k++) {
+ Unit *target;
+ Iterator i;
+
+ SET_FOREACH(target, u->dependencies[deps[k]], i) {
+ r = unit_add_default_target_dependency(u, target);
+ if (r < 0)
+ return r;
+ }
+ }
+ }
+
+ return r;
+}
+
unsigned manager_dispatch_load_queue(Manager *m) {
Unit *u;
unsigned n = 0;
@@ -1396,6 +1431,11 @@ unsigned manager_dispatch_load_queue(Manager *m) {
}
m->dispatching_load_queue = false;
+
+ /* Dispatch the units waiting for their target dependencies to be added now, as all targets that we know about
+ * should be loaded and have aliases resolved */
+ (void) manager_dispatch_target_deps_queue(m);
+
return n;
}
diff --git a/src/core/manager.h b/src/core/manager.h
index 90d2d982e..b0e4cad1f 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -114,6 +114,9 @@ struct Manager {
/* Units that should be realized */
LIST_HEAD(Unit, cgroup_queue);
+ /* Target units whose default target dependencies haven't been set yet */
+ LIST_HEAD(Unit, target_deps_queue);
+
sd_event *event;
/* We use two hash tables here, since the same PID might be
diff --git a/src/core/unit.c b/src/core/unit.c
index 22d9beed7..cfddce34d 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -519,6 +519,9 @@ void unit_free(Unit *u) {
u->manager->n_in_gc_queue--;
}
+ if (u->in_target_deps_queue)
+ LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
+
if (u->in_cgroup_queue)
LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
@@ -1065,6 +1068,18 @@ int unit_load_fragment_and_dropin_optional(Unit *u) {
return 0;
}
+void unit_add_to_target_deps_queue(Unit *u) {
+ Manager *m = u->manager;
+
+ assert(u);
+
+ if (u->in_target_deps_queue)
+ return;
+
+ LIST_PREPEND(target_deps_queue, m->target_deps_queue, u);
+ u->in_target_deps_queue = true;
+}
+
int unit_add_default_target_dependency(Unit *u, Unit *target) {
assert(u);
assert(target);
@@ -1091,32 +1106,6 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
return unit_add_dependency(target, UNIT_AFTER, u, true);
}
-static int unit_add_target_dependencies(Unit *u) {
-
- static const UnitDependency deps[] = {
- UNIT_REQUIRED_BY,
- UNIT_REQUIRED_BY_OVERRIDABLE,
- UNIT_WANTED_BY,
- UNIT_BOUND_BY
- };
-
- Unit *target;
- Iterator i;
- unsigned k;
- int r = 0;
-
- assert(u);
-
- for (k = 0; k < ELEMENTSOF(deps); k++)
- SET_FOREACH(target, u->dependencies[deps[k]], i) {
- r = unit_add_default_target_dependency(u, target);
- if (r < 0)
- return r;
- }
-
- return r;
-}
-
static int unit_add_slice_dependencies(Unit *u) {
assert(u);
@@ -1217,10 +1206,7 @@ int unit_load(Unit *u) {
}
if (u->load_state == UNIT_LOADED) {
-
- r = unit_add_target_dependencies(u);
- if (r < 0)
- goto fail;
+ unit_add_to_target_deps_queue(u);
r = unit_add_slice_dependencies(u);
if (r < 0)
diff --git a/src/core/unit.h b/src/core/unit.h
index 480e2e95f..dfec9cea0 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -162,6 +162,9 @@ struct Unit {
/* CGroup realize members queue */
LIST_FIELDS(Unit, cgroup_queue);
+ /* Target dependencies queue */
+ LIST_FIELDS(Unit, target_deps_queue);
+
/* PIDs we keep an eye on. Note that a unit might have many
* more, but these are the ones we care enough about to
* process SIGCHLD for */
@@ -228,6 +231,7 @@ struct Unit {
bool in_cleanup_queue:1;
bool in_gc_queue:1;
bool in_cgroup_queue:1;
+ bool in_target_deps_queue:1;
bool sent_dbus_new_signal:1;
@@ -498,6 +502,7 @@ void unit_add_to_load_queue(Unit *u);
void unit_add_to_dbus_queue(Unit *u);
void unit_add_to_cleanup_queue(Unit *u);
void unit_add_to_gc_queue(Unit *u);
+void unit_add_to_target_deps_queue(Unit *u);
int unit_merge(Unit *u, Unit *other);
int unit_merge_by_name(Unit *u, const char *other);

35
SOURCES/0649-man-correct-the-meaning-of-TimeoutStopSec.patch

@ -0,0 +1,35 @@
From 273a3d35df021128bd72e124d943cbb7b1c7194c Mon Sep 17 00:00:00 2001
From: Jan Synacek <jsynacek@redhat.com>
Date: Fri, 22 Jun 2018 09:11:49 +0200
Subject: [PATCH] man: correct the meaning of TimeoutStopSec=

Fixes: #9325
(cherry picked from commit 9a6da355a06e2b272717f2ac23e41945ce56eb6d)
Resolves: #1305509
---
man/systemd.service.xml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index a274db480..d147e449a 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -429,12 +429,12 @@
<varlistentry>
<term><varname>TimeoutStopSec=</varname></term>
- <listitem><para>Configures the time to wait for stop. If a
- service is asked to stop, but does not terminate in the
- specified time, it will be terminated forcibly via
- <constant>SIGTERM</constant>, and after another timeout of
- equal duration with <constant>SIGKILL</constant> (see
- <varname>KillMode=</varname> in
+ <listitem><para>This option serves two purposes. First, it configures the time to wait for each
+ <constant>ExecStop=</constant> command. If any of them times out, subsequent <constant>ExecStop=</constant> commands
+ are skipped and the service will be terminated by <constant>SIGTERM</constant>. If no <constant>ExecStop=</constant>
+ commands are specified, the service gets the <constant>SIGTERM</constant> immediately. Second, it configures the time
+ to wait for the service itself to stop. If it doesn't terminate in the specified time, it will be forcibly terminated
+ by <constant>SIGKILL</constant> (see <varname>KillMode=</varname> in
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
Takes a unit-less value in seconds, or a time span value such
as "5min 20s". Pass <literal>0</literal> to disable the

32
SOURCES/0650-rules-mark-hotplugged-memory-as-movable.patch

@ -0,0 +1,32 @@
From 7431c551954ad63fe61cda18888e1e89419bd631 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 20 Jul 2018 09:48:04 +0200
Subject: [PATCH] rules: mark hotplugged memory as movable

Otherwise the kernel is free to use to memory block also for storing
non-movable memory (any other memory except anonymous memory allocations
and page cache). If user later wants to hot unplug the memory the kernel
will return error in case that some non-movable memory has been place to
the memory block.

Marking hot plugged memory blocks as movable seems to be better
default. Users with specific needs are free to override this udev rule.

Resolves: #1563532
---
rules/40-redhat.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 34a1df9c4..26f726001 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,7 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online_movable"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

27
SOURCES/0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch

@ -0,0 +1,27 @@
From fa22d8e9697a0a896007998fdf2cabe7baf98bec Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Tue, 10 Jan 2017 17:36:46 +1000
Subject: [PATCH] udev: add ID_INPUT_SWITCH for devices with switch capability
(#5057)

(cherry picked from commit 64083a6078630372623bb1013a45d3bf31d8a836)

Resolves: #1597240
---
src/udev/udev-builtin-input_id.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 46f1c539d..d6ae07304 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -250,6 +250,9 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
test_key(dev, bitmask_ev, bitmask_key, test);
+
+ if (test_bit(EV_SW, bitmask_ev))
+ udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1");
}
devnode = udev_device_get_devnode(dev);

32
SOURCES/0652-rules-disable-support-for-Dell-IR-cameras.patch

@ -0,0 +1,32 @@
From e2a2326a283fe38463e637e34205c50ec3066424 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Wed, 18 Jul 2018 14:36:17 +0200
Subject: [PATCH] rules: disable support for Dell IR cameras

Resolves: #1591316
---
Makefile.am | 1 +
rules/40-redhat-disable-dell-ir-camera.rules | 2 ++
2 files changed, 3 insertions(+)
create mode 100644 rules/40-redhat-disable-dell-ir-camera.rules

diff --git a/Makefile.am b/Makefile.am
index cbc120dad..40ebbe98e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3523,6 +3523,7 @@ dist_udevrules_DATA += \
rules/95-udev-late.rules \
rules/40-redhat.rules \
rules/40-redhat-disable-lenovo-ir-camera.rules \
+ rules/40-redhat-disable-dell-ir-camera.rules \
rules/73-idrac.rules \
rules/80-net-name-slot.rules
diff --git a/rules/40-redhat-disable-dell-ir-camera.rules b/rules/40-redhat-disable-dell-ir-camera.rules
new file mode 100644
index 000000000..2806482a5
--- /dev/null
+++ b/rules/40-redhat-disable-dell-ir-camera.rules
@@ -0,0 +1,2 @@
+# Disable known IR cameras in Dell Notebooks
+SUBSYSTEM=="usb", ATTRS{idVendor}=="0BDA", ATTRS{idProduct}=="58F6", ATTR{authorized}="0"

36
SOURCES/0653-rpm-fix-systemd_user_post-macro.patch

@ -0,0 +1,36 @@
From dda4324fa0b1fb1e07dea18585df6962d8f34b0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tadej=20Jane=C5=BE?= <tadej.j@nez.si>
Date: Sun, 22 Nov 2015 20:38:05 +0100
Subject: [PATCH] rpm: fix %systemd_user_post() macro.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Escape "--user" and "--global" arguments with "\\" since rpm treats
arguments starting with "-" as macro options which causes "Unknown
option" rpm error.
Use %{expand:...} to force expansion of the inner macro. Otherwise %{?*}
is recursively defined as "\--user \--global {%?*}" which causes
"Too many levels of recursion in macro expansion" rpm error.

Thanks to Michael Mráka for helping me fix the above issues.

(cherry picked from commit e67ba783696f21782ad5c2ba00515d387016e785)
Related: #1582383
---
src/core/macros.systemd.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
index bea6ef1da..662791ccc 100644
--- a/src/core/macros.systemd.in
+++ b/src/core/macros.systemd.in
@@ -43,7 +43,7 @@ if [ $1 -eq 1 ] ; then \
fi \
%{nil}
-%systemd_user_post() %systemd_post --user --global %{?*}
+%systemd_user_post() %{expand:%systemd_post \\--user \\--global %%{?*}}
%systemd_preun() \
if [ $1 -eq 0 ] ; then \

35
SOURCES/0654-rpm-remove-confusing-user-before-global.patch

@ -0,0 +1,35 @@
From 4bc18a925e964f10b4e7ed92e8e0d84bf985c6a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sat, 19 May 2018 13:01:55 +0200
Subject: [PATCH] rpm: remove confusing --user before --global

Fixes #9027.

(cherry picked from commit 28d36da64a7a23a55e8d0a139f2620384fd058b3)
Resolves: #1582383
---
src/core/macros.systemd.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
index 662791ccc..3d6e41274 100644
--- a/src/core/macros.systemd.in
+++ b/src/core/macros.systemd.in
@@ -43,7 +43,7 @@ if [ $1 -eq 1 ] ; then \
fi \
%{nil}
-%systemd_user_post() %{expand:%systemd_post \\--user \\--global %%{?*}}
+%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}}
%systemd_preun() \
if [ $1 -eq 0 ] ; then \
@@ -56,7 +56,7 @@ fi \
%systemd_user_preun() \
if [ $1 -eq 0 ] ; then \
# Package removal, not upgrade \
- systemctl --no-reload --user --global disable %{?*} > /dev/null 2>&1 || : \
+ systemctl --global disable %{?*} > /dev/null 2>&1 || : \
fi \
%{nil}

58
SOURCES/0655-automount-handle-state-changes-of-the-corresponding-.patch

@ -0,0 +1,58 @@
From b4f506932592b991363b8be11e40b62f861bd032 Mon Sep 17 00:00:00 2001
From: Michael Olbrich <m.olbrich@pengutronix.de>
Date: Fri, 24 Jul 2015 22:25:28 +0200
Subject: [PATCH] automount: handle state changes of the corresponding mount
unit correctly

The expire timeout must be started/stopped if the corresponding mount unit
changes its state, e.g. it is started via local-fs.target or stopped by a
manual umount.

(cherry picked from commit 3dbadf9ef96e76f1bc472660ba5435dc0fa27a66)

Resolves: #1596241
---
src/core/automount.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/core/automount.c b/src/core/automount.c
index 08519e49c..f57782b9b 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -499,6 +499,7 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
int automount_update_mount(Automount *a, MountState old_state, MountState state) {
_cleanup_close_ int ioctl_fd = -1;
+ int r;
assert(a);
@@ -506,6 +507,9 @@ int automount_update_mount(Automount *a, MountState old_state, MountState state)
case MOUNT_MOUNTED:
case MOUNT_REMOUNTING:
automount_send_ready(a, a->tokens, 0);
+ r = automount_start_expire(a);
+ if (r < 0)
+ log_unit_warning_errno(UNIT(a)->id, r, "Failed to start expiration timer, ignoring: %m");
break;
case MOUNT_DEAD:
case MOUNT_UNMOUNTING:
@@ -518,6 +522,7 @@ int automount_update_mount(Automount *a, MountState old_state, MountState state)
case MOUNT_FAILED:
if (old_state != state)
automount_send_ready(a, a->tokens, -ENODEV);
+ (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
break;
default:
break;
@@ -768,10 +773,6 @@ static void automount_enter_running(Automount *a) {
goto fail;
}
- r = automount_start_expire(a);
- if (r < 0)
- log_unit_warning_errno(UNIT(a)->id, r, "Failed to start expiration timer, ignoring: %m");
-
automount_set_state(a, AUTOMOUNT_RUNNING);
return;

32
SOURCES/0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch

@ -0,0 +1,32 @@
From 210c9e5dd1e3d0e37a16225a63840d71b473684c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Jun 2015 12:05:11 +0200
Subject: [PATCH] man: document that SIGCONT always follows SIGTERM

As requested in #199.

(cherry picked from commit e8c53936316288ea3b33b5997b175862f0efef92)
Resolves: #1601794
---
man/systemd.kill.xml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml
index e57f0e724..1292f4f51 100644
--- a/man/systemd.kill.xml
+++ b/man/systemd.kill.xml
@@ -136,7 +136,13 @@
by <constant>SIGKILL</constant> (see above and below). For a
list of valid signals, see
<citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- Defaults to <constant>SIGTERM</constant>. </para></listitem>
+ Defaults to <constant>SIGTERM</constant>. </para>
+
+ <para>Note that right after sending the signal specified in
+ this setting systemd will always send
+ <constant>SIGCONT</constant>, to ensure that even suspended
+ tasks can be terminated cleanly.</para>
+ </listitem>
</varlistentry>
<varlistentry>

46
SOURCES/0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch

@ -0,0 +1,46 @@
From 6bc676b1a1bfa7145106f737a6747526ce662b93 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Mon, 23 Jul 2018 16:57:22 +0200
Subject: [PATCH] rules: add udev rule that automatically offline HW attached
to ACPI container

Resolves: #1597958
---
Makefile.am | 1 +
rules/40-redhat-hotunplug.rules | 14 ++++++++++++++
2 files changed, 15 insertions(+)
create mode 100644 rules/40-redhat-hotunplug.rules

diff --git a/Makefile.am b/Makefile.am
index 40ebbe98e..3995dcce8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3524,6 +3524,7 @@ dist_udevrules_DATA += \
rules/40-redhat.rules \
rules/40-redhat-disable-lenovo-ir-camera.rules \
rules/40-redhat-disable-dell-ir-camera.rules \
+ rules/40-redhat-hotunplug.rules \
rules/73-idrac.rules \
rules/80-net-name-slot.rules
diff --git a/rules/40-redhat-hotunplug.rules b/rules/40-redhat-hotunplug.rules
new file mode 100644
index 000000000..3befdaffc
--- /dev/null
+++ b/rules/40-redhat-hotunplug.rules
@@ -0,0 +1,14 @@
+# ACPI0004 container offline for Huawei Kunlun
+# do not edit this file, it will be overwritten on update
+
+SUBSYSTEM=="container", ACTION=="change", DEVPATH=="*/ACPI0004:??", \
+RUN+="/bin/sh -c ' \
+if [ $(cat /sys/$env{DEVPATH}/online) -eq 1 ]; then \
+ find -L /sys/$env{DEVPATH}/firmware_node/*/physical_node* -maxdepth 1 -name online | \
+ while read line; do \
+ if [ $(cat $line) -eq 1 ]; then \
+ /bin/echo 0 > $line; \
+ fi \
+ done; \
+ /bin/echo 0 > /sys/$env{DEVPATH}/online; \
+fi'"
\ No newline at end of file

25
SOURCES/0658-Revert-rules-mark-hotplugged-memory-as-movable.patch

@ -0,0 +1,25 @@
From e1311df43e9c63e72b1a6b329f5ffc9bcd0f37e1 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 16 Aug 2018 08:38:31 +0000
Subject: [PATCH] Revert "rules: mark hotplugged memory as movable"

This reverts commit 7431c551954ad63fe61cda18888e1e89419bd631.

Resolves: #1614686
---
rules/40-redhat.rules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 26f726001..34a1df9c4 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,7 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online_movable"
+SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

49
SOURCES/0659-rules-implement-new-memory-hotplug-policy.patch

@ -0,0 +1,49 @@
From c50b7bcbebcfebfce3a7e7fb77f88f4b590fb2b5 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 16 Aug 2018 09:31:51 +0000
Subject: [PATCH] rules: implement new memory hotplug policy

Our new policy is based on following motivations (assumptions),
* we want to allow the system to use hotplugged memory
* we want memory ballon inflation to work as expected in VMs (going for small
to big in terms of memory footprint)
* we want to allow memory hotplug and memory hot-unplug on high-end
enterprise server (we assume that node0 will have sufficient memory
resources and marking all memory as movable shouldn't be a problem)

Policy:
* nevert online memory on s390 (on both physical and z/VM)
* mark memory as "online_movable" on physical machines
* mark memory as "online" in VMs

If you have the feeling that all this is very wrong and we shouldn't
encode complex policies in udev rules you are absolutely right. However,
for now, we don't have any better place where to put it. In ideal world
we would have a user-space daemon that would be able to configure the
system wrt. to currently present HW and user-defined policy.

Resolves: #1614686
---
rules/40-redhat.rules | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
index 34a1df9c4..1b10e173d 100644
--- a/rules/40-redhat.rules
+++ b/rules/40-redhat.rules
@@ -4,7 +4,14 @@
SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
# Memory hotadd request
-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
+SUBSYSTEM!="memory", ACTION!="add", GOTO="memory_hotplug_end"
+PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
+
+ENV{.state}="online"
+PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
+ATTR{state}=="offline", ATTR{state}="$env{.state}"
+
+LABEL="memory_hotplug_end"
# reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"

48
SOURCES/0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch

@ -0,0 +1,48 @@
From 4b451af437d5d51b98d11d32130aac6938307798 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Fri, 17 Aug 2018 13:10:22 +0000
Subject: [PATCH] Revert "rules: add udev rule that automatically offline HW
attached to ACPI container"

This reverts commit 6bc676b1a1bfa7145106f737a6747526ce662b93.

Related: #1597958
---
Makefile.am | 1 -
rules/40-redhat-hotunplug.rules | 14 --------------
2 files changed, 15 deletions(-)
delete mode 100644 rules/40-redhat-hotunplug.rules

diff --git a/Makefile.am b/Makefile.am
index 3995dcce8..40ebbe98e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3524,7 +3524,6 @@ dist_udevrules_DATA += \
rules/40-redhat.rules \
rules/40-redhat-disable-lenovo-ir-camera.rules \
rules/40-redhat-disable-dell-ir-camera.rules \
- rules/40-redhat-hotunplug.rules \
rules/73-idrac.rules \
rules/80-net-name-slot.rules
diff --git a/rules/40-redhat-hotunplug.rules b/rules/40-redhat-hotunplug.rules
deleted file mode 100644
index 3befdaffc..000000000
--- a/rules/40-redhat-hotunplug.rules
+++ /dev/null
@@ -1,14 +0,0 @@
-# ACPI0004 container offline for Huawei Kunlun
-# do not edit this file, it will be overwritten on update
-
-SUBSYSTEM=="container", ACTION=="change", DEVPATH=="*/ACPI0004:??", \
-RUN+="/bin/sh -c ' \
-if [ $(cat /sys/$env{DEVPATH}/online) -eq 1 ]; then \
- find -L /sys/$env{DEVPATH}/firmware_node/*/physical_node* -maxdepth 1 -name online | \
- while read line; do \
- if [ $(cat $line) -eq 1 ]; then \
- /bin/echo 0 > $line; \
- fi \
- done; \
- /bin/echo 0 > /sys/$env{DEVPATH}/online; \
-fi'"
\ No newline at end of file

258
SOURCES/0661-cryptsetup-generator-introduce-basic-keydev-support.patch

@ -0,0 +1,258 @@
From aafa651e44df825abeec061f295f227862aad6d9 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Thu, 30 Aug 2018 08:45:11 +0000
Subject: [PATCH] cryptsetup-generator: introduce basic keydev support

Dracut has a support for unlocking encrypted drives with keyfile stored
on the external drive. This support is included in the generated initrd
only if systemd module is not included.

When systemd is used in initrd then attachment of encrypted drives is
handled by systemd-cryptsetup tools. Our generator has support for
keyfile, however, it didn't support keyfile on the external block
device (keydev).

This commit introduces basic keydev support. Keydev can be specified per
luks.uuid on the kernel command line. Keydev is automatically mounted
during boot and we look for keyfile in the keydev
mountpoint (i.e. keyfile path is prefixed with the keydev mount point
path). After crypt device is attached we automatically unmount
where keyfile resides.

Example:
rd.luks.key=70bc876b-f627-4038-9049-3080d79d2165=/key:LABEL=KEYDEV

(cherry-picked from commit 70f5f48eb891b12e969577b464de61e15a2593da)

Resolves: #1619743
---
man/systemd-cryptsetup-generator.xml | 14 ++++
src/cryptsetup/cryptsetup-generator.c | 122 ++++++++++++++++++++++++++++++++--
2 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml
index b6270358e..8cfd8b6a8 100644
--- a/man/systemd-cryptsetup-generator.xml
+++ b/man/systemd-cryptsetup-generator.xml
@@ -168,6 +168,20 @@
to the one specified by <varname>rd.luks.key=</varname> or
<varname>luks.key=</varname> of the corresponding UUID, or the
password file that was specified without a UUID.</para>
+
+ <para>It is also possible to specify an external device which
+ should be mounted before we attempt to unlock the LUKS device.
+ systemd-cryptsetup will use password file stored on that
+ device. Device containing password file is specified by
+ appending colon and a device identifier to the password file
+ path. For example,
+ <varname>rd.luks.uuid=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40
+ <varname>rd.luks.key=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40=/keyfile:LABEL=keydev.
+ Hence, in this case, we will attempt to mount file system
+ residing on the block device with label <literal>keydev</literal>.
+ This syntax is for now only supported on a per-device basis,
+ i.e. you have to specify LUKS device UUID.</para>
+
<para><varname>rd.luks.key=</varname>
is honored only by initial RAM disk
(initrd) while
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 5f29093f5..42c30c5ca 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -38,6 +38,7 @@
typedef struct crypto_device {
char *uuid;
char *keyfile;
+ char *keydev;
char *name;
char *options;
bool create;
@@ -51,14 +52,79 @@ static Hashmap *arg_disks = NULL;
static char *arg_default_options = NULL;
static char *arg_default_keyfile = NULL;
+static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) {
+ _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *p = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ int r;
+
+ assert(name);
+ assert(keydev);
+ assert(unit);
+ assert(mount);
+
+ r = mkdir_parents("/run/systemd/cryptsetup", 0755);
+ if (r < 0)
+ return r;
+
+ r = mkdir("/run/systemd/cryptsetup", 0700);
+ if (r < 0)
+ return r;
+
+ where = strjoin("/run/systemd/cryptsetup/keydev-", name, NULL);
+ if (!where)
+ return -ENOMEM;
+
+ r = mkdir(where, 0700);
+ if (r < 0)
+ return r;
+
+ u = unit_name_from_path(where, ".mount");
+ if (!u)
+ return -ENOMEM;
+
+ what = fstab_node_to_udev_node(keydev);
+ if (!what)
+ return -ENOMEM;
+
+ p = strjoin(arg_dest, "/", u, NULL);
+ if (!p)
+ return log_oom();
+
+ f = fopen(p, "wxe");
+ if (!f)
+ return log_error_errno(errno, "Failed to create unit file %s: %m", p);
+
+ fprintf(f,
+ "# Automatically generated by systemd-cryptsetup-generator\n\n"
+ "[Unit]\n"
+ "DefaultDependencies=no\n\n"
+ "[Mount]\n"
+ "What=%s\n"
+ "Where=%s\n"
+ "Options=ro\n", what, where);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ return r;
+
+ *unit = u;
+ u = NULL;
+
+ *mount = where;
+ where = NULL;
+
+ return 0;
+}
+
static int create_disk(
const char *name,
const char *device,
+ const char *keydev,
const char *password,
const char *options) {
_cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *to = NULL, *e = NULL,
- *filtered = NULL;
+ *filtered = NULL, *keydev_mount = NULL, *keyfile_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
bool noauto, nofail, tmp, swap, netdev;
char *from;
@@ -98,6 +164,9 @@ static int create_disk(
if (!d)
return log_oom();
+ if (keydev && !password)
+ return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m");
+
f = fopen(p, "wxe");
if (!f)
return log_error_errno(errno, "Failed to create unit file %s: %m", p);
@@ -115,6 +184,20 @@ static int create_disk(
"After=%s\n",
netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
+ if (keydev) {
+ _cleanup_free_ char *unit = NULL;
+
+ r = generate_keydev_mount(name, keydev, &unit, &keydev_mount);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate keydev mount unit: %m");
+
+ keyfile_path = prefix_root(keydev_mount, password);
+ if (!keyfile_path)
+ return log_oom();
+
+ password = keyfile_path;
+ }
+
if (!nofail)
fprintf(f,
"Before=%s\n",
@@ -181,6 +264,11 @@ static int create_disk(
"ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
name);
+ if (keydev)
+ fprintf(f,
+ "ExecStartPost=/bin/umount '%s'\n\n",
+ keydev_mount);
+
fflush(f);
if (ferror(f))
return log_error_errno(errno, "Failed to write file %s: %m", p);
@@ -248,6 +336,7 @@ static void free_arg_disks(void) {
while ((d = hashmap_steal_first(arg_disks))) {
free(d->uuid);
free(d->keyfile);
+ free(d->keydev);
free(d->name);
free(d->options);
free(d);
@@ -335,13 +424,36 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
if (r == 2) {
+ char *c;
+ _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+
d = get_crypto_device(uuid);
if (!d)
return log_oom();
+ c = strrchr(uuid_value, ':');
+ if (!c) {
+ free(d->keyfile);
+ d->keyfile = uuid_value;
+ uuid_value = NULL;
+
+ return 0;
+ }
+
+ *c = '\0';
+ keyfile = strdup(uuid_value);
+ keydev = strdup(++c);
+
+ if (!keyfile || !keydev)
+ return log_oom();
+
free(d->keyfile);
- d->keyfile = uuid_value;
- uuid_value = NULL;
+ d->keyfile = keyfile;
+ keyfile = NULL;
+
+ free(d->keydev);
+ d->keydev = keydev;
+ keydev = NULL;
} else if (free_and_strdup(&arg_default_keyfile, value))
return log_oom();
@@ -420,7 +532,7 @@ static int add_crypttab_devices(void) {
continue;
}
- r = create_disk(name, device, keyfile, (d && d->options) ? d->options : options);
+ r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options);
if (r < 0)
return r;
@@ -460,7 +572,7 @@ static int add_proc_cmdline_devices(void) {
else
options = "timeout=0";
- r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, options);
+ r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options);
if (r < 0)
return r;
}

38
SOURCES/0662-cryptsetup-generator-don-t-return-error-if-target-di.patch

@ -0,0 +1,38 @@
From 8f47d483dc4e0510977c8868278148c476f58c17 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 4 Sep 2018 19:51:14 +0200
Subject: [PATCH] cryptsetup-generator: don't return error if target directory
already exists

Related: #1619743
---
src/cryptsetup/cryptsetup-generator.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index 42c30c5ca..a9598180c 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -63,11 +63,11 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
assert(mount);
r = mkdir_parents("/run/systemd/cryptsetup", 0755);
- if (r < 0)
+ if (r < 0 && r != -EEXIST)
return r;
r = mkdir("/run/systemd/cryptsetup", 0700);
- if (r < 0)
+ if (r < 0 && errno != EEXIST)
return r;
where = strjoin("/run/systemd/cryptsetup/keydev-", name, NULL);
@@ -75,7 +75,7 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
return -ENOMEM;
r = mkdir(where, 0700);
- if (r < 0)
+ if (r < 0 && errno != EEXIST)
return r;
u = unit_name_from_path(where, ".mount");

62
SOURCES/0663-cryptsetup-generator-allow-whitespace-characters-in-.patch

@ -0,0 +1,62 @@
From afcf3919f5db85a00352a9937c9a5cb9c7b30269 Mon Sep 17 00:00:00 2001
From: Michal Sekletar <msekleta@redhat.com>
Date: Tue, 4 Sep 2018 20:03:34 +0200
Subject: [PATCH] cryptsetup-generator: allow whitespace characters in keydev
specification

For example, <luks.uuid>=/keyfile:LABEL="KEYFILE FS" previously wouldn't
work, because we truncated label at the first whitespace character,
i.e. LABEL="KEYFILE".

Related: #1619743
---
src/cryptsetup/cryptsetup-generator.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index a9598180c..7b90d2615 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -421,27 +421,36 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
return log_oom();
} else if (STR_IN_SET(key, "luks.key", "rd.luks.key") && value) {
+ int n;
- r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
- if (r == 2) {
+ r = sscanf(value, "%m[0-9a-fA-F-]=%n", &uuid, &n);
+ if (r == 1) {
char *c;
+ const char *keyspec;
_cleanup_free_ char *keyfile = NULL, *keydev = NULL;
d = get_crypto_device(uuid);
if (!d)
return log_oom();
- c = strrchr(uuid_value, ':');
+ keyspec = value + n;
+
+ c = strrchr(keyspec, ':');
if (!c) {
+ /* No keydev specified */
+ keyfile = strdup(keyspec);
+ if (!keyfile)
+ return log_oom();
+
free(d->keyfile);
- d->keyfile = uuid_value;
- uuid_value = NULL;
+ d->keyfile = keyfile;
+ keyfile = NULL;
return 0;
}
*c = '\0';
- keyfile = strdup(uuid_value);
+ keyfile = strdup(keyspec);
keydev = strdup(++c);
if (!keyfile || !keydev)

50
SOURCES/0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch

@ -0,0 +1,50 @@
From d772781b2810ae71bace24cce05f255212a348ed Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Thu, 8 Oct 2015 19:06:06 +0200
Subject: [PATCH] Make sure the mount units pulled by 'RequiresMountsFor=' are
loaded (if they exist)

We should make sure that mount units involved by 'RequiresMountsFor='
directives are really loaded if not required by any others units so
that Requires= dependencies on the mount units are applied and thus
the mount unit dependencies are started.

(cherry-picked from commit c7c89abb9edf9320246482bf4a8e0656199281ae)

Resolves: #1619743
---
src/core/unit.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/core/unit.c b/src/core/unit.c
index cfddce34d..e8532a057 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1131,13 +1131,23 @@ static int unit_add_mount_dependencies(Unit *u) {
char prefix[strlen(*i) + 1];
PATH_FOREACH_PREFIX_MORE(prefix, *i) {
+ _cleanup_free_ char *p = NULL;
Unit *m;
- r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
- if (r < 0)
- return r;
- if (r == 0)
+ p = unit_name_from_path(prefix, ".mount");
+ if (!p)
+ return -ENOMEM;
+
+ m = manager_get_unit(u->manager, p);
+ if (!m) {
+ /* Make sure to load the mount unit if
+ * it exists. If so the dependencies
+ * on this unit will be added later
+ * during the loading of the mount
+ * unit. */
+ (void) manager_load_unit_prepare(u->manager, p, NULL, NULL, &m);
continue;
+ }
if (m == u)
continue;

122
SPECS/systemd.spec

@ -3,12 +3,11 @@
# directory. # directory.
%global __requires_exclude pkg-config %global __requires_exclude pkg-config
%global _hardened_build 1 %global _hardened_build 1
%global optflags %(echo %{optflags} | sed 's/-O3/-O2/')


Name: systemd Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 219 Version: 219
Release: 57%{?dist} Release: 62%{?dist}
# For a breakdown of the licensing, see README # For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+ License: LGPLv2+ and MIT and GPLv2+
Summary: A System and Service Manager Summary: A System and Service Manager
@ -653,6 +652,57 @@ Patch0610: 0610-sd-journal-properly-handle-inotify-queue-overflow.patch
Patch0611: 0611-sd-journal-make-sure-it-s-safe-to-call-sd_journal_pr.patch Patch0611: 0611-sd-journal-make-sure-it-s-safe-to-call-sd_journal_pr.patch
Patch0612: 0612-journalctl-Periodically-call-sd_journal_process-in-j.patch Patch0612: 0612-journalctl-Periodically-call-sd_journal_process-in-j.patch
Patch0613: 0613-sd-journal-when-picking-up-a-new-file-compare-inode-.patch Patch0613: 0613-sd-journal-when-picking-up-a-new-file-compare-inode-.patch
Patch0614: 0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch
Patch0615: 0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch
Patch0616: 0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch
Patch0617: 0617-man-udevadm-remove-superfluous-version-from-subcomma.patch
Patch0618: 0618-man-udevadm-correctly-show-the-short-version-of-exit.patch
Patch0619: 0619-core-timer-downgrade-message-about-random-time-addit.patch
Patch0620: 0620-fd-util-add-new-acquire_data_fd-API-helper.patch
Patch0621: 0621-systemd-analyze-make-dump-work-for-large-of-units.patch
Patch0622: 0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch
Patch0623: 0623-cryptsetup-support-LUKS2-on-disk-format.patch
Patch0624: 0624-core-scope-fix-missing-fragment_path.patch
Patch0625: 0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch
Patch0626: 0626-rules-disable-support-for-Lenovo-IR-cameras.patch
Patch0627: 0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch
Patch0628: 0628-core-fix-confusing-logging-of-instantaneous-jobs.patch
Patch0629: 0629-core-correct-return-value-from-reload-methods.patch
Patch0630: 0630-core-always-try-harder-to-get-unit-status-message-fo.patch
Patch0631: 0631-core-unit_get_status_message_format-never-returns-NU.patch
Patch0632: 0632-core-try-harder-to-get-job-completion-messages-too.patch
Patch0633: 0633-core-remove-generic-job-completion-messages-from-uni.patch
Patch0634: 0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch
Patch0635: 0635-core-log-completion-of-remaining-job-types.patch
Patch0636: 0636-core-adjust-job-completion-message-log-levels.patch
Patch0637: 0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch
Patch0638: 0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch
Patch0639: 0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
Patch0640: 0640-core-Implement-timeout-based-umount-remount-limit.patch
Patch0641: 0641-core-Implement-sync_with_progress.patch
Patch0642: 0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch
Patch0643: 0643-journal-forward-messages-from-dev-log-unmodified-to-.patch
Patch0644: 0644-tmpfiles-use-safe_glob.patch
Patch0645: 0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch
Patch0646: 0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch
Patch0647: 0647-fix-race-between-daemon-reload-and-other-commands.patch
Patch0648: 0648-core-delay-adding-target-dependencies-until-all-unit.patch
Patch0649: 0649-man-correct-the-meaning-of-TimeoutStopSec.patch
Patch0650: 0650-rules-mark-hotplugged-memory-as-movable.patch
Patch0651: 0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch
Patch0652: 0652-rules-disable-support-for-Dell-IR-cameras.patch
Patch0653: 0653-rpm-fix-systemd_user_post-macro.patch
Patch0654: 0654-rpm-remove-confusing-user-before-global.patch
Patch0655: 0655-automount-handle-state-changes-of-the-corresponding-.patch
Patch0656: 0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch
Patch0657: 0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch
Patch0658: 0658-Revert-rules-mark-hotplugged-memory-as-movable.patch
Patch0659: 0659-rules-implement-new-memory-hotplug-policy.patch
Patch0660: 0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch
Patch0661: 0661-cryptsetup-generator-introduce-basic-keydev-support.patch
Patch0662: 0662-cryptsetup-generator-don-t-return-error-if-target-di.patch
Patch0663: 0663-cryptsetup-generator-allow-whitespace-characters-in-.patch
Patch0664: 0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch


%global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);} %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);}


@ -705,7 +755,7 @@ Requires(pre): /usr/sbin/groupadd
Requires: dbus Requires: dbus
Requires: %{name}-libs = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release}
Requires: kmod >= 18-4 Requires: kmod >= 18-4
Requires: powerel-release >= 7 Requires: redhat-release >= 7.0
Requires: diffutils Requires: diffutils


Provides: /bin/systemctl Provides: /bin/systemctl
@ -1050,6 +1100,9 @@ systemctl stop systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-
systemd-machine-id-setup >/dev/null 2>&1 || : systemd-machine-id-setup >/dev/null 2>&1 || :
/usr/lib/systemd/systemd-random-seed save >/dev/null 2>&1 || : /usr/lib/systemd/systemd-random-seed save >/dev/null 2>&1 || :
systemctl daemon-reexec >/dev/null 2>&1 || : systemctl daemon-reexec >/dev/null 2>&1 || :
for u in `systemctl show -p Id --state=active \*.automount | cut -d = -f 2`; do
systemctl try-restart $u >/dev/null 2>&1 || :
done
systemctl start systemd-udevd.service >/dev/null 2>&1 || : systemctl start systemd-udevd.service >/dev/null 2>&1 || :
udevadm hwdb --update >/dev/null 2>&1 || : udevadm hwdb --update >/dev/null 2>&1 || :
journalctl --update-catalog >/dev/null 2>&1 || : journalctl --update-catalog >/dev/null 2>&1 || :
@ -1367,7 +1420,7 @@ fi
%ghost %dir %{_localstatedir}/lib/systemd/coredump %ghost %dir %{_localstatedir}/lib/systemd/coredump
%ghost %dir %{_localstatedir}/lib/systemd/backlight %ghost %dir %{_localstatedir}/lib/systemd/backlight
%ghost %dir %{_localstatedir}/lib/systemd/rfkill %ghost %dir %{_localstatedir}/lib/systemd/rfkill
%ghost %{_localstatedir}/lib/systemd/random-seed %ghost %attr(0600, root, root) %{_localstatedir}/lib/systemd/random-seed
%ghost %{_localstatedir}/lib/systemd/clock %ghost %{_localstatedir}/lib/systemd/clock
%ghost %{_localstatedir}/lib/systemd/catalog/database %ghost %{_localstatedir}/lib/systemd/catalog/database
%ghost %attr(0664,root,utmp) %{_localstatedir}/run/utmp %ghost %attr(0664,root,utmp) %{_localstatedir}/run/utmp
@ -1390,7 +1443,7 @@ fi
%config(noreplace) %{_sysconfdir}/rsyslog.d/listen.conf %config(noreplace) %{_sysconfdir}/rsyslog.d/listen.conf
%config(noreplace) %{_sysconfdir}/yum/protected.d/systemd.conf %config(noreplace) %{_sysconfdir}/yum/protected.d/systemd.conf
%config(noreplace) %{_sysconfdir}/pam.d/systemd-user %config(noreplace) %{_sysconfdir}/pam.d/systemd-user
%ghost %{_sysconfdir}/udev/hwdb.bin %ghost %attr(0444, root, root) %{_sysconfdir}/udev/hwdb.bin
%{_rpmconfigdir}/macros.d/macros.systemd %{_rpmconfigdir}/macros.d/macros.systemd
%{_sysconfdir}/xdg/systemd %{_sysconfdir}/xdg/systemd
%{_sysconfdir}/rc.d/init.d/README %{_sysconfdir}/rc.d/init.d/README
@ -1398,7 +1451,7 @@ fi
%ghost %config(noreplace) %{_sysconfdir}/localtime %ghost %config(noreplace) %{_sysconfdir}/localtime
%ghost %config(noreplace) %{_sysconfdir}/vconsole.conf %ghost %config(noreplace) %{_sysconfdir}/vconsole.conf
%ghost %config(noreplace) %{_sysconfdir}/locale.conf %ghost %config(noreplace) %{_sysconfdir}/locale.conf
%ghost %config(noreplace) %{_sysconfdir}/machine-id %ghost %attr(0444, root, root) %config(noreplace) %{_sysconfdir}/machine-id
%ghost %config(noreplace) %{_sysconfdir}/machine-info %ghost %config(noreplace) %{_sysconfdir}/machine-info
%dir %{_sysconfdir}/X11/xorg.conf.d %dir %{_sysconfdir}/X11/xorg.conf.d
%ghost %config(noreplace) %{_sysconfdir}/X11/xorg.conf.d/00-keyboard.conf %ghost %config(noreplace) %{_sysconfdir}/X11/xorg.conf.d/00-keyboard.conf
@ -1626,6 +1679,63 @@ fi
%{_mandir}/man8/systemd-resolved.* %{_mandir}/man8/systemd-resolved.*


%changelog %changelog
* Fri Sep 07 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-62
- cryptsetup-generator: introduce basic keydev support (#1619743)
- cryptsetup-generator: don't return error if target directory already exists (#1619743)
- cryptsetup-generator: allow whitespace characters in keydev specification (#1619743)
- Make sure the mount units pulled by 'RequiresMountsFor=' are loaded (if they exist) (#1619743)

* Fri Aug 31 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-61
- restart automounts unit on update (#1596241)

* Fri Aug 17 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-60
- Revert "rules: mark hotplugged memory as movable" (#1614686)
- rules: implement new memory hotplug policy (#1614686)
- Revert "rules: add udev rule that automatically offline HW attached to ACPI container" (#1597958)

* Wed Jul 25 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-59
- man: correct the meaning of TimeoutStopSec= (#1305509)
- rules: mark hotplugged memory as movable (#1563532)
- udev: add ID_INPUT_SWITCH for devices with switch capability (#5057) (#1597240)
- rules: disable support for Dell IR cameras (#1591316)
- rpm: fix %systemd_user_post() macro. (#1582383)
- rpm: remove confusing --user before --global (#1582383)
- automount: handle state changes of the corresponding mount unit correctly (#1596241)
- man: document that SIGCONT always follows SIGTERM (#1601794)
- rules: add udev rule that automatically offline HW attached to ACPI container (#1597958)

* Thu Jun 21 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-58
- tmpfiles: don't skip cleanup of read-only root owned files if TMPFILES_AGE_ALL is set (#1533638)
- timer: we already got the trigger before, no need to call UNIT_TRIGGER again (#1549119)
- doc: fix links to binfmt_misc kernel documentation (#1572244)
- man/udevadm: remove superfluous --version from subcommand (#1553076)
- man/udevadm: correctly show the short version of --exit (#1552712)
- core/timer: downgrade message about random time addition (#5229) (#1587906)
- fd-util: add new acquire_data_fd() API helper (#1446095)
- systemd-analyze: make dump work for large # of units (#1446095)
- use max. message size allowed by DBus spec (#8936) (#1446095)
- cryptsetup: support LUKS2 on-disk format (#1573838)
- units: don't put udev to its own mount namespace with slave propagation (#1432211)
- rules: disable support for Lenovo IR cameras (#1540418)
- core: make sure "systemctl reload-or-try-restart is actually a noop if a unit is not running (#1191920)
- core: fix confusing logging of instantaneous jobs (#1506256)
- core: correct return value from reload methods (#1506256)
- core: always try harder to get unit status message format string (#1506256)
- core: unit_get_status_message_format() never returns NULL (#1506256)
- core: try harder to get job completion messages too (#1506256)
- core: remove generic job completion messages from unit vtables (#1506256)
- core: do not log done failed-condition jobs as if unit started (#1506256)
- core: log completion of remaining job types (#1506256)
- core: adjust job completion message log levels (#1506256)
- mount: add new LazyUnmount= setting for mount units, mapping to umount(8)'s "-l" switch (#3827) (#1497264)
- rules: Add MODEL_ID for NVMe device (#7037) (#1397264)
- umount: always use MNT_FORCE in umount_all() (#7213) (#1571098)
- core: Implement timeout based umount/remount limit (#1571098)
- core: Implement sync_with_progress() (#1571098)
- journal: forward messages from /dev/log unmodified to syslog.socket (#1409659)
- tmpfiles: use safe_glob() (#1436004)
- core: delay adding target dependencies until all units are loaded and aliases resolved (#8381) (#1368856)

* Tue Feb 20 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-57 * Tue Feb 20 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-57
- sd-journal: properly handle inotify queue overflow (#1540538) - sd-journal: properly handle inotify queue overflow (#1540538)
- sd-journal: make sure it's safe to call sd_journal_process() before the first sd_journal_wait() (#1540538) - sd-journal: make sure it's safe to call sd_journal_process() before the first sd_journal_wait() (#1540538)

Loading…
Cancel
Save