[systemd/f21] Fix for #1099299

Zbigniew Jędrzejewski-Szmek zbyszek at fedoraproject.org
Tue Oct 21 03:29:31 UTC 2014


commit 51ba67c89ae43e4a0a0e48e76dfa6131a5ef1c88
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Thu Oct 16 20:40:49 2014 -0400

    Fix for #1099299

 ...continue-switch-root-even-if-umount-fails.patch |   58 +++++++++++++
 ...md-log-deserialization-errors-as-warnings.patch |   87 ++++++++++++++++++++
 ...stemd-try-harder-to-bind-to-notify-socket.patch |   46 ++++++++++
 ...s-remove-dev-log-to-always-create-symlink.patch |   26 ++++++
 systemd.spec                                       |   10 ++-
 5 files changed, 226 insertions(+), 1 deletions(-)
---
diff --git a/0578-systemd-continue-switch-root-even-if-umount-fails.patch b/0578-systemd-continue-switch-root-even-if-umount-fails.patch
new file mode 100644
index 0000000..e8293f3
--- /dev/null
+++ b/0578-systemd-continue-switch-root-even-if-umount-fails.patch
@@ -0,0 +1,58 @@
+From 94467d852e939669c76fdca0fddf1944e1d6fecb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 16 Oct 2014 19:12:55 -0500
+Subject: [PATCH] systemd: continue switch-root even if umount fails
+
+Leaving the old root around seems better than aborting the
+switch.
+---
+ src/core/main.c          |  2 +-
+ src/shared/switch-root.c | 15 +++++++--------
+ 2 files changed, 8 insertions(+), 9 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 44373cc7ef..0388f46c36 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1857,7 +1857,7 @@ finish:
+                         /* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */
+                         r = switch_root(switch_root_dir, "/mnt", true, MS_MOVE);
+                         if (r < 0)
+-                                log_error("Failed to switch root, ignoring: %s", strerror(-r));
++                                log_error("Failed to switch root, trying to continue: %s", strerror(-r));
+                 }
+ 
+                 args_size = MAX(6, argc+1);
+diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c
+index 5f075e6003..bac0e5c349 100644
+--- a/src/shared/switch-root.c
++++ b/src/shared/switch-root.c
+@@ -62,10 +62,9 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot,
+                 return -errno;
+         }
+ 
+-        /* Work-around for a kernel bug: for some reason the kernel
+-         * refuses switching root if any file systems are mounted
+-         * MS_SHARED. Hence remount them MS_PRIVATE here as a
+-         * work-around.
++        /* Work-around for kernel design: the kernel refuses switching
++         * root if any file systems are mounted MS_SHARED. Hence
++         * remount them MS_PRIVATE here as a work-around.
+          *
+          * https://bugzilla.redhat.com/show_bug.cgi?id=847418 */
+         if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL) < 0)
+@@ -128,10 +127,10 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot,
+ 
+                 /* Immediately get rid of the old root, if detach_oldroot is set.
+                  * Since we are running off it we need to do this lazily. */
+-                if (detach_oldroot && umount2(oldroot, MNT_DETACH) < 0) {
+-                        log_error("Failed to umount old root dir %s: %m", oldroot);
+-                        return -errno;
+-                }
++                if (detach_oldroot && umount2(oldroot, MNT_DETACH) < 0)
++                        log_error("Failed to lazily umount old root dir %s, %s: %m",
++                                  oldroot,
++                                  errno == ENOENT ? "ignoring" : "leaving it around");
+ 
+         } else if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) {
+                 log_error("Failed to mount moving %s to /: %m", new_root);
diff --git a/0579-systemd-log-deserialization-errors-as-warnings.patch b/0579-systemd-log-deserialization-errors-as-warnings.patch
new file mode 100644
index 0000000..b8cb152
--- /dev/null
+++ b/0579-systemd-log-deserialization-errors-as-warnings.patch
@@ -0,0 +1,87 @@
+From 457d8b69d5365eb20d39391e2590304a923e9bd5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 16 Oct 2014 19:13:45 -0500
+Subject: [PATCH] systemd: log deserialization errors as warnings
+
+If we failed to parse something that we wrote ourselves,
+things are seriously off. This is also likely to lead to
+problems futher on.
+---
+ src/core/manager.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/src/core/manager.c b/src/core/manager.c
+index e0c1cd187e..1bf75e20b0 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -354,7 +354,7 @@ static int manager_setup_signals(Manager *m) {
+                 return r;
+ 
+         /* Process signals a bit earlier than the rest of things, but
+-         * later that notify_fd processing, so that the notify
++         * later than notify_fd processing, so that the notify
+          * processing can still figure out to which process/service a
+          * message belongs, before we reap the process. */
+         r = sd_event_source_set_priority(m->signal_event_source, -5);
+@@ -2229,7 +2229,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+                         uint32_t id;
+ 
+                         if (safe_atou32(l+15, &id) < 0)
+-                                log_debug("Failed to parse current job id value %s", l+15);
++                                log_warning("Failed to parse current job id value %s", l+15);
+                         else
+                                 m->current_job_id = MAX(m->current_job_id, id);
+ 
+@@ -2237,7 +2237,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+                         uint32_t n;
+ 
+                         if (safe_atou32(l+17, &n) < 0)
+-                                log_debug("Failed to parse installed jobs counter %s", l+17);
++                                log_warning("Failed to parse installed jobs counter %s", l+17);
+                         else
+                                 m->n_installed_jobs += n;
+ 
+@@ -2245,7 +2245,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+                         uint32_t n;
+ 
+                         if (safe_atou32(l+14, &n) < 0)
+-                                log_debug("Failed to parse failed jobs counter %s", l+14);
++                                log_warning("Failed to parse failed jobs counter %s", l+14);
+                         else
+                                 m->n_failed_jobs += n;
+ 
+@@ -2254,7 +2254,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+ 
+                         b = parse_boolean(l+10);
+                         if (b < 0)
+-                                log_debug("Failed to parse taint /usr flag %s", l+10);
++                                log_warning("Failed to parse taint /usr flag %s", l+10);
+                         else
+                                 m->taint_usr = m->taint_usr || b;
+ 
+@@ -2305,7 +2305,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+                         int fd;
+ 
+                         if (safe_atoi(l + 10, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+-                                log_debug("Failed to parse notify fd: %s", l + 10);
++                                log_warning("Failed to parse notify fd: %s", l + 10);
+                         else {
+                                 m->notify_event_source = sd_event_source_unref(m->notify_event_source);
+                                 safe_close(m->notify_fd);
+@@ -2328,14 +2328,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+                         int fd;
+ 
+                         if (safe_atoi(l + 9, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+-                                log_debug("Failed to parse kdbus fd: %s", l + 9);
++                                log_warning("Failed to parse kdbus fd: %s", l + 9);
+                         else {
+                                 safe_close(m->kdbus_fd);
+                                 m->kdbus_fd = fdset_remove(fds, fd);
+                         }
+ 
+                 } else if (bus_track_deserialize_item(&m->deserialized_subscribed, l) == 0)
+-                        log_debug("Unknown serialization item '%s'", l);
++                        log_warning("Unknown serialization item '%s'", l);
+         }
+ 
+         for (;;) {
diff --git a/0580-systemd-try-harder-to-bind-to-notify-socket.patch b/0580-systemd-try-harder-to-bind-to-notify-socket.patch
new file mode 100644
index 0000000..95909c3
--- /dev/null
+++ b/0580-systemd-try-harder-to-bind-to-notify-socket.patch
@@ -0,0 +1,46 @@
+From 1f74b9992240efc91bc6a95d919522c91a73bf5f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 16 Oct 2014 19:15:38 -0500
+Subject: [PATCH] systemd: try harder to bind to notify socket
+
+Without the socket open we are going to crash and burn. If for
+whatever reason we fail during deserialization we will fail when
+trying to open the socket. In this case it is better to unlink the old
+socket and maybe lose some messages, than to continue without the
+notification socket.
+
+Of course this situation should not happen, but we should handle
+it as gracefully as possible anyway.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1099299
+---
+ src/core/manager.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/manager.c b/src/core/manager.c
+index 1bf75e20b0..726977fcfc 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -565,7 +565,21 @@ static int manager_setup_notify(Manager *m) {
+                 r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
+                 if (r < 0) {
+                         log_error("bind(%s) failed: %m", sa.un.sun_path);
+-                        return -errno;
++                        if (errno == EADDRINUSE) {
++                                log_notice("Removing %s socket and trying again.", m->notify_socket);
++                                r = unlink(m->notify_socket);
++                                if (r < 0) {
++                                        log_error("Failed to remove %s: %m", m->notify_socket);
++                                        return -EADDRINUSE;
++                                }
++
++                                r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
++                                if (r < 0) {
++                                        log_error("bind(%s) failed: %m", sa.un.sun_path);
++                                        return -errno;
++                                }
++                        } else
++                                return -errno;
+                 }
+ 
+                 r = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one));
diff --git a/0581-units-remove-dev-log-to-always-create-symlink.patch b/0581-units-remove-dev-log-to-always-create-symlink.patch
new file mode 100644
index 0000000..cc6bda3
--- /dev/null
+++ b/0581-units-remove-dev-log-to-always-create-symlink.patch
@@ -0,0 +1,26 @@
+From 8b396e3c58284ee31a5649e62cb9645c5079135b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 16 Oct 2014 19:16:00 -0500
+Subject: [PATCH] units: remove /dev/log to always create symlink
+
+When upgrading from older systemds, /dev/log would
+exist and we wouldn't be able to create the symlink successfully.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1099299
+---
+ units/systemd-journald-dev-log.socket | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/units/systemd-journald-dev-log.socket b/units/systemd-journald-dev-log.socket
+index ffd44bb507..0950424163 100644
+--- a/units/systemd-journald-dev-log.socket
++++ b/units/systemd-journald-dev-log.socket
+@@ -17,6 +17,8 @@ Before=sockets.target
+ IgnoreOnIsolate=yes
+ 
+ [Socket]
++ExecStartPre=-/bin/rm -f /dev/log
++
+ Service=systemd-journald.service
+ ListenDatagram=/run/systemd/journal/dev-log
+ Symlinks=/dev/log
diff --git a/systemd.spec b/systemd.spec
index 01a100e..307bfae 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -16,7 +16,7 @@
 Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 Version:        216
-Release:        4%{?gitcommit:.git%{gitcommit}}%{?dist}
+Release:        5%{?gitcommit:.git%{gitcommit}}%{?dist}
 # For a breakdown of the licensing, see README
 License:        LGPLv2+ and MIT and GPLv2+
 Summary:        A System and Service Manager
@@ -616,6 +616,11 @@ Patch0574:      0574-man-reference-table-in-systemd-detect-virt-1-from-Co.patch
 Patch0575:      0575-kdbus-fix-buffer-overflow-in-bus_get_owner_kdbus-fun.patch
 Patch0576:      0576-fstab-generator-Honor-mount.usr-on-kernel-command-li.patch
 Patch0577:      0577-mount-setup-skip-relabelling-when-SELinux-and-SMACK-.patch
+Patch0578:      0578-systemd-continue-switch-root-even-if-umount-fails.patch
+Patch0579:      0579-systemd-log-deserialization-errors-as-warnings.patch
+Patch0580:      0580-systemd-try-harder-to-bind-to-notify-socket.patch
+Patch0581:      0581-units-remove-dev-log-to-always-create-symlink.patch
+
 
 Patch0997:      Revert-timedated-manage-systemd-timesyncd-directly-i.patch
 Patch0998:      fedora-disable-resolv.conf-symlink.patch
@@ -1403,6 +1408,9 @@ getent passwd systemd-journal-upload >/dev/null 2>&1 || useradd -r -l -g systemd
 %{_datadir}/systemd/gatewayd
 
 %changelog
+* Thu Oct 16 2014 Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl> - 216-5
+- Tentative fix for #1099299.
+
 * Sun Oct 12 2014 Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl> - 216-4
 - Move config files for sd-j-remote/upload to sd-journal-gateway subpackage
 


More information about the scm-commits mailing list