diff --git a/SOURCES/0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch b/SOURCES/0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch
new file mode 100644
index 0000000..67a051a
--- /dev/null
+++ b/SOURCES/0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch
@@ -0,0 +1,41 @@
+From 38c68c3b13e278a77a4bd02d97f6b3f81db46288 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Tue, 27 Mar 2018 10:34:06 +0200
+Subject: [PATCH] tmpfiles: don't skip cleanup of read-only root owned files if
+ TMPFILES_AGE_ALL is set
+
+Resolves: #1533638
+---
+ src/tmpfiles/tmpfiles.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index ddb274fce..5212d72f5 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -367,6 +367,7 @@ static int dir_cleanup(
+                 struct stat s;
+                 usec_t age;
+                 _cleanup_free_ char *sub_path = NULL;
++                const char *e;
+ 
+                 if (STR_IN_SET(dent->d_name, ".", ".."))
+                         continue;
+@@ -399,10 +400,13 @@ static int dir_cleanup(
+                         continue;
+                 }
+ 
+-                /* Do not delete read-only files owned by root */
+-                if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) {
+-                        log_debug("Ignoring \"%s/%s\": read-only and owner by root.", p, dent->d_name);
+-                        continue;
++                e = getenv("TMPFILES_AGE_ALL");
++                if (!e) {
++                        /* Do not delete read-only files owned by root */
++                        if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) {
++                                log_debug("Ignoring \"%s/%s\": read-only and owner by root.", p, dent->d_name);
++                                continue;
++                        }
+                 }
+ 
+                 sub_path = strjoin(p, "/", dent->d_name, NULL);
diff --git a/SOURCES/0614-umount-always-use-MNT_FORCE-in-umount_all-7213.patch b/SOURCES/0614-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
deleted file mode 100644
index bf44671..0000000
--- a/SOURCES/0614-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From d9232a652080ac260c78ab647608860269b45d03 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;
- 
diff --git a/SOURCES/0615-core-Implement-timeout-based-umount-remount-limit.patch b/SOURCES/0615-core-Implement-timeout-based-umount-remount-limit.patch
deleted file mode 100644
index 00af896..0000000
--- a/SOURCES/0615-core-Implement-timeout-based-umount-remount-limit.patch
+++ /dev/null
@@ -1,304 +0,0 @@
-From dd531b196e9dd794f7409f97320814e24f50081b 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         |  15 +++++++
- 5 files changed, 167 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 af0953273..5e27a41da 100644
---- a/src/shared/util.c
-+++ b/src/shared/util.c
-@@ -8893,3 +8893,64 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
- 
-         return m / max;
- }
-+
-+/*
-+ * 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 526a6fe84..81aef034e 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>
-@@ -1112,3 +1113,17 @@ int parse_percent(const char *p);
- 
- uint64_t system_tasks_max(void);
- uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
-+
-+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;                                                                \
-+        })
diff --git a/SOURCES/0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch b/SOURCES/0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch
new file mode 100644
index 0000000..7af159f
--- /dev/null
+++ b/SOURCES/0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch
@@ -0,0 +1,28 @@
+From cfa30c21a4e5324a43695fcf43fe984aed2a8a8e Mon Sep 17 00:00:00 2001
+From: Lukas Nykryn <lnykryn@redhat.com>
+Date: Mon, 26 Feb 2018 13:56:52 +0100
+Subject: [PATCH] timer: we already got the trigger before, no need to call
+ UNIT_TRIGGER again
+
+In d7b2f6ef we forgot to replace this occurence.
+
+rhel-only
+
+Resolves: #1549119
+---
+ src/core/timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/timer.c b/src/core/timer.c
+index 91d8db67e..0a264f60d 100644
+--- a/src/core/timer.c
++++ b/src/core/timer.c
+@@ -421,7 +421,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
+ 
+                         case TIMER_UNIT_INACTIVE:
+ 
+-                                base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
++                                base = trigger->inactive_enter_timestamp.monotonic;
+ 
+                                 if (base <= 0)
+                                         base = t->last_trigger.monotonic;
diff --git a/SOURCES/0616-core-Implement-sync_with_progress.patch b/SOURCES/0616-core-Implement-sync_with_progress.patch
deleted file mode 100644
index 11ff498..0000000
--- a/SOURCES/0616-core-Implement-sync_with_progress.patch
+++ /dev/null
@@ -1,169 +0,0 @@
-From ddc1464f3b129ea8490d7da3dd000ab1874b3a4d 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) {
- 
diff --git a/SOURCES/0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch b/SOURCES/0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch
new file mode 100644
index 0000000..4440cec
--- /dev/null
+++ b/SOURCES/0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch
@@ -0,0 +1,79 @@
+From fdc7b6b2af0b80e13bebae8d2f461f54cb71c9d2 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 27 Apr 2018 08:57:08 +0200
+Subject: [PATCH] doc: fix links to binfmt_misc kernel documentation
+
+Resolves: #1572244
+---
+ man/binfmt.d.xml                        | 2 +-
+ src/test/test-util.c                    | 2 +-
+ units/proc-sys-fs-binfmt_misc.automount | 2 +-
+ units/proc-sys-fs-binfmt_misc.mount     | 2 +-
+ units/systemd-binfmt.service.in         | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml
+index 5b63cfb4c..1a57517d0 100644
+--- a/man/binfmt.d.xml
++++ b/man/binfmt.d.xml
+@@ -67,7 +67,7 @@
+ 
+     <para>Each file contains a list of binfmt_misc kernel binary
+     format rules. Consult <ulink
+-    url="https://www.kernel.org/doc/Documentation/binfmt_misc.txt">binfmt_misc.txt</ulink>
++    url="https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst">binfmt_misc.rst</ulink>
+     for more information on registration of additional binary formats
+     and how to write rules.</para>
+ 
+diff --git a/src/test/test-util.c b/src/test/test-util.c
+index fcf5416c0..f2c52edce 100644
+--- a/src/test/test-util.c
++++ b/src/test/test-util.c
+@@ -1213,7 +1213,7 @@ static void test_files_same(void) {
+ 
+ static void test_is_valid_documentation_url(void) {
+         assert_se(documentation_url_is_valid("http://www.freedesktop.org/wiki/Software/systemd"));
+-        assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/binfmt_misc.txt"));
++        assert_se(documentation_url_is_valid("https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst"));
+         assert_se(documentation_url_is_valid("file:/foo/foo"));
+         assert_se(documentation_url_is_valid("man:systemd.special(7)"));
+         assert_se(documentation_url_is_valid("info:bar"));
+diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
+index 6be38937b..b28bf9bb8 100644
+--- a/units/proc-sys-fs-binfmt_misc.automount
++++ b/units/proc-sys-fs-binfmt_misc.automount
+@@ -7,7 +7,7 @@
+ 
+ [Unit]
+ Description=Arbitrary Executable File Formats File System Automount Point
+-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
++Documentation=https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
+ Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+ DefaultDependencies=no
+ Before=sysinit.target
+diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
+index 8c7c38631..8d22dc908 100644
+--- a/units/proc-sys-fs-binfmt_misc.mount
++++ b/units/proc-sys-fs-binfmt_misc.mount
+@@ -7,7 +7,7 @@
+ 
+ [Unit]
+ Description=Arbitrary Executable File Formats File System
+-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
++Documentation=https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
+ Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+ DefaultDependencies=no
+ 
+diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in
+index 02dfe774d..e066f7fec 100644
+--- a/units/systemd-binfmt.service.in
++++ b/units/systemd-binfmt.service.in
+@@ -8,7 +8,7 @@
+ [Unit]
+ Description=Set Up Additional Binary Formats
+ Documentation=man:systemd-binfmt.service(8) man:binfmt.d(5)
+-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
++Documentation=https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount
diff --git a/SOURCES/0617-automount-handle-state-changes-of-the-corresponding-.patch b/SOURCES/0617-automount-handle-state-changes-of-the-corresponding-.patch
deleted file mode 100644
index feb9a67..0000000
--- a/SOURCES/0617-automount-handle-state-changes-of-the-corresponding-.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 6869506c0f4e34163af53decdc08585c25be57ce 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 679fe071e..9046caba3 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;
- 
diff --git a/SOURCES/0617-man-udevadm-remove-superfluous-version-from-subcomma.patch b/SOURCES/0617-man-udevadm-remove-superfluous-version-from-subcomma.patch
new file mode 100644
index 0000000..cc5cc2d
--- /dev/null
+++ b/SOURCES/0617-man-udevadm-remove-superfluous-version-from-subcomma.patch
@@ -0,0 +1,27 @@
+From 5fa3a659c5d106734b3fa76270f048b8b2ea0194 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 23 Mar 2018 11:20:31 +0100
+Subject: [PATCH] man/udevadm: remove superfluous --version from subcommand
+
+Resolves: #1553076
+---
+ man/udevadm.xml | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/man/udevadm.xml b/man/udevadm.xml
+index 8ef9e23aa..99eae387f 100644
+--- a/man/udevadm.xml
++++ b/man/udevadm.xml
+@@ -187,12 +187,6 @@
+             <para>Cleanup the udev database.</para>
+           </listitem>
+         </varlistentry>
+-        <varlistentry>
+-          <term><option>--version</option></term>
+-          <listitem>
+-            <para>Print version.</para>
+-          </listitem>
+-        </varlistentry>
+         <varlistentry>
+           <term><option>-h</option></term>
+           <term><option>--help</option></term>
diff --git a/SOURCES/0618-man-udevadm-correctly-show-the-short-version-of-exit.patch b/SOURCES/0618-man-udevadm-correctly-show-the-short-version-of-exit.patch
new file mode 100644
index 0000000..f367e87
--- /dev/null
+++ b/SOURCES/0618-man-udevadm-correctly-show-the-short-version-of-exit.patch
@@ -0,0 +1,23 @@
+From 81725f613bebedc27f7ff763097bcb393f9c4bd9 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Wed, 7 Mar 2018 18:45:29 +0100
+Subject: [PATCH] man/udevadm: correctly show the short version of --exit
+
+Resolves: #1552712
+---
+ man/udevadm.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/man/udevadm.xml b/man/udevadm.xml
+index 99eae387f..e11c2cb2e 100644
+--- a/man/udevadm.xml
++++ b/man/udevadm.xml
+@@ -374,7 +374,7 @@
+       <para>Modify the internal state of the running udev daemon.</para>
+       <variablelist>
+         <varlistentry>
+-          <term><option>-x</option></term>
++          <term><option>-e</option></term>
+           <term><option>--exit</option></term>
+           <listitem>
+             <para>Signal and wait for systemd-udevd to exit.</para>
diff --git a/SOURCES/0619-core-timer-downgrade-message-about-random-time-addit.patch b/SOURCES/0619-core-timer-downgrade-message-about-random-time-addit.patch
new file mode 100644
index 0000000..e7a2256
--- /dev/null
+++ b/SOURCES/0619-core-timer-downgrade-message-about-random-time-addit.patch
@@ -0,0 +1,30 @@
+From 7adabea503fb86b3b33da17fe65a2b5a246fcac7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Sun, 5 Feb 2017 03:37:46 -0500
+Subject: [PATCH] core/timer: downgrade message about random time addition
+ (#5229)
+
+This seems like something that shouldn't be higher then debug level, even
+if it does not get emitted too often.
+
+Fixes #5228.
+
+(cherry picked from commit 382852fd581efe3cc0ae11154102ab9f435adea1)
+Resolves: #1587906
+---
+ src/core/timer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/timer.c b/src/core/timer.c
+index 0a264f60d..d32b007c7 100644
+--- a/src/core/timer.c
++++ b/src/core/timer.c
+@@ -335,7 +335,7 @@ static void add_random(Timer *t, usec_t *v) {
+         else
+                 *v += add;
+ 
+-        log_unit_info(UNIT(t)->id, "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
++        log_unit_debug(UNIT(t)->id, "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
+ }
+ 
+ static void timer_enter_waiting(Timer *t, bool initial) {
diff --git a/SOURCES/0620-fd-util-add-new-acquire_data_fd-API-helper.patch b/SOURCES/0620-fd-util-add-new-acquire_data_fd-API-helper.patch
new file mode 100644
index 0000000..af8d187
--- /dev/null
+++ b/SOURCES/0620-fd-util-add-new-acquire_data_fd-API-helper.patch
@@ -0,0 +1,277 @@
+From 581edd240f8dd68b1dbb4070353ddb2059eb8a67 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Fri, 27 Oct 2017 10:56:42 +0200
+Subject: [PATCH] fd-util: add new acquire_data_fd() API helper
+
+All this function does is place some data in an in-memory read-only fd,
+that may be read back to get the original data back.
+
+Doing this in a way that works everywhere, given the different kernels
+we support as well as different privilege levels is surprisingly
+complex.
+
+(cherry picked from commit a548e14d690133dd8cca2d5ab8082bb23259fd5f)
+
+Related: #1446095
+---
+ src/shared/util.c    | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/shared/util.h    |  10 ++++
+ src/test/test-util.c |  49 ++++++++++++++++
+ 3 files changed, 215 insertions(+)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index af0953273..982f5e044 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -95,6 +95,7 @@
+ #include "sparse-endian.h"
+ #include "conf-parser.h"
+ #include "cgroup-util.h"
++#include "memfd-util.h"
+ 
+ int saved_argc = 0;
+ char **saved_argv = NULL;
+@@ -8893,3 +8894,158 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
+ 
+         return m / max;
+ }
++
++int acquire_data_fd(const void *data, size_t size, unsigned flags) {
++
++        char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
++        _cleanup_close_pair_ int pipefds[2] = { -1, -1 };
++        char pattern[] = "/dev/shm/data-fd-XXXXXX";
++        _cleanup_close_ int fd = -1;
++        int isz = 0, r;
++        ssize_t n;
++        off_t f;
++
++        assert(data || size == 0);
++
++        /* Acquire a read-only file descriptor that when read from returns the specified data. This is much more
++         * complex than I wish it was. But here's why:
++         *
++         * a) First we try to use memfds. They are the best option, as we can seal them nicely to make them
++         *    read-only. Unfortunately they require kernel 3.17, and – at the time of writing – we still support 3.14.
++         *
++         * b) Then, we try classic pipes. They are the second best options, as we can close the writing side, retaining
++         *    a nicely read-only fd in the reading side. However, they are by default quite small, and unprivileged
++         *    clients can only bump their size to a system-wide limit, which might be quite low.
++         *
++         * c) Then, we try an O_TMPFILE file in /dev/shm (that dir is the only suitable one known to exist from
++         *    earliest boot on). To make it read-only we open the fd a second time with O_RDONLY via
++         *    /proc/self/<fd>. Unfortunately O_TMPFILE is not available on older kernels on tmpfs.
++         *
++         * d) Finally, we try creating a regular file in /dev/shm, which we then delete.
++         *
++         * It sucks a bit that depending on the situation we return very different objects here, but that's Linux I
++         * figure. */
++
++        if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) {
++                /* As a special case, return /dev/null if we have been called for an empty data block */
++                r = open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY);
++                if (r < 0)
++                        return -errno;
++
++                return r;
++        }
++
++        if ((flags & ACQUIRE_NO_MEMFD) == 0) {
++                fd = memfd_new("data-fd");
++                if (fd < 0)
++                        goto try_pipe;
++
++                n = write(fd, data, size);
++                if (n < 0)
++                        return -errno;
++                if ((size_t) n != size)
++                        return -EIO;
++
++                f = lseek(fd, 0, SEEK_SET);
++                if (f != 0)
++                        return -errno;
++
++                r = memfd_set_sealed(fd);
++                if (r < 0)
++                        return r;
++
++                r = fd;
++                fd = -1;
++
++                return r;
++        }
++
++try_pipe:
++        if ((flags & ACQUIRE_NO_PIPE) == 0) {
++                if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0)
++                        return -errno;
++
++                isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
++                if (isz < 0)
++                        return -errno;
++
++                if ((size_t) isz < size) {
++                        isz = (int) size;
++                        if (isz < 0 || (size_t) isz != size)
++                                return -E2BIG;
++
++                        /* Try to bump the pipe size */
++                        (void) fcntl(pipefds[1], F_SETPIPE_SZ, isz);
++
++                        /* See if that worked */
++                        isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
++                        if (isz < 0)
++                                return -errno;
++
++                        if ((size_t) isz < size)
++                                goto try_dev_shm;
++                }
++
++                n = write(pipefds[1], data, size);
++                if (n < 0)
++                        return -errno;
++                if ((size_t) n != size)
++                        return -EIO;
++
++                (void) fd_nonblock(pipefds[0], false);
++
++                r = pipefds[0];
++                pipefds[0] = -1;
++
++                return r;
++        }
++
++try_dev_shm:
++        if ((flags & ACQUIRE_NO_TMPFILE) == 0) {
++                fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500);
++                if (fd < 0)
++                        goto try_dev_shm_without_o_tmpfile;
++
++                n = write(fd, data, size);
++                if (n < 0)
++                        return -errno;
++                if ((size_t) n != size)
++                        return -EIO;
++
++                /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
++                xsprintf(procfs_path, "/proc/self/fd/%i", fd);
++                r = open(procfs_path, O_RDONLY|O_CLOEXEC);
++                if (r < 0)
++                        return -errno;
++
++                return r;
++        }
++
++try_dev_shm_without_o_tmpfile:
++        if ((flags & ACQUIRE_NO_REGULAR) == 0) {
++                fd = mkostemp_safe(pattern, O_CLOEXEC);
++                if (fd < 0)
++                        return fd;
++
++                n = write(fd, data, size);
++                if (n < 0) {
++                        r = -errno;
++                        goto unlink_and_return;
++                }
++                if ((size_t) n != size) {
++                        r = -EIO;
++                        goto unlink_and_return;
++                }
++
++                /* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
++                r = open(pattern, O_RDONLY|O_CLOEXEC);
++                if (r < 0)
++                        r = -errno;
++
++        unlink_and_return:
++                (void) unlink(pattern);
++                return r;
++        }
++
++        return -EOPNOTSUPP;
++}
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 526a6fe84..9c4be0256 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -1112,3 +1112,13 @@ int parse_percent(const char *p);
+ 
+ uint64_t system_tasks_max(void);
+ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
++
++enum {
++        ACQUIRE_NO_DEV_NULL = 1 << 0,
++        ACQUIRE_NO_MEMFD    = 1 << 1,
++        ACQUIRE_NO_PIPE     = 1 << 2,
++        ACQUIRE_NO_TMPFILE  = 1 << 3,
++        ACQUIRE_NO_REGULAR  = 1 << 4,
++};
++
++int acquire_data_fd(const void *data, size_t size, unsigned flags);
+diff --git a/src/test/test-util.c b/src/test/test-util.c
+index f2c52edce..efb02ff53 100644
+--- a/src/test/test-util.c
++++ b/src/test/test-util.c
+@@ -1861,6 +1861,54 @@ static void test_system_tasks_max_scale(void) {
+         assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
+ }
+ 
++static void test_acquire_data_fd_one(unsigned flags) {
++        char wbuffer[196*1024 - 7];
++        char rbuffer[sizeof(wbuffer)];
++        int fd;
++
++        fd = acquire_data_fd("foo", 3, flags);
++        assert_se(fd >= 0);
++
++        zero(rbuffer);
++        assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 3);
++        assert_se(streq(rbuffer, "foo"));
++
++        fd = safe_close(fd);
++
++        fd = acquire_data_fd("", 0, flags);
++        assert_se(fd >= 0);
++
++        zero(rbuffer);
++        assert_se(read(fd, rbuffer, sizeof(rbuffer)) == 0);
++        assert_se(streq(rbuffer, ""));
++
++        fd = safe_close(fd);
++
++        random_bytes(wbuffer, sizeof(wbuffer));
++
++        fd = acquire_data_fd(wbuffer, sizeof(wbuffer), flags);
++        assert_se(fd >= 0);
++
++        zero(rbuffer);
++        assert_se(read(fd, rbuffer, sizeof(rbuffer)) == sizeof(rbuffer));
++        assert_se(memcmp(rbuffer, wbuffer, sizeof(rbuffer)) == 0);
++
++        fd = safe_close(fd);
++}
++
++static void test_acquire_data_fd(void) {
++
++        test_acquire_data_fd_one(0);
++        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL);
++        test_acquire_data_fd_one(ACQUIRE_NO_MEMFD);
++        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD);
++        test_acquire_data_fd_one(ACQUIRE_NO_PIPE);
++        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_PIPE);
++        test_acquire_data_fd_one(ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
++        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE);
++        test_acquire_data_fd_one(ACQUIRE_NO_DEV_NULL|ACQUIRE_NO_MEMFD|ACQUIRE_NO_PIPE|ACQUIRE_NO_TMPFILE);
++}
++
+ int main(int argc, char *argv[]) {
+         log_parse_environment();
+         log_open();
+@@ -1943,6 +1991,7 @@ int main(int argc, char *argv[]) {
+         test_shell_maybe_quote();
+         test_system_tasks_max();
+         test_system_tasks_max_scale();
++        test_acquire_data_fd();
+ 
+         return 0;
+ }
diff --git a/SOURCES/0621-systemd-analyze-make-dump-work-for-large-of-units.patch b/SOURCES/0621-systemd-analyze-make-dump-work-for-large-of-units.patch
new file mode 100644
index 0000000..d62c2e6
--- /dev/null
+++ b/SOURCES/0621-systemd-analyze-make-dump-work-for-large-of-units.patch
@@ -0,0 +1,189 @@
+From 6772555b226a116bff07b7d8af28b16032273866 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Wed, 9 May 2018 09:35:52 +0200
+Subject: [PATCH] systemd-analyze: make dump work for large # of units
+
+If there is a large number of units, the size of the generated dump
+string can overstep DBus message size limit. So let's pass that string
+via a fd.
+
+(cherry picked from commit c0a1bfacfea9c65ea79fd07682a5b60b5d711a33)
+
+Resolves: #1446095
+---
+ src/analyze/analyze.c                  | 57 ++++++++++++++++++++++++++++------
+ src/core/dbus-manager.c                | 26 ++++++++++++++--
+ src/core/org.freedesktop.systemd1.conf |  4 +++
+ 3 files changed, 76 insertions(+), 11 deletions(-)
+
+diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
+index ff84f6894..7116aaa88 100644
+--- a/src/analyze/analyze.c
++++ b/src/analyze/analyze.c
+@@ -29,6 +29,7 @@
+ #include "sd-bus.h"
+ #include "bus-util.h"
+ #include "bus-error.h"
++#include "copy.h"
+ #include "install.h"
+ #include "log.h"
+ #include "build.h"
+@@ -1096,12 +1097,42 @@ static int dot(sd_bus *bus, char* patterns[]) {
+         return 0;
+ }
+ 
+-static int dump(sd_bus *bus, char **args) {
+-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
++static int dump_fallback(sd_bus *bus) {
++        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+         const char *text = NULL;
+         int r;
+ 
++        assert(bus);
++
++        r = sd_bus_call_method(
++                        bus,
++                        "org.freedesktop.systemd1",
++                        "/org/freedesktop/systemd1",
++                        "org.freedesktop.systemd1.Manager",
++                        "Dump",
++                        &error,
++                        &reply,
++                        "");
++        if (r < 0) {
++                log_error("Failed to issue method call Dump: %s", bus_error_message(&error, -r));
++                return r;
++        }
++
++        r = sd_bus_message_read(reply, "s", &text);
++        if (r < 0)
++                return bus_log_parse_error(r);
++
++        fputs(text, stdout);
++        return 0;
++}
++
++static int dump(sd_bus *bus, char **args) {
++        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
++        int fd = -1;
++        int r;
++
+         if (!strv_isempty(args)) {
+                 log_error("Too many arguments.");
+                 return -E2BIG;
+@@ -1109,26 +1140,34 @@ static int dump(sd_bus *bus, char **args) {
+ 
+         pager_open_if_enabled();
+ 
++        if (!sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD))
++                return dump_fallback(bus);
++
+         r = sd_bus_call_method(
+                         bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+-                       "Dump",
++                       "DumpByFileDescriptor",
+                        &error,
+                        &reply,
+                        "");
+         if (r < 0) {
+-                log_error("Failed issue method call: %s", bus_error_message(&error, -r));
+-                return r;
++                /* fall back to Dump if DumpByFileDescriptor is not supported */
++                if (!IN_SET(r, -EACCES, -EBADR)) {
++                        log_error("Failed to issue method call DumpByFileDescriptor: %s", bus_error_message(&error, -r));
++                        return r;
++                }
++
++                return dump_fallback(bus);
+         }
+ 
+-        r = sd_bus_message_read(reply, "s", &text);
++        r = sd_bus_message_read(reply, "h", &fd);
+         if (r < 0)
+                 return bus_log_parse_error(r);
+ 
+-        fputs(text, stdout);
+-        return 0;
++        fflush(stdout);
++        return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
+ }
+ 
+ static int set_log_level(sd_bus *bus, char **args) {
+diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
+index d34ed042f..1766163b3 100644
+--- a/src/core/dbus-manager.c
++++ b/src/core/dbus-manager.c
+@@ -1064,7 +1064,7 @@ static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userda
+         return sd_bus_reply_method_return(message, NULL);
+ }
+ 
+-static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
++static int dump_impl(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, int (*reply)(sd_bus_message *, char *)) {
+         _cleanup_free_ char *dump = NULL;
+         _cleanup_fclose_ FILE *f = NULL;
+         Manager *m = userdata;
+@@ -1089,13 +1089,34 @@ static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
+         manager_dump_jobs(m, f, NULL);
+ 
+         fflush(f);
+-
+         if (ferror(f))
+                 return -ENOMEM;
+ 
++        return reply(message, dump);
++}
++
++static int reply_dump(sd_bus_message *message, char *dump) {
+         return sd_bus_reply_method_return(message, "s", dump);
+ }
+ 
++static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
++        return dump_impl(bus, message, userdata, error, reply_dump);
++}
++
++static int reply_dump_by_fd(sd_bus_message *message, char *dump) {
++        _cleanup_close_ int fd = -1;
++
++        fd = acquire_data_fd(dump, strlen(dump), 0);
++        if (fd < 0)
++                return fd;
++
++        return sd_bus_reply_method_return(message, "h", fd);
++}
++
++static int method_dump_by_fd(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
++        return dump_impl(bus, message, userdata, error, reply_dump_by_fd);
++}
++
+ static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+         _cleanup_free_ char *path = NULL;
+         Manager *m = userdata;
+@@ -2092,6 +2113,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
+         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("DumpByFileDescriptor", NULL, "h", method_dump_by_fd, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
+         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
+         SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
+diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
+index 3997dd0b4..8187cf173 100644
+--- a/src/core/org.freedesktop.systemd1.conf
++++ b/src/core/org.freedesktop.systemd1.conf
+@@ -96,6 +96,10 @@
+                        send_interface="org.freedesktop.systemd1.Manager"
+                        send_member="Dump"/>
+ 
++                <allow send_destination="org.freedesktop.systemd1"
++                       send_interface="org.freedesktop.systemd1.Manager"
++                       send_member="DumpByFileDescriptor"/>
++
+                 <allow send_destination="org.freedesktop.systemd1"
+                        send_interface="org.freedesktop.systemd1.Manager"
+                        send_member="GetDefaultTarget"/>
diff --git a/SOURCES/0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch b/SOURCES/0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch
new file mode 100644
index 0000000..18fbab6
--- /dev/null
+++ b/SOURCES/0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch
@@ -0,0 +1,27 @@
+From 191e504e9847ba3f46fe579922bbee64f02a04c1 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Wed, 9 May 2018 10:33:28 +0200
+Subject: [PATCH] use max. message size allowed by DBus spec (#8936)
+
+C.f. https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages.
+
+(cherry picked from commit 33d8fe60573dd3e88fe98e368437bb4d29534b5a)
+
+Related: #1446095
+---
+ src/libsystemd/sd-bus/bus-internal.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
+index 6a106862e..9c1e5a35b 100644
+--- a/src/libsystemd/sd-bus/bus-internal.h
++++ b/src/libsystemd/sd-bus/bus-internal.h
+@@ -329,7 +329,7 @@ struct sd_bus {
+ #define BUS_WQUEUE_MAX (192*1024)
+ #define BUS_RQUEUE_MAX (192*1024)
+ 
+-#define BUS_MESSAGE_SIZE_MAX (64*1024*1024)
++#define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
+ #define BUS_AUTH_SIZE_MAX (64*1024)
+ 
+ #define BUS_CONTAINER_DEPTH 128
diff --git a/SOURCES/0623-cryptsetup-support-LUKS2-on-disk-format.patch b/SOURCES/0623-cryptsetup-support-LUKS2-on-disk-format.patch
new file mode 100644
index 0000000..a6fd5b4
--- /dev/null
+++ b/SOURCES/0623-cryptsetup-support-LUKS2-on-disk-format.patch
@@ -0,0 +1,77 @@
+From be973ab9f6585be762ea0888c81b011222eabb13 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Thu, 3 May 2018 11:21:27 +0200
+Subject: [PATCH] cryptsetup: support LUKS2 on-disk format
+
+Allow cryptsetup utility to activate LUKS2 devices (with appropriate
+libcryptsetup)
+
+The change itself doesn't enforce new libcryptsetup 2.x and is backward
+compatible with versions 1.x
+
+(cherry-picked from commit b3b4ebab02395933cde554b5a5d5c363dae3920d)
+
+Resolves: #1573838
+---
+ src/cryptsetup/cryptsetup.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index 69a015614..528c36c48 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -36,7 +36,15 @@
+ #include "libudev.h"
+ #include "udev-util.h"
+ 
+-static const char *arg_type = NULL; /* CRYPT_LUKS1, CRYPT_TCRYPT or CRYPT_PLAIN */
++/* libcryptsetup define for any LUKS version, compatible with libcryptsetup 1.x */
++#ifndef CRYPT_LUKS
++#define CRYPT_LUKS NULL
++#endif
++
++/* internal helper */
++#define ANY_LUKS "LUKS"
++
++static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
+ static char *arg_cipher = NULL;
+ static unsigned arg_key_size = 0;
+ static int arg_key_slot = CRYPT_ANY_SLOT;
+@@ -98,7 +106,7 @@ static int parse_one_option(const char *option) {
+ 
+         } else if (startswith(option, "key-slot=")) {
+ 
+-                arg_type = CRYPT_LUKS1;
++                arg_type = ANY_LUKS;
+                 if (safe_atoi(option+9, &arg_key_slot) < 0) {
+                         log_error("key-slot= parse failure, ignoring.");
+                         return 0;
+@@ -138,7 +146,7 @@ static int parse_one_option(const char *option) {
+                 arg_hash = t;
+ 
+         } else if (startswith(option, "header=")) {
+-                arg_type = CRYPT_LUKS1;
++                arg_type = ANY_LUKS;
+ 
+                 if (!path_is_absolute(option+7)) {
+                         log_error("Header path '%s' is not absolute, refusing.", option+7);
+@@ -168,7 +176,7 @@ static int parse_one_option(const char *option) {
+         else if (STR_IN_SET(option, "allow-discards", "discard"))
+                 arg_discards = true;
+         else if (streq(option, "luks"))
+-                arg_type = CRYPT_LUKS1;
++                arg_type = ANY_LUKS;
+         else if (streq(option, "tcrypt"))
+                 arg_type = CRYPT_TCRYPT;
+         else if (streq(option, "tcrypt-hidden")) {
+@@ -430,8 +438,8 @@ static int attach_luks_or_plain(struct crypt_device *cd,
+         assert(name);
+         assert(key_file || passwords);
+ 
+-        if (!arg_type || streq(arg_type, CRYPT_LUKS1)) {
+-                r = crypt_load(cd, CRYPT_LUKS1, NULL);
++        if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
++                r = crypt_load(cd, CRYPT_LUKS, NULL);
+                 if (r < 0) {
+                         log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
+                         return r;
diff --git a/SOURCES/0624-core-scope-fix-missing-fragment_path.patch b/SOURCES/0624-core-scope-fix-missing-fragment_path.patch
new file mode 100644
index 0000000..43fd578
--- /dev/null
+++ b/SOURCES/0624-core-scope-fix-missing-fragment_path.patch
@@ -0,0 +1,56 @@
+From f838bf376249b68205641d1736da2622c0279ed2 Mon Sep 17 00:00:00 2001
+From: chenglin130 <cheng.lin130@zte.com.cn>
+Date: Sat, 20 Jan 2018 17:45:27 +0800
+Subject: [PATCH] core:scope: fix missing fragment_path
+
+fragment_path in struct unit is a record of unit file, which will
+be deleted (unlink) in unit_free().
+
+After a daemon-reload process, the u->fragment_path of scope unit
+will be missing (NULL). Then, the discarded session scope unit file
+will be redundant until reboot.
+
+Steps to Reproduce problem:
+1. ssh access and login
+2. systemctl daemon-reload
+3. ssh logout
+4. discarded session-xxx.scope file will be found in /run/systemd/system/
+
+So in a daemon-reload case, scope_load() need unit_load_fragment() to reload
+u->fragment_path.
+---
+ src/core/load-fragment.c | 5 +++++
+ src/core/scope.c         | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index da58bcc5c..f3d0851fe 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -3950,6 +3950,11 @@ int unit_load_fragment(Unit *u) {
+         assert(u->load_state == UNIT_STUB);
+         assert(u->id);
+ 
++        if (u->transient && u->fragment_path) {
++                u->load_state = UNIT_LOADED;
++                return 0;
++        }
++
+         /* First, try to find the unit under its id. We always look
+          * for unit files in the default directories, to make it easy
+          * to override things by placing things in /etc/systemd/system */
+diff --git a/src/core/scope.c b/src/core/scope.c
+index ae6614fbf..29954ba28 100644
+--- a/src/core/scope.c
++++ b/src/core/scope.c
+@@ -150,6 +150,10 @@ static int scope_load(Unit *u) {
+         if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
+                 return -ENOENT;
+ 
++        r = unit_load_fragment(u);
++        if (r < 0)
++                return r;
++
+         u->load_state = UNIT_LOADED;
+ 
+         r = unit_load_dropin(u);
diff --git a/SOURCES/0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch b/SOURCES/0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch
new file mode 100644
index 0000000..8a4703c
--- /dev/null
+++ b/SOURCES/0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch
@@ -0,0 +1,27 @@
+From 5c62e7afe2197c7b5bb00ed70bc6960b49a0317e Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Thu, 18 Jan 2018 19:23:56 +0100
+Subject: [PATCH] units: don't put udev to its own mount namespace with slave
+ propagation
+
+Change in upstream was done mostly for political reasons to discourage
+people from doing mounts in udev rules. RHEL is very bad place for
+such experiments. Revert to default we shipped with RHEL-7 GA.
+
+RHEL-only
+
+Resolves: #1432211
+---
+ units/systemd-udevd.service.in | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
+index 32f04d901..46b079515 100644
+--- a/units/systemd-udevd.service.in
++++ b/units/systemd-udevd.service.in
+@@ -21,5 +21,4 @@ Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
+ Restart=always
+ RestartSec=0
+ ExecStart=@rootlibexecdir@/systemd-udevd
+-MountFlags=slave
+ KillMode=mixed
diff --git a/SOURCES/0626-rules-disable-support-for-Lenovo-IR-cameras.patch b/SOURCES/0626-rules-disable-support-for-Lenovo-IR-cameras.patch
new file mode 100644
index 0000000..ffdd7e3
--- /dev/null
+++ b/SOURCES/0626-rules-disable-support-for-Lenovo-IR-cameras.patch
@@ -0,0 +1,37 @@
+From 647615bfa4015336eb88f6cb44dc111f1d713df7 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Wed, 13 Jun 2018 14:33:18 +0200
+Subject: [PATCH] rules: disable support for Lenovo IR cameras
+
+Resolves: #1540418
+---
+ Makefile.am                                    | 1 +
+ rules/40-redhat-disable-lenovo-ir-camera.rules | 6 ++++++
+ 2 files changed, 7 insertions(+)
+ create mode 100644 rules/40-redhat-disable-lenovo-ir-camera.rules
+
+diff --git a/Makefile.am b/Makefile.am
+index 8c73326fa..cbc120dad 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -3522,6 +3522,7 @@ dist_udevrules_DATA += \
+ 	rules/80-net-setup-link.rules \
+ 	rules/95-udev-late.rules \
+ 	rules/40-redhat.rules \
++	rules/40-redhat-disable-lenovo-ir-camera.rules \
+ 	rules/73-idrac.rules \
+         rules/80-net-name-slot.rules
+ 
+diff --git a/rules/40-redhat-disable-lenovo-ir-camera.rules b/rules/40-redhat-disable-lenovo-ir-camera.rules
+new file mode 100644
+index 000000000..ea326d4ab
+--- /dev/null
++++ b/rules/40-redhat-disable-lenovo-ir-camera.rules
+@@ -0,0 +1,6 @@
++# Disable known IR cameras in Lenovo Notebooks
++SUBSYSTEM=="usb", ATTRS{idVendor}=="5986", ATTRS{idProduct}=="211a", ATTR{authorized}="0"
++SUBSYSTEM=="usb", ATTRS{idVendor}=="5986", ATTRS{idProduct}=="1141", ATTR{authorized}="0"
++SUBSYSTEM=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b605", ATTR{authorized}="0"
++SUBSYSTEM=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b613", ATTR{authorized}="0"
++SUBSYSTEM=="usb", ATTRS{idVendor}=="04f2", ATTRS{idProduct}=="b615", ATTR{authorized}="0"
+\ No newline at end of file
diff --git a/SOURCES/0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch b/SOURCES/0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch
new file mode 100644
index 0000000..ad3a14e
--- /dev/null
+++ b/SOURCES/0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch
@@ -0,0 +1,92 @@
+From f7507f4bb5385ed0303451d812d220f14f341629 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 28 Jan 2016 18:48:42 +0100
+Subject: [PATCH] core: make sure "systemctl reload-or-try-restart is actually
+ a noop if a unit is not running
+
+This makes sure we follow the same basic logic for try-restart if we have a try-reload.
+
+Fixes #688
+
+(cherry picked from commit 3282591dc30b2934a895c7403d2f0b0690260947)
+Resolves: #1191920
+---
+ src/core/dbus-unit.c | 2 +-
+ src/core/job.c       | 8 ++++++++
+ src/core/job.h       | 3 +++
+ src/core/unit.c      | 2 ++
+ 4 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
+index 1d0d6f67c..f0f75e01b 100644
+--- a/src/core/dbus-unit.c
++++ b/src/core/dbus-unit.c
+@@ -850,7 +850,7 @@ int bus_unit_queue_job(
+                 if (type == JOB_RESTART)
+                         type = JOB_RELOAD_OR_START;
+                 else if (type == JOB_TRY_RESTART)
+-                        type = JOB_RELOAD;
++                        type = JOB_TRY_RELOAD;
+         }
+ 
+         r = mac_selinux_unit_access_check(
+diff --git a/src/core/job.c b/src/core/job.c
+index 1617e24c0..c9a43a4cb 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -404,6 +404,13 @@ JobType job_type_collapse(JobType t, Unit *u) {
+ 
+                 return JOB_RESTART;
+ 
++        case JOB_TRY_RELOAD:
++                s = unit_active_state(u);
++                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
++                        return JOB_NOP;
++
++                return JOB_RELOAD;
++
+         case JOB_RELOAD_OR_START:
+                 s = unit_active_state(u);
+                 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+@@ -1212,6 +1219,7 @@ static const char* const job_type_table[_JOB_TYPE_MAX] = {
+         [JOB_RELOAD_OR_START] = "reload-or-start",
+         [JOB_RESTART] = "restart",
+         [JOB_TRY_RESTART] = "try-restart",
++        [JOB_TRY_RELOAD] = "try-reload",
+         [JOB_NOP] = "nop",
+ };
+ 
+diff --git a/src/core/job.h b/src/core/job.h
+index ce81607de..535052b48 100644
+--- a/src/core/job.h
++++ b/src/core/job.h
+@@ -63,6 +63,9 @@ enum JobType {
+          * Thus we never need to merge it with anything. */
+         JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
+ 
++        /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
++        JOB_TRY_RELOAD,
++
+         /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
+          * from transaction merging (there's no way for JOB_RELOAD and
+          * JOB_START to meet in one transaction). It can result from a merge
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 41d7b63d7..6d535ae12 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1868,6 +1868,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
+ 
+                 case JOB_RELOAD:
+                 case JOB_RELOAD_OR_START:
++                case JOB_TRY_RELOAD:
+ 
+                         if (u->job->state == JOB_RUNNING) {
+                                 if (ns == UNIT_ACTIVE)
+@@ -2144,6 +2145,7 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
+                 return unit_can_start(u);
+ 
+         case JOB_RELOAD:
++        case JOB_TRY_RELOAD:
+                 return unit_can_reload(u);
+ 
+         case JOB_RELOAD_OR_START:
diff --git a/SOURCES/0628-core-fix-confusing-logging-of-instantaneous-jobs.patch b/SOURCES/0628-core-fix-confusing-logging-of-instantaneous-jobs.patch
new file mode 100644
index 0000000..30a8a3c
--- /dev/null
+++ b/SOURCES/0628-core-fix-confusing-logging-of-instantaneous-jobs.patch
@@ -0,0 +1,247 @@
+From 7bc07eb6c9a31f2c26d0fe3e6d7a26a13cbb2369 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Thu, 16 Jul 2015 20:08:30 +0200
+Subject: [PATCH] core: fix confusing logging of instantaneous jobs
+
+For instantaneous jobs (e.g. starting of targets, sockets, slices, or
+Type=simple services) the log shows the job completion
+before starting:
+
+        systemd[1]: Created slice -.slice.
+        systemd[1]: Starting -.slice.
+        systemd[1]: Created slice System Slice.
+        systemd[1]: Starting System Slice.
+        systemd[1]: Listening on Journal Audit Socket.
+        systemd[1]: Starting Journal Audit Socket.
+        systemd[1]: Reached target Timers.
+        systemd[1]: Starting Timers.
+        ...
+
+The reason is that the job completes before the ->start() method returns
+and only then does unit_start() print the "Starting ..." message.
+The same thing happens when stopping units.
+
+Rather than fixing the order of the messages, let's just not emit the
+Starting/Stopping message at all when the job completes instantaneously.
+The job completion message is sufficient in this case.
+
+(cherry picked from commit d1a34ae9c20f1c02aab17884919eccef572b1d21)
+
+Resolves: #1506256
+---
+ src/core/job.c  | 65 +++++++++++++++++++++++++++++++++++++++------------------
+ src/core/unit.c | 36 +++++++++++---------------------
+ src/core/unit.h |  1 +
+ 3 files changed, 58 insertions(+), 44 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index c9a43a4cb..612caa604 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -504,10 +504,48 @@ static void job_change_type(Job *j, JobType newtype) {
+         j->type = newtype;
+ }
+ 
++static int job_perform_on_unit(Job **j) {
++        /* While we execute this operation the job might go away (for
++         * example: because it finishes immediately or is replaced by a new,
++         * conflicting job.) To make sure we don't access a freed job later on
++         * we store the id here, so that we can verify the job is still
++         * valid. */
++        Manager *m  = (*j)->manager;
++        Unit *u     = (*j)->unit;
++        JobType t   = (*j)->type;
++        uint32_t id = (*j)->id;
++        int r;
++
++        switch (t) {
++                case JOB_START:
++                        r = unit_start(u);
++                        break;
++
++                case JOB_RESTART:
++                        t = JOB_STOP;
++                case JOB_STOP:
++                        r = unit_stop(u);
++                        break;
++
++                case JOB_RELOAD:
++                        r = unit_reload(u);
++                        break;
++
++                default:
++                        assert_not_reached("Invalid job type");
++        }
++
++        /* Log if the job still exists and the start/stop/reload function
++         * actually did something. */
++        *j = manager_get_job(m, id);
++        if (*j && r > 0)
++                unit_status_emit_starting_stopping_reloading(u, t);
++
++        return r;
++}
++
+ int job_run_and_invalidate(Job *j) {
+         int r;
+-        uint32_t id;
+-        Manager *m = j->manager;
+ 
+         assert(j);
+         assert(j->installed);
+@@ -526,23 +564,9 @@ int job_run_and_invalidate(Job *j) {
+         job_set_state(j, JOB_RUNNING);
+         job_add_to_dbus_queue(j);
+ 
+-        /* While we execute this operation the job might go away (for
+-         * example: because it is replaced by a new, conflicting
+-         * job.) To make sure we don't access a freed job later on we
+-         * store the id here, so that we can verify the job is still
+-         * valid. */
+-        id = j->id;
+ 
+         switch (j->type) {
+ 
+-                case JOB_START:
+-                        r = unit_start(j->unit);
+-
+-                        /* If this unit cannot be started, then simply wait */
+-                        if (r == -EBADR)
+-                                r = 0;
+-                        break;
+-
+                 case JOB_VERIFY_ACTIVE: {
+                         UnitActiveState t = unit_active_state(j->unit);
+                         if (UNIT_IS_ACTIVE_OR_RELOADING(t))
+@@ -554,17 +578,19 @@ int job_run_and_invalidate(Job *j) {
+                         break;
+                 }
+ 
++                case JOB_START:
+                 case JOB_STOP:
+                 case JOB_RESTART:
+-                        r = unit_stop(j->unit);
++                        r = job_perform_on_unit(&j);
+ 
+-                        /* If this unit cannot stopped, then simply wait. */
++                        /* If the unit type does not support starting/stopping,
++                         * then simply wait. */
+                         if (r == -EBADR)
+                                 r = 0;
+                         break;
+ 
+                 case JOB_RELOAD:
+-                        r = unit_reload(j->unit);
++                        r = job_perform_on_unit(&j);
+                         break;
+ 
+                 case JOB_NOP:
+@@ -575,7 +601,6 @@ int job_run_and_invalidate(Job *j) {
+                         assert_not_reached("Unknown job type");
+         }
+ 
+-        j = manager_get_job(m, id);
+         if (j) {
+                 if (r == -EALREADY)
+                         r = job_finish_and_invalidate(j, JOB_DONE, true, true);
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 6d535ae12..907a4bf7f 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1417,6 +1417,15 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
+                         NULL);
+ }
+ 
++void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) {
++
++        unit_status_log_starting_stopping_reloading(u, t);
++
++        /* Reload status messages have traditionally not been printed to console. */
++        if (t != JOB_RELOAD)
++                unit_status_print_starting_stopping(u, t);
++}
++
+ /* Errors:
+  *         -EBADR:     This unit type does not support starting.
+  *         -EALREADY:  Unit is already started.
+@@ -1427,7 +1436,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
+ int unit_start(Unit *u) {
+         UnitActiveState state;
+         Unit *following;
+-        int r;
+ 
+         assert(u);
+ 
+@@ -1481,14 +1489,7 @@ int unit_start(Unit *u) {
+ 
+         unit_add_to_dbus_queue(u);
+ 
+-        r = UNIT_VTABLE(u)->start(u);
+-        if (r <= 0)
+-                return r;
+-
+-        /* Log if the start function actually did something */
+-        unit_status_log_starting_stopping_reloading(u, JOB_START);
+-        unit_status_print_starting_stopping(u, JOB_START);
+-        return r;
++        return UNIT_VTABLE(u)->start(u);
+ }
+ 
+ bool unit_can_start(Unit *u) {
+@@ -1512,7 +1513,6 @@ bool unit_can_isolate(Unit *u) {
+ int unit_stop(Unit *u) {
+         UnitActiveState state;
+         Unit *following;
+-        int r;
+ 
+         assert(u);
+ 
+@@ -1531,13 +1531,7 @@ int unit_stop(Unit *u) {
+ 
+         unit_add_to_dbus_queue(u);
+ 
+-        r = UNIT_VTABLE(u)->stop(u);
+-        if (r <= 0)
+-                return r;
+-
+-        unit_status_log_starting_stopping_reloading(u, JOB_STOP);
+-        unit_status_print_starting_stopping(u, JOB_STOP);
+-        return r;
++        return UNIT_VTABLE(u)->stop(u);
+ }
+ 
+ /* Errors:
+@@ -1548,7 +1542,6 @@ int unit_stop(Unit *u) {
+ int unit_reload(Unit *u) {
+         UnitActiveState state;
+         Unit *following;
+-        int r;
+ 
+         assert(u);
+ 
+@@ -1575,12 +1568,7 @@ int unit_reload(Unit *u) {
+ 
+         unit_add_to_dbus_queue(u);
+ 
+-        r = UNIT_VTABLE(u)->reload(u);
+-        if (r <= 0)
+-                return r;
+-
+-        unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
+-        return r;
++        return UNIT_VTABLE(u)->reload(u);
+ }
+ 
+ bool unit_can_reload(Unit *u) {
+diff --git a/src/core/unit.h b/src/core/unit.h
+index 85f52df18..480e2e95f 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -562,6 +562,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency d);
+ int unit_coldplug(Unit *u, Hashmap *deferred_work);
+ 
+ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0);
++void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t);
+ 
+ bool unit_need_daemon_reload(Unit *u);
+ 
diff --git a/SOURCES/0629-core-correct-return-value-from-reload-methods.patch b/SOURCES/0629-core-correct-return-value-from-reload-methods.patch
new file mode 100644
index 0000000..f140ed2
--- /dev/null
+++ b/SOURCES/0629-core-correct-return-value-from-reload-methods.patch
@@ -0,0 +1,43 @@
+From bc54eb811caf738ee54867359f798dc0f4be9e7e Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Thu, 16 Jul 2015 21:39:56 +0200
+Subject: [PATCH] core: correct return value from reload methods
+
+Return 1 from *_reload() methods to signify "we did something", just
+like in *_start(). This causes "Reloading foo..." messages to be logged.
+"Reloaded foo." messages are already logged.
+
+(cherry picked from commit 2d018ae23b838f050516d06859f50ecb9733d44b)
+
+Related: #1506256
+---
+ src/core/mount.c   | 2 +-
+ src/core/service.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/mount.c b/src/core/mount.c
+index a6d93b869..f726d9659 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -1081,7 +1081,7 @@ static int mount_reload(Unit *u) {
+         assert(m->state == MOUNT_MOUNTED);
+ 
+         mount_enter_remounting(m);
+-        return 0;
++        return 1;
+ }
+ 
+ static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
+diff --git a/src/core/service.c b/src/core/service.c
+index 71ec5e37c..9622ce11f 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -1939,7 +1939,7 @@ static int service_reload(Unit *u) {
+         assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED);
+ 
+         service_enter_reload(s);
+-        return 0;
++        return 1;
+ }
+ 
+ _pure_ static bool service_can_reload(Unit *u) {
diff --git a/SOURCES/0630-core-always-try-harder-to-get-unit-status-message-fo.patch b/SOURCES/0630-core-always-try-harder-to-get-unit-status-message-fo.patch
new file mode 100644
index 0000000..d0579ac
--- /dev/null
+++ b/SOURCES/0630-core-always-try-harder-to-get-unit-status-message-fo.patch
@@ -0,0 +1,91 @@
+From c571dc5f7d593a4526da9e19b35ae3d1ed11bfaa Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Mon, 20 Jul 2015 17:18:13 +0200
+Subject: [PATCH] core: always try harder to get unit status message format
+ string
+
+The starting/stopping messages are printed to the console only if the
+corresponding format string is defined in the unit's vtable. To avoid
+excessive messages on the console, the unit types whose start/stop
+jobs are instantaneous had the format strings intentionally undefined.
+When logging the same event to the journal, a fallback to generic
+Starting/Stopping/Reloading messages is used.
+
+The problem of excessive console messages with instantaneous jobs
+is already resolved in a nicer way ("core: fix confusing logging of
+instantaneous jobs"), so there's no longer a need to have two ways of
+getting the format strings. Let's fold them into one function with
+the fallback to generic message strings.
+
+(cherry picked from commit a85ca902c9f7f5aa8f2f3e3299147733802cf09d)
+
+Related: #1506256
+---
+ src/core/unit.c | 34 ++++++++++------------------------
+ 1 file changed, 10 insertions(+), 24 deletions(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 907a4bf7f..a33cbdf73 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1328,32 +1328,21 @@ static bool unit_assert_test(Unit *u) {
+ }
+ 
+ _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
+-        const UnitStatusMessageFormats *format_table;
+-
+-        assert(u);
+-        assert(t >= 0);
+-        assert(t < _JOB_TYPE_MAX);
+-
+-        if (t != JOB_START && t != JOB_STOP)
+-                return NULL;
+-
+-        format_table = &UNIT_VTABLE(u)->status_message_formats;
+-        if (!format_table)
+-                return NULL;
+-
+-        return format_table->starting_stopping[t == JOB_STOP];
+-}
+-
+-_pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
+         const char *format;
++        const UnitStatusMessageFormats *format_table;
+ 
+         assert(u);
+         assert(t >= 0);
+         assert(t < _JOB_TYPE_MAX);
+ 
+-        format = unit_get_status_message_format(u, t);
+-        if (format)
+-                return format;
++        if (t == JOB_START || t == JOB_STOP) {
++                format_table = &UNIT_VTABLE(u)->status_message_formats;
++                if (format_table) {
++                        format = format_table->starting_stopping[t == JOB_STOP];
++                        if (format)
++                                return format;
++                }
++        }
+ 
+         /* Return generic strings */
+         if (t == JOB_START)
+@@ -1371,9 +1360,6 @@ static void unit_status_print_starting_stopping(Unit *u, JobType t) {
+ 
+         assert(u);
+ 
+-        /* We only print status messages for selected units on
+-         * selected operations. */
+-
+         format = unit_get_status_message_format(u, t);
+         if (!format)
+                 return;
+@@ -1398,7 +1384,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
+ 
+         /* We log status messages for all units and all operations. */
+ 
+-        format = unit_get_status_message_format_try_harder(u, t);
++        format = unit_get_status_message_format(u, t);
+         if (!format)
+                 return;
+ 
diff --git a/SOURCES/0631-core-unit_get_status_message_format-never-returns-NU.patch b/SOURCES/0631-core-unit_get_status_message_format-never-returns-NU.patch
new file mode 100644
index 0000000..a838a48
--- /dev/null
+++ b/SOURCES/0631-core-unit_get_status_message_format-never-returns-NU.patch
@@ -0,0 +1,63 @@
+From 0204371780cbcae7635544abc61846d33d04c317 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Mon, 20 Jul 2015 18:36:12 +0200
+Subject: [PATCH] core: unit_get_status_message_format() never returns NULL
+
+unit_get_status_message_format() is used only with one of JOB_START,
+JOB_STOP, JOB_RELOAD, all of which have fallback message strings
+defined, so the function may never return NULL.
+
+(cherry picked from commit b5bf308ba50ab0bac0f0caec2d8e4d5c75c107d0)
+
+Related: #1506256
+---
+ src/core/unit.c | 13 +++----------
+ 1 file changed, 3 insertions(+), 10 deletions(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index a33cbdf73..22d9beed7 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1332,10 +1332,9 @@ _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
+         const UnitStatusMessageFormats *format_table;
+ 
+         assert(u);
+-        assert(t >= 0);
+-        assert(t < _JOB_TYPE_MAX);
++        assert(t == JOB_START || t == JOB_STOP || t == JOB_RELOAD);
+ 
+-        if (t == JOB_START || t == JOB_STOP) {
++        if (t != JOB_RELOAD) {
+                 format_table = &UNIT_VTABLE(u)->status_message_formats;
+                 if (format_table) {
+                         format = format_table->starting_stopping[t == JOB_STOP];
+@@ -1349,10 +1348,8 @@ _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
+                 return "Starting %s.";
+         else if (t == JOB_STOP)
+                 return "Stopping %s.";
+-        else if (t == JOB_RELOAD)
++        else
+                 return "Reloading %s.";
+-
+-        return NULL;
+ }
+ 
+ static void unit_status_print_starting_stopping(Unit *u, JobType t) {
+@@ -1361,8 +1358,6 @@ static void unit_status_print_starting_stopping(Unit *u, JobType t) {
+         assert(u);
+ 
+         format = unit_get_status_message_format(u, t);
+-        if (!format)
+-                return;
+ 
+         DISABLE_WARNING_FORMAT_NONLITERAL;
+         unit_status_printf(u, "", format);
+@@ -1385,8 +1380,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
+         /* We log status messages for all units and all operations. */
+ 
+         format = unit_get_status_message_format(u, t);
+-        if (!format)
+-                return;
+ 
+         DISABLE_WARNING_FORMAT_NONLITERAL;
+         snprintf(buf, sizeof(buf), format, unit_description(u));
diff --git a/SOURCES/0632-core-try-harder-to-get-job-completion-messages-too.patch b/SOURCES/0632-core-try-harder-to-get-job-completion-messages-too.patch
new file mode 100644
index 0000000..debc518
--- /dev/null
+++ b/SOURCES/0632-core-try-harder-to-get-job-completion-messages-too.patch
@@ -0,0 +1,254 @@
+From 50ce13182e07af7f240c61d03bf113e86a269917 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Tue, 21 Jul 2015 14:54:24 +0200
+Subject: [PATCH] core: try harder to get job completion messages too
+
+This is similar to "core: always try harder to get unit status
+message format string", but for job completion status messages.
+It makes generic status messages applicable for printing to the console.
+And it rewrites the functions in a more table-based style.
+
+(cherry picked from commit aa49ab5f22c0fdc7a5381d4e452f40705f3d7bf8)
+
+Related: #1506256
+---
+ src/core/job.c | 192 ++++++++++++++++++++-------------------------------------
+ 1 file changed, 68 insertions(+), 124 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index 612caa604..f371f914d 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -622,156 +622,100 @@ int job_run_and_invalidate(Job *j) {
+ }
+ 
+ _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
++        const char *format;
+         const UnitStatusMessageFormats *format_table;
++        static const char *const generic_finished_start_job[_JOB_RESULT_MAX] = {
++                [JOB_DONE]        = "Started %s.",
++                [JOB_TIMEOUT]     = "Timed out starting %s.",
++                [JOB_FAILED]      = "Failed to start %s.",
++                [JOB_DEPENDENCY]  = "Dependency failed for %s.",
++                [JOB_ASSERT]      = "Assertion failed for %s.",
++                [JOB_UNSUPPORTED] = "Starting of %s not supported.",
++        };
++        static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
++                [JOB_DONE]        = "Stopped %s.",
++                [JOB_FAILED]      = "Stopped (with error) %s.",
++                [JOB_TIMEOUT]     = "Timed out stoppping %s.",
++        };
++        static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = {
++                [JOB_DONE]        = "Reloaded %s.",
++                [JOB_FAILED]      = "Reload failed for %s.",
++                [JOB_TIMEOUT]     = "Timed out reloading %s.",
++        };
++        /* When verify-active detects the unit is inactive, report it.
++         * Most likely a DEPEND warning from a requisiting unit will
++         * occur next and it's nice to see what was requisited. */
++        static const char *const generic_finished_verify_active_job[_JOB_RESULT_MAX] = {
++                [JOB_SKIPPED]     = "%s is not active.",
++        };
+ 
+         assert(u);
+         assert(t >= 0);
+         assert(t < _JOB_TYPE_MAX);
+ 
+-        format_table = &UNIT_VTABLE(u)->status_message_formats;
+-        if (!format_table)
+-                return NULL;
++        if (t == JOB_START || t == JOB_STOP || t == JOB_RESTART) {
++                format_table = &UNIT_VTABLE(u)->status_message_formats;
++                if (format_table) {
++                        format = t == JOB_START ? format_table->finished_start_job[result] :
++                                                  format_table->finished_stop_job[result];
++                        if (format)
++                                return format;
++                }
++        }
+ 
++        /* Return generic strings */
+         if (t == JOB_START)
+-                return format_table->finished_start_job[result];
++                return generic_finished_start_job[result];
+         else if (t == JOB_STOP || t == JOB_RESTART)
+-                return format_table->finished_stop_job[result];
+-
+-        return NULL;
+-}
+-
+-_pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
+-        const char *format;
+-
+-        assert(u);
+-        assert(t >= 0);
+-        assert(t < _JOB_TYPE_MAX);
+-
+-        format = job_get_status_message_format(u, t, result);
+-        if (format)
+-                return format;
+-
+-        /* Return generic strings */
+-        if (t == JOB_START) {
+-                if (result == JOB_DONE)
+-                        return "Started %s.";
+-                else if (result == JOB_TIMEOUT)
+-                        return "Timed out starting %s.";
+-                else if (result == JOB_FAILED)
+-                        return "Failed to start %s.";
+-                else if (result == JOB_DEPENDENCY)
+-                        return "Dependency failed for %s.";
+-                else if (result == JOB_ASSERT)
+-                        return "Assertion failed for %s.";
+-                else if (result == JOB_UNSUPPORTED)
+-                        return "Starting of %s not supported.";
+-        } else if (t == JOB_STOP || t == JOB_RESTART) {
+-                if (result == JOB_DONE)
+-                        return "Stopped %s.";
+-                else if (result == JOB_FAILED)
+-                        return "Stopped (with error) %s.";
+-                else if (result == JOB_TIMEOUT)
+-                        return "Timed out stoppping %s.";
+-        } else if (t == JOB_RELOAD) {
+-                if (result == JOB_DONE)
+-                        return "Reloaded %s.";
+-                else if (result == JOB_FAILED)
+-                        return "Reload failed for %s.";
+-                else if (result == JOB_TIMEOUT)
+-                        return "Timed out reloading %s.";
+-        }
++                return generic_finished_stop_job[result];
++        else if (t == JOB_RELOAD)
++                return generic_finished_reload_job[result];
++        else if (t == JOB_VERIFY_ACTIVE)
++                return generic_finished_verify_active_job[result];
+ 
+         return NULL;
+ }
+ 
+ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+         const char *format;
++        static const char* const job_result_status_table[_JOB_RESULT_MAX] = {
++                [JOB_DONE]        = ANSI_GREEN_ON            "  OK  " ANSI_HIGHLIGHT_OFF,
++                [JOB_TIMEOUT]     = ANSI_HIGHLIGHT_RED_ON    " TIME " ANSI_HIGHLIGHT_OFF,
++                [JOB_FAILED]      = ANSI_HIGHLIGHT_RED_ON    "FAILED" ANSI_HIGHLIGHT_OFF,
++                [JOB_DEPENDENCY]  = ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF,
++                [JOB_SKIPPED]     = ANSI_HIGHLIGHT_ON        " INFO " ANSI_HIGHLIGHT_OFF,
++                [JOB_ASSERT]      = ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF,
++                [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF,
++        };
+ 
+         assert(u);
+         assert(t >= 0);
+         assert(t < _JOB_TYPE_MAX);
+ 
+-        DISABLE_WARNING_FORMAT_NONLITERAL;
+-
+-        if (t == JOB_START) {
+-                format = job_get_status_message_format(u, t, result);
+-                if (!format)
+-                        return;
+-
+-                switch (result) {
+-
+-                case JOB_DONE:
+-                        if (u->condition_result)
+-                                unit_status_printf(u, ANSI_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format);
+-                        break;
+-
+-                case JOB_TIMEOUT:
+-                        manager_flip_auto_status(u->manager, true);
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
+-                        break;
+-
+-                case JOB_FAILED: {
+-                        _cleanup_free_ char *quoted = NULL;
+-
+-                        quoted = shell_maybe_quote(u->id);
+-
+-                        manager_flip_auto_status(u->manager, true);
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
+-                        manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, "See 'systemctl status %s' for details.", strna(quoted));
+-                        break;
+-                }
+-
+-                case JOB_DEPENDENCY:
+-                        manager_flip_auto_status(u->manager, true);
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format);
+-                        break;
+-
+-                case JOB_ASSERT:
+-                        manager_flip_auto_status(u->manager, true);
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF, format);
+-                        break;
+-
+-                case JOB_UNSUPPORTED:
+-                        manager_flip_auto_status(u->manager, true);
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF, format);
+-                        break;
+-
+-                default:
+-                        ;
+-                }
+-
+-        } else if (t == JOB_STOP || t == JOB_RESTART) {
+-
+-                format = job_get_status_message_format(u, t, result);
+-                if (!format)
+-                        return;
++        /* Reload status messages have traditionally not been printed to console. */
++        if (t == JOB_RELOAD)
++                return;
+ 
+-                switch (result) {
++        if (t == JOB_START && result == JOB_DONE && !u->condition_result)
++                return;
+ 
+-                case JOB_TIMEOUT:
+-                        manager_flip_auto_status(u->manager, true);
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
+-                        break;
++        format = job_get_status_message_format(u, t, result);
++        if (!format)
++                return;
+ 
+-                case JOB_DONE:
+-                case JOB_FAILED:
+-                        unit_status_printf(u, ANSI_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format);
+-                        break;
++        if (result != JOB_DONE)
++                manager_flip_auto_status(u->manager, true);
+ 
+-                default:
+-                        ;
+-                }
++        DISABLE_WARNING_FORMAT_NONLITERAL;
++        unit_status_printf(u, job_result_status_table[result], format);
++        REENABLE_WARNING;
+ 
+-        } else if (t == JOB_VERIFY_ACTIVE) {
++        if (t == JOB_START && result == JOB_FAILED) {
++                _cleanup_free_ char *quoted = shell_maybe_quote(u->id);
+ 
+-                /* When verify-active detects the unit is inactive, report it.
+-                 * Most likely a DEPEND warning from a requisiting unit will
+-                 * occur next and it's nice to see what was requisited. */
+-                if (result == JOB_SKIPPED)
+-                        unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.");
++                manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
++                                      "See 'systemctl status %s' for details.", strna(quoted));
+         }
+-
+-        REENABLE_WARNING;
+ }
+ 
+ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+@@ -788,7 +732,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+         if (log_on_console())
+                 return;
+ 
+-        format = job_get_status_message_format_try_harder(u, t, result);
++        format = job_get_status_message_format(u, t, result);
+         if (!format)
+                 return;
+ 
diff --git a/SOURCES/0633-core-remove-generic-job-completion-messages-from-uni.patch b/SOURCES/0633-core-remove-generic-job-completion-messages-from-uni.patch
new file mode 100644
index 0000000..64e31a3
--- /dev/null
+++ b/SOURCES/0633-core-remove-generic-job-completion-messages-from-uni.patch
@@ -0,0 +1,132 @@
+From 60545c63716ecc720728c221c61d575b267fbfc8 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Tue, 21 Jul 2015 15:51:16 +0200
+Subject: [PATCH] core: remove generic job completion messages from unit
+ vtables
+
+These units' message format strings are identical to the generic
+strings. Since we can always rely on the fallback, these are now
+redundant.
+
+(cherry picked from commit c382d69e3d39daedebcedb2da882beeb147a3cda)
+
+Related: #1506256
+---
+ src/core/automount.c | 1 -
+ src/core/busname.c   | 3 ---
+ src/core/mount.c     | 1 -
+ src/core/service.c   | 3 ---
+ src/core/slice.c     | 1 -
+ src/core/socket.c    | 1 -
+ src/core/swap.c      | 1 -
+ src/core/target.c    | 1 -
+ 8 files changed, 12 deletions(-)
+
+diff --git a/src/core/automount.c b/src/core/automount.c
+index 679fe071e..08519e49c 100644
+--- a/src/core/automount.c
++++ b/src/core/automount.c
+@@ -1126,7 +1126,6 @@ const UnitVTable automount_vtable = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Set up automount %s.",
+                         [JOB_FAILED]     = "Failed to set up automount %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                 },
+                 .finished_stop_job = {
+                         [JOB_DONE]       = "Unset automount %s.",
+diff --git a/src/core/busname.c b/src/core/busname.c
+index f626ba96d..a5e659049 100644
+--- a/src/core/busname.c
++++ b/src/core/busname.c
+@@ -1064,13 +1064,10 @@ const UnitVTable busname_vtable = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Listening on %s.",
+                         [JOB_FAILED]     = "Failed to listen on %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+-                        [JOB_TIMEOUT]    = "Timed out starting %s.",
+                 },
+                 .finished_stop_job = {
+                         [JOB_DONE]       = "Closed %s.",
+                         [JOB_FAILED]     = "Failed stopping %s.",
+-                        [JOB_TIMEOUT]    = "Timed out stopping %s.",
+                 },
+         },
+ };
+diff --git a/src/core/mount.c b/src/core/mount.c
+index f726d9659..0dc67dde6 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -1978,7 +1978,6 @@ const UnitVTable mount_vtable = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Mounted %s.",
+                         [JOB_FAILED]     = "Failed to mount %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                         [JOB_TIMEOUT]    = "Timed out mounting %s.",
+                 },
+                 .finished_stop_job = {
+diff --git a/src/core/service.c b/src/core/service.c
+index 9622ce11f..8303a1e7e 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -3398,13 +3398,10 @@ const UnitVTable service_vtable = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Started %s.",
+                         [JOB_FAILED]     = "Failed to start %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+-                        [JOB_TIMEOUT]    = "Timed out starting %s.",
+                 },
+                 .finished_stop_job = {
+                         [JOB_DONE]       = "Stopped %s.",
+                         [JOB_FAILED]     = "Stopped (with error) %s.",
+-                        [JOB_TIMEOUT]    = "Timed out stopping %s.",
+                 },
+         },
+ };
+diff --git a/src/core/slice.c b/src/core/slice.c
+index 9154558b7..1cce3e121 100644
+--- a/src/core/slice.c
++++ b/src/core/slice.c
+@@ -299,7 +299,6 @@ const UnitVTable slice_vtable = {
+         .status_message_formats = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Created slice %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                 },
+                 .finished_stop_job = {
+                         [JOB_DONE]       = "Removed slice %s.",
+diff --git a/src/core/socket.c b/src/core/socket.c
+index 771af0d24..efefe7ce5 100644
+--- a/src/core/socket.c
++++ b/src/core/socket.c
+@@ -2736,7 +2736,6 @@ const UnitVTable socket_vtable = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Listening on %s.",
+                         [JOB_FAILED]     = "Failed to listen on %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                         [JOB_TIMEOUT]    = "Timed out starting %s.",
+                 },
+                 .finished_stop_job = {
+diff --git a/src/core/swap.c b/src/core/swap.c
+index 984be2d9a..e71de4e65 100644
+--- a/src/core/swap.c
++++ b/src/core/swap.c
+@@ -1525,7 +1525,6 @@ const UnitVTable swap_vtable = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Activated swap %s.",
+                         [JOB_FAILED]     = "Failed to activate swap %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                         [JOB_TIMEOUT]    = "Timed out activating swap %s.",
+                 },
+                 .finished_stop_job = {
+diff --git a/src/core/target.c b/src/core/target.c
+index 2411a8e75..45248ad02 100644
+--- a/src/core/target.c
++++ b/src/core/target.c
+@@ -231,7 +231,6 @@ const UnitVTable target_vtable = {
+         .status_message_formats = {
+                 .finished_start_job = {
+                         [JOB_DONE]       = "Reached target %s.",
+-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
+                 },
+                 .finished_stop_job = {
+                         [JOB_DONE]       = "Stopped target %s.",
diff --git a/SOURCES/0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch b/SOURCES/0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch
new file mode 100644
index 0000000..7223ea3
--- /dev/null
+++ b/SOURCES/0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch
@@ -0,0 +1,67 @@
+From 0fd062edc435d9cf39022e2e92c895bf8625ad0d Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Tue, 21 Jul 2015 16:15:19 +0200
+Subject: [PATCH] core: do not log done failed-condition jobs as if unit
+ started
+
+It is misleading to see "Started foo." in the log when the unit's
+condition was false.
+
+(cherry picked from commit 30961fa300cad21b50fe47baee523beeadb5d0bc)
+
+Related: #1506256
+---
+ src/core/job.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index f371f914d..5e582b3d3 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -692,13 +692,6 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+         assert(t >= 0);
+         assert(t < _JOB_TYPE_MAX);
+ 
+-        /* Reload status messages have traditionally not been printed to console. */
+-        if (t == JOB_RELOAD)
+-                return;
+-
+-        if (t == JOB_START && result == JOB_DONE && !u->condition_result)
+-                return;
+-
+         format = job_get_status_message_format(u, t, result);
+         if (!format)
+                 return;
+@@ -768,6 +761,19 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+                                 NULL);
+ }
+ 
++static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
++
++        /* No message if the job did not actually do anything due to failed condition. */
++        if (t == JOB_START && result == JOB_DONE && !u->condition_result)
++                return;
++
++        job_log_status_message(u, t, result);
++
++        /* Reload status messages have traditionally not been printed to console. */
++        if (t != JOB_RELOAD)
++                job_print_status_message(u, t, result);
++}
++
+ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
+         Unit *u;
+         Unit *other;
+@@ -787,10 +793,8 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
+                        u->id, job_type_to_string(t), job_result_to_string(result));
+ 
+         /* If this job did nothing to respective unit we don't log the status message */
+-        if (!already) {
+-                job_print_status_message(u, t, result);
+-                job_log_status_message(u, t, result);
+-        }
++        if (!already)
++                job_emit_status_message(u, t, result);
+ 
+         job_add_to_dbus_queue(j);
+ 
diff --git a/SOURCES/0635-core-log-completion-of-remaining-job-types.patch b/SOURCES/0635-core-log-completion-of-remaining-job-types.patch
new file mode 100644
index 0000000..6208a2b
--- /dev/null
+++ b/SOURCES/0635-core-log-completion-of-remaining-job-types.patch
@@ -0,0 +1,42 @@
+From 010b80c6215da7357114911f46742939772e18fc Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Tue, 21 Jul 2015 16:20:18 +0200
+Subject: [PATCH] core: log completion of remaining job types
+
+JOB_RESTART and failed JOB_VERIFY_ACTIVE completions were printed to
+console but not to the log.
+
+(cherry picked from commit 4f29c6fea6a6c5c2c9406ad091cd6f56da21e2cb)
+
+Related: #1506256
+---
+ src/core/job.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index 5e582b3d3..086050aa7 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -743,8 +743,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+                                 LOG_MESSAGE("%s", buf),
+                                 "RESULT=%s", job_result_to_string(result),
+                                 NULL);
+-
+-        } else if (t == JOB_STOP)
++        } else if (t == JOB_STOP || t == JOB_RESTART)
+                 log_unit_struct(u->id,
+                                 result == JOB_DONE ? LOG_INFO : LOG_ERR,
+                                 LOG_MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
+@@ -759,6 +758,12 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+                                 LOG_MESSAGE("%s", buf),
+                                 "RESULT=%s", job_result_to_string(result),
+                                 NULL);
++        else
++                log_unit_struct(u->id,
++                                result == JOB_DONE ? LOG_INFO : LOG_ERR,
++                                LOG_MESSAGE("%s", buf),
++                                "RESULT=%s", job_result_to_string(result),
++                                NULL);
+ }
+ 
+ static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
diff --git a/SOURCES/0636-core-adjust-job-completion-message-log-levels.patch b/SOURCES/0636-core-adjust-job-completion-message-log-levels.patch
new file mode 100644
index 0000000..2d8d576
--- /dev/null
+++ b/SOURCES/0636-core-adjust-job-completion-message-log-levels.patch
@@ -0,0 +1,75 @@
+From ea366cda56dc0550b9829e4d9e733cb8b70ffb30 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Tue, 21 Jul 2015 19:07:24 +0200
+Subject: [PATCH] core: adjust job completion message log levels
+
+We do not print all non-OK job completion status messages to the console
+in red, because not all of them are plain errors. We do however log the
+same messages as LOG_ERR.
+
+Differentiate the log levels by deducing them from the job result in a
+way that more or less matches the color of the console message.
+
+(cherry picked from commit 64f575d2ab9a6743d3c7172b7591c88ba243cf1b)
+
+Related: #1506256
+---
+ src/core/job.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index 086050aa7..1861c8a63 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -714,6 +714,17 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+         const char *format;
+         char buf[LINE_MAX];
++        static const int job_result_log_level[_JOB_RESULT_MAX] = {
++                [JOB_DONE]        = LOG_INFO,
++                [JOB_CANCELED]    = LOG_INFO,
++                [JOB_TIMEOUT]     = LOG_ERR,
++                [JOB_FAILED]      = LOG_ERR,
++                [JOB_DEPENDENCY]  = LOG_WARNING,
++                [JOB_SKIPPED]     = LOG_NOTICE,
++                [JOB_INVALID]     = LOG_INFO,
++                [JOB_ASSERT]      = LOG_WARNING,
++                [JOB_UNSUPPORTED] = LOG_WARNING,
++        };
+ 
+         assert(u);
+         assert(t >= 0);
+@@ -738,14 +749,14 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+ 
+                 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
+                 log_unit_struct(u->id,
+-                                result == JOB_DONE ? LOG_INFO : LOG_ERR,
++                                job_result_log_level[result],
+                                 LOG_MESSAGE_ID(mid),
+                                 LOG_MESSAGE("%s", buf),
+                                 "RESULT=%s", job_result_to_string(result),
+                                 NULL);
+         } else if (t == JOB_STOP || t == JOB_RESTART)
+                 log_unit_struct(u->id,
+-                                result == JOB_DONE ? LOG_INFO : LOG_ERR,
++                                job_result_log_level[result],
+                                 LOG_MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
+                                 LOG_MESSAGE("%s", buf),
+                                 "RESULT=%s", job_result_to_string(result),
+@@ -753,14 +764,14 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
+ 
+         else if (t == JOB_RELOAD)
+                 log_unit_struct(u->id,
+-                                result == JOB_DONE ? LOG_INFO : LOG_ERR,
++                                job_result_log_level[result],
+                                 LOG_MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
+                                 LOG_MESSAGE("%s", buf),
+                                 "RESULT=%s", job_result_to_string(result),
+                                 NULL);
+         else
+                 log_unit_struct(u->id,
+-                                result == JOB_DONE ? LOG_INFO : LOG_ERR,
++                                job_result_log_level[result],
+                                 LOG_MESSAGE("%s", buf),
+                                 "RESULT=%s", job_result_to_string(result),
+                                 NULL);
diff --git a/SOURCES/0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch b/SOURCES/0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch
new file mode 100644
index 0000000..87b4410
--- /dev/null
+++ b/SOURCES/0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch
@@ -0,0 +1,111 @@
+From 048ed4b2fecef7003925772740bab651cb08b260 Mon Sep 17 00:00:00 2001
+From: brulon <barron@lexmark.com>
+Date: Fri, 26 Aug 2016 11:57:22 -0400
+Subject: [PATCH] mount: add new LazyUnmount= setting for mount units, mapping
+ to umount(8)'s "-l" switch (#3827)
+
+(cherry-picked commit from e520950a03419957875034bc27795b0b81d8e793)
+
+Resolves: #1497264
+---
+ man/systemd.mount.xml                 | 13 +++++++++++++
+ src/core/dbus-mount.c                 |  1 +
+ src/core/load-fragment-gperf.gperf.m4 |  1 +
+ src/core/mount.c                      |  8 ++++++--
+ src/core/mount.h                      |  2 ++
+ 5 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
+index dfa437b5d..1590c44ce 100644
+--- a/man/systemd.mount.xml
++++ b/man/systemd.mount.xml
+@@ -329,6 +329,19 @@
+         off.</para></listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><varname>LazyUnmount=</varname></term>
++
++        <listitem><para>Takes a boolean argument. If true, detach the
++        filesystem from the filesystem hierarchy at time of the unmount
++        operation, and clean up all references to the filesystem as
++        soon as they are not busy anymore.
++        This corresponds with
++        <citerefentry project='man-pages'><refentrytitle>umount</refentrytitle><manvolnum>8</manvolnum></citerefentry>'s
++        <parameter>-l</parameter> switch. Defaults to
++        off.</para></listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><varname>DirectoryMode=</varname></term>
+         <listitem><para>Directories of mount points (and any parent
+diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
+index 04beba631..cbb842f70 100644
+--- a/src/core/dbus-mount.c
++++ b/src/core/dbus-mount.c
+@@ -110,6 +110,7 @@ const sd_bus_vtable bus_mount_vtable[] = {
+         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+         SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
++        SD_BUS_PROPERTY("LazyUnmount", "b", bus_property_get_bool, offsetof(Mount, lazy_unmount), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+         BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+         BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index b2fe627af..664bba0ef 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -316,6 +316,7 @@ Mount.Type,                      config_parse_string,                0,
+ Mount.TimeoutSec,                config_parse_sec,                   0,                             offsetof(Mount, timeout_usec)
+ Mount.DirectoryMode,             config_parse_mode,                  0,                             offsetof(Mount, directory_mode)
+ Mount.SloppyOptions,             config_parse_bool,                  0,                             offsetof(Mount, sloppy_options)
++Mount.LazyUnmount,               config_parse_bool,                  0,                             offsetof(Mount, lazy_unmount)
+ EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
+ CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
+ KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
+diff --git a/src/core/mount.c b/src/core/mount.c
+index 0dc67dde6..5fd7a86dd 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -690,7 +690,8 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
+                 "%sOptions: %s\n"
+                 "%sFrom /proc/self/mountinfo: %s\n"
+                 "%sFrom fragment: %s\n"
+-                "%sDirectoryMode: %04o\n",
++                "%sDirectoryMode: %04o\n"
++                "%sLazyUnmount: %s\n",
+                 prefix, mount_state_to_string(m->state),
+                 prefix, mount_result_to_string(m->result),
+                 prefix, m->where,
+@@ -699,7 +700,8 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
+                 prefix, p ? strna(p->options) : "n/a",
+                 prefix, yes_no(m->from_proc_self_mountinfo),
+                 prefix, yes_no(m->from_fragment),
+-                prefix, m->directory_mode);
++                prefix, m->directory_mode,
++                prefix, yes_no(m->lazy_unmount));
+ 
+         if (m->control_pid > 0)
+                 fprintf(f,
+@@ -891,6 +893,8 @@ static void mount_enter_unmounting(Mount *m) {
+         m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
+ 
+         r = exec_command_set(m->control_command, "/bin/umount", m->where, NULL);
++        if (r >= 0 && m->lazy_unmount)
++                r = exec_command_append(m->control_command, "-l", NULL);
+         if (r < 0)
+                 goto fail;
+ 
+diff --git a/src/core/mount.h b/src/core/mount.h
+index 353222000..4e870299c 100644
+--- a/src/core/mount.h
++++ b/src/core/mount.h
+@@ -90,6 +90,8 @@ struct Mount {
+ 
+         bool sloppy_options;
+ 
++        bool lazy_unmount;
++
+         MountResult result;
+         MountResult reload_result;
+ 
diff --git a/SOURCES/0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch b/SOURCES/0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch
new file mode 100644
index 0000000..7d742c7
--- /dev/null
+++ b/SOURCES/0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch
@@ -0,0 +1,42 @@
+From 14ca846073e3b7accb71012a9612d0a7cb6b5ea6 Mon Sep 17 00:00:00 2001
+From: gwendalcr <gwendal@chromium.org>
+Date: Wed, 20 Jun 2018 16:54:05 +0200
+Subject: [PATCH] rules: Add MODEL_ID for NVMe device (#7037)
+
+To mimic MODEL_ID variable built for ATA and SCSI devices, add rules
+to add MODEL_ID variable for NVMe devices.
+
+TEST: Check on a system with NVMe device that MODEL_ID variable is
+present:
+ udevadm info --query=all -n /dev/nvme0n1p1 | grep ID_MODEL
+and
+ udevadm info --query=all -n /dev/nvme0n1p1 | grep ID_MODEL
+return:
+E: ID_MODEL=SAMSUNG...
+
+(cherry picked from commit e2c2d70ba7cc7497b03c4a377bfb529035540aa7)
+
+Resolves: #1397264
+---
+ rules/60-persistent-storage.rules | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/rules/60-persistent-storage.rules b/rules/60-persistent-storage.rules
+index ba619633b..4aae97a9f 100644
+--- a/rules/60-persistent-storage.rules
++++ b/rules/60-persistent-storage.rules
+@@ -28,10 +28,12 @@ KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{wwid}=="?*"
+ 
+ KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
+ KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{wwid}=="?*", ENV{ID_WWN}="$attr{wwid}"
+-KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}", OPTIONS="string_escape=replace"
++KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
++KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}", OPTIONS="string_escape=replace"
+ 
+ KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
+-KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$attr{model}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n", OPTIONS="string_escape=replace"
++KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
++KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n", OPTIONS="string_escape=replace"
+ 
+ # virtio-blk
+ KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"
diff --git a/SOURCES/0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch b/SOURCES/0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
new file mode 100644
index 0000000..95946ca
--- /dev/null
+++ b/SOURCES/0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
@@ -0,0 +1,72 @@
+From 5bace483dedc9098da8191f39c823649948a7a3c Mon Sep 17 00:00:00 2001
+From: NeilBrown <neil@brown.name>
+Date: Wed, 8 Nov 2017 19:29:32 +1100
+Subject: [PATCH] umount: always use MNT_FORCE in umount_all() (#7213)
+
+The linux umount2() systemcall accepts a MNT_FORCE flags
+which some filesystems honor, particularly FUSE and various
+network filesystems such as NFS.
+These filesystems can sometimes wait for an indefinite period
+for a response from an external service, and the wait if
+sometimes "uninterruptible" meaning that the process cannot be
+killed.
+Using MNT_FORCE causes any such request that are outstanding to
+be aborted.  This normally allows the waiting process to
+be killed.  It will then realease and reference it has to the
+filesytem, this allowing the filesystem to be unmounted.
+
+If there remain active references to the filesystem, MNT_FORCE
+is *not* forcefull enough to unmount the filesystem anyway.
+
+By the time that umount_all() is run by systemd-shutdown, all
+filesystems *should* be unmounted, and sync() will have been
+called.  Anything that remains cannot be unmounted in a
+completely clean manner and just nees to be dealt with as firmly
+as possible.  So use MNT_FORCE and try to explain why in the
+comment.
+
+Also enhance an earlier comment to explain why umount2() is
+safe even though mount(MNT_REMOUNT) isn't.
+
+(cherry picked from commit c44cac7c6c43407d28bd8daebff39f6145a2a33e)
+
+Resolves: #1571098
+---
+ src/core/umount.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/umount.c b/src/core/umount.c
+index 3eec0d459..91d67c06c 100644
+--- a/src/core/umount.c
++++ b/src/core/umount.c
+@@ -377,7 +377,9 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
+                    the superblock here, not the bind mount.
+                    If the filesystem is a network fs, also skip the
+                    remount.  It brings no value (we cannot leave
+-                   a "dirty fs") and could hang if the network is down.  */
++                   a "dirty fs") and could hang if the network is down.
++                   Note that umount2() is more careful and will not
++                   hang because of the network being down. */
+                 if (detect_container(NULL) <= 0 &&
+                     !fstype_is_network(m->type)) {
+                         _cleanup_free_ char *options = NULL;
+@@ -418,11 +420,15 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
+                 )
+                         continue;
+ 
+-                /* Trying to umount. We don't force here since we rely
+-                 * on busy NFS and FUSE file systems to return EBUSY
+-                 * until we closed everything on top of them. */
++                /* Trying to umount. Using MNT_FORCE causes some
++                 * filesystems (e.g. FUSE and NFS and other network
++                 * filesystems) to abort any pending requests and
++                 * return -EIO rather than blocking indefinitely.
++                 * If the filesysten is "busy", this may allow processes
++                 * to die, thus making the filesystem less busy so
++                 * the unmount might succeed (rather then return EBUSY).*/
+                 log_info("Unmounting %s.", m->path);
+-                if (umount2(m->path, 0) == 0) {
++                if (umount2(m->path, MNT_FORCE) == 0) {
+                         if (changed)
+                                 *changed = true;
+ 
diff --git a/SOURCES/0640-core-Implement-timeout-based-umount-remount-limit.patch b/SOURCES/0640-core-Implement-timeout-based-umount-remount-limit.patch
new file mode 100644
index 0000000..a2be213
--- /dev/null
+++ b/SOURCES/0640-core-Implement-timeout-based-umount-remount-limit.patch
@@ -0,0 +1,305 @@
+From 5ccae46f2a192a9347feb604901127c55ce1e039 Mon Sep 17 00:00:00 2001
+From: Kyle Walker <kwalker@redhat.com>
+Date: Wed, 13 Dec 2017 12:49:26 -0500
+Subject: [PATCH] core: Implement timeout based umount/remount limit
+
+Remount, and subsequent umount, attempts can hang for inaccessible network
+based mount points. This can leave a system in a hard hang state that
+requires a hard reset in order to recover. This change moves the remount,
+and umount attempts into separate child processes. The remount and umount
+operations will block for up to 90 seconds (DEFAULT_TIMEOUT_USEC). Should
+those waits fail, the parent will issue a SIGKILL to the child and continue
+with the shutdown efforts.
+
+In addition, instead of only reporting some additional errors on the final
+attempt, failures are reported as they occur.
+
+(cherry picked from commit d5641e0d7e8f55937fbc3a7ecd667e42c5836d80)
+
+Related: #1571098
+---
+ src/core/umount.c         | 112 +++++++++++++++++++++++++++++++++++++---------
+ src/shared/def.h          |   2 -
+ src/shared/login-shared.c |   1 +
+ src/shared/util.c         |  61 +++++++++++++++++++++++++
+ src/shared/util.h         |  16 +++++++
+ 5 files changed, 168 insertions(+), 24 deletions(-)
+
+diff --git a/src/core/umount.c b/src/core/umount.c
+index 91d67c06c..bd3896612 100644
+--- a/src/core/umount.c
++++ b/src/core/umount.c
+@@ -363,7 +363,84 @@ static int delete_dm(dev_t devnum) {
+         return r >= 0 ? 0 : -errno;
+ }
+ 
+-static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
++static int remount_with_timeout(MountPoint *m, char *options, int *n_failed) {
++        pid_t pid;
++        int r;
++
++        BLOCK_SIGNALS(SIGCHLD);
++
++        /* Due to the possiblity of a remount operation hanging, we
++         * fork a child process and set a timeout. If the timeout
++         * lapses, the assumption is that that particular remount
++         * failed. */
++        pid = fork();
++        if (pid < 0)
++                return log_error_errno(errno, "Failed to fork: %m");
++
++        if (pid == 0) {
++                log_info("Remounting '%s' read-only in with options '%s'.", m->path, options);
++
++                /* Start the mount operation here in the child */
++                r = mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
++                if (r < 0)
++                        log_error_errno(errno, "Failed to remount '%s' read-only: %m", m->path);
++
++                _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
++        }
++
++        r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
++        if (r == -ETIMEDOUT) {
++                log_error_errno(errno, "Remounting '%s' - timed out, issuing SIGKILL to PID "PID_FMT".", m->path, pid);
++                (void) kill(pid, SIGKILL);
++        } else if (r < 0)
++                log_error_errno(r, "Failed to wait for process: %m");
++
++        return r;
++}
++
++static int umount_with_timeout(MountPoint *m, bool *changed) {
++        pid_t pid;
++        int r;
++
++        BLOCK_SIGNALS(SIGCHLD);
++
++        /* Due to the possiblity of a umount operation hanging, we
++         * fork a child process and set a timeout. If the timeout
++         * lapses, the assumption is that that particular umount
++         * failed. */
++        pid = fork();
++        if (pid < 0)
++                return log_error_errno(errno, "Failed to fork: %m");
++
++        if (pid == 0) {
++                log_info("Unmounting '%s'.", m->path);
++
++                /* Start the mount operation here in the child Using MNT_FORCE
++                 * causes some filesystems (e.g. FUSE and NFS and other network
++                 * filesystems) to abort any pending requests and return -EIO
++                 * rather than blocking indefinitely. If the filesysten is
++                 * "busy", this may allow processes to die, thus making the
++                 * filesystem less busy so the unmount might succeed (rather
++                 * then return EBUSY).*/
++                r = umount2(m->path, MNT_FORCE);
++                if (r < 0)
++                        log_error_errno(errno, "Failed to unmount %s: %m", m->path);
++
++                _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
++        }
++
++        r = wait_for_terminate_with_timeout(pid, DEFAULT_TIMEOUT_USEC);
++        if (r == -ETIMEDOUT) {
++                log_error_errno(errno, "Unmounting '%s' - timed out, issuing SIGKILL to PID "PID_FMT".", m->path, pid);
++                (void) kill(pid, SIGKILL);
++        } else if (r < 0)
++                log_error_errno(r, "Failed to wait for process: %m");
++
++        return r;
++}
++
++
++static int mount_points_list_umount(MountPoint **head, bool *changed) {
+         MountPoint *m, *n;
+         int n_failed = 0;
+ 
+@@ -405,9 +482,13 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
+                          * explicitly remount the super block of that
+                          * alias read-only we hence should be
+                          * relatively safe regarding keeping the fs we
+-                         * can otherwise not see dirty. */
+-                        log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
+-                        (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
++                         * can otherwise not see dirty.
++                         *
++                         * Since the remount can hang in the instance of
++                         * remote filesystems, we remount asynchronously
++                         * and skip the subsequent umount if it fails */
++                        if (remount_with_timeout(m, options, &n_failed) < 0)
++                                continue;
+                 }
+ 
+                 /* Skip / and /usr since we cannot unmount that
+@@ -420,22 +501,14 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
+                 )
+                         continue;
+ 
+-                /* Trying to umount. Using MNT_FORCE causes some
+-                 * filesystems (e.g. FUSE and NFS and other network
+-                 * filesystems) to abort any pending requests and
+-                 * return -EIO rather than blocking indefinitely.
+-                 * If the filesysten is "busy", this may allow processes
+-                 * to die, thus making the filesystem less busy so
+-                 * the unmount might succeed (rather then return EBUSY).*/
+-                log_info("Unmounting %s.", m->path);
+-                if (umount2(m->path, MNT_FORCE) == 0) {
++                /* Trying to umount */
++                if (umount_with_timeout(m, changed) < 0)
++                        n_failed++;
++                else {
+                         if (changed)
+                                 *changed = true;
+ 
+                         mount_point_free(head, m);
+-                } else if (log_error) {
+-                        log_warning_errno(errno, "Could not unmount %s: %m", m->path);
+-                        n_failed++;
+                 }
+         }
+ 
+@@ -550,17 +623,12 @@ int umount_all(bool *changed) {
+         do {
+                 umount_changed = false;
+ 
+-                mount_points_list_umount(&mp_list_head, &umount_changed, false);
++                mount_points_list_umount(&mp_list_head, &umount_changed);
+                 if (umount_changed)
+                         *changed = true;
+ 
+         } while (umount_changed);
+ 
+-        /* umount one more time with logging enabled */
+-        r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
+-        if (r <= 0)
+-                goto end;
+-
+   end:
+         mount_points_list_free(&mp_list_head);
+ 
+diff --git a/src/shared/def.h b/src/shared/def.h
+index 9e008a6d2..f193ab1f9 100644
+--- a/src/shared/def.h
++++ b/src/shared/def.h
+@@ -21,8 +21,6 @@
+   along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
+ 
+-#include "util.h"
+-
+ #define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC)
+ #define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
+ #define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC)
+diff --git a/src/shared/login-shared.c b/src/shared/login-shared.c
+index 054c77503..5da0f0583 100644
+--- a/src/shared/login-shared.c
++++ b/src/shared/login-shared.c
+@@ -21,6 +21,7 @@
+ 
+ #include "login-shared.h"
+ #include "def.h"
++#include "util.h"
+ 
+ bool session_id_valid(const char *id) {
+         assert(id);
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 982f5e044..3216f004a 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -9049,3 +9049,64 @@ try_dev_shm_without_o_tmpfile:
+ 
+         return -EOPNOTSUPP;
+ }
++
++/*
++ * Return values:
++ * < 0 : wait_for_terminate_with_timeout() failed to get the state of the
++ *       process, the process timed out, the process was terminated by a
++ *       signal, or failed for an unknown reason.
++ * >=0 : The process terminated normally with no failures.
++ *
++ * Success is indicated by a return value of zero, a timeout is indicated
++ * by ETIMEDOUT, and all other child failure states are indicated by error
++ * is indicated by a non-zero value.
++*/
++int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
++        sigset_t mask;
++        int r;
++        usec_t until;
++
++        assert_se(sigemptyset(&mask) == 0);
++        assert_se(sigaddset(&mask, SIGCHLD) == 0);
++
++        /* Drop into a sigtimewait-based timeout. Waiting for the
++         * pid to exit. */
++        until = now(CLOCK_MONOTONIC) + timeout;
++        for (;;) {
++                usec_t n;
++                siginfo_t status = {};
++                struct timespec ts;
++
++                n = now(CLOCK_MONOTONIC);
++                if (n >= until)
++                        break;
++
++                r = sigtimedwait(&mask, NULL, timespec_store(&ts, until - n)) < 0 ? -errno : 0;
++                /* Assuming we woke due to the child exiting. */
++                if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) {
++                        if (status.si_pid == pid) {
++                                /* This is the correct child.*/
++                                if (status.si_code == CLD_EXITED)
++                                        return (status.si_status == 0) ? 0 : -EPROTO;
++                                else
++                                        return -EPROTO;
++                        }
++                }
++                /* Not the child, check for errors and proceed appropriately */
++                if (r < 0) {
++                        switch (r) {
++                        case -EAGAIN:
++                                /* Timed out, child is likely hung. */
++                                return -ETIMEDOUT;
++                        case -EINTR:
++                                /* Received a different signal and should retry */
++                                continue;
++                        default:
++                                /* Return any unexpected errors */
++                                return r;
++                        }
++                }
++        }
++
++        return -EPROTO;
++}
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 9c4be0256..998f882bb 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -22,6 +22,7 @@
+ ***/
+ 
+ #include <alloca.h>
++#include <def.h>
+ #include <fcntl.h>
+ #include <inttypes.h>
+ #include <time.h>
+@@ -1122,3 +1123,18 @@ enum {
+ };
+ 
+ int acquire_data_fd(const void *data, size_t size, unsigned flags);
++
++int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout);
++
++static inline void block_signals_reset(sigset_t *ss) {
++        assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
++}
++
++#define BLOCK_SIGNALS(...)                                                         \
++        _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({        \
++                sigset_t _t;                                                       \
++                assert_se(sigprocmask(SIG_SETMASK, NULL, &_t) == 0);               \
++                assert_se(sigprocmask_many(SIG_BLOCK, __VA_ARGS__, -1) >= 0);      \
++                _t;                                                                \
++        })
++
diff --git a/SOURCES/0641-core-Implement-sync_with_progress.patch b/SOURCES/0641-core-Implement-sync_with_progress.patch
new file mode 100644
index 0000000..bbadec6
--- /dev/null
+++ b/SOURCES/0641-core-Implement-sync_with_progress.patch
@@ -0,0 +1,169 @@
+From db57bf73d3e5e650b261834a0c39c9d368f9eeea Mon Sep 17 00:00:00 2001
+From: Kyle Walker <kwalker@redhat.com>
+Date: Thu, 14 Dec 2017 11:46:03 -0500
+Subject: [PATCH] core: Implement sync_with_progress()
+
+In similar fashion to the previous change, sync() operations can stall
+endlessly if cache is unable to be written out. In order to avoid an
+unbounded hang, the sync takes place within a child process. Every 10
+seconds (SYNC_TIMEOUT_USEC), the value of /proc/meminfo "Dirty" is checked
+to verify it is smaller than the last iteration. If the sync is not making
+progress for 3 successive iterations (SYNC_PROGRESS_ATTEMPTS), a SIGKILL is
+sent to the sync process and the shutdown continues.
+
+(cherry picked from commit 73ad712fcfea5d8ba475044698d31d2c15d4180d)
+
+Related: #1571098
+---
+ src/core/shutdown.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 111 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/shutdown.c b/src/core/shutdown.c
+index 71f001ac1..0b0a54a7d 100644
+--- a/src/core/shutdown.c
++++ b/src/core/shutdown.c
+@@ -53,6 +53,9 @@
+ 
+ #define FINALIZE_ATTEMPTS 50
+ 
++#define SYNC_PROGRESS_ATTEMPTS 3
++#define SYNC_TIMEOUT_USEC (10*USEC_PER_SEC)
++
+ static char* arg_verb;
+ 
+ static int parse_argv(int argc, char *argv[]) {
+@@ -152,6 +155,102 @@ static int switch_root_initramfs(void) {
+         return switch_root("/run/initramfs", "/oldroot", false, MS_BIND);
+ }
+ 
++/* Read the following fields from /proc/meminfo:
++ *
++ *  NFS_Unstable
++ *  Writeback
++ *  Dirty
++ *
++ * Return true if the sum of these fields is greater than the previous
++ * value input. For all other issues, report the failure and indicate that
++ * the sync is not making progress.
++ */
++static bool sync_making_progress(unsigned long long *prev_dirty) {
++        _cleanup_fclose_ FILE *f = NULL;
++        char line[LINE_MAX];
++        bool r = false;
++        unsigned long long val = 0;
++
++        f = fopen("/proc/meminfo", "re");
++        if (!f)
++                return log_warning_errno(errno, "Failed to open /proc/meminfo: %m");
++
++        FOREACH_LINE(line, f, log_warning_errno(errno, "Failed to parse /proc/meminfo: %m")) {
++                unsigned long long ull = 0;
++
++                if (!first_word(line, "NFS_Unstable:") && !first_word(line, "Writeback:") && !first_word(line, "Dirty:"))
++                        continue;
++
++                errno = 0;
++                if (sscanf(line, "%*s %llu %*s", &ull) != 1) {
++                        if (errno != 0)
++                                log_warning_errno(errno, "Failed to parse /proc/meminfo: %m");
++                        else
++                                log_warning("Failed to parse /proc/meminfo");
++
++                        return false;
++                }
++
++                val += ull;
++        }
++
++        r = *prev_dirty > val;
++
++        *prev_dirty = val;
++
++        return r;
++}
++
++static void sync_with_progress(void) {
++        unsigned checks;
++        pid_t pid;
++        int r;
++        unsigned long long dirty = ULONG_LONG_MAX;
++
++        BLOCK_SIGNALS(SIGCHLD);
++
++        /* Due to the possiblity of the sync operation hanging, we fork
++         * a child process and monitor the progress. If the timeout
++         * lapses, the assumption is that that particular sync stalled. */
++        pid = fork();
++        if (pid < 0) {
++                log_error_errno(errno, "Failed to fork: %m");
++                return;
++        }
++
++        if (pid == 0) {
++                /* Start the sync operation here in the child */
++                sync();
++                _exit(EXIT_SUCCESS);
++        }
++
++        log_info("Syncing filesystems and block devices.");
++
++        /* Start monitoring the sync operation. If more than
++         * SYNC_PROGRESS_ATTEMPTS lapse without progress being made,
++         * we assume that the sync is stalled */
++        for (checks = 0; checks < SYNC_PROGRESS_ATTEMPTS; checks++) {
++                r = wait_for_terminate_with_timeout(pid, SYNC_TIMEOUT_USEC);
++                if (r == 0)
++                        /* Sync finished without error.
++                         * (The sync itself does not return an error code) */
++                        return;
++                else if (r == -ETIMEDOUT) {
++                        /* Reset the check counter if the "Dirty" value is
++                         * decreasing */
++                        if (sync_making_progress(&dirty))
++                                checks = 0;
++                } else {
++                        log_error_errno(r, "Failed to sync filesystems and block devices: %m");
++                        return;
++                }
++        }
++
++        /* Only reached in the event of a timeout. We should issue a kill
++         * to the stray process. */
++        log_error("Syncing filesystems and block devices - timed out, issuing SIGKILL to PID "PID_FMT".", pid);
++        (void) kill(pid, SIGKILL);
++}
+ 
+ int main(int argc, char *argv[]) {
+         bool need_umount, need_swapoff, need_loop_detach, need_dm_detach;
+@@ -202,6 +301,13 @@ int main(int argc, char *argv[]) {
+         /* lock us into memory */
+         mlockall(MCL_CURRENT|MCL_FUTURE);
+ 
++        /* Synchronize everything that is not written to disk yet at this point already. This is a good idea so that
++         * slow IO is processed here already and the final process killing spree is not impacted by processes
++         * desperately trying to sync IO to disk within their timeout. Do not remove this sync, data corruption will
++         * result. */
++        if (!in_container)
++                sync_with_progress();
++
+         log_info("Sending SIGTERM to remaining processes...");
+         broadcast_signal(SIGTERM, true, true);
+ 
+@@ -338,12 +444,12 @@ int main(int argc, char *argv[]) {
+                           need_loop_detach ? " loop devices," : "",
+                           need_dm_detach ? " DM devices," : "");
+ 
+-        /* The kernel will automaticall flush ATA disks and suchlike
+-         * on reboot(), but the file systems need to be synce'd
+-         * explicitly in advance. So let's do this here, but not
+-         * needlessly slow down containers. */
++        /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
++         * sync'ed explicitly in advance. So let's do this here, but not needlessly slow down containers. Note that we
++         * sync'ed things already once above, but we did some more work since then which might have caused IO, hence
++         * let's do it once more. Do not remove this sync, data corruption will result. */
+         if (!in_container)
+-                sync();
++                sync_with_progress();
+ 
+         switch (cmd) {
+ 
diff --git a/SOURCES/0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch b/SOURCES/0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch
new file mode 100644
index 0000000..0a34165
--- /dev/null
+++ b/SOURCES/0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch
@@ -0,0 +1,48 @@
+From 4f36220ccfe40621cd7df3595568278d7bca4f87 Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Fri, 23 Sep 2016 13:33:01 +0200
+Subject: [PATCH] journal: fix HMAC calculation when appending a data object
+
+Since commit 5996c7c295e073ce21d41305169132c8aa993ad0 (v190 !), the
+calculation of the HMAC is broken because the hash for a data object
+including a field is done in the wrong order: the field object is
+hashed before the data object is.
+
+However during verification, the hash is done in the opposite order as
+objects are scanned sequentially.
+
+(cherry picked from commit 33685a5a3a98c6ded64d0cc25e37d0180ceb0a6a)
+---
+ src/journal/journal-file.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
+index 2bb3a9757..586f620e2 100644
+--- a/src/journal/journal-file.c
++++ b/src/journal/journal-file.c
+@@ -1099,6 +1099,12 @@ static int journal_file_append_data(
+         if (r < 0)
+                 return r;
+ 
++#ifdef HAVE_GCRYPT
++        r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p);
++        if (r < 0)
++                return r;
++#endif
++
+         /* The linking might have altered the window, so let's
+          * refresh our pointer */
+         r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
+@@ -1123,12 +1129,6 @@ static int journal_file_append_data(
+                 fo->field.head_data_offset = le64toh(p);
+         }
+ 
+-#ifdef HAVE_GCRYPT
+-        r = journal_file_hmac_put_object(f, OBJECT_DATA, o, p);
+-        if (r < 0)
+-                return r;
+-#endif
+-
+         if (ret)
+                 *ret = o;
+ 
diff --git a/SOURCES/0643-journal-forward-messages-from-dev-log-unmodified-to-.patch b/SOURCES/0643-journal-forward-messages-from-dev-log-unmodified-to-.patch
new file mode 100644
index 0000000..75fd731
--- /dev/null
+++ b/SOURCES/0643-journal-forward-messages-from-dev-log-unmodified-to-.patch
@@ -0,0 +1,135 @@
+From d82c40a2377b487ef83aa1fb907ec275a1b3e86e Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Wed, 30 May 2018 16:27:22 +0200
+Subject: [PATCH] journal: forward messages from /dev/log unmodified to
+ syslog.socket
+
+(cherry picked from commit bb3ff70a86faff85fe482995c8ba5332b1a34f76)
+
+Resolves: #1409659
+---
+ src/journal/journald-server.c |  2 +-
+ src/journal/journald-syslog.c | 39 +++++++++++++++++++++++++--------------
+ src/journal/journald-syslog.h |  2 +-
+ 3 files changed, 27 insertions(+), 16 deletions(-)
+
+diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
+index 7c69061f4..7e67e055e 100644
+--- a/src/journal/journald-server.c
++++ b/src/journal/journald-server.c
+@@ -1294,7 +1294,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
+ 
+         if (fd == s->syslog_fd) {
+                 if (n > 0 && n_fds == 0)
+-                        server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
++                        server_process_syslog_message(s, s->buffer, n, ucred, tv, label, label_len);
+                 else if (n_fds > 0)
+                         log_warning("Got file descriptors via syslog socket. Ignoring.");
+ 
+diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
+index b499a0d38..01d2bf69f 100644
+--- a/src/journal/journald-syslog.c
++++ b/src/journal/journald-syslog.c
+@@ -109,7 +109,7 @@ static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned
+                 log_debug_errno(errno, "Failed to forward syslog message: %m");
+ }
+ 
+-static void forward_syslog_raw(Server *s, int priority, const char *buffer, const struct ucred *ucred, const struct timeval *tv) {
++static void forward_syslog_raw(Server *s, int priority, const char *buffer, size_t buffer_len, const struct ucred *ucred, const struct timeval *tv) {
+         struct iovec iovec;
+ 
+         assert(s);
+@@ -118,7 +118,9 @@ static void forward_syslog_raw(Server *s, int priority, const char *buffer, cons
+         if (LOG_PRI(priority) > s->max_level_syslog)
+                 return;
+ 
+-        IOVEC_SET_STRING(iovec, buffer);
++        iovec.iov_base = (char *) buffer;
++        iovec.iov_len = buffer_len;
++
+         forward_syslog_iovec(s, &iovec, 1, ucred, tv);
+ }
+ 
+@@ -311,40 +313,49 @@ static void syslog_skip_date(char **buf) {
+ void server_process_syslog_message(
+         Server *s,
+         const char *buf,
++        size_t buf_len,
+         const struct ucred *ucred,
+         const struct timeval *tv,
+         const char *label,
+         size_t label_len) {
+ 
+         char syslog_priority[sizeof("PRIORITY=") + DECIMAL_STR_MAX(int)],
+-             syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
++             syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)], *msg;
+         const char *message = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
+         struct iovec iovec[N_IOVEC_META_FIELDS + 6];
+-        unsigned n = 0;
++        unsigned n = 0, i;
+         int priority = LOG_USER | LOG_INFO;
+         _cleanup_free_ char *identifier = NULL, *pid = NULL;
+-        const char *orig;
+ 
+         assert(s);
+         assert(buf);
+ 
+-        orig = buf;
+-        syslog_parse_priority(&buf, &priority, true);
++        /* We are creating copy of the message because we want to forward original message verbatim to the legacy
++           syslog implementation */
++        for (i = buf_len; i > 0; i--)
++                if (!strchr(WHITESPACE, buf[i-1]))
++                        break;
++
++        msg = newa(char, i + 1);
++        *((char *) mempcpy(msg, buf, i)) = 0;
++        msg += strspn(msg, WHITESPACE);
++
++        syslog_parse_priority((const char **)&msg, &priority, true);
+ 
+         if (s->forward_to_syslog)
+-                forward_syslog_raw(s, priority, orig, ucred, tv);
++                forward_syslog_raw(s, priority, buf, buf_len, ucred, tv);
+ 
+-        syslog_skip_date((char**) &buf);
+-        syslog_parse_identifier(&buf, &identifier, &pid);
++        syslog_skip_date(&msg);
++        syslog_parse_identifier((const char**)&msg, &identifier, &pid);
+ 
+         if (s->forward_to_kmsg)
+-                server_forward_kmsg(s, priority, identifier, buf, ucred);
++                server_forward_kmsg(s, priority, identifier, msg, ucred);
+ 
+         if (s->forward_to_console)
+-                server_forward_console(s, priority, identifier, buf, ucred);
++                server_forward_console(s, priority, identifier, msg, ucred);
+ 
+         if (s->forward_to_wall)
+-                server_forward_wall(s, priority, identifier, buf, ucred);
++                server_forward_wall(s, priority, identifier, msg, ucred);
+ 
+         IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
+ 
+@@ -368,7 +379,7 @@ void server_process_syslog_message(
+                         IOVEC_SET_STRING(iovec[n++], syslog_pid);
+         }
+ 
+-        message = strjoina("MESSAGE=", buf);
++        message = strjoina("MESSAGE=", msg);
+         if (message)
+                 IOVEC_SET_STRING(iovec[n++], message);
+ 
+diff --git a/src/journal/journald-syslog.h b/src/journal/journald-syslog.h
+index 3774ebdf0..e593be99a 100644
+--- a/src/journal/journald-syslog.h
++++ b/src/journal/journald-syslog.h
+@@ -29,7 +29,7 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid);
+ 
+ void server_forward_syslog(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred, const struct timeval *tv);
+ 
+-void server_process_syslog_message(Server *s, const char *buf, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
++void server_process_syslog_message(Server *s, const char *buf, size_t buf_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len);
+ int server_open_syslog_socket(Server *s);
+ 
+ void server_maybe_warn_forward_syslog_missed(Server *s);
diff --git a/SOURCES/0644-tmpfiles-use-safe_glob.patch b/SOURCES/0644-tmpfiles-use-safe_glob.patch
new file mode 100644
index 0000000..65b1fce
--- /dev/null
+++ b/SOURCES/0644-tmpfiles-use-safe_glob.patch
@@ -0,0 +1,158 @@
+From 2f9ee3163c44a71c99fe104daf01d4d9ab51d2c9 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Mon, 28 May 2018 10:52:52 +0200
+Subject: [PATCH] tmpfiles: use safe_glob()
+
+This filters out "." and ".." from glob results. Fixes #5655 and #5644.
+
+Any judgements on whether the path is "safe" are removed. We will not remove
+"/" under any name (including "/../" and such), but we will remove stuff that
+is specified using paths that include "//", "/./" and "/../". Such paths can be
+created when joining strings automatically, or for other reasons, and people
+generally know what ".." and "." is.
+
+Tests are added to make sure that the helper functions behave as expected.
+
+Original commit: 84e72b5ef445ffb256bc4add4209c4c9c9855206
+Resolves: #1436004
+---
+ src/shared/util.c       | 63 +++++++++++++++++++++++++++++++++++++++++++++++--
+ src/shared/util.h       |  2 ++
+ src/tmpfiles/tmpfiles.c | 11 +++------
+ 3 files changed, 66 insertions(+), 10 deletions(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 3216f004a..78967103a 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -49,7 +49,6 @@
+ #include <dlfcn.h>
+ #include <sys/wait.h>
+ #include <sys/time.h>
+-#include <glob.h>
+ #include <grp.h>
+ #include <sys/mman.h>
+ #include <sys/vfs.h>
+@@ -3370,7 +3369,7 @@ static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bo
+         /* We refuse to clean the root file system with this
+          * call. This is extra paranoia to never cause a really
+          * seriously broken system. */
+-        if (path_equal(path, "/")) {
++        if (path_equal_or_files_same(path, "/")) {
+                 log_error("Attempted to remove entire root file system, and we can't allow that.");
+                 return -EPERM;
+         }
+@@ -5096,6 +5095,66 @@ int in_group(const char *name) {
+         return in_gid(gid);
+ }
+ 
++static void closedir_wrapper(void* v) {
++        (void) closedir(v);
++}
++
++static bool dot_or_dot_dot(const char *path) {
++        if (!path)
++                return false;
++        if (path[0] != '.')
++                return false;
++        if (path[1] == 0)
++                return true;
++        if (path[1] != '.')
++                return false;
++
++        return path[2] == 0;
++}
++
++static struct dirent* readdir_no_dot(DIR *dirp) {
++        struct dirent* d;
++
++        for (;;) {
++                d = readdir(dirp);
++                if (d && dot_or_dot_dot(d->d_name))
++                        continue;
++                return d;
++        }
++}
++
++int safe_glob(const char *path, int flags, glob_t *pglob) {
++        int k;
++
++        /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
++        assert(!(flags & GLOB_ALTDIRFUNC));
++
++        if (!pglob->gl_closedir)
++                pglob->gl_closedir = closedir_wrapper;
++        if (!pglob->gl_readdir)
++                pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
++        if (!pglob->gl_opendir)
++                pglob->gl_opendir = (void *(*)(const char *)) opendir;
++        if (!pglob->gl_lstat)
++                pglob->gl_lstat = lstat;
++        if (!pglob->gl_stat)
++                pglob->gl_stat = stat;
++
++        errno = 0;
++        k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
++
++        if (k == GLOB_NOMATCH)
++                return -ENOENT;
++        if (k == GLOB_NOSPACE)
++                return -ENOMEM;
++        if (k != 0)
++                return errno > 0 ? -errno : -EIO;
++        if (strv_isempty(pglob->gl_pathv))
++                return -ENOENT;
++
++        return 0;
++}
++
+ int glob_exists(const char *path) {
+         _cleanup_globfree_ glob_t g = {};
+         int k;
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 998f882bb..cf096aa07 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -44,6 +44,7 @@
+ #include <mntent.h>
+ #include <sys/socket.h>
+ #include <sys/inotify.h>
++#include <glob.h>
+ 
+ #if SIZEOF_PID_T == 4
+ #  define PID_PRI PRIi32
+@@ -595,6 +596,7 @@ char* gid_to_name(gid_t gid);
+ 
+ int glob_exists(const char *path);
+ int glob_extend(char ***strv, const char *path);
++int safe_glob(const char *path, int flags, glob_t *pglob);
+ 
+ int dirent_ensure_type(DIR *d, struct dirent *de);
+ 
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index 5212d72f5..8a75efb22 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -1095,19 +1095,14 @@ static int item_do_children(Item *i, const char *path, action_t action) {
+ 
+ static int glob_item(Item *i, action_t action, bool recursive) {
+         _cleanup_globfree_ glob_t g = {
+-                .gl_closedir = (void (*)(void *)) closedir,
+-                .gl_readdir = (struct dirent *(*)(void *)) readdir,
+                 .gl_opendir = (void *(*)(const char *)) opendir_nomod,
+-                .gl_lstat = lstat,
+-                .gl_stat = stat,
+         };
+         int r = 0, k;
+         char **fn;
+ 
+-        errno = 0;
+-        k = glob(i->path, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
+-        if (k != 0 && k != GLOB_NOMATCH)
+-                return log_error_errno(errno ?: EIO, "glob(%s) failed: %m", i->path);
++        k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
++        if (k < 0 && k != -ENOENT)
++                return log_error_errno(k, "glob(%s) failed: %m", i->path);
+ 
+         STRV_FOREACH(fn, g.gl_pathv) {
+                 k = action(i, *fn);
diff --git a/SOURCES/0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch b/SOURCES/0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch
new file mode 100644
index 0000000..76c05e5
--- /dev/null
+++ b/SOURCES/0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch
@@ -0,0 +1,52 @@
+From c043ae5b2ef2e1e437bf738bbf522799c6213230 Mon Sep 17 00:00:00 2001
+From: Krzysztof Nowicki <krzysztof.a.nowicki+github@gmail.com>
+Date: Thu, 30 Nov 2017 11:59:29 +0100
+Subject: [PATCH] Fix SELinux labels in cgroup filesystem root directory
+ (#7496)
+
+When using SELinux with legacy cgroups the tmpfs on /sys/fs/cgroup is by
+default labelled as tmpfs_t. This label is also inherited by the "cpu"
+and "cpuacct" symbolic links. Unfortunately the policy expects them to
+be labelled as cgroup_t, which is used for all the actual cgroup
+filesystems. Failure to do so results in a stream of denials.
+
+This state cannot be fixed reliably when the cgroup filesystem structure
+is set-up as the SELinux policy is not yet loaded at this
+moment. It also cannot be fixed later as the root of the cgroup
+filesystem is remounted read-only. In order to fix it the root of the
+cgroup filesystem needs to be temporary remounted read-write, relabelled
+and remounted back read-only.
+
+(cherry picked from commit 8739f23e3c26bbf8b0296421578e56daa63cbf4b)
+---
+ src/core/mount-setup.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
+index 521545e5c..7a2cae4a3 100644
+--- a/src/core/mount-setup.c
++++ b/src/core/mount-setup.c
+@@ -363,14 +363,22 @@ int mount_setup(bool loaded_policy) {
+                 usec_t before_relabel, after_relabel;
+                 char timespan[FORMAT_TIMESPAN_MAX];
+ 
++                mkdir_label("/run/systemd/policy-relabelling", 0755);
+                 before_relabel = now(CLOCK_MONOTONIC);
+ 
+                 nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+                 nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+ 
++                /* Temporarily remount the root cgroup filesystem to give it a proper label. */
++                (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
++                label_fix("/sys/fs/cgroup", false, false);
++                nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
++                (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
++
+                 after_relabel = now(CLOCK_MONOTONIC);
+ 
+-                log_info("Relabelled /dev and /run in %s.",
++                mkdir_label("/run/systemd/policy-relabelled", 0755);
++                log_info("Relabelled /dev, /run and /sys/fs/cgroup in %s.",
+                          format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel, 0));
+         }
+ #endif
diff --git a/SOURCES/0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch b/SOURCES/0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch
new file mode 100644
index 0000000..0a3f6e4
--- /dev/null
+++ b/SOURCES/0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch
@@ -0,0 +1,91 @@
+From 1707b9959e67e5e73987e1ff8a72189d24656fa0 Mon Sep 17 00:00:00 2001
+From: Krzysztof Nowicki <krzysztof.a.nowicki+github@gmail.com>
+Date: Wed, 28 Mar 2018 13:36:33 +0200
+Subject: [PATCH] core: dont't remount /sys/fs/cgroup for relabel if not needed
+ (#8595)
+
+The initial fix for relabelling the cgroup filesystem for
+SELinux delivered in commit 8739f23e3 was based on the assumption that
+the cgroup filesystem is already populated once mount_setup() is
+executed, which was true for my system. What I wasn't aware is that this
+is the case only when another instance of systemd was running before
+this one, which can happen if systemd is used in the initrd (for ex. by
+dracut).
+
+In case of a clean systemd start-up the cgroup filesystem is actually
+being populated after mount_setup() and does not need relabelling as at
+that moment the SELinux policy is already loaded. Since however the root
+cgroup filesystem was remounted read-only in the meantime this operation
+will now fail.
+
+To fix this check for the filesystem mount flags before relabelling and
+only remount ro->rw->ro if necessary and leave the filesystem read-write
+otherwise.
+
+Fixes #7901.
+
+(cherry picked from commit 6f7729c1767998110c4460c85c94435c5782a613)
+---
+ src/core/mount-setup.c | 35 ++++++++++++++++++++++++++++++-----
+ 1 file changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
+index 7a2cae4a3..ed493cbe3 100644
+--- a/src/core/mount-setup.c
++++ b/src/core/mount-setup.c
+@@ -25,6 +25,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
++#include <sys/statfs.h>
++#include <sys/statvfs.h>
+ #include <unistd.h>
+ #include <ftw.h>
+ 
+@@ -337,6 +339,31 @@ static int nftw_cb(
+ 
+         return FTW_CONTINUE;
+ };
++
++static int relabel_cgroup_filesystems(void) {
++        int r;
++        struct statfs st;
++
++        /* Temporarily remount the root cgroup filesystem to give it a proper label. Do this
++           only when the filesystem has been already populated by a previous instance of systemd
++           running from initrd. Otherwise don't remount anything and leave the filesystem read-write
++           for the cgroup filesystems to be mounted inside. */
++        r = statfs("/sys/fs/cgroup", &st);
++        if (r < 0) {
++                return log_error_errno(errno, "Failed to determine mount flags for /sys/fs/cgroup: %m");
++        }
++
++        if (st.f_flags & ST_RDONLY)
++                (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
++
++        (void) label_fix("/sys/fs/cgroup", false, false);
++        nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
++
++        if (st.f_flags & ST_RDONLY)
++                (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
++
++        return 0;
++}
+ #endif
+ 
+ int mount_setup(bool loaded_policy) {
+@@ -369,11 +396,9 @@ int mount_setup(bool loaded_policy) {
+                 nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+                 nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+ 
+-                /* Temporarily remount the root cgroup filesystem to give it a proper label. */
+-                (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT, NULL);
+-                label_fix("/sys/fs/cgroup", false, false);
+-                nftw("/sys/fs/cgroup", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+-                (void) mount(NULL, "/sys/fs/cgroup", NULL, MS_REMOUNT|MS_RDONLY, NULL);
++                r = relabel_cgroup_filesystems();
++                if (r < 0)
++                        return r;
+ 
+                 after_relabel = now(CLOCK_MONOTONIC);
+ 
diff --git a/SOURCES/0647-fix-race-between-daemon-reload-and-other-commands.patch b/SOURCES/0647-fix-race-between-daemon-reload-and-other-commands.patch
new file mode 100644
index 0000000..088800a
--- /dev/null
+++ b/SOURCES/0647-fix-race-between-daemon-reload-and-other-commands.patch
@@ -0,0 +1,188 @@
+From 13bcf85ffab4b4e67039599246604a3f5b503975 Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Tue, 24 Apr 2018 15:19:38 +0200
+Subject: [PATCH] fix race between daemon-reload and other commands
+
+When "systemctl daemon-reload" is run at the same time as "systemctl
+start foo", the latter might hang. That's because commands like start
+wait for JobRemoved signal to know when the job is finished. But if the
+job is finished during reloading, the signal is never sent.
+
+The hang can be easily reproduced by running
+
+    # for ((N=1; N>0; N++)) ; do echo $N ; systemctl daemon-reload ; done
+    # for ((N=1; N>0; N++)) ; do echo $N ; systemctl start systemd-coredump.socket ; done
+
+in two different terminals. The start command will hang after 1-2
+iterations.
+
+This keeps track of jobs that were started before reload and finished
+during it and sends JobRemoved after the reload has finished.
+
+(cherry picked from commit a7a7163df7fc8a9f794f6803b2f6c9c9b0745a1f)
+---
+ src/core/job.c     | 45 ++++++++++++++++++++++++++++++++++++++++-----
+ src/core/job.h     |  2 ++
+ src/core/manager.c | 15 +++++++++++++++
+ src/core/manager.h |  3 +++
+ 4 files changed, 60 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index 1861c8a63..275503169 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -53,6 +53,7 @@ Job* job_new_raw(Unit *unit) {
+         j->manager = unit->manager;
+         j->unit = unit;
+         j->type = _JOB_TYPE_INVALID;
++        j->reloaded = false;
+ 
+         return j;
+ }
+@@ -74,7 +75,7 @@ Job* job_new(Unit *unit, JobType type) {
+         return j;
+ }
+ 
+-void job_free(Job *j) {
++void job_unlink(Job *j) {
+         assert(j);
+         assert(!j->installed);
+         assert(!j->transaction_prev);
+@@ -82,13 +83,28 @@ void job_free(Job *j) {
+         assert(!j->subject_list);
+         assert(!j->object_list);
+ 
+-        if (j->in_run_queue)
++        if (j->in_run_queue) {
+                 LIST_REMOVE(run_queue, j->manager->run_queue, j);
++                j->in_run_queue = false;
++        }
+ 
+-        if (j->in_dbus_queue)
++        if (j->in_dbus_queue) {
+                 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
++                j->in_dbus_queue = false;
++        }
++
++        j->timer_event_source = sd_event_source_unref(j->timer_event_source);
++}
++
++void job_free(Job *j) {
++        assert(j);
++        assert(!j->installed);
++        assert(!j->transaction_prev);
++        assert(!j->transaction_next);
++        assert(!j->subject_list);
++        assert(!j->object_list);
+ 
+-        sd_event_source_unref(j->timer_event_source);
++        job_unlink(j);
+ 
+         sd_bus_track_unref(j->clients);
+         strv_free(j->deserialized_clients);
+@@ -246,6 +262,7 @@ int job_install_deserialized(Job *j) {
+ 
+         *pj = j;
+         j->installed = true;
++        j->reloaded = true;
+ 
+         if (j->state == JOB_RUNNING)
+                 j->unit->manager->n_running_jobs++;
+@@ -790,6 +807,19 @@ static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
+                 job_print_status_message(u, t, result);
+ }
+ 
++static int job_save_pending_finished_job(Job *j) {
++        int r;
++
++        assert(j);
++
++        r = set_ensure_allocated(&j->manager->pending_finished_jobs, NULL);
++        if (r < 0)
++                return r;
++
++        job_unlink(j);
++        return set_put(j->manager->pending_finished_jobs, j);
++}
++
+ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
+         Unit *u;
+         Unit *other;
+@@ -829,7 +859,12 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
+                 j->manager->n_failed_jobs ++;
+ 
+         job_uninstall(j);
+-        job_free(j);
++        /* Remember jobs started before the reload */
++        if (j->manager->n_reloading > 0 && j->reloaded) {
++                if (job_save_pending_finished_job(j) < 0)
++                        job_free(j);
++        } else
++                job_free(j);
+ 
+         /* Fail depending jobs on failure */
+         if (result != JOB_DONE && recursive) {
+diff --git a/src/core/job.h b/src/core/job.h
+index 535052b48..4ae6f2802 100644
+--- a/src/core/job.h
++++ b/src/core/job.h
+@@ -172,10 +172,12 @@ struct Job {
+         bool sent_dbus_new_signal:1;
+         bool ignore_order:1;
+         bool irreversible:1;
++        bool reloaded:1;
+ };
+ 
+ Job* job_new(Unit *unit, JobType type);
+ Job* job_new_raw(Unit *unit);
++void job_unlink(Job *job);
+ void job_free(Job *job);
+ Job* job_install(Job *j);
+ int job_install_deserialized(Job *j);
+diff --git a/src/core/manager.c b/src/core/manager.c
+index 47b09e1e9..9c406bb5b 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -2702,6 +2702,18 @@ finish:
+         return r;
+ }
+ 
++static void manager_flush_finished_jobs(Manager *m) {
++        Job *j;
++
++        while ((j = set_steal_first(m->pending_finished_jobs))) {
++                bus_job_send_removed_signal(j);
++                job_free(j);
++        }
++
++        set_free(m->pending_finished_jobs);
++        m->pending_finished_jobs = NULL;
++}
++
+ int manager_reload(Manager *m) {
+         int r, q;
+         _cleanup_fclose_ FILE *f = NULL;
+@@ -2784,6 +2796,9 @@ int manager_reload(Manager *m) {
+         assert(m->n_reloading > 0);
+         m->n_reloading--;
+ 
++        if (m->n_reloading <= 0)
++                manager_flush_finished_jobs(m);
++
+         m->send_reloading_done = true;
+ 
+         return r;
+diff --git a/src/core/manager.h b/src/core/manager.h
+index e91e7bd8b..90d2d982e 100644
+--- a/src/core/manager.h
++++ b/src/core/manager.h
+@@ -270,6 +270,9 @@ struct Manager {
+ 
+         /* non-zero if we are reloading or reexecuting, */
+         int n_reloading;
++        /* A set which contains all jobs that started before reload and finished
++         * during it */
++        Set *pending_finished_jobs;
+ 
+         unsigned n_installed_jobs;
+         unsigned n_failed_jobs;
diff --git a/SOURCES/0648-core-delay-adding-target-dependencies-until-all-unit.patch b/SOURCES/0648-core-delay-adding-target-dependencies-until-all-unit.patch
new file mode 100644
index 0000000..4145956
--- /dev/null
+++ b/SOURCES/0648-core-delay-adding-target-dependencies-until-all-unit.patch
@@ -0,0 +1,223 @@
+From 36226a9afe96bdffce9d0697be020f2ca9d7fe6f Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekletar@users.noreply.github.com>
+Date: Fri, 23 Mar 2018 15:28:06 +0100
+Subject: [PATCH] core: delay adding target dependencies until all units are
+ loaded and aliases resolved (#8381)
+
+Currently we add target dependencies while we are loading units. This
+can create ordering loops even if configuration doesn't contain any
+loop. Take for example following configuration,
+
+$ systemctl get-default
+multi-user.target
+
+$ cat /etc/systemd/system/test.service
+[Unit]
+After=default.target
+
+[Service]
+ExecStart=/bin/true
+
+[Install]
+WantedBy=multi-user.target
+
+If we encounter such unit file early during manager start-up (e.g. load
+queue is dispatched while enumerating devices due to SYSTEMD_WANTS in
+udev rules) we would add stub unit default.target and we order it Before
+test.service. At the same time we add implicit Before to
+multi-user.target. Later we merge two units and we create ordering cycle
+in the process.
+
+To fix the issue we will now never add any target dependencies until we
+loaded all the unit files and resolved all the aliases.
+
+(cherry picked from commit 19496554e23ea4861ce780430052dcf86a2ffcba)
+
+Resolves: #1368856
+---
+ src/core/manager.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ src/core/manager.h |  3 +++
+ src/core/unit.c    | 46 ++++++++++++++++------------------------------
+ src/core/unit.h    |  5 +++++
+ 4 files changed, 64 insertions(+), 30 deletions(-)
+
+diff --git a/src/core/manager.c b/src/core/manager.c
+index 9c406bb5b..0466e4bb8 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -1373,6 +1373,41 @@ Unit *manager_get_unit(Manager *m, const char *name) {
+         return hashmap_get(m->units, name);
+ }
+ 
++static int manager_dispatch_target_deps_queue(Manager *m) {
++        Unit *u;
++        unsigned k;
++        int r = 0;
++
++        static const UnitDependency deps[] = {
++                UNIT_REQUIRED_BY,
++                UNIT_REQUIRED_BY_OVERRIDABLE,
++                UNIT_WANTED_BY,
++                UNIT_BOUND_BY
++        };
++
++        assert(m);
++
++        while ((u = m->target_deps_queue)) {
++                assert(u->in_target_deps_queue);
++
++                LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
++                u->in_target_deps_queue = false;
++
++                for (k = 0; k < ELEMENTSOF(deps); k++) {
++                        Unit *target;
++                        Iterator i;
++
++                        SET_FOREACH(target, u->dependencies[deps[k]], i) {
++                                r = unit_add_default_target_dependency(u, target);
++                                if (r < 0)
++                                        return r;
++                        }
++                }
++        }
++
++        return r;
++}
++
+ unsigned manager_dispatch_load_queue(Manager *m) {
+         Unit *u;
+         unsigned n = 0;
+@@ -1396,6 +1431,11 @@ unsigned manager_dispatch_load_queue(Manager *m) {
+         }
+ 
+         m->dispatching_load_queue = false;
++
++        /* Dispatch the units waiting for their target dependencies to be added now, as all targets that we know about
++         * should be loaded and have aliases resolved */
++        (void) manager_dispatch_target_deps_queue(m);
++
+         return n;
+ }
+ 
+diff --git a/src/core/manager.h b/src/core/manager.h
+index 90d2d982e..b0e4cad1f 100644
+--- a/src/core/manager.h
++++ b/src/core/manager.h
+@@ -114,6 +114,9 @@ struct Manager {
+         /* Units that should be realized */
+         LIST_HEAD(Unit, cgroup_queue);
+ 
++        /* Target units whose default target dependencies haven't been set yet */
++        LIST_HEAD(Unit, target_deps_queue);
++
+         sd_event *event;
+ 
+         /* We use two hash tables here, since the same PID might be
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 22d9beed7..cfddce34d 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -519,6 +519,9 @@ void unit_free(Unit *u) {
+                 u->manager->n_in_gc_queue--;
+         }
+ 
++        if (u->in_target_deps_queue)
++                LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
++
+         if (u->in_cgroup_queue)
+                 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
+ 
+@@ -1065,6 +1068,18 @@ int unit_load_fragment_and_dropin_optional(Unit *u) {
+         return 0;
+ }
+ 
++void unit_add_to_target_deps_queue(Unit *u) {
++        Manager *m = u->manager;
++
++        assert(u);
++
++        if (u->in_target_deps_queue)
++                return;
++
++        LIST_PREPEND(target_deps_queue, m->target_deps_queue, u);
++        u->in_target_deps_queue = true;
++}
++
+ int unit_add_default_target_dependency(Unit *u, Unit *target) {
+         assert(u);
+         assert(target);
+@@ -1091,32 +1106,6 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
+         return unit_add_dependency(target, UNIT_AFTER, u, true);
+ }
+ 
+-static int unit_add_target_dependencies(Unit *u) {
+-
+-        static const UnitDependency deps[] = {
+-                UNIT_REQUIRED_BY,
+-                UNIT_REQUIRED_BY_OVERRIDABLE,
+-                UNIT_WANTED_BY,
+-                UNIT_BOUND_BY
+-        };
+-
+-        Unit *target;
+-        Iterator i;
+-        unsigned k;
+-        int r = 0;
+-
+-        assert(u);
+-
+-        for (k = 0; k < ELEMENTSOF(deps); k++)
+-                SET_FOREACH(target, u->dependencies[deps[k]], i) {
+-                        r = unit_add_default_target_dependency(u, target);
+-                        if (r < 0)
+-                                return r;
+-                }
+-
+-        return r;
+-}
+-
+ static int unit_add_slice_dependencies(Unit *u) {
+         assert(u);
+ 
+@@ -1217,10 +1206,7 @@ int unit_load(Unit *u) {
+         }
+ 
+         if (u->load_state == UNIT_LOADED) {
+-
+-                r = unit_add_target_dependencies(u);
+-                if (r < 0)
+-                        goto fail;
++                unit_add_to_target_deps_queue(u);
+ 
+                 r = unit_add_slice_dependencies(u);
+                 if (r < 0)
+diff --git a/src/core/unit.h b/src/core/unit.h
+index 480e2e95f..dfec9cea0 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -162,6 +162,9 @@ struct Unit {
+         /* CGroup realize members queue */
+         LIST_FIELDS(Unit, cgroup_queue);
+ 
++        /* Target dependencies queue */
++        LIST_FIELDS(Unit, target_deps_queue);
++
+         /* PIDs we keep an eye on. Note that a unit might have many
+          * more, but these are the ones we care enough about to
+          * process SIGCHLD for */
+@@ -228,6 +231,7 @@ struct Unit {
+         bool in_cleanup_queue:1;
+         bool in_gc_queue:1;
+         bool in_cgroup_queue:1;
++        bool in_target_deps_queue:1;
+ 
+         bool sent_dbus_new_signal:1;
+ 
+@@ -498,6 +502,7 @@ void unit_add_to_load_queue(Unit *u);
+ void unit_add_to_dbus_queue(Unit *u);
+ void unit_add_to_cleanup_queue(Unit *u);
+ void unit_add_to_gc_queue(Unit *u);
++void unit_add_to_target_deps_queue(Unit *u);
+ 
+ int unit_merge(Unit *u, Unit *other);
+ int unit_merge_by_name(Unit *u, const char *other);
diff --git a/SOURCES/0649-man-correct-the-meaning-of-TimeoutStopSec.patch b/SOURCES/0649-man-correct-the-meaning-of-TimeoutStopSec.patch
new file mode 100644
index 0000000..aa55434
--- /dev/null
+++ b/SOURCES/0649-man-correct-the-meaning-of-TimeoutStopSec.patch
@@ -0,0 +1,35 @@
+From 273a3d35df021128bd72e124d943cbb7b1c7194c Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 22 Jun 2018 09:11:49 +0200
+Subject: [PATCH] man: correct the meaning of TimeoutStopSec=
+
+Fixes: #9325
+(cherry picked from commit 9a6da355a06e2b272717f2ac23e41945ce56eb6d)
+Resolves: #1305509
+---
+ man/systemd.service.xml | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/man/systemd.service.xml b/man/systemd.service.xml
+index a274db480..d147e449a 100644
+--- a/man/systemd.service.xml
++++ b/man/systemd.service.xml
+@@ -429,12 +429,12 @@
+ 
+       <varlistentry>
+         <term><varname>TimeoutStopSec=</varname></term>
+-        <listitem><para>Configures the time to wait for stop. If a
+-        service is asked to stop, but does not terminate in the
+-        specified time, it will be terminated forcibly via
+-        <constant>SIGTERM</constant>, and after another timeout of
+-        equal duration with <constant>SIGKILL</constant> (see
+-        <varname>KillMode=</varname> in
++        <listitem><para>This option serves two purposes. First, it configures the time to wait for each
++        <constant>ExecStop=</constant> command. If any of them times out, subsequent <constant>ExecStop=</constant> commands
++        are skipped and the service will be terminated by <constant>SIGTERM</constant>. If no <constant>ExecStop=</constant>
++        commands are specified, the service gets the <constant>SIGTERM</constant> immediately. Second, it configures the time
++        to wait for the service itself to stop. If it doesn't terminate in the specified time, it will be forcibly terminated
++        by <constant>SIGKILL</constant> (see <varname>KillMode=</varname> in
+         <citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+         Takes a unit-less value in seconds, or a time span value such
+         as "5min 20s". Pass <literal>0</literal> to disable the
diff --git a/SOURCES/0650-rules-mark-hotplugged-memory-as-movable.patch b/SOURCES/0650-rules-mark-hotplugged-memory-as-movable.patch
new file mode 100644
index 0000000..996c107
--- /dev/null
+++ b/SOURCES/0650-rules-mark-hotplugged-memory-as-movable.patch
@@ -0,0 +1,32 @@
+From 7431c551954ad63fe61cda18888e1e89419bd631 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Fri, 20 Jul 2018 09:48:04 +0200
+Subject: [PATCH] rules: mark hotplugged memory as movable
+
+Otherwise the kernel is free to use to memory block also for storing
+non-movable memory (any other memory except anonymous memory allocations
+and page cache). If user later wants to hot unplug the memory the kernel
+will return error in case that some non-movable memory has been place to
+the memory block.
+
+Marking hot plugged memory blocks as movable seems to be better
+default. Users with specific needs are free to override this udev rule.
+
+Resolves: #1563532
+---
+ rules/40-redhat.rules | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
+index 34a1df9c4..26f726001 100644
+--- a/rules/40-redhat.rules
++++ b/rules/40-redhat.rules
+@@ -4,7 +4,7 @@
+ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
+ 
+ # Memory hotadd request
+-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
++SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online_movable"
+ 
+ # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
+ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"
diff --git a/SOURCES/0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch b/SOURCES/0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch
new file mode 100644
index 0000000..712b78f
--- /dev/null
+++ b/SOURCES/0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch
@@ -0,0 +1,27 @@
+From fa22d8e9697a0a896007998fdf2cabe7baf98bec Mon Sep 17 00:00:00 2001
+From: Peter Hutterer <peter.hutterer@who-t.net>
+Date: Tue, 10 Jan 2017 17:36:46 +1000
+Subject: [PATCH] udev: add ID_INPUT_SWITCH for devices with switch capability
+ (#5057)
+
+(cherry picked from commit 64083a6078630372623bb1013a45d3bf31d8a836)
+
+Resolves: #1597240
+---
+ src/udev/udev-builtin-input_id.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
+index 46f1c539d..d6ae07304 100644
+--- a/src/udev/udev-builtin-input_id.c
++++ b/src/udev/udev-builtin-input_id.c
+@@ -250,6 +250,9 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
+                 get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
+                 test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
+                 test_key(dev, bitmask_ev, bitmask_key, test);
++
++                if (test_bit(EV_SW, bitmask_ev))
++                        udev_builtin_add_property(dev, test, "ID_INPUT_SWITCH", "1");
+         }
+ 
+         devnode = udev_device_get_devnode(dev);
diff --git a/SOURCES/0652-rules-disable-support-for-Dell-IR-cameras.patch b/SOURCES/0652-rules-disable-support-for-Dell-IR-cameras.patch
new file mode 100644
index 0000000..f1348c2
--- /dev/null
+++ b/SOURCES/0652-rules-disable-support-for-Dell-IR-cameras.patch
@@ -0,0 +1,32 @@
+From e2a2326a283fe38463e637e34205c50ec3066424 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Wed, 18 Jul 2018 14:36:17 +0200
+Subject: [PATCH] rules: disable support for Dell IR cameras
+
+Resolves: #1591316
+---
+ Makefile.am                                  | 1 +
+ rules/40-redhat-disable-dell-ir-camera.rules | 2 ++
+ 2 files changed, 3 insertions(+)
+ create mode 100644 rules/40-redhat-disable-dell-ir-camera.rules
+
+diff --git a/Makefile.am b/Makefile.am
+index cbc120dad..40ebbe98e 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -3523,6 +3523,7 @@ dist_udevrules_DATA += \
+ 	rules/95-udev-late.rules \
+ 	rules/40-redhat.rules \
+ 	rules/40-redhat-disable-lenovo-ir-camera.rules \
++	rules/40-redhat-disable-dell-ir-camera.rules \
+ 	rules/73-idrac.rules \
+         rules/80-net-name-slot.rules
+ 
+diff --git a/rules/40-redhat-disable-dell-ir-camera.rules b/rules/40-redhat-disable-dell-ir-camera.rules
+new file mode 100644
+index 000000000..2806482a5
+--- /dev/null
++++ b/rules/40-redhat-disable-dell-ir-camera.rules
+@@ -0,0 +1,2 @@
++# Disable known IR cameras in Dell Notebooks
++SUBSYSTEM=="usb", ATTRS{idVendor}=="0BDA", ATTRS{idProduct}=="58F6", ATTR{authorized}="0"
diff --git a/SOURCES/0653-rpm-fix-systemd_user_post-macro.patch b/SOURCES/0653-rpm-fix-systemd_user_post-macro.patch
new file mode 100644
index 0000000..0a2c82b
--- /dev/null
+++ b/SOURCES/0653-rpm-fix-systemd_user_post-macro.patch
@@ -0,0 +1,36 @@
+From dda4324fa0b1fb1e07dea18585df6962d8f34b0f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tadej=20Jane=C5=BE?= <tadej.j@nez.si>
+Date: Sun, 22 Nov 2015 20:38:05 +0100
+Subject: [PATCH] rpm: fix %systemd_user_post() macro.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Escape "--user" and "--global" arguments with "\\" since rpm treats
+arguments starting with "-" as macro options which causes "Unknown
+option" rpm error.
+Use %{expand:...} to force expansion of the inner macro. Otherwise %{?*}
+is recursively defined as "\--user \--global {%?*}" which causes
+"Too many levels of recursion in macro expansion" rpm error.
+
+Thanks to Michael Mráka for helping me fix the above issues.
+
+(cherry picked from commit e67ba783696f21782ad5c2ba00515d387016e785)
+Related: #1582383
+---
+ src/core/macros.systemd.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
+index bea6ef1da..662791ccc 100644
+--- a/src/core/macros.systemd.in
++++ b/src/core/macros.systemd.in
+@@ -43,7 +43,7 @@ if [ $1 -eq 1 ] ; then \
+ fi \
+ %{nil}
+ 
+-%systemd_user_post() %systemd_post --user --global %{?*}
++%systemd_user_post() %{expand:%systemd_post \\--user \\--global %%{?*}}
+ 
+ %systemd_preun() \
+ if [ $1 -eq 0 ] ; then \
diff --git a/SOURCES/0654-rpm-remove-confusing-user-before-global.patch b/SOURCES/0654-rpm-remove-confusing-user-before-global.patch
new file mode 100644
index 0000000..965083e
--- /dev/null
+++ b/SOURCES/0654-rpm-remove-confusing-user-before-global.patch
@@ -0,0 +1,35 @@
+From 4bc18a925e964f10b4e7ed92e8e0d84bf985c6a8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Sat, 19 May 2018 13:01:55 +0200
+Subject: [PATCH] rpm: remove confusing --user before --global
+
+Fixes #9027.
+
+(cherry picked from commit 28d36da64a7a23a55e8d0a139f2620384fd058b3)
+Resolves: #1582383
+---
+ src/core/macros.systemd.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
+index 662791ccc..3d6e41274 100644
+--- a/src/core/macros.systemd.in
++++ b/src/core/macros.systemd.in
+@@ -43,7 +43,7 @@ if [ $1 -eq 1 ] ; then \
+ fi \
+ %{nil}
+ 
+-%systemd_user_post() %{expand:%systemd_post \\--user \\--global %%{?*}}
++%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}}
+ 
+ %systemd_preun() \
+ if [ $1 -eq 0 ] ; then \
+@@ -56,7 +56,7 @@ fi \
+ %systemd_user_preun() \
+ if [ $1 -eq 0 ] ; then \
+         # Package removal, not upgrade \
+-        systemctl --no-reload --user --global disable %{?*} > /dev/null 2>&1 || : \
++        systemctl --global disable %{?*} > /dev/null 2>&1 || : \
+ fi \
+ %{nil}
+ 
diff --git a/SOURCES/0655-automount-handle-state-changes-of-the-corresponding-.patch b/SOURCES/0655-automount-handle-state-changes-of-the-corresponding-.patch
new file mode 100644
index 0000000..f835f2f
--- /dev/null
+++ b/SOURCES/0655-automount-handle-state-changes-of-the-corresponding-.patch
@@ -0,0 +1,58 @@
+From b4f506932592b991363b8be11e40b62f861bd032 Mon Sep 17 00:00:00 2001
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Fri, 24 Jul 2015 22:25:28 +0200
+Subject: [PATCH] automount: handle state changes of the corresponding mount
+ unit correctly
+
+The expire timeout must be started/stopped if the corresponding mount unit
+changes its state, e.g. it is started via local-fs.target or stopped by a
+manual umount.
+
+(cherry picked from commit 3dbadf9ef96e76f1bc472660ba5435dc0fa27a66)
+
+Resolves: #1596241
+---
+ src/core/automount.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/automount.c b/src/core/automount.c
+index 08519e49c..f57782b9b 100644
+--- a/src/core/automount.c
++++ b/src/core/automount.c
+@@ -499,6 +499,7 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
+ 
+ int automount_update_mount(Automount *a, MountState old_state, MountState state) {
+         _cleanup_close_ int ioctl_fd = -1;
++        int r;
+ 
+         assert(a);
+ 
+@@ -506,6 +507,9 @@ int automount_update_mount(Automount *a, MountState old_state, MountState state)
+         case MOUNT_MOUNTED:
+         case MOUNT_REMOUNTING:
+                 automount_send_ready(a, a->tokens, 0);
++                r = automount_start_expire(a);
++                if (r < 0)
++                        log_unit_warning_errno(UNIT(a)->id, r, "Failed to start expiration timer, ignoring: %m");
+                 break;
+          case MOUNT_DEAD:
+          case MOUNT_UNMOUNTING:
+@@ -518,6 +522,7 @@ int automount_update_mount(Automount *a, MountState old_state, MountState state)
+          case MOUNT_FAILED:
+                 if (old_state != state)
+                         automount_send_ready(a, a->tokens, -ENODEV);
++                (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
+                 break;
+         default:
+                 break;
+@@ -768,10 +773,6 @@ static void automount_enter_running(Automount *a) {
+                 goto fail;
+         }
+ 
+-        r = automount_start_expire(a);
+-        if (r < 0)
+-                log_unit_warning_errno(UNIT(a)->id, r, "Failed to start expiration timer, ignoring: %m");
+-
+         automount_set_state(a, AUTOMOUNT_RUNNING);
+         return;
+ 
diff --git a/SOURCES/0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch b/SOURCES/0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch
new file mode 100644
index 0000000..a288f3b
--- /dev/null
+++ b/SOURCES/0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch
@@ -0,0 +1,32 @@
+From 210c9e5dd1e3d0e37a16225a63840d71b473684c Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Mon, 15 Jun 2015 12:05:11 +0200
+Subject: [PATCH] man: document that SIGCONT always follows SIGTERM
+
+As requested in #199.
+
+(cherry picked from commit e8c53936316288ea3b33b5997b175862f0efef92)
+Resolves: #1601794
+---
+ man/systemd.kill.xml | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml
+index e57f0e724..1292f4f51 100644
+--- a/man/systemd.kill.xml
++++ b/man/systemd.kill.xml
+@@ -136,7 +136,13 @@
+         by <constant>SIGKILL</constant> (see above and below). For a
+         list of valid signals, see
+         <citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+-        Defaults to <constant>SIGTERM</constant>. </para></listitem>
++        Defaults to <constant>SIGTERM</constant>. </para>
++
++        <para>Note that right after sending the signal specified in
++        this setting systemd will always send
++        <constant>SIGCONT</constant>, to ensure that even suspended
++        tasks can be terminated cleanly.</para>
++        </listitem>
+       </varlistentry>
+ 
+       <varlistentry>
diff --git a/SOURCES/0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch b/SOURCES/0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch
new file mode 100644
index 0000000..fcef9bc
--- /dev/null
+++ b/SOURCES/0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch
@@ -0,0 +1,46 @@
+From 6bc676b1a1bfa7145106f737a6747526ce662b93 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Mon, 23 Jul 2018 16:57:22 +0200
+Subject: [PATCH] rules: add udev rule that automatically offline HW attached
+ to ACPI container
+
+Resolves: #1597958
+---
+ Makefile.am                     |  1 +
+ rules/40-redhat-hotunplug.rules | 14 ++++++++++++++
+ 2 files changed, 15 insertions(+)
+ create mode 100644 rules/40-redhat-hotunplug.rules
+
+diff --git a/Makefile.am b/Makefile.am
+index 40ebbe98e..3995dcce8 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -3524,6 +3524,7 @@ dist_udevrules_DATA += \
+ 	rules/40-redhat.rules \
+ 	rules/40-redhat-disable-lenovo-ir-camera.rules \
+ 	rules/40-redhat-disable-dell-ir-camera.rules \
++	rules/40-redhat-hotunplug.rules \
+ 	rules/73-idrac.rules \
+         rules/80-net-name-slot.rules
+ 
+diff --git a/rules/40-redhat-hotunplug.rules b/rules/40-redhat-hotunplug.rules
+new file mode 100644
+index 000000000..3befdaffc
+--- /dev/null
++++ b/rules/40-redhat-hotunplug.rules
+@@ -0,0 +1,14 @@
++# ACPI0004 container offline for Huawei Kunlun
++# do not edit this file, it will be overwritten on update
++
++SUBSYSTEM=="container", ACTION=="change", DEVPATH=="*/ACPI0004:??", \
++RUN+="/bin/sh -c ' \
++if [ $(cat /sys/$env{DEVPATH}/online) -eq 1 ]; then \
++        find -L /sys/$env{DEVPATH}/firmware_node/*/physical_node* -maxdepth 1 -name online | \
++        while read line; do \
++                if [ $(cat $line) -eq 1 ]; then \
++                        /bin/echo 0 > $line; \
++                fi \
++        done; \
++        /bin/echo 0 > /sys/$env{DEVPATH}/online; \
++fi'"
+\ No newline at end of file
diff --git a/SOURCES/0658-Revert-rules-mark-hotplugged-memory-as-movable.patch b/SOURCES/0658-Revert-rules-mark-hotplugged-memory-as-movable.patch
new file mode 100644
index 0000000..264a428
--- /dev/null
+++ b/SOURCES/0658-Revert-rules-mark-hotplugged-memory-as-movable.patch
@@ -0,0 +1,25 @@
+From e1311df43e9c63e72b1a6b329f5ffc9bcd0f37e1 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Thu, 16 Aug 2018 08:38:31 +0000
+Subject: [PATCH] Revert "rules: mark hotplugged memory as movable"
+
+This reverts commit 7431c551954ad63fe61cda18888e1e89419bd631.
+
+Resolves: #1614686
+---
+ rules/40-redhat.rules | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
+index 26f726001..34a1df9c4 100644
+--- a/rules/40-redhat.rules
++++ b/rules/40-redhat.rules
+@@ -4,7 +4,7 @@
+ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
+ 
+ # Memory hotadd request
+-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online_movable"
++SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
+ 
+ # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
+ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"
diff --git a/SOURCES/0659-rules-implement-new-memory-hotplug-policy.patch b/SOURCES/0659-rules-implement-new-memory-hotplug-policy.patch
new file mode 100644
index 0000000..250ce61
--- /dev/null
+++ b/SOURCES/0659-rules-implement-new-memory-hotplug-policy.patch
@@ -0,0 +1,49 @@
+From c50b7bcbebcfebfce3a7e7fb77f88f4b590fb2b5 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Thu, 16 Aug 2018 09:31:51 +0000
+Subject: [PATCH] rules: implement new memory hotplug policy
+
+Our new policy is based on following motivations (assumptions),
+  * we want to allow the system to use hotplugged memory
+  * we want memory ballon inflation to work as expected in VMs (going for small
+  to big in terms of memory footprint)
+  * we want to allow memory hotplug and memory hot-unplug on high-end
+  enterprise server (we assume that node0 will have sufficient memory
+  resources and marking all memory as movable shouldn't be a problem)
+
+Policy:
+  * nevert online memory on s390 (on both physical and z/VM)
+  * mark memory as "online_movable" on physical machines
+  * mark memory as "online" in VMs
+
+If you have the feeling that all this is very wrong and we shouldn't
+encode complex policies in udev rules you are absolutely right. However,
+for now, we don't have any better place where to put it. In ideal world
+we would have a user-space daemon that would be able to configure the
+system wrt. to currently present HW and user-defined policy.
+
+Resolves: #1614686
+---
+ rules/40-redhat.rules | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
+index 34a1df9c4..1b10e173d 100644
+--- a/rules/40-redhat.rules
++++ b/rules/40-redhat.rules
+@@ -4,7 +4,14 @@
+ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}="1"
+ 
+ # Memory hotadd request
+-SUBSYSTEM=="memory", ACTION=="add", PROGRAM="/bin/uname -p", RESULT!="s390*", ATTR{state}=="offline", ATTR{state}="online"
++SUBSYSTEM!="memory", ACTION!="add", GOTO="memory_hotplug_end"
++PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
++
++ENV{.state}="online"
++PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
++ATTR{state}=="offline", ATTR{state}="$env{.state}"
++
++LABEL="memory_hotplug_end"
+ 
+ # reload sysctl.conf / sysctl.conf.d settings when the bridge module is loaded
+ ACTION=="add", SUBSYSTEM=="module", KERNEL=="bridge", RUN+="/usr/lib/systemd/systemd-sysctl --prefix=/proc/sys/net/bridge"
diff --git a/SOURCES/0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch b/SOURCES/0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch
new file mode 100644
index 0000000..26899fc
--- /dev/null
+++ b/SOURCES/0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch
@@ -0,0 +1,48 @@
+From 4b451af437d5d51b98d11d32130aac6938307798 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Fri, 17 Aug 2018 13:10:22 +0000
+Subject: [PATCH] Revert "rules: add udev rule that automatically offline HW
+ attached to ACPI container"
+
+This reverts commit 6bc676b1a1bfa7145106f737a6747526ce662b93.
+
+Related: #1597958
+---
+ Makefile.am                     |  1 -
+ rules/40-redhat-hotunplug.rules | 14 --------------
+ 2 files changed, 15 deletions(-)
+ delete mode 100644 rules/40-redhat-hotunplug.rules
+
+diff --git a/Makefile.am b/Makefile.am
+index 3995dcce8..40ebbe98e 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -3524,7 +3524,6 @@ dist_udevrules_DATA += \
+ 	rules/40-redhat.rules \
+ 	rules/40-redhat-disable-lenovo-ir-camera.rules \
+ 	rules/40-redhat-disable-dell-ir-camera.rules \
+-	rules/40-redhat-hotunplug.rules \
+ 	rules/73-idrac.rules \
+         rules/80-net-name-slot.rules
+ 
+diff --git a/rules/40-redhat-hotunplug.rules b/rules/40-redhat-hotunplug.rules
+deleted file mode 100644
+index 3befdaffc..000000000
+--- a/rules/40-redhat-hotunplug.rules
++++ /dev/null
+@@ -1,14 +0,0 @@
+-# ACPI0004 container offline for Huawei Kunlun
+-# do not edit this file, it will be overwritten on update
+-
+-SUBSYSTEM=="container", ACTION=="change", DEVPATH=="*/ACPI0004:??", \
+-RUN+="/bin/sh -c ' \
+-if [ $(cat /sys/$env{DEVPATH}/online) -eq 1 ]; then \
+-        find -L /sys/$env{DEVPATH}/firmware_node/*/physical_node* -maxdepth 1 -name online | \
+-        while read line; do \
+-                if [ $(cat $line) -eq 1 ]; then \
+-                        /bin/echo 0 > $line; \
+-                fi \
+-        done; \
+-        /bin/echo 0 > /sys/$env{DEVPATH}/online; \
+-fi'"
+\ No newline at end of file
diff --git a/SOURCES/0661-cryptsetup-generator-introduce-basic-keydev-support.patch b/SOURCES/0661-cryptsetup-generator-introduce-basic-keydev-support.patch
new file mode 100644
index 0000000..52f415a
--- /dev/null
+++ b/SOURCES/0661-cryptsetup-generator-introduce-basic-keydev-support.patch
@@ -0,0 +1,258 @@
+From aafa651e44df825abeec061f295f227862aad6d9 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Thu, 30 Aug 2018 08:45:11 +0000
+Subject: [PATCH] cryptsetup-generator: introduce basic keydev support
+
+Dracut has a support for unlocking encrypted drives with keyfile stored
+on the external drive. This support is included in the generated initrd
+only if systemd module is not included.
+
+When systemd is used in initrd then attachment of encrypted drives is
+handled by systemd-cryptsetup tools. Our generator has support for
+keyfile, however, it didn't support keyfile on the external block
+device (keydev).
+
+This commit introduces basic keydev support. Keydev can be specified per
+luks.uuid on the kernel command line. Keydev is automatically mounted
+during boot and we look for keyfile in the keydev
+mountpoint (i.e. keyfile path is prefixed with the keydev mount point
+path). After crypt device is attached we automatically unmount
+where keyfile resides.
+
+Example:
+        rd.luks.key=70bc876b-f627-4038-9049-3080d79d2165=/key:LABEL=KEYDEV
+
+(cherry-picked from commit 70f5f48eb891b12e969577b464de61e15a2593da)
+
+Resolves: #1619743
+---
+ man/systemd-cryptsetup-generator.xml  |  14 ++++
+ src/cryptsetup/cryptsetup-generator.c | 122 ++++++++++++++++++++++++++++++++--
+ 2 files changed, 131 insertions(+), 5 deletions(-)
+
+diff --git a/man/systemd-cryptsetup-generator.xml b/man/systemd-cryptsetup-generator.xml
+index b6270358e..8cfd8b6a8 100644
+--- a/man/systemd-cryptsetup-generator.xml
++++ b/man/systemd-cryptsetup-generator.xml
+@@ -168,6 +168,20 @@
+         to the one specified by <varname>rd.luks.key=</varname> or
+         <varname>luks.key=</varname> of the corresponding UUID, or the
+         password file that was specified without a UUID.</para>
++
++        <para>It is also possible to specify an external device which
++        should be mounted before we attempt to unlock the LUKS device.
++        systemd-cryptsetup will use password file stored on that
++        device. Device containing password file is specified by
++        appending colon and a device identifier to the password file
++        path. For example,
++        <varname>rd.luks.uuid=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40
++        <varname>rd.luks.key=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40=/keyfile:LABEL=keydev.
++        Hence, in this case, we will attempt to mount file system
++        residing on the block device with label <literal>keydev</literal>.
++        This syntax is for now only supported on a per-device basis,
++        i.e. you have to specify LUKS device UUID.</para>
++
+         <para><varname>rd.luks.key=</varname>
+         is honored only by initial RAM disk
+         (initrd) while
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 5f29093f5..42c30c5ca 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -38,6 +38,7 @@
+ typedef struct crypto_device {
+         char *uuid;
+         char *keyfile;
++        char *keydev;
+         char *name;
+         char *options;
+         bool create;
+@@ -51,14 +52,79 @@ static Hashmap *arg_disks = NULL;
+ static char *arg_default_options = NULL;
+ static char *arg_default_keyfile = NULL;
+ 
++static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) {
++        _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *p = NULL;
++        _cleanup_fclose_ FILE *f = NULL;
++        int r;
++
++        assert(name);
++        assert(keydev);
++        assert(unit);
++        assert(mount);
++
++        r = mkdir_parents("/run/systemd/cryptsetup", 0755);
++        if (r < 0)
++                return r;
++
++        r = mkdir("/run/systemd/cryptsetup", 0700);
++        if (r < 0)
++                return r;
++
++        where = strjoin("/run/systemd/cryptsetup/keydev-", name, NULL);
++        if (!where)
++                return -ENOMEM;
++
++        r = mkdir(where, 0700);
++        if (r < 0)
++                return r;
++
++        u = unit_name_from_path(where, ".mount");
++        if (!u)
++                return -ENOMEM;
++
++        what = fstab_node_to_udev_node(keydev);
++        if (!what)
++                return -ENOMEM;
++
++        p = strjoin(arg_dest, "/", u, NULL);
++        if (!p)
++                return log_oom();
++
++        f = fopen(p, "wxe");
++        if (!f)
++                return log_error_errno(errno, "Failed to create unit file %s: %m", p);
++
++        fprintf(f,
++                "# Automatically generated by systemd-cryptsetup-generator\n\n"
++                "[Unit]\n"
++                "DefaultDependencies=no\n\n"
++                "[Mount]\n"
++                "What=%s\n"
++                "Where=%s\n"
++                "Options=ro\n", what, where);
++
++        r = fflush_and_check(f);
++        if (r < 0)
++                return r;
++
++        *unit = u;
++        u = NULL;
++
++        *mount = where;
++        where = NULL;
++
++        return 0;
++}
++
+ static int create_disk(
+                 const char *name,
+                 const char *device,
++                const char *keydev,
+                 const char *password,
+                 const char *options) {
+ 
+         _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *to = NULL, *e = NULL,
+-                *filtered = NULL;
++                *filtered = NULL, *keydev_mount = NULL, *keyfile_path = NULL;
+         _cleanup_fclose_ FILE *f = NULL;
+         bool noauto, nofail, tmp, swap, netdev;
+         char *from;
+@@ -98,6 +164,9 @@ static int create_disk(
+         if (!d)
+                 return log_oom();
+ 
++        if (keydev && !password)
++                return log_error_errno(-EINVAL, "Keydev is specified, but path to the password file is missing: %m");
++
+         f = fopen(p, "wxe");
+         if (!f)
+                 return log_error_errno(errno, "Failed to create unit file %s: %m", p);
+@@ -115,6 +184,20 @@ static int create_disk(
+                 "After=%s\n",
+                 netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
+ 
++        if (keydev) {
++                _cleanup_free_ char *unit = NULL;
++
++                r = generate_keydev_mount(name, keydev, &unit, &keydev_mount);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to generate keydev mount unit: %m");
++
++                keyfile_path = prefix_root(keydev_mount, password);
++                if (!keyfile_path)
++                        return log_oom();
++
++                password = keyfile_path;
++        }
++
+         if (!nofail)
+                 fprintf(f,
+                         "Before=%s\n",
+@@ -181,6 +264,11 @@ static int create_disk(
+                         "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
+                         name);
+ 
++        if (keydev)
++                fprintf(f,
++                        "ExecStartPost=/bin/umount '%s'\n\n",
++                        keydev_mount);
++
+         fflush(f);
+         if (ferror(f))
+                 return log_error_errno(errno, "Failed to write file %s: %m", p);
+@@ -248,6 +336,7 @@ static void free_arg_disks(void) {
+         while ((d = hashmap_steal_first(arg_disks))) {
+                 free(d->uuid);
+                 free(d->keyfile);
++                free(d->keydev);
+                 free(d->name);
+                 free(d->options);
+                 free(d);
+@@ -335,13 +424,36 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
+ 
+                 r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
+                 if (r == 2) {
++                        char *c;
++                        _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
++
+                         d = get_crypto_device(uuid);
+                         if (!d)
+                                 return log_oom();
+ 
++                        c = strrchr(uuid_value, ':');
++                        if (!c) {
++                                free(d->keyfile);
++                                d->keyfile = uuid_value;
++                                uuid_value = NULL;
++
++                                return 0;
++                        }
++
++                        *c = '\0';
++                        keyfile = strdup(uuid_value);
++                        keydev = strdup(++c);
++
++                        if (!keyfile || !keydev)
++                                return log_oom();
++
+                         free(d->keyfile);
+-                        d->keyfile = uuid_value;
+-                        uuid_value = NULL;
++                        d->keyfile = keyfile;
++                        keyfile = NULL;
++
++                        free(d->keydev);
++                        d->keydev = keydev;
++                        keydev = NULL;
+                 } else if (free_and_strdup(&arg_default_keyfile, value))
+                         return log_oom();
+ 
+@@ -420,7 +532,7 @@ static int add_crypttab_devices(void) {
+                         continue;
+                 }
+ 
+-                r = create_disk(name, device, keyfile, (d && d->options) ? d->options : options);
++                r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options);
+                 if (r < 0)
+                         return r;
+ 
+@@ -460,7 +572,7 @@ static int add_proc_cmdline_devices(void) {
+                 else
+                         options = "timeout=0";
+ 
+-                r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, options);
++                r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options);
+                 if (r < 0)
+                         return r;
+         }
diff --git a/SOURCES/0662-cryptsetup-generator-don-t-return-error-if-target-di.patch b/SOURCES/0662-cryptsetup-generator-don-t-return-error-if-target-di.patch
new file mode 100644
index 0000000..2282395
--- /dev/null
+++ b/SOURCES/0662-cryptsetup-generator-don-t-return-error-if-target-di.patch
@@ -0,0 +1,38 @@
+From 8f47d483dc4e0510977c8868278148c476f58c17 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Tue, 4 Sep 2018 19:51:14 +0200
+Subject: [PATCH] cryptsetup-generator: don't return error if target directory
+ already exists
+
+Related: #1619743
+---
+ src/cryptsetup/cryptsetup-generator.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 42c30c5ca..a9598180c 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -63,11 +63,11 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
+         assert(mount);
+ 
+         r = mkdir_parents("/run/systemd/cryptsetup", 0755);
+-        if (r < 0)
++        if (r < 0 && r != -EEXIST)
+                 return r;
+ 
+         r = mkdir("/run/systemd/cryptsetup", 0700);
+-        if (r < 0)
++        if (r < 0 && errno != EEXIST)
+                 return r;
+ 
+         where = strjoin("/run/systemd/cryptsetup/keydev-", name, NULL);
+@@ -75,7 +75,7 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
+                 return -ENOMEM;
+ 
+         r = mkdir(where, 0700);
+-        if (r < 0)
++        if (r < 0 && errno != EEXIST)
+                 return r;
+ 
+         u = unit_name_from_path(where, ".mount");
diff --git a/SOURCES/0663-cryptsetup-generator-allow-whitespace-characters-in-.patch b/SOURCES/0663-cryptsetup-generator-allow-whitespace-characters-in-.patch
new file mode 100644
index 0000000..0f31200
--- /dev/null
+++ b/SOURCES/0663-cryptsetup-generator-allow-whitespace-characters-in-.patch
@@ -0,0 +1,62 @@
+From afcf3919f5db85a00352a9937c9a5cb9c7b30269 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Tue, 4 Sep 2018 20:03:34 +0200
+Subject: [PATCH] cryptsetup-generator: allow whitespace characters in keydev
+ specification
+
+For example, <luks.uuid>=/keyfile:LABEL="KEYFILE FS" previously wouldn't
+work, because we truncated label at the first whitespace character,
+i.e. LABEL="KEYFILE".
+
+Related: #1619743
+---
+ src/cryptsetup/cryptsetup-generator.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index a9598180c..7b90d2615 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -421,27 +421,36 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
+                         return log_oom();
+ 
+         } else if (STR_IN_SET(key, "luks.key", "rd.luks.key") && value) {
++                int n;
+ 
+-                r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
+-                if (r == 2) {
++                r = sscanf(value, "%m[0-9a-fA-F-]=%n", &uuid, &n);
++                if (r == 1) {
+                         char *c;
++                        const char *keyspec;
+                         _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+ 
+                         d = get_crypto_device(uuid);
+                         if (!d)
+                                 return log_oom();
+ 
+-                        c = strrchr(uuid_value, ':');
++                        keyspec = value + n;
++
++                        c = strrchr(keyspec, ':');
+                         if (!c) {
++                                /* No keydev specified */
++                                keyfile = strdup(keyspec);
++                                if (!keyfile)
++                                        return log_oom();
++
+                                 free(d->keyfile);
+-                                d->keyfile = uuid_value;
+-                                uuid_value = NULL;
++                                d->keyfile = keyfile;
++                                keyfile = NULL;
+ 
+                                 return 0;
+                         }
+ 
+                         *c = '\0';
+-                        keyfile = strdup(uuid_value);
++                        keyfile = strdup(keyspec);
+                         keydev = strdup(++c);
+ 
+                         if (!keyfile || !keydev)
diff --git a/SOURCES/0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch b/SOURCES/0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch
new file mode 100644
index 0000000..192052c
--- /dev/null
+++ b/SOURCES/0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch
@@ -0,0 +1,50 @@
+From d772781b2810ae71bace24cce05f255212a348ed Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Thu, 8 Oct 2015 19:06:06 +0200
+Subject: [PATCH] Make sure the mount units pulled by 'RequiresMountsFor=' are
+ loaded (if they exist)
+
+We should make sure that mount units involved by 'RequiresMountsFor='
+directives are really loaded if not required by any others units so
+that Requires= dependencies on the mount units are applied and thus
+the mount unit dependencies are started.
+
+(cherry-picked from commit c7c89abb9edf9320246482bf4a8e0656199281ae)
+
+Resolves: #1619743
+---
+ src/core/unit.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index cfddce34d..e8532a057 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1131,13 +1131,23 @@ static int unit_add_mount_dependencies(Unit *u) {
+                 char prefix[strlen(*i) + 1];
+ 
+                 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
++                        _cleanup_free_ char *p = NULL;
+                         Unit *m;
+ 
+-                        r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
+-                        if (r < 0)
+-                                return r;
+-                        if (r == 0)
++                        p = unit_name_from_path(prefix, ".mount");
++                        if (!p)
++                                return -ENOMEM;
++
++                        m = manager_get_unit(u->manager, p);
++                        if (!m) {
++                                /* Make sure to load the mount unit if
++                                 * it exists. If so the dependencies
++                                 * on this unit will be added later
++                                 * during the loading of the mount
++                                 * unit. */
++                                (void) manager_load_unit_prepare(u->manager, p, NULL, NULL, &m);
+                                 continue;
++                        }
+                         if (m == u)
+                                 continue;
+ 
diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec
index 49247cf..2e4d29c 100644
--- a/SPECS/systemd.spec
+++ b/SPECS/systemd.spec
@@ -7,7 +7,7 @@
 Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 Version:        219
-Release:        57%{?dist}.3
+Release:        62%{?dist}
 # For a breakdown of the licensing, see README
 License:        LGPLv2+ and MIT and GPLv2+
 Summary:        A System and Service Manager
@@ -652,10 +652,57 @@ Patch0610: 0610-sd-journal-properly-handle-inotify-queue-overflow.patch
 Patch0611: 0611-sd-journal-make-sure-it-s-safe-to-call-sd_journal_pr.patch
 Patch0612: 0612-journalctl-Periodically-call-sd_journal_process-in-j.patch
 Patch0613: 0613-sd-journal-when-picking-up-a-new-file-compare-inode-.patch
-Patch0614: 0614-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
-Patch0615: 0615-core-Implement-timeout-based-umount-remount-limit.patch
-Patch0616: 0616-core-Implement-sync_with_progress.patch
-Patch0617: 0617-automount-handle-state-changes-of-the-corresponding-.patch
+Patch0614: 0614-tmpfiles-don-t-skip-cleanup-of-read-only-root-owned-.patch
+Patch0615: 0615-timer-we-already-got-the-trigger-before-no-need-to-c.patch
+Patch0616: 0616-doc-fix-links-to-binfmt_misc-kernel-documentation.patch
+Patch0617: 0617-man-udevadm-remove-superfluous-version-from-subcomma.patch
+Patch0618: 0618-man-udevadm-correctly-show-the-short-version-of-exit.patch
+Patch0619: 0619-core-timer-downgrade-message-about-random-time-addit.patch
+Patch0620: 0620-fd-util-add-new-acquire_data_fd-API-helper.patch
+Patch0621: 0621-systemd-analyze-make-dump-work-for-large-of-units.patch
+Patch0622: 0622-use-max.-message-size-allowed-by-DBus-spec-8936.patch
+Patch0623: 0623-cryptsetup-support-LUKS2-on-disk-format.patch
+Patch0624: 0624-core-scope-fix-missing-fragment_path.patch
+Patch0625: 0625-units-don-t-put-udev-to-its-own-mount-namespace-with.patch
+Patch0626: 0626-rules-disable-support-for-Lenovo-IR-cameras.patch
+Patch0627: 0627-core-make-sure-systemctl-reload-or-try-restart-is-ac.patch
+Patch0628: 0628-core-fix-confusing-logging-of-instantaneous-jobs.patch
+Patch0629: 0629-core-correct-return-value-from-reload-methods.patch
+Patch0630: 0630-core-always-try-harder-to-get-unit-status-message-fo.patch
+Patch0631: 0631-core-unit_get_status_message_format-never-returns-NU.patch
+Patch0632: 0632-core-try-harder-to-get-job-completion-messages-too.patch
+Patch0633: 0633-core-remove-generic-job-completion-messages-from-uni.patch
+Patch0634: 0634-core-do-not-log-done-failed-condition-jobs-as-if-uni.patch
+Patch0635: 0635-core-log-completion-of-remaining-job-types.patch
+Patch0636: 0636-core-adjust-job-completion-message-log-levels.patch
+Patch0637: 0637-mount-add-new-LazyUnmount-setting-for-mount-units-ma.patch
+Patch0638: 0638-rules-Add-MODEL_ID-for-NVMe-device-7037.patch
+Patch0639: 0639-umount-always-use-MNT_FORCE-in-umount_all-7213.patch
+Patch0640: 0640-core-Implement-timeout-based-umount-remount-limit.patch
+Patch0641: 0641-core-Implement-sync_with_progress.patch
+Patch0642: 0642-journal-fix-HMAC-calculation-when-appending-a-data-o.patch
+Patch0643: 0643-journal-forward-messages-from-dev-log-unmodified-to-.patch
+Patch0644: 0644-tmpfiles-use-safe_glob.patch
+Patch0645: 0645-Fix-SELinux-labels-in-cgroup-filesystem-root-directo.patch
+Patch0646: 0646-core-dont-t-remount-sys-fs-cgroup-for-relabel-if-not.patch
+Patch0647: 0647-fix-race-between-daemon-reload-and-other-commands.patch
+Patch0648: 0648-core-delay-adding-target-dependencies-until-all-unit.patch
+Patch0649: 0649-man-correct-the-meaning-of-TimeoutStopSec.patch
+Patch0650: 0650-rules-mark-hotplugged-memory-as-movable.patch
+Patch0651: 0651-udev-add-ID_INPUT_SWITCH-for-devices-with-switch-cap.patch
+Patch0652: 0652-rules-disable-support-for-Dell-IR-cameras.patch
+Patch0653: 0653-rpm-fix-systemd_user_post-macro.patch
+Patch0654: 0654-rpm-remove-confusing-user-before-global.patch
+Patch0655: 0655-automount-handle-state-changes-of-the-corresponding-.patch
+Patch0656: 0656-man-document-that-SIGCONT-always-follows-SIGTERM.patch
+Patch0657: 0657-rules-add-udev-rule-that-automatically-offline-HW-at.patch
+Patch0658: 0658-Revert-rules-mark-hotplugged-memory-as-movable.patch
+Patch0659: 0659-rules-implement-new-memory-hotplug-policy.patch
+Patch0660: 0660-Revert-rules-add-udev-rule-that-automatically-offlin.patch
+Patch0661: 0661-cryptsetup-generator-introduce-basic-keydev-support.patch
+Patch0662: 0662-cryptsetup-generator-don-t-return-error-if-target-di.patch
+Patch0663: 0663-cryptsetup-generator-allow-whitespace-characters-in-.patch
+Patch0664: 0664-Make-sure-the-mount-units-pulled-by-RequiresMountsFo.patch
 
 %global num_patches %{lua: c=0; for i,p in ipairs(patches) do c=c+1; end; print(c);}
 
@@ -1373,7 +1420,7 @@ fi
 %ghost %dir %{_localstatedir}/lib/systemd/coredump
 %ghost %dir %{_localstatedir}/lib/systemd/backlight
 %ghost %dir %{_localstatedir}/lib/systemd/rfkill
-%ghost %{_localstatedir}/lib/systemd/random-seed
+%ghost %attr(0600, root, root) %{_localstatedir}/lib/systemd/random-seed
 %ghost %{_localstatedir}/lib/systemd/clock
 %ghost %{_localstatedir}/lib/systemd/catalog/database
 %ghost %attr(0664,root,utmp) %{_localstatedir}/run/utmp
@@ -1396,7 +1443,7 @@ fi
 %config(noreplace) %{_sysconfdir}/rsyslog.d/listen.conf
 %config(noreplace) %{_sysconfdir}/yum/protected.d/systemd.conf
 %config(noreplace) %{_sysconfdir}/pam.d/systemd-user
-%ghost %{_sysconfdir}/udev/hwdb.bin
+%ghost %attr(0444, root, root) %{_sysconfdir}/udev/hwdb.bin
 %{_rpmconfigdir}/macros.d/macros.systemd
 %{_sysconfdir}/xdg/systemd
 %{_sysconfdir}/rc.d/init.d/README
@@ -1404,7 +1451,7 @@ fi
 %ghost %config(noreplace) %{_sysconfdir}/localtime
 %ghost %config(noreplace) %{_sysconfdir}/vconsole.conf
 %ghost %config(noreplace) %{_sysconfdir}/locale.conf
-%ghost %config(noreplace) %{_sysconfdir}/machine-id
+%ghost %attr(0444, root, root) %config(noreplace) %{_sysconfdir}/machine-id
 %ghost %config(noreplace) %{_sysconfdir}/machine-info
 %dir %{_sysconfdir}/X11/xorg.conf.d
 %ghost %config(noreplace) %{_sysconfdir}/X11/xorg.conf.d/00-keyboard.conf
@@ -1632,16 +1679,62 @@ fi
 %{_mandir}/man8/systemd-resolved.*
 
 %changelog
-* Fri Aug 31 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-57.3
+* Fri Sep 07 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-62
+- cryptsetup-generator: introduce basic keydev support (#1619743)
+- cryptsetup-generator: don't return error if target directory already exists (#1619743)
+- cryptsetup-generator: allow whitespace characters in keydev specification (#1619743)
+- Make sure the mount units pulled by 'RequiresMountsFor=' are loaded (if they exist) (#1619743)
+
+* Fri Aug 31 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-61
 - restart automounts unit on update (#1596241)
 
-* Mon Jul 30 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-57.2
+* Fri Aug 17 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-60
+- Revert "rules: mark hotplugged memory as movable" (#1614686)
+- rules: implement new memory hotplug policy (#1614686)
+- Revert "rules: add udev rule that automatically offline HW attached to ACPI container" (#1597958)
+
+* Wed Jul 25 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-59
+- man: correct the meaning of TimeoutStopSec= (#1305509)
+- rules: mark hotplugged memory as movable (#1563532)
+- udev: add ID_INPUT_SWITCH for devices with switch capability (#5057) (#1597240)
+- rules: disable support for Dell IR cameras (#1591316)
+- rpm: fix %systemd_user_post() macro. (#1582383)
+- rpm: remove confusing --user before --global (#1582383)
 - automount: handle state changes of the corresponding mount unit correctly (#1596241)
-
-* Mon Jun 25 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-57.1
+- man: document that SIGCONT always follows SIGTERM (#1601794)
+- rules: add udev rule that automatically offline HW attached to ACPI container (#1597958)
+
+* Thu Jun 21 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-58
+- tmpfiles: don't skip cleanup of read-only root owned files if TMPFILES_AGE_ALL is set (#1533638)
+- timer: we already got the trigger before, no need to call UNIT_TRIGGER again (#1549119)
+- doc: fix links to binfmt_misc kernel documentation (#1572244)
+- man/udevadm: remove superfluous --version from subcommand (#1553076)
+- man/udevadm: correctly show the short version of --exit (#1552712)
+- core/timer: downgrade message about random time addition (#5229) (#1587906)
+- fd-util: add new acquire_data_fd() API helper (#1446095)
+- systemd-analyze: make dump work for large # of units (#1446095)
+- use max. message size allowed by DBus spec (#8936) (#1446095)
+- cryptsetup: support LUKS2 on-disk format (#1573838)
+- units: don't put udev to its own mount namespace with slave propagation (#1432211)
+- rules: disable support for Lenovo IR cameras (#1540418)
+- core: make sure "systemctl reload-or-try-restart is actually a noop if a unit is not running (#1191920)
+- core: fix confusing logging of instantaneous jobs (#1506256)
+- core: correct return value from reload methods (#1506256)
+- core: always try harder to get unit status message format string (#1506256)
+- core: unit_get_status_message_format() never returns NULL (#1506256)
+- core: try harder to get job completion messages too (#1506256)
+- core: remove generic job completion messages from unit vtables (#1506256)
+- core: do not log done failed-condition jobs as if unit started (#1506256)
+- core: log completion of remaining job types (#1506256)
+- core: adjust job completion message log levels (#1506256)
+- mount: add new LazyUnmount= setting for mount units, mapping to umount(8)'s "-l" switch (#3827) (#1497264)
+- rules: Add MODEL_ID for NVMe device (#7037) (#1397264)
 - umount: always use MNT_FORCE in umount_all() (#7213) (#1571098)
 - core: Implement timeout based umount/remount limit (#1571098)
 - core: Implement sync_with_progress() (#1571098)
+- journal: forward messages from /dev/log unmodified to syslog.socket (#1409659)
+- tmpfiles: use safe_glob() (#1436004)
+- core: delay adding target dependencies until all units are loaded and aliases resolved (#8381) (#1368856)
 
 * Tue Feb 20 2018 Lukas Nykryn <lnykryn@redhat.com> - 219-57
 - sd-journal: properly handle inotify queue overflow (#1540538)