basebuilder_pel7x64builder0
6 years ago
52 changed files with 4597 additions and 6 deletions
@ -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); |
@ -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; |
@ -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 |
@ -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> |
@ -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> |
@ -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) { |
@ -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; |
||||||
|
} |
@ -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"/> |
@ -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 |
@ -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; |
@ -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); |
@ -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 |
@ -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 |
@ -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: |
@ -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); |
||||||
|
|
@ -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) { |
@ -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; |
||||||
|
|
@ -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)); |
@ -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; |
||||||
|
|
@ -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.", |
@ -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); |
||||||
|
|
@ -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) { |
@ -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); |
@ -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; |
||||||
|
|
@ -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}" |
@ -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; |
||||||
|
|
@ -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; \ |
||||||
|
+ }) |
||||||
|
+ |
@ -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) { |
||||||
|
|
@ -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; |
||||||
|
|
@ -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); |
@ -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); |
@ -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 |
@ -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); |
||||||
|
|
@ -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; |
@ -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); |
@ -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 |
@ -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" |
@ -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); |
@ -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" |
@ -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 \ |
@ -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} |
||||||
|
|
@ -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; |
||||||
|
|
@ -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> |
@ -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 |
@ -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" |
@ -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" |
@ -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 |
@ -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; |
||||||
|
} |
@ -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"); |
@ -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) |
@ -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; |
||||||
|
|
Loading…
Reference in new issue