basebuilder_pel7x64builder0
6 years ago
52 changed files with 4597 additions and 6 deletions
@ -0,0 +1,41 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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