diff --git a/SOURCES/0216-core-never-propagate-reload-failure-to-service-resul.patch b/SOURCES/0216-core-never-propagate-reload-failure-to-service-resul.patch
new file mode 100644
index 0000000..2d967cf
--- /dev/null
+++ b/SOURCES/0216-core-never-propagate-reload-failure-to-service-resul.patch
@@ -0,0 +1,26 @@
+From cffe5d0e781f6fa7f2275b94d2dcc26e00859a78 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 17 Jul 2019 19:16:33 +0200
+Subject: [PATCH] core: never propagate reload failure to service result
+
+Fixes: #11238
+(cherry picked from commit d611cfa748aaf600832160132774074e808c82c7)
+
+Resolves: #1735787
+---
+ src/core/service.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/service.c b/src/core/service.c
+index 8342c131c8..24f167572a 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -3310,7 +3310,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+                               "Control process exited, code=%s status=%i",
+                               sigchld_code_to_string(code), status);
+ 
+-                if (s->result == SERVICE_SUCCESS)
++                if (s->state != SERVICE_RELOAD && s->result == SERVICE_SUCCESS)
+                         s->result = f;
+ 
+                 if (s->control_command &&
diff --git a/SOURCES/0216-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch b/SOURCES/0216-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
deleted file mode 100644
index b46c491..0000000
--- a/SOURCES/0216-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From c4b02a7b15c21db44542d0a136d032f8098985b8 Mon Sep 17 00:00:00 2001
-From: Evgeny Vereshchagin <evvers@ya.ru>
-Date: Mon, 24 Dec 2018 00:29:56 +0100
-Subject: [PATCH] journal: rely on _cleanup_free_ to free a temporary string
- used in client_context_read_cgroup
-
-Closes https://github.com/systemd/systemd/issues/11253.
-
-(cherry picked from commit ef30f7cac18a810814ada7e6a68a31d48cc9fccd)
-(cherry picked from commit 3513426adcecc322937635c11ebb89f174f849ed)
-
-Resolves: #1767716
----
- src/journal/journald-context.c | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
-
-diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
-index dba3525ed8..4f1278492f 100644
---- a/src/journal/journald-context.c
-+++ b/src/journal/journald-context.c
-@@ -276,7 +276,7 @@ static int client_context_read_label(
- }
- 
- static int client_context_read_cgroup(Server *s, ClientContext *c, const char *unit_id) {
--        char *t = NULL;
-+        _cleanup_free_ char *t = NULL;
-         int r;
- 
-         assert(c);
-@@ -284,7 +284,6 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
-         /* Try to acquire the current cgroup path */
-         r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t);
-         if (r < 0 || empty_or_root(t)) {
--
-                 /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted()
-                  * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup
-                  * on cgroupsv1 and we want to be able to map log messages from them too. */
-@@ -298,10 +297,8 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
-         }
- 
-         /* Let's shortcut this if the cgroup path didn't change */
--        if (streq_ptr(c->cgroup, t)) {
--                free(t);
-+        if (streq_ptr(c->cgroup, t))
-                 return 0;
--        }
- 
-         free_and_replace(c->cgroup, t);
- 
diff --git a/SOURCES/0217-man-document-systemd-analyze-security.patch b/SOURCES/0217-man-document-systemd-analyze-security.patch
new file mode 100644
index 0000000..07ec674
--- /dev/null
+++ b/SOURCES/0217-man-document-systemd-analyze-security.patch
@@ -0,0 +1,59 @@
+From d11fdacaf3c804b60dfe8371062f34ac2b624ac9 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 13 Sep 2019 09:23:32 +0200
+Subject: [PATCH] man: document systemd-analyze security
+
+(cherry-picked from commit ee93c1e664a7bbc59f1578e285c871999507b14d)
+
+Resolves: #1750343
+---
+ man/systemd-analyze.xml | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
+index 7aa10fc68e..f3b595880f 100644
+--- a/man/systemd-analyze.xml
++++ b/man/systemd-analyze.xml
+@@ -106,6 +106,12 @@
+       <arg choice="plain">service-watchdogs</arg>
+       <arg choice="opt"><replaceable>BOOL</replaceable></arg>
+     </cmdsynopsis>
++    <cmdsynopsis>
++      <command>systemd-analyze</command>
++      <arg choice="opt" rep="repeat">OPTIONS</arg>
++      <arg choice="plain">security</arg>
++      <arg choice="plain" rep="repeat"><replaceable>UNIT</replaceable></arg>
++    </cmdsynopsis>
+   </refsynopsisdiv>
+ 
+   <refsect1>
+@@ -253,6 +259,29 @@ NAutoVTs=8
+     <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+     The hardware watchdog is not affected by this setting.</para>
+ 
++    <para><command>systemd-analyze security</command> analyzes the security and sandboxing settings of one or more
++    specified service units. If at least one unit name is specified the security settings of the specified service
++    units are inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded,
++    long-running service units are inspected and a terse table with results shown. The command checks for various
++    security-related service settings, assigning each a numeric "exposure level" value, depending on how important a
++    setting is. It then calculates an overall exposure level for the whole unit, which is an estimation in the range
++    0.0…10.0 indicating how exposed a service is security-wise. High exposure levels indicate very little applied
++    sandboxing. Low exposure levels indicate tight sandboxing and strongest security restrictions. Note that this only
++    analyzes the per-service security features systemd itself implements. This means that any additional security
++    mechanisms applied by the service code itself are not accounted for. The exposure level determined this way should
++    not be misunderstood: a high exposure level neither means that there is no effective sandboxing applied by the
++    service code itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels
++    do indicate however that most likely the service might benefit from additional settings applied to them. Please
++    note that many of the security and sandboxing settings individually can be circumvented — unless combined with
++    others. For example, if a service retains the privilege to establish or undo mount points many of the sandboxing
++    options can be undone by the service code itself. Due to that is essential that each service uses the most
++    comprehensive and strict sandboxing and security settings possible. The tool will take into account some of these
++    combinations and relationships between the settings, but not all. Also note that the security and sandboxing
++    settings analyzed here only apply to the operations executed by the service code itself. If a service has access to
++    an IPC system (such as D-Bus) it might request operations from other services that are not subject to the same
++    restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access policy is
++    not validated too.</para>
++
+     <para>If no command is passed, <command>systemd-analyze
+     time</command> is implied.</para>
+ 
diff --git a/SOURCES/0217-shared-but-util-drop-trusted-annotation-from-bus_ope.patch b/SOURCES/0217-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
deleted file mode 100644
index f161aaf..0000000
--- a/SOURCES/0217-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 4eedaaad7c0abb937482bc93c29c213acfe6c308 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Tue, 27 Aug 2019 19:00:34 +0200
-Subject: [PATCH] shared/but-util: drop trusted annotation from
- bus_open_system_watch_bind_with_description()
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1746057
-
-This only affects systemd-resolved. bus_open_system_watch_bind_with_description()
-is also used in timesyncd, but it has no methods, only read-only properties, and
-in networkd, but it annotates all methods with SD_BUS_VTABLE_UNPRIVILEGED and does
-polkit checks.
-
-Resolves: #1746857
----
- src/shared/bus-util.c | 4 ----
- 1 file changed, 4 deletions(-)
-
-diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
-index a4f2deba31..302dbb4c2e 100644
---- a/src/shared/bus-util.c
-+++ b/src/shared/bus-util.c
-@@ -1699,10 +1699,6 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
-         if (r < 0)
-                 return r;
- 
--        r = sd_bus_set_trusted(bus, true);
--        if (r < 0)
--                return r;
--
-         r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
-         if (r < 0)
-                 return r;
diff --git a/SOURCES/0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch b/SOURCES/0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch
new file mode 100644
index 0000000..4cfc715
--- /dev/null
+++ b/SOURCES/0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch
@@ -0,0 +1,772 @@
+From a2e00522971897909db2a81b4daf10e5700f453e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 15 Mar 2019 10:13:55 +0100
+Subject: [PATCH] man: reorder and add examples to systemd-analyze(1)
+
+The number of verbs supported by systemd-analyze has grown quite a bit, and the
+man page has become an unreadable wall of text. Let's put each verb in a
+separate subsection, grouping similar verbs together, and add a lot of examples
+to guide the user.
+
+(cherry picked from commit d323a99001c1f7625e8ac902e18deb514a4ca18d)
+
+Related: #1750343
+---
+ man/systemd-analyze.xml | 678 +++++++++++++++++++++++++---------------
+ 1 file changed, 429 insertions(+), 249 deletions(-)
+
+diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
+index f3b595880f..7c873cbdd1 100644
+--- a/man/systemd-analyze.xml
++++ b/man/systemd-analyze.xml
+@@ -41,46 +41,50 @@
+       <arg choice="plain">critical-chain</arg>
+       <arg choice="opt" rep="repeat"><replaceable>UNIT</replaceable></arg>
+     </cmdsynopsis>
++
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">plot</arg>
+-      <arg choice="opt">&gt; file.svg</arg>
++      <arg choice="plain">log-level</arg>
++      <arg choice="opt"><replaceable>LEVEL</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">dot</arg>
+-      <arg choice="opt" rep="repeat"><replaceable>PATTERN</replaceable></arg>
+-      <arg choice="opt">&gt; file.dot</arg>
++      <arg choice="plain">log-target</arg>
++      <arg choice="opt"><replaceable>TARGET</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">dump</arg>
++      <arg choice="plain">service-watchdogs</arg>
++      <arg choice="opt"><replaceable>BOOL</replaceable></arg>
+     </cmdsynopsis>
++
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">cat-config</arg>
+-      <arg choice="plain" rep="repeat"><replaceable>NAME</replaceable>|<replaceable>PATH</replaceable></arg>
++      <arg choice="plain">dump</arg>
+     </cmdsynopsis>
++
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">unit-paths</arg>
++      <arg choice="plain">plot</arg>
++      <arg choice="opt">>file.svg</arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">log-level</arg>
+-      <arg choice="opt"><replaceable>LEVEL</replaceable></arg>
++      <arg choice="plain">dot</arg>
++      <arg choice="opt" rep="repeat"><replaceable>PATTERN</replaceable></arg>
++      <arg choice="opt">>file.dot</arg>
+     </cmdsynopsis>
++
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">log-target</arg>
+-      <arg choice="opt"><replaceable>TARGET</replaceable></arg>
++      <arg choice="plain">unit-paths</arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+@@ -91,20 +95,20 @@
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">verify</arg>
+-      <arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
++      <arg choice="plain">calendar</arg>
++      <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">calendar</arg>
+-      <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
++      <arg choice="plain">timespan</arg>
++      <arg choice="plain" rep="repeat"><replaceable>SPAN</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+       <arg choice="opt" rep="repeat">OPTIONS</arg>
+-      <arg choice="plain">service-watchdogs</arg>
+-      <arg choice="opt"><replaceable>BOOL</replaceable></arg>
++      <arg choice="plain">cat-config</arg>
++      <arg choice="plain" rep="repeat"><replaceable>NAME</replaceable>|<replaceable>PATH</replaceable></arg>
+     </cmdsynopsis>
+     <cmdsynopsis>
+       <command>systemd-analyze</command>
+@@ -123,73 +127,299 @@
+     verify the correctness of unit files. It is also used to access
+     special functions useful for advanced system manager debugging.</para>
+ 
+-    <para><command>systemd-analyze time</command> prints the time
+-    spent in the kernel before userspace has been reached, the time
+-    spent in the initial RAM disk (initrd) before normal system
+-    userspace has been reached, and the time normal system userspace
+-    took to initialize. Note that these measurements simply measure
+-    the time passed up to the point where all system services have
+-    been spawned, but not necessarily until they fully finished
+-    initialization or the disk is idle.</para>
+-
+-    <para><command>systemd-analyze blame</command> prints a list of
+-    all running units, ordered by the time they took to initialize.
+-    This information may be used to optimize boot-up times. Note that
+-    the output might be misleading as the initialization of one
+-    service might be slow simply because it waits for the
+-    initialization of another service to complete.
+-    Also note: <command>systemd-analyze blame</command> doesn't display
+-    results for services with <varname>Type=simple</varname>,
+-    because systemd considers such services to be started immediately,
+-    hence no measurement of the initialization delays can be done.</para>
+-
+-    <para><command>systemd-analyze critical-chain
+-    [<replaceable>UNIT…</replaceable>]</command> prints a tree of
+-    the time-critical chain of units (for each of the specified
+-    <replaceable>UNIT</replaceable>s or for the default target
+-    otherwise). The time after the unit is active or started is
+-    printed after the "@" character. The time the unit takes to start
+-    is printed after the "+" character. Note that the output might be
+-    misleading as the initialization of one service might depend on
+-    socket activation and because of the parallel execution of
+-    units.</para>
+-
+-    <para><command>systemd-analyze plot</command> prints an SVG
+-    graphic detailing which system services have been started at what
+-    time, highlighting the time they spent on initialization.</para>
+-
+-    <para><command>systemd-analyze dot</command> generates textual
+-    dependency graph description in dot format for further processing
+-    with the GraphViz
+-    <citerefentry project='die-net'><refentrytitle>dot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+-    tool. Use a command line like <command>systemd-analyze dot | dot
+-    -Tsvg > systemd.svg</command> to generate a graphical dependency
+-    tree. Unless <option>--order</option> or
+-    <option>--require</option> is passed, the generated graph will
+-    show both ordering and requirement dependencies. Optional pattern
+-    globbing style specifications (e.g. <filename>*.target</filename>)
+-    may be given at the end. A unit dependency is included in the
+-    graph if any of these patterns match either the origin or
+-    destination node.</para>
+-
+-    <para><command>systemd-analyze dump</command> outputs a (usually
+-    very long) human-readable serialization of the complete server
+-    state. Its format is subject to change without notice and should
+-    not be parsed by applications.</para>
+-
+-    <para><command>systemd-analyze cat-config</command> is similar
+-    to <command>systemctl cat</command>, but operates on config files.
+-    It will copy the contents of a config file and any drop-ins to standard
+-    output, using the usual systemd set of directories and rules for
+-    precedence. Each argument must be either an absolute path including
+-    the prefix (such as <filename>/etc/systemd/logind.conf</filename> or
+-    <filename>/usr/lib/systemd/logind.conf</filename>), or a name
+-    relative to the prefix (such as <filename>systemd/logind.conf</filename>).
+-    </para>
++    <para>If no command is passed, <command>systemd-analyze
++    time</command> is implied.</para>
++
++    <refsect2>
++      <title><command>systemd-analyze time</command></title>
++
++      <para>This command prints the time spent in the kernel before userspace has been reached, the time
++      spent in the initial RAM disk (initrd) before normal system userspace has been reached, and the time
++      normal system userspace took to initialize. Note that these measurements simply measure the time passed
++      up to the point where all system services have been spawned, but not necessarily until they fully
++      finished initialization or the disk is idle.</para>
++
++      <example>
++        <title><command>Show how long the boot took</command></title>
++
++        <programlisting># in a container
++$ systemd-analyze time
++Startup finished in 296ms (userspace)
++multi-user.target reached after 275ms in userspace
++
++# on a real machine
++$ systemd-analyze time
++Startup finished in 2.584s (kernel) + 19.176s (initrd) + 47.847s (userspace) = 1min 9.608s
++multi-user.target reached after 47.820s in userspace
++</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze blame</command></title>
++
++      <para>This command prints a list of all running units, ordered by the time they took to initialize.
++      This information may be used to optimize boot-up times. Note that the output might be misleading as the
++      initialization of one service might be slow simply because it waits for the initialization of another
++      service to complete.  Also note: <command>systemd-analyze blame</command> doesn't display results for
++      services with <varname>Type=simple</varname>, because systemd considers such services to be started
++      immediately, hence no measurement of the initialization delays can be done.</para>
++
++      <example>
++        <title><command>Show which units took the most time during boot</command></title>
++
++        <programlisting>$ systemd-analyze blame
++         32.875s pmlogger.service
++         20.905s systemd-networkd-wait-online.service
++         13.299s dev-vda1.device
++         ...
++            23ms sysroot.mount
++            11ms initrd-udevadm-cleanup-db.service
++             3ms sys-kernel-config.mount
++        </programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze critical-chain <optional><replaceable>UNIT</replaceable>...</optional></command></title>
++
++      <para>This command prints a tree of the time-critical chain of units (for each of the specified
++      <replaceable>UNIT</replaceable>s or for the default target otherwise). The time after the unit is
++      active or started is printed after the "@" character. The time the unit takes to start is printed after
++      the "+" character. Note that the output might be misleading as the initialization of services might
++      depend on socket activation and because of the parallel execution of units.</para>
++
++      <example>
++        <title><command>systemd-analyze time</command></title>
++
++      <programlisting>$ systemd-analyze critical-chain
++multi-user.target @47.820s
++└─pmie.service @35.968s +548ms
++  └─pmcd.service @33.715s +2.247s
++    └─network-online.target @33.712s
++      └─systemd-networkd-wait-online.service @12.804s +20.905s
++        └─systemd-networkd.service @11.109s +1.690s
++          └─systemd-udevd.service @9.201s +1.904s
++            └─systemd-tmpfiles-setup-dev.service @7.306s +1.776s
++              └─kmod-static-nodes.service @6.976s +177ms
++                └─systemd-journald.socket
++                  └─system.slice
++                    └─-.slice
++</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze log-level [<replaceable>LEVEL</replaceable>]</command></title>
++
++      <para><command>systemd-analyze log-level</command> prints the current log level of the
++      <command>systemd</command> daemon.  If an optional argument <replaceable>LEVEL</replaceable> is
++      provided, then the command changes the current log level of the <command>systemd</command> daemon to
++      <replaceable>LEVEL</replaceable> (accepts the same values as <option>--log-level=</option> described in
++      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze log-target [<replaceable>TARGET</replaceable>]</command></title>
++
++      <para><command>systemd-analyze log-target</command> prints the current log target of the
++      <command>systemd</command> daemon.  If an optional argument <replaceable>TARGET</replaceable> is
++      provided, then the command changes the current log target of the <command>systemd</command> daemon to
++      <replaceable>TARGET</replaceable> (accepts the same values as <option>--log-target=</option>, described
++      in <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze service-watchdogs [yes|no]</command></title>
++
++      <para><command>systemd-analyze service-watchdogs</command> prints the current state of service runtime
++      watchdogs of the <command>systemd</command> daemon. If an optional boolean argument is provided, then
++      globally enables or disables the service runtime watchdogs (<option>WatchdogSec=</option>) and
++      emergency actions (e.g.  <option>OnFailure=</option> or <option>StartLimitAction=</option>); see
++      <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
++      The hardware watchdog is not affected by this setting.</para>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze dump</command></title>
++
++      <para>This command outputs a (usually very long) human-readable serialization of the complete server
++      state. Its format is subject to change without notice and should not be parsed by applications.</para>
++
++      <example>
++        <title>Show the internal state of user manager</title>
++
++        <programlisting>$ systemd-analyze --user dump
++Timestamp userspace: Thu 2019-03-14 23:28:07 CET
++Timestamp finish: Thu 2019-03-14 23:28:07 CET
++Timestamp generators-start: Thu 2019-03-14 23:28:07 CET
++Timestamp generators-finish: Thu 2019-03-14 23:28:07 CET
++Timestamp units-load-start: Thu 2019-03-14 23:28:07 CET
++Timestamp units-load-finish: Thu 2019-03-14 23:28:07 CET
++-> Unit proc-timer_list.mount:
++        Description: /proc/timer_list
++        ...
++-> Unit default.target:
++        Description: Main user target
++...
++</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze plot</command></title>
++
++      <para>This command prints an SVG graphic detailing which system services have been started at what
++      time, highlighting the time they spent on initialization.</para>
++
++      <example>
++        <title><command>Plot a bootchart</command></title>
++
++        <programlisting>$ systemd-analyze plot >bootup.svg
++$ eog bootup.svg&amp;
++</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze dot [<replaceable>pattern</replaceable>...]</command></title>
++
++      <para>This command generates textual dependency graph description in dot format for further processing
++      with the GraphViz
++      <citerefentry project='die-net'><refentrytitle>dot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++      tool. Use a command line like <command>systemd-analyze dot | dot -Tsvg >systemd.svg</command> to
++      generate a graphical dependency tree. Unless <option>--order</option> or <option>--require</option> is
++      passed, the generated graph will show both ordering and requirement dependencies. Optional pattern
++      globbing style specifications (e.g. <filename>*.target</filename>) may be given at the end. A unit
++      dependency is included in the graph if any of these patterns match either the origin or destination
++      node.</para>
++
++      <example>
++        <title>Plot all dependencies of any unit whose name starts with <literal>avahi-daemon</literal>
++        </title>
++
++        <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg >avahi.svg
++$ eog avahi.svg</programlisting>
++      </example>
++
++      <example>
++        <title>Plot the dependencies between all known target units</title>
+ 
+-    <example>
+-      <title>Showing logind configuration</title>
+-      <programlisting>$ systemd-analyze cat-config systemd/logind.conf
++        <programlisting>$ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' \
++      | dot -Tsvg >targets.svg
++$ eog targets.svg</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze unit-paths</command></title>
++
++      <para>This command outputs a list of all directories from which unit files, <filename>.d</filename>
++      overrides, and <filename>.wants</filename>, <filename>.requires</filename> symlinks may be
++      loaded. Combine with <option>--user</option> to retrieve the list for the user manager instance, and
++      <option>--global</option> for the global configuration of user manager instances.</para>
++
++      <example>
++        <title><command>Show all paths for generated units</command></title>
++
++        <programlisting>$ systemd-analyze unit-paths | grep '^/run'
++/run/systemd/system.control
++/run/systemd/transient
++/run/systemd/generator.early
++/run/systemd/system
++/run/systemd/system.attached
++/run/systemd/generator
++/run/systemd/generator.late
++</programlisting>
++      </example>
++
++      <para>Note that this verb prints the list that is compiled into <command>systemd-analyze</command>
++      itself, and does not comunicate with the running manager. Use
++      <programlisting>systemctl [--user] [--global] show -p UnitPath --value</programlisting>
++      to retrieve the actual list that the manager uses, with any empty directories omitted.</para>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>...</optional></command></title>
++
++      <para>This command will list system calls contained in the specified system call set
++      <replaceable>SET</replaceable>, or all known sets if no sets are specified. Argument
++      <replaceable>SET</replaceable> must include the <literal>@</literal> prefix.</para>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze calendar <replaceable>EXPRESSION</replaceable>...</command></title>
++
++      <para>This command will parse and normalize repetitive calendar time events, and will calculate when
++      they elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting in
++      <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
++      following the syntax described in
++      <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. By
++      default, only the next time the calendar expression will elapse is shown; use
++      <option>--iterations=</option> to show the specified number of next times the expression
++      elapses.</para>
++
++      <example>
++        <title>Show leap days in the near future</title>
++
++        <programlisting>$ systemd-analyze calendar --iterations=5 '*-2-29 0:0:0'
++  Original form: *-2-29 0:0:0
++Normalized form: *-02-29 00:00:00
++    Next elapse: Sat 2020-02-29 00:00:00 UTC
++       From now: 11 months 15 days left
++       Iter. #2: Thu 2024-02-29 00:00:00 UTC
++       From now: 4 years 11 months left
++       Iter. #3: Tue 2028-02-29 00:00:00 UTC
++       From now: 8 years 11 months left
++       Iter. #4: Sun 2032-02-29 00:00:00 UTC
++       From now: 12 years 11 months left
++       Iter. #5: Fri 2036-02-29 00:00:00 UTC
++       From now: 16 years 11 months left
++</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze timespan <replaceable>EXPRESSION</replaceable>...</command></title>
++
++      <para>This command parses a time span and outputs the normalized form and the equivalent value in
++      microseconds. The time span should adhere to the same syntax documented in
++      <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
++      Values without associated magnitudes are parsed as seconds.</para>
++
++      <example>
++        <title>Show parsing of timespans</title>
++
++        <programlisting>$ systemd-analyze timespan 1s 300s '1year 0.000001s'
++Original: 1s
++      μs: 1000000
++   Human: 1s
++
++Original: 300s
++      μs: 300000000
++   Human: 5min
++
++Original: 1year 0.000001s
++      μs: 31557600000001
++   Human: 1y 1us
++</programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze cat-config</command>
++      <replaceable>NAME</replaceable>|<replaceable>PATH</replaceable>...</title>
++
++      <para>This command is similar to <command>systemctl cat</command>, but operates on config files. It
++      will copy the contents of a config file and any drop-ins to standard output, using the usual systemd
++      set of directories and rules for precedence. Each argument must be either an absolute path including
++      the prefix (such as <filename>/etc/systemd/logind.conf</filename> or
++      <filename>/usr/lib/systemd/logind.conf</filename>), or a name relative to the prefix (such as
++      <filename>systemd/logind.conf</filename>).</para>
++
++      <example>
++        <title>Showing logind configuration</title>
++        <programlisting>$ systemd-analyze cat-config systemd/logind.conf
+ # /etc/systemd/logind.conf
+ ...
+ [Login]
+@@ -201,90 +431,122 @@ NAutoVTs=8
+ 
+ # /etc/systemd/logind.conf.d/50-override.conf
+ ... some administrator override
+-      </programlisting>
+-    </example>
+-
+-    <para><command>systemd-analyze unit-paths</command> outputs a list of all
+-    directories from which unit files, <filename>.d</filename> overrides, and
+-    <filename>.wants</filename>, <filename>.requires</filename> symlinks may be
+-    loaded. Combine with <option>--user</option> to retrieve the list for the user
+-    manager instance, and <option>--global</option> for the global configuration of
+-    user manager instances. Note that this verb prints the list that is compiled into
+-    <command>systemd-analyze</command> itself, and does not comunicate with the
+-    running manager. Use
+-    <programlisting>systemctl [--user] [--global] show -p UnitPath --value</programlisting>
+-    to retrieve the actual list that the manager uses, with any empty directories
+-    omitted.</para>
+-
+-    <para><command>systemd-analyze log-level</command>
+-    prints the current log level of the <command>systemd</command> daemon.
+-    If an optional argument <replaceable>LEVEL</replaceable> is provided, then the command changes the current log
+-    level of the <command>systemd</command> daemon to <replaceable>LEVEL</replaceable> (accepts the same values as
+-    <option>--log-level=</option> described in
+-    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
+-
+-    <para><command>systemd-analyze log-target</command>
+-    prints the current log target of the <command>systemd</command> daemon.
+-    If an optional argument <replaceable>TARGET</replaceable> is provided, then the command changes the current log
+-    target of the <command>systemd</command> daemon to <replaceable>TARGET</replaceable> (accepts the same values as
+-    <option>--log-target=</option>, described in
+-    <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
+-
+-    <para><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>…</optional></command>
+-    will list system calls contained in the specified system call set <replaceable>SET</replaceable>,
+-    or all known sets if no sets are specified. Argument <replaceable>SET</replaceable> must include
+-    the <literal>@</literal> prefix.</para>
+-
+-    <para><command>systemd-analyze verify</command> will load unit files and print
+-    warnings if any errors are detected. Files specified on the command line will be
+-    loaded, but also any other units referenced by them. The full unit search path is
+-    formed by combining the directories for all command line arguments, and the usual unit
+-    load paths (variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be
+-    used to replace or augment the compiled in set of unit load paths; see
+-    <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+-    All units files present in the directories containing the command line arguments will
+-    be used in preference to the other paths.</para>
+-
+-    <para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time events, and
+-    will calculate when they will elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting
+-    in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>, following the
+-    syntax described in
+-    <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+-
+-    <para><command>systemd-analyze service-watchdogs</command>
+-    prints the current state of service runtime watchdogs of the <command>systemd</command> daemon.
+-    If an optional boolean argument is provided, then globally enables or disables the service
+-    runtime watchdogs (<option>WatchdogSec=</option>) and emergency actions (e.g.
+-    <option>OnFailure=</option> or <option>StartLimitAction=</option>); see
+-    <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+-    The hardware watchdog is not affected by this setting.</para>
+-
+-    <para><command>systemd-analyze security</command> analyzes the security and sandboxing settings of one or more
+-    specified service units. If at least one unit name is specified the security settings of the specified service
+-    units are inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded,
+-    long-running service units are inspected and a terse table with results shown. The command checks for various
+-    security-related service settings, assigning each a numeric "exposure level" value, depending on how important a
+-    setting is. It then calculates an overall exposure level for the whole unit, which is an estimation in the range
+-    0.0…10.0 indicating how exposed a service is security-wise. High exposure levels indicate very little applied
+-    sandboxing. Low exposure levels indicate tight sandboxing and strongest security restrictions. Note that this only
+-    analyzes the per-service security features systemd itself implements. This means that any additional security
+-    mechanisms applied by the service code itself are not accounted for. The exposure level determined this way should
+-    not be misunderstood: a high exposure level neither means that there is no effective sandboxing applied by the
+-    service code itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels
+-    do indicate however that most likely the service might benefit from additional settings applied to them. Please
+-    note that many of the security and sandboxing settings individually can be circumvented — unless combined with
+-    others. For example, if a service retains the privilege to establish or undo mount points many of the sandboxing
+-    options can be undone by the service code itself. Due to that is essential that each service uses the most
+-    comprehensive and strict sandboxing and security settings possible. The tool will take into account some of these
+-    combinations and relationships between the settings, but not all. Also note that the security and sandboxing
+-    settings analyzed here only apply to the operations executed by the service code itself. If a service has access to
+-    an IPC system (such as D-Bus) it might request operations from other services that are not subject to the same
+-    restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access policy is
+-    not validated too.</para>
++        </programlisting>
++      </example>
++    </refsect2>
+ 
+-    <para>If no command is passed, <command>systemd-analyze
+-    time</command> is implied.</para>
++    <refsect2>
++      <title><command>systemd-analyze verify <replaceable>FILE</replaceable>...</command></title>
++
++      <para>This command will load unit files and print warnings if any errors are detected. Files specified
++      on the command line will be loaded, but also any other units referenced by them. The full unit search
++      path is formed by combining the directories for all command line arguments, and the usual unit load
++      paths (variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be used to replace or
++      augment the compiled in set of unit load paths; see
++      <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>).  All
++      units files present in the directories containing the command line arguments will be used in preference
++      to the other paths.</para>
++
++      <para>The following errors are currently detected:</para>
++      <itemizedlist>
++        <listitem><para>unknown sections and directives,</para></listitem>
++
++        <listitem><para>missing dependencies which are required to start the given unit,</para></listitem>
++
++        <listitem><para>man pages listed in <varname>Documentation=</varname> which are not found in the
++        system,</para></listitem>
++
++        <listitem><para>commands listed in <varname>ExecStart=</varname> and similar which are not found in
++        the system or not executable.</para></listitem>
++      </itemizedlist>
+ 
++      <example>
++        <title>Misspelt directives</title>
++
++        <programlisting>$ cat ./user.slice
++[Unit]
++WhatIsThis=11
++Documentation=man:nosuchfile(1)
++Requires=different.service
++
++[Service]
++Description=x
++
++$ systemd-analyze verify ./user.slice
++[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
++[./user.slice:13] Unknown section 'Service'. Ignoring.
++Error: org.freedesktop.systemd1.LoadFailed:
++   Unit different.service failed to load:
++   No such file or directory.
++Failed to create user.slice/start: Invalid argument
++user.slice: man nosuchfile(1) command failed with code 16
++        </programlisting>
++      </example>
++
++      <example>
++        <title>Missing service units</title>
++
++        <programlisting>$ tail ./a.socket ./b.socket
++==> ./a.socket &lt;==
++[Socket]
++ListenStream=100
++
++==> ./b.socket &lt;==
++[Socket]
++ListenStream=100
++Accept=yes
++
++$ systemd-analyze verify ./a.socket ./b.socket
++Service a.service not loaded, a.socket cannot be started.
++Service b@0.service not loaded, b.socket cannot be started.
++        </programlisting>
++      </example>
++    </refsect2>
++
++    <refsect2>
++      <title><command>systemd-analyze security <optional><replaceable>UNIT</replaceable>...</optional></command></title>
++
++      <para>This command analyzes the security and sandboxing settings of one or more specified service
++      units. If at least one unit name is specified the security settings of the specified service units are
++      inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded,
++      long-running service units are inspected and a terse table with results shown. The command checks for
++      various security-related service settings, assigning each a numeric "exposure level" value, depending
++      on how important a setting is. It then calculates an overall exposure level for the whole unit, which
++      is an estimation in the range 0.0…10.0 indicating how exposed a service is security-wise. High exposure
++      levels indicate very little applied sandboxing. Low exposure levels indicate tight sandboxing and
++      strongest security restrictions. Note that this only analyzes the per-service security features systemd
++      itself implements. This means that any additional security mechanisms applied by the service code
++      itself are not accounted for. The exposure level determined this way should not be misunderstood: a
++      high exposure level neither means that there is no effective sandboxing applied by the service code
++      itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels do
++      indicate however that most likely the service might benefit from additional settings applied to
++      them.</para>
++
++      <para>Please note that many of the security and sandboxing settings individually can be circumvented —
++      unless combined with others. For example, if a service retains the privilege to establish or undo mount
++      points many of the sandboxing options can be undone by the service code itself. Due to that is
++      essential that each service uses the most comprehensive and strict sandboxing and security settings
++      possible. The tool will take into account some of these combinations and relationships between the
++      settings, but not all. Also note that the security and sandboxing settings analyzed here only apply to
++      the operations executed by the service code itself. If a service has access to an IPC system (such as
++      D-Bus) it might request operations from other services that are not subject to the same
++      restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access
++      policy is not validated too.</para>
++
++      <example>
++      <title>Analyze <filename noindex="true">systemd-logind.service</filename></title>
++
++      <programlisting>$ systemd-analyze security --no-pager systemd-logind.service
++  NAME                DESCRIPTION                              EXPOSURE
++✗ PrivateNetwork=     Service has access to the host's network      0.5
++✗ User=/DynamicUser=  Service runs as root user                     0.4
++✗ DeviceAllow=        Service has no device ACL                     0.2
++✓ IPAddressDeny=      Service blocks all IP address ranges
++...
++→ Overall exposure level for systemd-logind.service: 4.1 OK 🙂
++</programlisting>
++      </example>
++    </refsect2>
+   </refsect1>
+ 
+   <refsect1>
+@@ -408,88 +670,6 @@ NAutoVTs=8
+     otherwise.</para>
+   </refsect1>
+ 
+-  <refsect1>
+-    <title>Examples for <command>dot</command></title>
+-
+-    <example>
+-      <title>Plots all dependencies of any unit whose name starts with
+-      <literal>avahi-daemon</literal></title>
+-
+-      <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
+-$ eog avahi.svg</programlisting>
+-    </example>
+-
+-    <example>
+-      <title>Plots the dependencies between all known target units</title>
+-
+-      <programlisting>$ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
+-$ eog targets.svg</programlisting>
+-    </example>
+-  </refsect1>
+-
+-  <refsect1>
+-    <title>Examples for <command>verify</command></title>
+-
+-    <para>The following errors are currently detected:</para>
+-    <itemizedlist>
+-      <listitem><para>unknown sections and directives,
+-      </para></listitem>
+-
+-      <listitem><para>missing dependencies which are required to start
+-      the given unit,</para></listitem>
+-
+-      <listitem><para>man pages listed in
+-      <varname>Documentation=</varname> which are not found in the
+-      system,</para></listitem>
+-
+-      <listitem><para>commands listed in <varname>ExecStart=</varname>
+-      and similar which are not found in the system or not
+-      executable.</para></listitem>
+-    </itemizedlist>
+-
+-    <example>
+-      <title>Misspelt directives</title>
+-
+-      <programlisting>$ cat ./user.slice
+-[Unit]
+-WhatIsThis=11
+-Documentation=man:nosuchfile(1)
+-Requires=different.service
+-
+-[Service]
+-Description=x
+-
+-$ systemd-analyze verify ./user.slice
+-[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
+-[./user.slice:13] Unknown section 'Service'. Ignoring.
+-Error: org.freedesktop.systemd1.LoadFailed:
+-   Unit different.service failed to load:
+-   No such file or directory.
+-Failed to create user.slice/start: Invalid argument
+-user.slice: man nosuchfile(1) command failed with code 16
+-      </programlisting>
+-    </example>
+-
+-    <example>
+-      <title>Missing service units</title>
+-
+-      <programlisting>$ tail ./a.socket ./b.socket
+-==> ./a.socket &lt;==
+-[Socket]
+-ListenStream=100
+-
+-==> ./b.socket &lt;==
+-[Socket]
+-ListenStream=100
+-Accept=yes
+-
+-$ systemd-analyze verify ./a.socket ./b.socket
+-Service a.service not loaded, a.socket cannot be started.
+-Service b@0.service not loaded, b.socket cannot be started.
+-      </programlisting>
+-    </example>
+-  </refsect1>
+-
+   <xi:include href="less-variables.xml" />
+ 
+   <refsect1>
diff --git a/SOURCES/0218-sd-bus-adjust-indentation-of-comments.patch b/SOURCES/0218-sd-bus-adjust-indentation-of-comments.patch
deleted file mode 100644
index 14b6174..0000000
--- a/SOURCES/0218-sd-bus-adjust-indentation-of-comments.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 0bd92f0fbaf7105b6d1dd6a2d96dad7e5522e027 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Tue, 27 Aug 2019 19:00:50 +0200
-Subject: [PATCH] sd-bus: adjust indentation of comments
-
-Related: #1746857
----
- src/libsystemd/sd-bus/sd-bus.c | 3 +--
- src/shared/bus-util.c          | 7 ++++---
- 2 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index 3583e24e64..1c9e967ae0 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -1341,8 +1341,7 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip
-         b->bus_client = true;
-         b->is_user = true;
- 
--        /* We don't do any per-method access control on the user
--         * bus. */
-+        /* We don't do any per-method access control on the user bus. */
-         b->trusted = true;
-         b->is_local = true;
- 
-diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
-index 302dbb4c2e..2d908eb45c 100644
---- a/src/shared/bus-util.c
-+++ b/src/shared/bus-util.c
-@@ -1675,7 +1675,8 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
- 
-         assert(ret);
- 
--        /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */
-+        /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal
-+         * turned on. */
- 
-         r = sd_bus_new(&bus);
-         if (r < 0)
-@@ -1890,8 +1891,8 @@ int bus_reply_pair_array(sd_bus_message *m, char **l) {
- 
-         assert(m);
- 
--        /* Reply to the specified message with a message containing a dictionary put together from the specified
--         * strv */
-+        /* Reply to the specified message with a message containing a dictionary put together from the
-+         * specified strv */
- 
-         r = sd_bus_message_new_method_return(m, &reply);
-         if (r < 0)
diff --git a/SOURCES/0219-resolved-do-not-run-loop-twice.patch b/SOURCES/0219-resolved-do-not-run-loop-twice.patch
deleted file mode 100644
index 4a706d4..0000000
--- a/SOURCES/0219-resolved-do-not-run-loop-twice.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 1ae0cf8c3ae565a19283d628f833668babf81b82 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Tue, 27 Aug 2019 19:02:53 +0200
-Subject: [PATCH] resolved: do not run loop twice
-
-This doesn't matter much, but let's just do the loop once and allocate
-the populate the result set on the fly. If we find an error, it'll get
-cleaned up automatically.
-
-Related: #1746857
----
- src/resolve/resolved-link-bus.c | 13 ++++++-------
- 1 file changed, 6 insertions(+), 7 deletions(-)
-
-diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
-index b1581740d8..46d2b11636 100644
---- a/src/resolve/resolved-link-bus.c
-+++ b/src/resolve/resolved-link-bus.c
-@@ -492,6 +492,10 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
-         if (r < 0)
-                 return r;
- 
-+        ns = set_new(&dns_name_hash_ops);
-+        if (!ns)
-+                return -ENOMEM;
-+
-         r = sd_bus_message_read_strv(message, &ntas);
-         if (r < 0)
-                 return r;
-@@ -501,14 +505,9 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
-                 if (r < 0)
-                         return r;
-                 if (r == 0)
--                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i);
--        }
-+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
-+                                                 "Invalid negative trust anchor domain: %s", *i);
- 
--        ns = set_new(&dns_name_hash_ops);
--        if (!ns)
--                return -ENOMEM;
--
--        STRV_FOREACH(i, ntas) {
-                 r = set_put_strdup(ns, *i);
-                 if (r < 0)
-                         return r;
diff --git a/SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch b/SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch
new file mode 100644
index 0000000..f5ba536
--- /dev/null
+++ b/SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch
@@ -0,0 +1,132 @@
+From ac7db0c5b48f1090f77dbcfa0a1e0dc08d5c471e Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <fsumsal@redhat.com>
+Date: Mon, 14 Oct 2019 15:26:48 +0200
+Subject: [PATCH] travis: move to CentOS 8 docker images
+
+As the CentOS 8 Docker images is finally out, we can use it and drop the
+plethora of workarounds we had to implement to compile RHEL8 systemd on
+CentOS 7.
+
+Resolves: #1761519
+---
+ .travis.yml               | 22 ++++++++++------------
+ ci/travis-centos-rhel8.sh | 32 +++++++++-----------------------
+ 2 files changed, 19 insertions(+), 35 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index 0010da5784..70c60cf24e 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -9,42 +9,40 @@ env:
+ 
+ jobs:
+     include:
+-        - name: CentOS 7
++        - name: CentOS 8
+           language: bash
+           env:
+-              - CENTOS_RELEASE="centos7"
++              - CENTOS_RELEASE="centos8"
+               - CONT_NAME="systemd-centos-$CENTOS_RELEASE"
+               - DOCKER_EXEC="docker exec -ti $CONT_NAME"
+           before_install:
+               - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
+               - docker --version
+           install:
+-              - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi
+-              - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP
++              - $CI_ROOT/travis-centos-rhel8.sh SETUP
+           script:
+               - set -e
+               # Build systemd
+-              - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN
++              - $CI_ROOT/travis-centos-rhel8.sh RUN
+               - set +e
+           after_script:
+-              - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP
++              - $CI_ROOT/travis-centos-rhel8.sh CLEANUP
+ 
+-        - name: CentOS 7 (ASan+UBSan)
++        - name: CentOS 8 (ASan+UBSan)
+           language: bash
+           env:
+-              - CENTOS_RELEASE="centos7"
++              - CENTOS_RELEASE="centos8"
+               - CONT_NAME="systemd-centos-$CENTOS_RELEASE"
+               - DOCKER_EXEC="docker exec -ti $CONT_NAME"
+           before_install:
+               - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
+               - docker --version
+           install:
+-              - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi
+-              - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP
++              - $CI_ROOT/travis-centos-rhel8.sh SETUP
+           script:
+               - set -e
+               # Build systemd
+-              - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN_ASAN
++              - $CI_ROOT/travis-centos-rhel8.sh RUN_ASAN
+               - set +e
+           after_script:
+-              - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP
++              - $CI_ROOT/travis-centos-rhel8.sh CLEANUP
+diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
+index c3d1018682..ade44a0413 100755
+--- a/ci/travis-centos-rhel8.sh
++++ b/ci/travis-centos-rhel8.sh
+@@ -15,10 +15,7 @@ CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}"
+ DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
+ DOCKER_RUN="${DOCKER_RUN:-docker run}"
+ REPO_ROOT="${REPO_ROOT:-$PWD}"
+-ADDITIONAL_DEPS=(systemd-ci-environment libidn2-devel python-lxml python36 ninja-build libasan net-tools strace nc busybox e2fsprogs quota dnsmasq)
+-# Repo with additional depencencies to compile newer systemd on CentOS 7
+-COPR_REPO="https://copr.fedorainfracloud.org/coprs/mrc0mmand/systemd-centos-ci/repo/epel-7/mrc0mmand-systemd-centos-ci-epel-7.repo"
+-COPR_REPO_PATH="/etc/yum.repos.d/${COPR_REPO##*/}"
++ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq)
+ # RHEL8 options
+ CONFIGURE_OPTS=(
+     -Dsysvinit-path=/etc/rc.d/init.d
+@@ -95,18 +92,14 @@ for phase in "${PHASES[@]}"; do
+                         -dit --net=host centos:$CENTOS_RELEASE /sbin/init
+             # Beautiful workaround for Fedora's version of Docker
+             sleep 1
+-            $DOCKER_EXEC yum makecache
+-            $DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH"
+-            $DOCKER_EXEC yum -q -y install epel-release yum-utils
+-            $DOCKER_EXEC yum-config-manager -q --enable epel
+-            $DOCKER_EXEC yum -y upgrade
+-            # Install necessary build/test requirements
+-            $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}"
+-            $DOCKER_EXEC python3.6 -m ensurepip
+-            $DOCKER_EXEC python3.6 -m pip install meson
+-            # Create necessary symlinks
+-            $DOCKER_EXEC ln --force -s /usr/bin/python3.6 /usr/bin/python3
+-            $DOCKER_EXEC ln --force -s /usr/bin/ninja-build /usr/bin/ninja
++            $DOCKER_EXEC dnf makecache
++            # Install and enable EPEL
++            $DOCKER_EXEC dnf -q -y install epel-release dnf-utils "${ADDITIONAL_DEPS[@]}"
++            $DOCKER_EXEC dnf config-manager -q --enable epel
++            # Upgrade the container to get the most recent environment
++            $DOCKER_EXEC dnf -y upgrade
++            # Install systemd's build dependencies
++            $DOCKER_EXEC dnf -q -y --enablerepo "PowerTools" builddep systemd
+             ;;
+         RUN)
+             info "Run phase"
+@@ -117,16 +110,9 @@ for phase in "${PHASES[@]}"; do
+             # unexpected fails due to incompatibilities with older systemd
+             $DOCKER_EXEC ninja -C build install
+             docker restart $CONT_NAME
+-            # "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt
+-            # and it's pointless to run it on a VM in a Docker container...
+-            echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl"
+             $DOCKER_EXEC ninja -C build test
+             ;;
+         RUN_ASAN|RUN_CLANG_ASAN)
+-            # Let's install newer gcc for proper ASan/UBSan support
+-            $DOCKER_EXEC yum -y install centos-release-scl
+-            $DOCKER_EXEC yum -y install devtoolset-8 devtoolset-8-libasan-devel libasan5 devtoolset-8-libubsan-devel libubsan1
+-            $DOCKER_EXEC bash -c "echo 'source scl_source enable devtoolset-8' >> /root/.bashrc"
+             # Note to my future frustrated self: docker exec runs the given command
+             # as sh -c 'command' - which means both .bash_profile and .bashrc will
+             # be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e.
diff --git a/SOURCES/0220-resolved-allow-access-to-Set-Link-and-Revert-methods.patch b/SOURCES/0220-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
deleted file mode 100644
index 0d8cbcd..0000000
--- a/SOURCES/0220-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
+++ /dev/null
@@ -1,347 +0,0 @@
-From aa39a552bb52287c1a1da56e109c0fb4c0dc9621 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Tue, 27 Aug 2019 19:25:05 +0200
-Subject: [PATCH] resolved: allow access to Set*Link and Revert methods through
- polkit
-
-This matches what is done in networkd very closely. In fact even the
-policy descriptions are all identical (with s/network/resolve), except
-for the last one:
-resolved has org.freedesktop.resolve1.revert while
-networkd has org.freedesktop.network1.revert-ntp and
-org.freedesktop.network1.revert-dns so the description is a bit different.
-
-Conflicts:
-	src/resolve/resolved-bus.c
-	src/resolve/resolved-link-bus.c
-
-Related: #1746857
----
- src/resolve/org.freedesktop.resolve1.policy | 99 +++++++++++++++++++++
- src/resolve/resolved-bus.c                  | 22 ++---
- src/resolve/resolved-link-bus.c             | 97 +++++++++++++++++---
- 3 files changed, 197 insertions(+), 21 deletions(-)
-
-diff --git a/src/resolve/org.freedesktop.resolve1.policy b/src/resolve/org.freedesktop.resolve1.policy
-index b65ba3e56a..592c4eb8b0 100644
---- a/src/resolve/org.freedesktop.resolve1.policy
-+++ b/src/resolve/org.freedesktop.resolve1.policy
-@@ -40,4 +40,103 @@
-                 <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-         </action>
- 
-+        <action id="org.freedesktop.resolve1.set-dns-servers">
-+                <description gettext-domain="systemd">Set DNS servers</description>
-+                <message gettext-domain="systemd">Authentication is required to set DNS servers.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-domains">
-+                <description gettext-domain="systemd">Set domains</description>
-+                <message gettext-domain="systemd">Authentication is required to set domains.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-default-route">
-+                <description gettext-domain="systemd">Set default route</description>
-+                <message gettext-domain="systemd">Authentication is required to set default route.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-llmnr">
-+                <description gettext-domain="systemd">Enable/disable LLMNR</description>
-+                <message gettext-domain="systemd">Authentication is required to enable or disable LLMNR.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-mdns">
-+                <description gettext-domain="systemd">Enable/disable multicast DNS</description>
-+                <message gettext-domain="systemd">Authentication is required to enable or disable multicast DNS.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-dns-over-tls">
-+                <description gettext-domain="systemd">Enable/disable DNS over TLS</description>
-+                <message gettext-domain="systemd">Authentication is required to enable or disable DNS over TLS.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-dnssec">
-+                <description gettext-domain="systemd">Enable/disable DNSSEC</description>
-+                <message gettext-domain="systemd">Authentication is required to enable or disable DNSSEC.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.set-dnssec-negative-trust-anchors">
-+                <description gettext-domain="systemd">Set DNSSEC Negative Trust Anchors</description>
-+                <message gettext-domain="systemd">Authentication is required to set DNSSEC Negative Trust Anchros.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
-+        <action id="org.freedesktop.resolve1.revert">
-+                <description gettext-domain="systemd">Revert name resolution settings</description>
-+                <message gettext-domain="systemd">Authentication is required to revert name resolution settings.</message>
-+                <defaults>
-+                        <allow_any>auth_admin</allow_any>
-+                        <allow_inactive>auth_admin</allow_inactive>
-+                        <allow_active>auth_admin_keep</allow_active>
-+                </defaults>
-+                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
-+        </action>
-+
- </policyconfig>
-diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
-index da0a909dd6..4d6cc4fd48 100644
---- a/src/resolve/resolved-bus.c
-+++ b/src/resolve/resolved-bus.c
-@@ -1848,18 +1848,18 @@ static const sd_bus_vtable resolve_vtable[] = {
-         SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
-         SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
-         SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
--        SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
--        SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, 0),
--        SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, 0),
-+        SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, SD_BUS_VTABLE_UNPRIVILEGED),
-         SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
--        SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
--        SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0),
--        SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0),
--        SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0),
--        SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, 0),
--        SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0),
--        SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0),
--        SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0),
-+        SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, SD_BUS_VTABLE_UNPRIVILEGED),
- 
-         SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED),
-         SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED),
-diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
-index 46d2b11636..bf3e42264e 100644
---- a/src/resolve/resolved-link-bus.c
-+++ b/src/resolve/resolved-link-bus.c
-@@ -1,5 +1,9 @@
- /* SPDX-License-Identifier: LGPL-2.1+ */
- 
-+#include <net/if.h>
-+#include <netinet/in.h>
-+#include <sys/capability.h>
-+
- #include "alloc-util.h"
- #include "bus-common-errors.h"
- #include "bus-util.h"
-@@ -9,6 +13,7 @@
- #include "resolved-link-bus.h"
- #include "resolved-resolv-conf.h"
- #include "strv.h"
-+#include "user-util.h"
- 
- static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
- static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
-@@ -235,6 +240,15 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
-         if (r < 0)
-                 return r;
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-dns-servers",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         dns_server_mark_all(l->dns_servers);
- 
-         for (i = 0; i < n; i++) {
-@@ -298,12 +312,21 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
-         }
- 
--        dns_search_domain_mark_all(l->search_domains);
--
-         r = sd_bus_message_rewind(message, false);
-         if (r < 0)
-                 return r;
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-domains",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-+        dns_search_domain_mark_all(l->search_domains);
-+
-         for (;;) {
-                 DnsSearchDomain *d;
-                 const char *name;
-@@ -371,6 +394,15 @@ int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_er
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr);
-         }
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-llmnr",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         l->llmnr_support = mode;
-         link_allocate_scopes(l);
-         link_add_rrs(l, false);
-@@ -405,6 +437,15 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns);
-         }
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-mdns",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         l->mdns_support = mode;
-         link_allocate_scopes(l);
-         link_add_rrs(l, false);
-@@ -439,6 +480,15 @@ int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls);
-         }
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-dns-over-tls",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         link_set_dns_over_tls_mode(l, mode);
- 
-         (void) link_save_user(l);
-@@ -471,6 +521,15 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec);
-         }
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-dnssec",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         link_set_dnssec_mode(l, mode);
- 
-         (void) link_save_user(l);
-@@ -513,6 +572,15 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
-                         return r;
-         }
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.set-dnssec-negative-trust-anchors",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         set_free_free(l->dnssec_negative_trust_anchors);
-         l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
- 
-@@ -532,6 +600,15 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error
-         if (r < 0)
-                 return r;
- 
-+        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
-+                                    "org.freedesktop.resolve1.revert",
-+                                    NULL, true, UID_INVALID,
-+                                    &l->manager->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         link_flush_settings(l);
-         link_allocate_scopes(l);
-         link_add_rrs(l, false);
-@@ -556,14 +633,14 @@ const sd_bus_vtable link_vtable[] = {
-         SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
-         SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
- 
--        SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0),
--        SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0),
--        SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
--        SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
--        SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, 0),
--        SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
--        SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, 0),
--        SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, 0),
-+        SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
-+        SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED),
- 
-         SD_BUS_VTABLE_END
- };
diff --git a/SOURCES/0220-travis-drop-SCL-remains.patch b/SOURCES/0220-travis-drop-SCL-remains.patch
new file mode 100644
index 0000000..30d5378
--- /dev/null
+++ b/SOURCES/0220-travis-drop-SCL-remains.patch
@@ -0,0 +1,50 @@
+From 5b14988845b591f6fa2fc1e032618fe882827f4a Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <fsumsal@redhat.com>
+Date: Mon, 14 Oct 2019 16:22:51 +0200
+Subject: [PATCH] travis: drop SCL remains
+
+The `bash -ic` wrapper existed solely to make SCL work as expected
+
+Resolves: #1761519
+---
+ ci/travis-centos-rhel8.sh | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
+index ade44a0413..da131c726b 100755
+--- a/ci/travis-centos-rhel8.sh
++++ b/ci/travis-centos-rhel8.sh
+@@ -113,22 +113,12 @@ for phase in "${PHASES[@]}"; do
+             $DOCKER_EXEC ninja -C build test
+             ;;
+         RUN_ASAN|RUN_CLANG_ASAN)
+-            # Note to my future frustrated self: docker exec runs the given command
+-            # as sh -c 'command' - which means both .bash_profile and .bashrc will
+-            # be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e.
+-            # sh -l), whereas .bashrc is sourced for NON-LOGIN INTERACTIVE shells
+-            # (i.e. sh -i).
+-            # As the default docker exec command lacks either of those options,
+-            # we need to use a wrapper command which runs the wanted command
+-            # under an explicit bash -i, so the SCL source above works properly.
+-            docker exec -it $CONT_NAME bash -ic 'gcc --version'
+-
+             if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
+                 ENV_VARS="-e CC=clang -e CXX=clang++"
+                 MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
+             fi
+-            docker exec $ENV_VARS -it $CONT_NAME bash -ic "meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}"
+-            docker exec -it $CONT_NAME bash -ic 'ninja -v -C build'
++            docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}
++            docker exec -it $CONT_NAME ninja -v -C build
+ 
+             # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb.
+             travis_wait docker exec --interactive=false \
+@@ -136,7 +126,7 @@ for phase in "${PHASES[@]}"; do
+                 -e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \
+                 -e "TRAVIS=$TRAVIS" \
+                 -t $CONT_NAME \
+-                bash -ic 'meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs'
++                meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
+             ;;
+         CLEANUP)
+             info "Cleanup phase"
diff --git a/SOURCES/0221-resolved-query-polkit-only-after-parsing-the-data.patch b/SOURCES/0221-resolved-query-polkit-only-after-parsing-the-data.patch
deleted file mode 100644
index c94d670..0000000
--- a/SOURCES/0221-resolved-query-polkit-only-after-parsing-the-data.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 7c9077683df0c3959b1bcae973a05e114b15a600 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Tue, 27 Aug 2019 19:28:19 +0200
-Subject: [PATCH] resolved: query polkit only after parsing the data
-
-That's what we do everywhere else because it leads to nicer user experience.
-
-Related: #1746857
----
- src/resolve/resolved-bus.c | 18 +++++++++---------
- 1 file changed, 9 insertions(+), 9 deletions(-)
-
-diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
-index 4d6cc4fd48..3f6a6f9e12 100644
---- a/src/resolve/resolved-bus.c
-+++ b/src/resolve/resolved-bus.c
-@@ -1632,15 +1632,6 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
-         if (m->mdns_support != RESOLVE_SUPPORT_YES)
-                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled");
- 
--        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
--                                    "org.freedesktop.resolve1.register-service",
--                                    NULL, false, UID_INVALID,
--                                    &m->polkit_registry, error);
--        if (r < 0)
--                return r;
--        if (r == 0)
--                return 1; /* Polkit will call us back */
--
-         service = new0(DnssdService, 1);
-         if (!service)
-                 return log_oom();
-@@ -1765,6 +1756,15 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
-         if (r < 0)
-                 return r;
- 
-+        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
-+                                    "org.freedesktop.resolve1.register-service",
-+                                    NULL, false, UID_INVALID,
-+                                    &m->polkit_registry, error);
-+        if (r < 0)
-+                return r;
-+        if (r == 0)
-+                return 1; /* Polkit will call us back */
-+
-         r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops);
-         if (r < 0)
-                 return r;
diff --git a/SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch b/SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch
new file mode 100644
index 0000000..97f64e0
--- /dev/null
+++ b/SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch
@@ -0,0 +1,110 @@
+From 8bd791fb3a8e85063e297204bdef8004aacd22b1 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Wed, 8 Aug 2018 18:27:15 +0900
+Subject: [PATCH] syslog: fix segfault in syslog_parse_priority()
+
+(cherry picked from commit a5ee33b951cfa22db53d0274c9c6c0d9d4dae39d)
+
+Resolves: #1761519
+---
+ src/basic/syslog-util.c           | 20 +++++++++++---------
+ src/journal/test-journal-syslog.c | 20 ++++++++++++++++++++
+ 2 files changed, 31 insertions(+), 9 deletions(-)
+
+diff --git a/src/basic/syslog-util.c b/src/basic/syslog-util.c
+index 21461fa581..fe129482f3 100644
+--- a/src/basic/syslog-util.c
++++ b/src/basic/syslog-util.c
+@@ -10,7 +10,8 @@
+ 
+ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
+         int a = 0, b = 0, c = 0;
+-        int k;
++        const char *end;
++        size_t k;
+ 
+         assert(p);
+         assert(*p);
+@@ -19,21 +20,22 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
+         if ((*p)[0] != '<')
+                 return 0;
+ 
+-        if (!strchr(*p, '>'))
++        end = strchr(*p, '>');
++        if (!end)
+                 return 0;
+ 
+-        if ((*p)[2] == '>') {
++        k = end - *p;
++        assert(k > 0);
++
++        if (k == 2)
+                 c = undecchar((*p)[1]);
+-                k = 3;
+-        } else if ((*p)[3] == '>') {
++        else if (k == 3) {
+                 b = undecchar((*p)[1]);
+                 c = undecchar((*p)[2]);
+-                k = 4;
+-        } else if ((*p)[4] == '>') {
++        } else if (k == 4) {
+                 a = undecchar((*p)[1]);
+                 b = undecchar((*p)[2]);
+                 c = undecchar((*p)[3]);
+-                k = 5;
+         } else
+                 return 0;
+ 
+@@ -46,7 +48,7 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
+         else
+                 *priority = (*priority & LOG_FACMASK) | c;
+ 
+-        *p += k;
++        *p += k + 1;
+         return 1;
+ }
+ 
+diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
+index 7294cde032..120477cc9f 100644
+--- a/src/journal/test-journal-syslog.c
++++ b/src/journal/test-journal-syslog.c
+@@ -4,6 +4,7 @@
+ #include "journald-syslog.h"
+ #include "macro.h"
+ #include "string-util.h"
++#include "syslog-util.h"
+ 
+ static void test_syslog_parse_identifier(const char *str,
+                                          const char *ident, const char *pid, const char *rest, int ret) {
+@@ -19,6 +20,17 @@ static void test_syslog_parse_identifier(const char *str,
+         assert_se(streq(buf, rest));
+ }
+ 
++static void test_syslog_parse_priority(const char *str, int priority, int ret) {
++        const char *buf = str;
++        int priority2, ret2;
++
++        ret2 = syslog_parse_priority(&buf, &priority2, false);
++
++        assert_se(ret == ret2);
++        if (ret2 == 1)
++                assert_se(priority == priority2);
++}
++
+ int main(void) {
+         test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11);
+         test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6);
+@@ -33,5 +45,13 @@ int main(void) {
+         test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
+         test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
+ 
++        test_syslog_parse_priority("<>", 0, 0);
++        test_syslog_parse_priority("<>aaa", 0, 0);
++        test_syslog_parse_priority("<aaaa>", 0, 0);
++        test_syslog_parse_priority("<aaaa>aaa", 0, 0);
++        test_syslog_parse_priority(" <aaaa>", 0, 0);
++        test_syslog_parse_priority(" <aaaa>aaa", 0, 0);
++        /* TODO: add test cases of valid priorities */
++
+         return 0;
+ }
diff --git a/SOURCES/0222-ask-password-prevent-buffer-overrow-when-reading-fro.patch b/SOURCES/0222-ask-password-prevent-buffer-overrow-when-reading-fro.patch
deleted file mode 100644
index aa2bc12..0000000
--- a/SOURCES/0222-ask-password-prevent-buffer-overrow-when-reading-fro.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 7200c0b173bec49c63ac5ecdf6d510d26e8c8271 Mon Sep 17 00:00:00 2001
-From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
-Date: Mon, 13 May 2019 16:58:01 -0300
-Subject: [PATCH] ask-password: prevent buffer overrow when reading from
- keyring
-
-When we read from keyring, a temporary buffer is allocated in order to
-determine the size needed for the entire data. However, when zeroing that area,
-we use the data size returned by the read instead of the lesser size allocate
-for the buffer.
-
-That will cause memory corruption that causes systemd-cryptsetup to crash
-either when a single large password is used or when multiple passwords have
-already been pushed to the keyring.
-
-Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
-(cherry picked from commit 59c55e73eaee345e1ee67c23eace8895ed499693)
-(cherry picked from commit c6c8e0d097d6ba12471c6112c3fd339ea40329d5)
-
-Resolves: #1777037
----
- src/shared/ask-password-api.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
-index 682dc754fc..764ebd08e1 100644
---- a/src/shared/ask-password-api.c
-+++ b/src/shared/ask-password-api.c
-@@ -79,7 +79,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
-                 if (n < m)
-                         break;
- 
--                explicit_bzero(p, n);
-+                explicit_bzero(p, m);
-                 free(p);
-                 m *= 2;
-         }
diff --git a/SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch b/SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch
new file mode 100644
index 0000000..bfe310a
--- /dev/null
+++ b/SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch
@@ -0,0 +1,45 @@
+From fbe5fa22f5b99d4e444db54aadb661e9c932eb6c Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Fri, 16 Nov 2018 13:00:40 +0100
+Subject: [PATCH] sd-bus: make strict asan shut up
+
+asan doesn't like it if we use strndup() (i.e. a string function) on a
+non-NULL terminated buffer (i.e. something that isn't really a string).
+
+Let's hence use memdup_suffix0() instead of strndup(), which is more
+appropriate for binary data that is to become a string.
+
+Fixes: #10385
+(cherry picked from commit ac0a94f7438b49a0890d9806db1fa211a5bca10a)
+
+Resolves: #1761519
+---
+ src/libsystemd/sd-bus/bus-message.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
+index 53cbd675b7..19cb2b9a97 100644
+--- a/src/libsystemd/sd-bus/bus-message.c
++++ b/src/libsystemd/sd-bus/bus-message.c
+@@ -5101,6 +5101,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
+                                 return -EBADMSG;
+ 
+                         if (*p == 0) {
++                                char *k;
+                                 size_t l;
+ 
+                                 /* We found the beginning of the signature
+@@ -5114,9 +5115,11 @@ int bus_message_parse_fields(sd_bus_message *m) {
+                                     p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
+                                         return -EBADMSG;
+ 
+-                                if (free_and_strndup(&m->root_container.signature,
+-                                                     p + 1 + 1, l - 2) < 0)
++                                k = memdup_suffix0(p + 1 + 1, l - 2);
++                                if (!k)
+                                         return -ENOMEM;
++
++                                free_and_replace(m->root_container.signature, k);
+                                 break;
+                         }
+ 
diff --git a/SOURCES/0223-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch b/SOURCES/0223-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
deleted file mode 100644
index 117dca9..0000000
--- a/SOURCES/0223-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From c4a7251ed4ca98d6d4faf6228ffe68166c1906cb Mon Sep 17 00:00:00 2001
-From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
-Date: Mon, 28 Oct 2019 19:35:24 +0900
-Subject: [PATCH] core, job: fix breakage of ordering dependencies by systemctl
- reload command
-
-Currently, systemctl reload command breaks ordering dependencies if it's
-executed when its target service unit is in activating state.
-
-For example, prepare A.service, B.service and C.target as follows:
-
-    # systemctl cat A.service B.service C.target
-    # /etc/systemd/system/A.service
-    [Unit]
-    Description=A
-
-    [Service]
-    Type=oneshot
-    ExecStart=/usr/bin/echo A1
-    ExecStart=/usr/bin/sleep 60
-    ExecStart=/usr/bin/echo A2
-    ExecReload=/usr/bin/echo A reloaded
-    RemainAfterExit=yes
-
-    # /etc/systemd/system/B.service
-    [Unit]
-    Description=B
-    After=A.service
-
-    [Service]
-    Type=oneshot
-    ExecStart=/usr/bin/echo B
-    RemainAfterExit=yes
-
-    # /etc/systemd/system/C.target
-    [Unit]
-    Description=C
-    Wants=A.service B.service
-
-Start them.
-
-    # systemctl daemon-reload
-    # systemctl start C.target
-
-Then, we have:
-
-    # LANG=C journalctl --no-pager -u A.service -u B.service -u C.target -b
-    -- Logs begin at Mon 2019-09-09 00:25:06 EDT, end at Thu 2019-10-24 22:28:47 EDT. --
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: Starting A...
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Child 967 belongs to A.service.
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/sleep 60
-    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/sleep as 968
-    Oct 24 22:27:47 localhost.localdomain systemd[968]: A.service: Executing: /usr/bin/sleep 60
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Trying to enqueue job A.service/reload/replace
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Merged into running job, re-running: A.service/reload as 1288
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Enqueued job A.service/reload as 1288
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Unit cannot be reloaded because it is inactive.
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Job 1288 A.service/reload finished, result=invalid
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Passing 0 fds to service
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: About to execute: /usr/bin/echo B
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Forked /usr/bin/echo as 970
-    Oct 24 22:27:52 localhost.localdomain systemd[970]: B.service: Executing: /usr/bin/echo B
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Failed to send unit change signal for B.service: Connection reset by peer
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed dead -> start
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: Starting B...
-    Oct 24 22:27:52 localhost.localdomain echo[970]: B
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Child 970 belongs to B.service.
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Main process exited, code=exited, status=0/SUCCESS
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed start -> exited
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Job 1371 B.service/start finished, result=done
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: Started B.
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Job 1287 C.target/start finished, result=done
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: Reached target C.
-    Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Failed to send unit change signal for C.target: Connection reset by peer
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 968 belongs to A.service.
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/echo A2
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/echo as 972
-    Oct 24 22:28:47 localhost.localdomain systemd[972]: A.service: Executing: /usr/bin/echo A2
-    Oct 24 22:28:47 localhost.localdomain echo[972]: A2
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 972 belongs to A.service.
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
-    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Changed start -> exited
-
-The issue occurs not only in reload command, i.e.:
-
-  - reload
-  - try-restart
-  - reload-or-restart
-  - reload-or-try-restart commands
-
-The cause of this issue is that job_type_collapse() doesn't take care of the
-activating state.
-
-Fixes: #10464
-(cherry picked from commit d1559793df555212271e490a4a72f55826caf5b4)
-(cherry picked from commit cb084637ba1c8558f1538ce300c5520a6764dc76)
-Resolves: #1781712
----
- src/core/job.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/core/job.c b/src/core/job.c
-index 8552ffb704..769ed6d603 100644
---- a/src/core/job.c
-+++ b/src/core/job.c
-@@ -403,21 +403,21 @@ JobType job_type_collapse(JobType t, Unit *u) {
- 
-         case JOB_TRY_RESTART:
-                 s = unit_active_state(u);
--                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
-+                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
-                         return JOB_NOP;
- 
-                 return JOB_RESTART;
- 
-         case JOB_TRY_RELOAD:
-                 s = unit_active_state(u);
--                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
-+                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
-                         return JOB_NOP;
- 
-                 return JOB_RELOAD;
- 
-         case JOB_RELOAD_OR_START:
-                 s = unit_active_state(u);
--                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
-+                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
-                         return JOB_START;
- 
-                 return JOB_RELOAD;
diff --git a/SOURCES/0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch b/SOURCES/0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch
new file mode 100644
index 0000000..d5df9f1
--- /dev/null
+++ b/SOURCES/0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch
@@ -0,0 +1,43 @@
+From 2f44943836b69455792a5422673f8a69bc9705ba Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <fsumsal@redhat.com>
+Date: Mon, 14 Oct 2019 17:14:35 +0200
+Subject: [PATCH] travis: don't run slow tests under ASan/UBSan
+
+Resolves: #1761519
+---
+ ci/travis-centos-rhel8.sh | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
+index da131c726b..a1502e15ee 100755
+--- a/ci/travis-centos-rhel8.sh
++++ b/ci/travis-centos-rhel8.sh
+@@ -65,10 +65,6 @@ CONFIGURE_OPTS=(
+     -Dnetworkd=false
+     -Dtimesyncd=false
+     -Ddefault-hierarchy=legacy
+-    # Custom options
+-    -Dslow-tests=true
+-    -Dtests=unsafe
+-    -Dinstall-tests=true
+ )
+ 
+ function info() {
+@@ -104,7 +100,7 @@ for phase in "${PHASES[@]}"; do
+         RUN)
+             info "Run phase"
+             # Build systemd
+-            docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}"
++            docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}"
+             $DOCKER_EXEC ninja -v -C build
+             # Let's install the new systemd and "reboot" the container to avoid
+             # unexpected fails due to incompatibilities with older systemd
+@@ -117,7 +113,7 @@ for phase in "${PHASES[@]}"; do
+                 ENV_VARS="-e CC=clang -e CXX=clang++"
+                 MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
+             fi
+-            docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}
++            docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}"
+             docker exec -it $CONT_NAME ninja -v -C build
+ 
+             # Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb.
diff --git a/SOURCES/0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch b/SOURCES/0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch
new file mode 100644
index 0000000..b79434e
--- /dev/null
+++ b/SOURCES/0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch
@@ -0,0 +1,67 @@
+From 6240d78097c6f828aa2ca3b50ac322b41dc41fd1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 23 Aug 2019 11:34:45 +0200
+Subject: [PATCH] kernel-install: do not require non-empty kernel cmdline
+
+When booting with Fedora-Server-dvd-x86_64-30-20190411.n.0.iso,
+/proc/cmdline is empty (libvirt, qemu host with bios, not sure if that
+matters), after installation to disk, anaconda would "crash" in kernel-core
+%posttrans, after calling kernel-install, because dracut would fail
+with
+
+> Could not determine the kernel command line parameters.
+> Please specify the kernel command line in /etc/kernel/cmdline!
+
+I guess it's legitimate, even if unusual, to have no cmdline parameters.
+Two changes are done in this patch:
+
+1. do not fail if the cmdline is empty.
+2. if /usr/lib/kernel/cmdline or /etc/kernel/cmdline are present, but
+   empty, ignore /proc/cmdline. If there's explicit configuration to
+   have empty cmdline, don't ignore it.
+
+The same change was done in dracut:
+https://github.com/dracutdevs/dracut/pull/561.
+
+(cherry picked from commit 88e1306af6380794842fb31108ba67895799fab4)
+
+Resolves: #1701454
+---
+ src/kernel-install/90-loaderentry.install | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
+index a271cdb8a0..1619301536 100644
+--- a/src/kernel-install/90-loaderentry.install
++++ b/src/kernel-install/90-loaderentry.install
+@@ -43,13 +43,13 @@ if ! [[ $PRETTY_NAME ]]; then
+     PRETTY_NAME="Linux $KERNEL_VERSION"
+ fi
+ 
+-declare -a BOOT_OPTIONS
+-
+ if [[ -f /etc/kernel/cmdline ]]; then
+     read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
+-fi
++elif [[ -f /usr/lib/kernel/cmdline ]]; then
++    read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline
++else
++    declare -a BOOT_OPTIONS
+ 
+-if ! [[ ${BOOT_OPTIONS[*]} ]]; then
+     read -r -d '' -a line < /proc/cmdline
+     for i in "${line[@]}"; do
+         [[ "${i#initrd=*}" != "$i" ]] && continue
+@@ -57,12 +57,6 @@ if ! [[ ${BOOT_OPTIONS[*]} ]]; then
+     done
+ fi
+ 
+-if ! [[ ${BOOT_OPTIONS[*]} ]]; then
+-    echo "Could not determine the kernel command line parameters." >&2
+-    echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2
+-    exit 1
+-fi
+-
+ cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" &&
+    chown root:root "$BOOT_DIR_ABS/linux" &&
+    chmod 0644 "$BOOT_DIR_ABS/linux" || {
diff --git a/SOURCES/0224-syslog-fix-segfault-in-syslog_parse_priority.patch b/SOURCES/0224-syslog-fix-segfault-in-syslog_parse_priority.patch
deleted file mode 100644
index d243bc1..0000000
--- a/SOURCES/0224-syslog-fix-segfault-in-syslog_parse_priority.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From a9e1b3a33f65721e7f77f8d8253512dd16cbafdb Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Wed, 8 Aug 2018 18:27:15 +0900
-Subject: [PATCH] syslog: fix segfault in syslog_parse_priority()
-
-(cherry picked from commit a5ee33b951cfa22db53d0274c9c6c0d9d4dae39d)
-(cherry picked from commit 8bd791fb3a8e85063e297204bdef8004aacd22b1)
-Related: #1781712
----
- src/basic/syslog-util.c           | 20 +++++++++++---------
- src/journal/test-journal-syslog.c | 20 ++++++++++++++++++++
- 2 files changed, 31 insertions(+), 9 deletions(-)
-
-diff --git a/src/basic/syslog-util.c b/src/basic/syslog-util.c
-index 21461fa581..fe129482f3 100644
---- a/src/basic/syslog-util.c
-+++ b/src/basic/syslog-util.c
-@@ -10,7 +10,8 @@
- 
- int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
-         int a = 0, b = 0, c = 0;
--        int k;
-+        const char *end;
-+        size_t k;
- 
-         assert(p);
-         assert(*p);
-@@ -19,21 +20,22 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
-         if ((*p)[0] != '<')
-                 return 0;
- 
--        if (!strchr(*p, '>'))
-+        end = strchr(*p, '>');
-+        if (!end)
-                 return 0;
- 
--        if ((*p)[2] == '>') {
-+        k = end - *p;
-+        assert(k > 0);
-+
-+        if (k == 2)
-                 c = undecchar((*p)[1]);
--                k = 3;
--        } else if ((*p)[3] == '>') {
-+        else if (k == 3) {
-                 b = undecchar((*p)[1]);
-                 c = undecchar((*p)[2]);
--                k = 4;
--        } else if ((*p)[4] == '>') {
-+        } else if (k == 4) {
-                 a = undecchar((*p)[1]);
-                 b = undecchar((*p)[2]);
-                 c = undecchar((*p)[3]);
--                k = 5;
-         } else
-                 return 0;
- 
-@@ -46,7 +48,7 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
-         else
-                 *priority = (*priority & LOG_FACMASK) | c;
- 
--        *p += k;
-+        *p += k + 1;
-         return 1;
- }
- 
-diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
-index 7294cde032..120477cc9f 100644
---- a/src/journal/test-journal-syslog.c
-+++ b/src/journal/test-journal-syslog.c
-@@ -4,6 +4,7 @@
- #include "journald-syslog.h"
- #include "macro.h"
- #include "string-util.h"
-+#include "syslog-util.h"
- 
- static void test_syslog_parse_identifier(const char *str,
-                                          const char *ident, const char *pid, const char *rest, int ret) {
-@@ -19,6 +20,17 @@ static void test_syslog_parse_identifier(const char *str,
-         assert_se(streq(buf, rest));
- }
- 
-+static void test_syslog_parse_priority(const char *str, int priority, int ret) {
-+        const char *buf = str;
-+        int priority2, ret2;
-+
-+        ret2 = syslog_parse_priority(&buf, &priority2, false);
-+
-+        assert_se(ret == ret2);
-+        if (ret2 == 1)
-+                assert_se(priority == priority2);
-+}
-+
- int main(void) {
-         test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11);
-         test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6);
-@@ -33,5 +45,13 @@ int main(void) {
-         test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
-         test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
- 
-+        test_syslog_parse_priority("<>", 0, 0);
-+        test_syslog_parse_priority("<>aaa", 0, 0);
-+        test_syslog_parse_priority("<aaaa>", 0, 0);
-+        test_syslog_parse_priority("<aaaa>aaa", 0, 0);
-+        test_syslog_parse_priority(" <aaaa>", 0, 0);
-+        test_syslog_parse_priority(" <aaaa>aaa", 0, 0);
-+        /* TODO: add test cases of valid priorities */
-+
-         return 0;
- }
diff --git a/SOURCES/0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch b/SOURCES/0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch
new file mode 100644
index 0000000..1a3af20
--- /dev/null
+++ b/SOURCES/0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch
@@ -0,0 +1,36 @@
+From c6c8e0d097d6ba12471c6112c3fd339ea40329d5 Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+Date: Mon, 13 May 2019 16:58:01 -0300
+Subject: [PATCH] ask-password: prevent buffer overrow when reading from
+ keyring
+
+When we read from keyring, a temporary buffer is allocated in order to
+determine the size needed for the entire data. However, when zeroing that area,
+we use the data size returned by the read instead of the lesser size allocate
+for the buffer.
+
+That will cause memory corruption that causes systemd-cryptsetup to crash
+either when a single large password is used or when multiple passwords have
+already been pushed to the keyring.
+
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
+(cherry picked from commit 59c55e73eaee345e1ee67c23eace8895ed499693)
+
+Resolves: #1752050
+---
+ src/shared/ask-password-api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
+index 682dc754fc..764ebd08e1 100644
+--- a/src/shared/ask-password-api.c
++++ b/src/shared/ask-password-api.c
+@@ -79,7 +79,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
+                 if (n < m)
+                         break;
+ 
+-                explicit_bzero(p, n);
++                explicit_bzero(p, m);
+                 free(p);
+                 m *= 2;
+         }
diff --git a/SOURCES/0225-journald-fixed-assertion-failure-when-system-journal.patch b/SOURCES/0225-journald-fixed-assertion-failure-when-system-journal.patch
deleted file mode 100644
index ff2e481..0000000
--- a/SOURCES/0225-journald-fixed-assertion-failure-when-system-journal.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 7fdcc0e9cc7f047a778a2f1776d2398f46c6ac86 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Renaud=20M=C3=A9trich?=
- <1163635+rmetrich@users.noreply.github.com>
-Date: Mon, 3 Sep 2018 05:42:39 +0200
-Subject: [PATCH] journald: fixed assertion failure when system journal
- rotation fails (#9893)
-
-(cherry picked from commit fd790d6f09b10a87b007b71403cb018f18ff91c9)
-(cherry picked from commit 33aa231f5bf3335cdacfb38ffba757865019ce4d)
-Related: #1781712
----
- src/journal/journald-server.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index 8de45552f6..f2d2856e03 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1041,7 +1041,8 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
-         r = 0;
- 
- finish:
--        journal_file_post_change(s->system_journal);
-+        if (s->system_journal)
-+                journal_file_post_change(s->system_journal);
- 
-         s->runtime_journal = journal_file_close(s->runtime_journal);
- 
diff --git a/SOURCES/0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch b/SOURCES/0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch
new file mode 100644
index 0000000..d568e76
--- /dev/null
+++ b/SOURCES/0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch
@@ -0,0 +1,37 @@
+From 985837dab9c892858a92ae50043843307f5e0714 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Fri, 19 Jul 2019 18:29:11 +0200
+Subject: [PATCH] core: try to reopen /dev/kmsg again right after mounting /dev
+
+I was debugging stuff during early boot, and was confused that I never
+found the logs for it in kmsg. The reason for that was that /proc is
+generally not mounted the first time we do log_open() and hence
+log_set_target(LOG_TARGET_KMSG) we do when running as PID 1 had not
+effect. A lot later during start-up we call log_open() again where this
+is fixed (after the point where we close all remaining fds still open),
+but in the meantime no logs every got written to kmsg. This patch fixes
+that.
+
+(cherry picked from commit 0a2eef1ee1fef74be9d12f7dc4d0006b645b579c)
+
+Resolves: #1749212
+---
+ src/core/main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 44dd8348be..af7b26d6f1 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -2215,6 +2215,11 @@ int main(int argc, char *argv[]) {
+                                         goto finish;
+                                 }
+ 
++                                /* Let's open the log backend a second time, in case the first time didn't
++                                 * work. Quite possibly we have mounted /dev just now, so /dev/kmsg became
++                                 * available, and it previously wasn't. */
++                                log_open();
++
+                                 r = initialize_security(
+                                                 &loaded_policy,
+                                                 &security_start_timestamp,
diff --git a/SOURCES/0226-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch b/SOURCES/0226-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
deleted file mode 100644
index 57d7275..0000000
--- a/SOURCES/0226-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 9896fd236594fba4c2288ab33884f23a709565ab Mon Sep 17 00:00:00 2001
-From: Frantisek Sumsal <frantisek@sumsal.cz>
-Date: Fri, 15 Mar 2019 10:05:33 +0100
-Subject: [PATCH] test: use PBKDF2 instead of Argon2 in cryptsetup...
-
-to reduce memory requirements for volume manipulation. Also,
-to further improve the test performance, reduce number of PBKDF
-iterations to 1000 (allowed minimum).
-
-(cherry picked from commit 5b69d297c153478f6f5e74ba66e1f4e5b6422baf)
-(cherry picked from commit a7f18f9ef4abc7e0732d1710ead2a18a38c3ec6d)
-Related: #1781712
----
- test/TEST-02-CRYPTSETUP/test.sh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
-index 545602e17a..c38e56f72e 100755
---- a/test/TEST-02-CRYPTSETUP/test.sh
-+++ b/test/TEST-02-CRYPTSETUP/test.sh
-@@ -29,7 +29,7 @@ check_result_qemu() {
- test_setup() {
-     create_empty_image
-     echo -n test >$TESTDIR/keyfile
--    cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile
-+    cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile
-     cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
-     mkfs.ext4 -L var /dev/mapper/varcrypt
-     mkdir -p $TESTDIR/root
diff --git a/SOURCES/0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch b/SOURCES/0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch
new file mode 100644
index 0000000..d305484
--- /dev/null
+++ b/SOURCES/0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch
@@ -0,0 +1,29 @@
+From 9f259b46b760b2aa08ac1fe76fe61df514e2768f Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Tue, 3 Sep 2019 10:05:42 +0200
+Subject: [PATCH] buildsys: don't garbage collect sections while linking
+
+gc-sections is actually very aggressive and garbage collects ELF
+sections used by annobin gcc plugin and annocheck then reports gaps in
+coverage. Let's drop that linker flag.
+
+RHEL-only
+
+Resolves: #1748258
+---
+ meson.build | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/meson.build b/meson.build
+index 04b461dcd4..613a5133b6 100644
+--- a/meson.build
++++ b/meson.build
+@@ -357,8 +357,6 @@ if get_option('buildtype') != 'debug'
+                 '-ffunction-sections',
+                 '-fdata-sections',
+         ]
+-
+-        possible_link_flags += '-Wl,--gc-sections'
+ endif
+ 
+ add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c')
diff --git a/SOURCES/0227-test-mask-several-unnecessary-services.patch b/SOURCES/0227-test-mask-several-unnecessary-services.patch
deleted file mode 100644
index d1a4f13..0000000
--- a/SOURCES/0227-test-mask-several-unnecessary-services.patch
+++ /dev/null
@@ -1,252 +0,0 @@
-From 0b16c6baa6b24c984a1b4bcd7026172f1627fe92 Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Thu, 1 Nov 2018 17:26:36 +0900
-Subject: [PATCH] test: mask several unnecessary services
-
-This may make CIs run faster.
-
-(cherry picked from commit 056ae88152a722bdbea54ff33db815d585c8b9c6)
-(cherry picked from commit c748b95f5a00b6d9c46026c3d251c40437e6b64a)
-Related: #1781712
----
- test/TEST-02-CRYPTSETUP/test.sh    | 8 ++++++++
- test/TEST-03-JOBS/test.sh          | 8 ++++++++
- test/TEST-04-JOURNAL/test.sh       | 8 ++++++++
- test/TEST-05-RLIMITS/test.sh       | 8 ++++++++
- test/TEST-07-ISSUE-1981/test.sh    | 8 ++++++++
- test/TEST-11-ISSUE-3166/test.sh    | 8 ++++++++
- test/TEST-12-ISSUE-3171/test.sh    | 8 ++++++++
- test/TEST-13-NSPAWN-SMOKE/test.sh  | 8 ++++++++
- test/TEST-18-FAILUREACTION/test.sh | 7 +++++++
- test/TEST-19-DELEGATE/test.sh      | 8 ++++++++
- test/TEST-20-MAINPIDGAMES/test.sh  | 8 ++++++++
- test/TEST-23-TYPE-EXEC/test.sh     | 8 ++++++++
- 12 files changed, 95 insertions(+)
-
-diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
-index c38e56f72e..97eb2f409e 100755
---- a/test/TEST-02-CRYPTSETUP/test.sh
-+++ b/test/TEST-02-CRYPTSETUP/test.sh
-@@ -45,6 +45,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-03-JOBS/test.sh b/test/TEST-03-JOBS/test.sh
-index 08e5cfe6c8..93a387df59 100755
---- a/test/TEST-03-JOBS/test.sh
-+++ b/test/TEST-03-JOBS/test.sh
-@@ -19,6 +19,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh
-index 30e7b181b2..80e5fb0a73 100755
---- a/test/TEST-04-JOURNAL/test.sh
-+++ b/test/TEST-04-JOURNAL/test.sh
-@@ -18,6 +18,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-05-RLIMITS/test.sh b/test/TEST-05-RLIMITS/test.sh
-index a1b855c5fb..711f87f585 100755
---- a/test/TEST-05-RLIMITS/test.sh
-+++ b/test/TEST-05-RLIMITS/test.sh
-@@ -18,6 +18,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         cat >$initdir/etc/systemd/system.conf <<EOF
- [Manager]
- DefaultLimitNOFILE=10000:16384
-diff --git a/test/TEST-07-ISSUE-1981/test.sh b/test/TEST-07-ISSUE-1981/test.sh
-index 88d143e479..8d3ed04712 100755
---- a/test/TEST-07-ISSUE-1981/test.sh
-+++ b/test/TEST-07-ISSUE-1981/test.sh
-@@ -21,6 +21,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh
-index 8aae4d5ed9..e6e96101aa 100755
---- a/test/TEST-11-ISSUE-3166/test.sh
-+++ b/test/TEST-11-ISSUE-3166/test.sh
-@@ -20,6 +20,14 @@ test_setup() {
-         setup_basic_environment
-         dracut_install false touch
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
-index 559fa469cd..915cc21cd8 100755
---- a/test/TEST-12-ISSUE-3171/test.sh
-+++ b/test/TEST-12-ISSUE-3171/test.sh
-@@ -20,6 +20,14 @@ test_setup() {
-         setup_basic_environment
-         dracut_install cat mv stat nc
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
-index a676384bfc..cec59fa24d 100755
---- a/test/TEST-13-NSPAWN-SMOKE/test.sh
-+++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
-@@ -20,6 +20,14 @@ test_setup() {
-         setup_basic_environment
-         dracut_install busybox chmod rmdir unshare ip sysctl
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         cp create-busybox-container $initdir/
- 
-         ./create-busybox-container $initdir/nc-container
-diff --git a/test/TEST-18-FAILUREACTION/test.sh b/test/TEST-18-FAILUREACTION/test.sh
-index e48ba9bac3..783b3aac6e 100755
---- a/test/TEST-18-FAILUREACTION/test.sh
-+++ b/test/TEST-18-FAILUREACTION/test.sh
-@@ -35,6 +35,13 @@ EOF
-     ) || return 1
-     setup_nspawn_root
- 
-+    # mask some services that we do not want to run in these tests
-+    ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+    ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+    ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+
-     ddebug "umount $TESTDIR/root"
-     umount $TESTDIR/root
- }
-diff --git a/test/TEST-19-DELEGATE/test.sh b/test/TEST-19-DELEGATE/test.sh
-index 841a29c06f..ef1d99932a 100755
---- a/test/TEST-19-DELEGATE/test.sh
-+++ b/test/TEST-19-DELEGATE/test.sh
-@@ -20,6 +20,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-20-MAINPIDGAMES/test.sh b/test/TEST-20-MAINPIDGAMES/test.sh
-index b14083a256..4ec8081478 100755
---- a/test/TEST-20-MAINPIDGAMES/test.sh
-+++ b/test/TEST-20-MAINPIDGAMES/test.sh
-@@ -17,6 +17,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
-diff --git a/test/TEST-23-TYPE-EXEC/test.sh b/test/TEST-23-TYPE-EXEC/test.sh
-index bdcea239a7..2e76451f5b 100755
---- a/test/TEST-23-TYPE-EXEC/test.sh
-+++ b/test/TEST-23-TYPE-EXEC/test.sh
-@@ -17,6 +17,14 @@ test_setup() {
- 
-         setup_basic_environment
- 
-+        # mask some services that we do not want to run in these tests
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
-+        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
-+
-         # setup the testsuite service
-         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
- [Unit]
diff --git a/SOURCES/0228-test-bump-the-second-partition-s-size-to-50M.patch b/SOURCES/0228-test-bump-the-second-partition-s-size-to-50M.patch
deleted file mode 100644
index b91afd7..0000000
--- a/SOURCES/0228-test-bump-the-second-partition-s-size-to-50M.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 3b7b7d44d8175751fe6da24e5e300196e9d11c4d Mon Sep 17 00:00:00 2001
-From: Frantisek Sumsal <fsumsal@redhat.com>
-Date: Mon, 21 Oct 2019 18:39:39 +0200
-Subject: [PATCH] test: bump the second partition's size to 50M
-
-The former size (10M) caused systemd-journald to crash with SIGABRT when
-used on a LUKS2 partition, as the LUKS2 metadata consume a significant
-part of the 10M partition, thus leaving no space for the journal file
-itself (relevant for TEST-02-CRYPTSETUP). This change has been present
-in upstream for a while anyway.
-
-rhel-only
-
-(cherry picked from commit 27d1acaa1d4c9299db461f0f1922c573be6a52c0)
-Related: #1781712
----
- test/test-functions | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/test/test-functions b/test/test-functions
-index af9d16140f..fe25a501da 100644
---- a/test/test-functions
-+++ b/test/test-functions
-@@ -433,7 +433,7 @@ create_empty_image() {
-     [ -b "$LOOPDEV" ] || return 1
-     echo "LOOPDEV=$LOOPDEV" >> $STATEFILE
-     sfdisk "$LOOPDEV" <<EOF
--,390M
-+,350M
- ,
- EOF
- 
diff --git a/SOURCES/0228-udev-introduce-CONST-key-name.patch b/SOURCES/0228-udev-introduce-CONST-key-name.patch
new file mode 100644
index 0000000..127eea3
--- /dev/null
+++ b/SOURCES/0228-udev-introduce-CONST-key-name.patch
@@ -0,0 +1,186 @@
+From d6210c3d053d70175d72ed1d1719497eed76000b Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Thu, 17 Oct 2019 09:37:35 +0200
+Subject: [PATCH] udev: introduce CONST key name
+
+Currently, there is no way to match against system-wide constants, such
+as architecture or virtualization type, without forking helper binaries.
+That potentially results in a huge number of spawned processes which
+output always the same answer.
+
+This patch introduces a special CONST keyword which takes a hard-coded
+string as its key and returns a value assigned to that key. Currently
+implemented are CONST{arch} and CONST{virt}, which can be used to match
+against the system's architecture and virtualization type.
+
+(based on commit 4801d8afe2ff1c1c075c9f0bc5631612172e0bb7)
+
+Resolves: #1762679
+---
+ man/udev.xml              | 26 ++++++++++++++++++++++++++
+ rules/40-redhat.rules     |  6 +++---
+ src/udev/udev-rules.c     | 32 ++++++++++++++++++++++++++++++++
+ test/rule-syntax-check.py |  2 +-
+ 4 files changed, 62 insertions(+), 4 deletions(-)
+
+diff --git a/man/udev.xml b/man/udev.xml
+index bdf901a8f0..8c1eb41787 100644
+--- a/man/udev.xml
++++ b/man/udev.xml
+@@ -236,6 +236,32 @@
+           </listitem>
+         </varlistentry>
+ 
++        <varlistentry>
++          <term><varname>CONST{<replaceable>key</replaceable>}</varname></term>
++          <listitem>
++            <para>Match against a system-wide constant. Supported keys are:</para>
++            <variablelist>
++              <varlistentry>
++                <term><literal>arch</literal></term>
++                <listitem>
++                  <para>System's architecture. See <option>ConditionArchitecture=</option> in
++                  <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
++                  for possible values.</para>
++                </listitem>
++              </varlistentry>
++              <varlistentry>
++                <term><literal>virt</literal></term>
++                <listitem>
++                  <para>System's virtualization environment. See
++                  <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                  for possible values.</para>
++                </listitem>
++              </varlistentry>
++            </variablelist>
++            <para>Unknown keys will never match.</para>
++          </listitem>
++        </varlistentry>
++
+         <varlistentry>
+           <term><varname>TAG</varname></term>
+           <listitem>
+diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
+index fadc6e59f1..3c95cd2df0 100644
+--- a/rules/40-redhat.rules
++++ b/rules/40-redhat.rules
+@@ -6,11 +6,11 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}
+ # Memory hotadd request
+ SUBSYSTEM!="memory", GOTO="memory_hotplug_end"
+ ACTION!="add", GOTO="memory_hotplug_end"
+-PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
+-PROGRAM="/bin/uname -p", RESULT=="ppc64*", GOTO="memory_hotplug_end"
++CONST{arch}=="s390*", GOTO="memory_hotplug_end"
++CONST{arch}=="ppc64*", GOTO="memory_hotplug_end"
+ 
+ ENV{.state}="online"
+-PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
++CONST{virt}=="none", ENV{.state}="online_movable"
+ ATTR{state}=="offline", ATTR{state}="$env{.state}"
+ 
+ LABEL="memory_hotplug_end"
+diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
+index 58af863f3d..a246cbe67e 100644
+--- a/src/udev/udev-rules.c
++++ b/src/udev/udev-rules.c
+@@ -17,6 +17,7 @@
+ #include <unistd.h>
+ 
+ #include "alloc-util.h"
++#include "architecture.h"
+ #include "conf-files.h"
+ #include "dirent-util.h"
+ #include "escape.h"
+@@ -34,6 +35,7 @@
+ #include "udev.h"
+ #include "user-util.h"
+ #include "util.h"
++#include "virt.h"
+ 
+ #define PREALLOC_TOKEN          2048
+ 
+@@ -123,6 +125,7 @@ enum token_type {
+         TK_M_DEVLINK,                   /* val */
+         TK_M_NAME,                      /* val */
+         TK_M_ENV,                       /* val, attr */
++        TK_M_CONST,                     /* val, attr */
+         TK_M_TAG,                       /* val */
+         TK_M_SUBSYSTEM,                 /* val */
+         TK_M_DRIVER,                    /* val */
+@@ -259,6 +262,7 @@ static const char *token_str(enum token_type type) {
+                 [TK_M_DEVLINK] =                "M DEVLINK",
+                 [TK_M_NAME] =                   "M NAME",
+                 [TK_M_ENV] =                    "M ENV",
++                [TK_M_CONST] =                  "M CONST",
+                 [TK_M_TAG] =                    "M TAG",
+                 [TK_M_SUBSYSTEM] =              "M SUBSYSTEM",
+                 [TK_M_DRIVER] =                 "M DRIVER",
+@@ -370,6 +374,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
+         case TK_M_SYSCTL:
+         case TK_M_ATTRS:
+         case TK_M_ENV:
++        case TK_M_CONST:
+         case TK_A_ATTR:
+         case TK_A_SYSCTL:
+         case TK_A_ENV:
+@@ -903,6 +908,7 @@ static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
+                 token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
+                 break;
+         case TK_M_ENV:
++        case TK_M_CONST:
+         case TK_M_ATTR:
+         case TK_M_SYSCTL:
+         case TK_M_ATTRS:
+@@ -1226,6 +1232,17 @@ static void add_rule(struct udev_rules *rules, char *line,
+                                 rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr);
+                         }
+ 
++                } else if (startswith(key, "CONST{")) {
++                        attr = get_key_attribute(rules->udev, key + STRLEN("CONST"));
++                        if (attr == NULL || !STR_IN_SET(attr, "arch", "virt"))
++                                LOG_AND_RETURN("error parsing %s attribute", "CONST");
++
++                        if (op == OP_REMOVE)
++                                LOG_AND_RETURN("invalid %s operation", "CONST");
++
++                        if (op < OP_MATCH_MAX)
++                                rule_add_key(&rule_tmp, TK_M_CONST, op, value, attr);
++
+                 } else if (streq(key, "TAG")) {
+                         if (op < OP_MATCH_MAX)
+                                 rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
+@@ -1855,6 +1872,21 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
+                                 goto nomatch;
+                         break;
+                 }
++                case TK_M_CONST: {
++                        const char *key_name = rules_str(rules, cur->key.attr_off);
++                        const char *value = NULL;
++
++                        if (streq(key_name, "arch")) {
++                                value = architecture_to_string(uname_architecture());
++                        } else if (streq(key_name, "virt")) {
++                                value = virtualization_to_string(detect_virtualization());
++                        } else
++                                assert_not_reached("Invalid CONST key");
++
++                        if (match_key(rules, cur, value))
++                                goto nomatch;
++                        break;
++                }
+                 case TK_M_TAG: {
+                         struct udev_list_entry *list_entry;
+                         bool match = false;
+diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
+index c7c0a1a656..6e59f421f5 100755
+--- a/test/rule-syntax-check.py
++++ b/test/rule-syntax-check.py
+@@ -19,7 +19,7 @@ quoted_string_re = r'"(?:[^\\"]|\\.)*"'
+ no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
+ # PROGRAM can also be specified as an assignment.
+ program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$')
+-args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
++args_tests = re.compile(r'(ATTRS?|ENV|CONST|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
+ no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
+ args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
+ # Find comma-separated groups, but allow commas that are inside quoted strings.
diff --git a/SOURCES/0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch b/SOURCES/0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch
new file mode 100644
index 0000000..655f32a
--- /dev/null
+++ b/SOURCES/0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch
@@ -0,0 +1,50 @@
+From e1bd03e75860fb349a6de589bbb1274acc454aef Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
+Date: Fri, 13 Sep 2019 11:18:18 +0200
+Subject: [PATCH] Call getgroups() to know size of supplementary groups array
+ to allocate
+
+Resolves RHBZ #1743230 - journalctl dumps core when stack limit is reduced to 256 KB
+
+(cherry picked from commit f5e0b942af1e86993c21f4e5c84342bb10403dac)
+
+Resolves: #1743235
+---
+ src/basic/user-util.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/src/basic/user-util.c b/src/basic/user-util.c
+index a562a397c7..c533f67025 100644
+--- a/src/basic/user-util.c
++++ b/src/basic/user-util.c
+@@ -358,9 +358,8 @@ char* gid_to_name(gid_t gid) {
+ }
+ 
+ int in_gid(gid_t gid) {
+-        long ngroups_max;
+         gid_t *gids;
+-        int r, i;
++        int ngroups, r, i;
+ 
+         if (getgid() == gid)
+                 return 1;
+@@ -371,12 +370,15 @@ int in_gid(gid_t gid) {
+         if (!gid_is_valid(gid))
+                 return -EINVAL;
+ 
+-        ngroups_max = sysconf(_SC_NGROUPS_MAX);
+-        assert(ngroups_max > 0);
++        ngroups = getgroups(0, NULL);
++        if (ngroups < 0)
++                return -errno;
++        if (ngroups == 0)
++                return 0;
+ 
+-        gids = newa(gid_t, ngroups_max);
++        gids = newa(gid_t, ngroups);
+ 
+-        r = getgroups(ngroups_max, gids);
++        r = getgroups(ngroups, gids);
+         if (r < 0)
+                 return -errno;
+ 
diff --git a/SOURCES/0229-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch b/SOURCES/0229-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch
deleted file mode 100644
index 86ad50c..0000000
--- a/SOURCES/0229-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From a115123d009dde9bcaf508eea066934459940348 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 18:13:03 +0100
-Subject: [PATCH] sd-bus: make rqueue/wqueue sizes of type size_t
-
-Let's do this like we usually do and size arrays with size_t.
-
-We already do this for the "allocated" counter correctly, and externally
-we expose the queue sizes as uint64_t anyway, hence there's really no
-point in usigned "unsigned" internally.
-
-(cherry picked from commit 143d4e045a798ccc87889b2a8a60d7fbe44be441)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/bus-internal.h | 4 ++--
- src/libsystemd/sd-bus/sd-bus.c       | 2 +-
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
-index 90e6028983..2d21319df5 100644
---- a/src/libsystemd/sd-bus/bus-internal.h
-+++ b/src/libsystemd/sd-bus/bus-internal.h
-@@ -221,11 +221,11 @@ struct sd_bus {
-         size_t rbuffer_size;
- 
-         sd_bus_message **rqueue;
--        unsigned rqueue_size;
-+        size_t rqueue_size;
-         size_t rqueue_allocated;
- 
-         sd_bus_message **wqueue;
--        unsigned wqueue_size;
-+        size_t wqueue_size;
-         size_t windex;
-         size_t wqueue_allocated;
- 
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index 1c9e967ae0..64026f7ee1 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -2080,7 +2080,7 @@ _public_ int sd_bus_call(
-         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
-         usec_t timeout;
-         uint64_t cookie;
--        unsigned i;
-+        size_t i;
-         int r;
- 
-         bus_assert_return(m, -EINVAL, error);
diff --git a/SOURCES/0230-Consider-smb3-as-remote-filesystem.patch b/SOURCES/0230-Consider-smb3-as-remote-filesystem.patch
new file mode 100644
index 0000000..691f180
--- /dev/null
+++ b/SOURCES/0230-Consider-smb3-as-remote-filesystem.patch
@@ -0,0 +1,30 @@
+From 1bf923686a6842f222b1ef5f5174511340c75685 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Tue, 1 Oct 2019 08:45:08 +0200
+Subject: [PATCH] Consider smb3 as remote filesystem
+
+Currently systemd will treat smb3 as local filesystem and cause
+can't boot failures. Add smb3 to the list of remote filesystems
+to fix this issue.
+
+Signed-off-by: Kenneth D'souza <kdsouza@redhat.com>
+
+(cherry picked from commit ff7d6a740b0c6fa3be63d3908a0858730a0837c5)
+
+Resolves: #1757257
+---
+ src/basic/mount-util.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
+index 3670b7f591..5b04e21f34 100644
+--- a/src/basic/mount-util.c
++++ b/src/basic/mount-util.c
+@@ -603,6 +603,7 @@ bool fstype_is_network(const char *fstype) {
+         return STR_IN_SET(fstype,
+                           "afs",
+                           "cifs",
++                          "smb3",
+                           "smbfs",
+                           "sshfs",
+                           "ncpfs",
diff --git a/SOURCES/0230-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch b/SOURCES/0230-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch
deleted file mode 100644
index 0074f56..0000000
--- a/SOURCES/0230-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 90dedb47d2cb060a366d12bf467f03fa20c5ed24 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 18:14:17 +0100
-Subject: [PATCH] sd-bus: reorder bus ref and bus message ref handling
-
-Let's always place handling of these references together, so that all
-reference counting during allocation is at a single place.
-
-(cherry picked from commit e593b6a87a335267e5f7238b14683b7f840a01a3)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/bus-message.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
-index 53cbd675b7..2ea3c5bba9 100644
---- a/src/libsystemd/sd-bus/bus-message.c
-+++ b/src/libsystemd/sd-bus/bus-message.c
-@@ -461,7 +461,6 @@ int bus_message_from_header(
-         if (!m)
-                 return -ENOMEM;
- 
--        m->n_ref = 1;
-         m->sealed = true;
-         m->header = header;
-         m->header_accessible = header_accessible;
-@@ -515,7 +514,9 @@ int bus_message_from_header(
-                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
-         }
- 
-+        m->n_ref = 1;
-         m->bus = sd_bus_ref(bus);
-+
-         *ret = TAKE_PTR(m);
- 
-         return 0;
-@@ -588,13 +589,13 @@ _public_ int sd_bus_message_new(
-                 return -ENOMEM;
- 
-         t->n_ref = 1;
-+        t->bus = sd_bus_ref(bus);
-         t->header = (struct bus_header*) ((uint8_t*) t + ALIGN(sizeof(struct sd_bus_message)));
-         t->header->endian = BUS_NATIVE_ENDIAN;
-         t->header->type = type;
-         t->header->version = bus->message_version;
-         t->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING);
-         t->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(t);
--        t->bus = sd_bus_ref(bus);
- 
-         if (bus->allow_interactive_authorization)
-                 t->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
diff --git a/SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch b/SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch
new file mode 100644
index 0000000..5d740cf
--- /dev/null
+++ b/SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch
@@ -0,0 +1,114 @@
+From f057aa6bb604845fa10ad569bca306e5e1e8fe0d Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Mon, 18 Mar 2019 11:48:34 +0100
+Subject: [PATCH] process-util: introduce pid_is_my_child() helper
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+No functional changes.
+
+Thanks Renaud Métrich for backporting this to RHEL.
+Resolves: #1744972
+---
+ src/basic/process-util.c | 14 ++++++++++++++
+ src/basic/process-util.h |  1 +
+ src/core/cgroup.c        |  7 ++-----
+ src/core/service.c       |  8 ++------
+ 4 files changed, 19 insertions(+), 11 deletions(-)
+
+diff --git a/src/basic/process-util.c b/src/basic/process-util.c
+index aa3eff779a..6dbeee9dda 100644
+--- a/src/basic/process-util.c
++++ b/src/basic/process-util.c
+@@ -903,6 +903,20 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
+         return 0;
+ }
+ 
++int pid_is_my_child(pid_t pid) {
++        pid_t ppid;
++        int r;
++
++        if (pid <= 1)
++                return false;
++
++        r = get_process_ppid(pid, &ppid);
++        if (r < 0)
++                return r;
++
++        return ppid == getpid_cached();
++}
++
+ bool pid_is_unwaited(pid_t pid) {
+         /* Checks whether a PID is still valid at all, including a zombie */
+ 
+diff --git a/src/basic/process-util.h b/src/basic/process-util.h
+index a5bb072b25..a3bd2851b4 100644
+--- a/src/basic/process-util.h
++++ b/src/basic/process-util.h
+@@ -68,6 +68,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value);
+ 
+ bool pid_is_alive(pid_t pid);
+ bool pid_is_unwaited(pid_t pid);
++int pid_is_my_child(pid_t pid);
+ int pid_from_same_root_fs(pid_t pid);
+ 
+ bool is_main_thread(void);
+diff --git a/src/core/cgroup.c b/src/core/cgroup.c
+index 62ab41a288..b7ed07e65b 100644
+--- a/src/core/cgroup.c
++++ b/src/core/cgroup.c
+@@ -1876,7 +1876,7 @@ void unit_prune_cgroup(Unit *u) {
+ 
+ int unit_search_main_pid(Unit *u, pid_t *ret) {
+         _cleanup_fclose_ FILE *f = NULL;
+-        pid_t pid = 0, npid, mypid;
++        pid_t pid = 0, npid;
+         int r;
+ 
+         assert(u);
+@@ -1889,15 +1889,12 @@ int unit_search_main_pid(Unit *u, pid_t *ret) {
+         if (r < 0)
+                 return r;
+ 
+-        mypid = getpid_cached();
+         while (cg_read_pid(f, &npid) > 0)  {
+-                pid_t ppid;
+ 
+                 if (npid == pid)
+                         continue;
+ 
+-                /* Ignore processes that aren't our kids */
+-                if (get_process_ppid(npid, &ppid) >= 0 && ppid != mypid)
++                if (pid_is_my_child(npid) == 0)
+                         continue;
+ 
+                 if (pid != 0)
+diff --git a/src/core/service.c b/src/core/service.c
+index 24f167572a..614ba05d89 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -139,8 +139,6 @@ static void service_unwatch_pid_file(Service *s) {
+ }
+ 
+ static int service_set_main_pid(Service *s, pid_t pid) {
+-        pid_t ppid;
+-
+         assert(s);
+ 
+         if (pid <= 1)
+@@ -159,12 +157,10 @@ static int service_set_main_pid(Service *s, pid_t pid) {
+ 
+         s->main_pid = pid;
+         s->main_pid_known = true;
++        s->main_pid_alien = pid_is_my_child(pid) == 0;
+ 
+-        if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid_cached()) {
++        if (s->main_pid_alien)
+                 log_unit_warning(UNIT(s), "Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", pid);
+-                s->main_pid_alien = true;
+-        } else
+-                s->main_pid_alien = false;
+ 
+         return 0;
+ }
diff --git a/SOURCES/0231-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch b/SOURCES/0231-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch
deleted file mode 100644
index fbd6a7f..0000000
--- a/SOURCES/0231-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From d2725078f0da567eb2bcae3bef53f013d7fa3ba5 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 18:15:37 +0100
-Subject: [PATCH] sd-bus: make sure dispatch_rqueue() initializes return
- parameter on all types of success
-
-Let's make sure our own code follows coding style and initializes all
-return values on all types of success (and leaves it uninitialized in
-all types of failure).
-
-(cherry picked from commit c0bc4ec5cc17ac61773d1e9362b0ffa8382c1ff1)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/sd-bus.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index 64026f7ee1..55b008cc9f 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -1814,8 +1814,10 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd
-                 r = bus_read_message(bus, hint_priority, priority);
-                 if (r < 0)
-                         return r;
--                if (r == 0)
-+                if (r == 0) {
-+                        *m = NULL;
-                         return ret;
-+                }
- 
-                 ret = 1;
-         }
diff --git a/SOURCES/0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch b/SOURCES/0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch
new file mode 100644
index 0000000..46cf59e
--- /dev/null
+++ b/SOURCES/0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch
@@ -0,0 +1,323 @@
+From 79e9566ec0a61d887ab63f17192dbd71aae36ee0 Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Mon, 18 Mar 2019 20:59:36 +0100
+Subject: [PATCH] core: reduce the number of stalled PIDs from the watched
+ processes list when possible
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some PIDs can remain in the watched list even though their processes have
+exited since a long time. It can easily happen if the main process of a forking
+service manages to spawn a child before the control process exits for example.
+
+However when a pid is about to be mapped to a unit by calling unit_watch_pid(),
+the caller usually knows if the pid should belong to this unit exclusively: if
+we just forked() off a child, then we can be sure that its PID is otherwise
+unused. In this case we take this opportunity to remove any stalled PIDs from
+the watched process list.
+
+If we learnt about a PID in any other form (for example via PID file, via
+searching, MAINPID= and so on), then we can't assume anything.
+
+Thanks Renaud Métrich for backporting this to RHEL.
+Resolves: #1744972
+---
+ src/core/cgroup.c         |  2 +-
+ src/core/dbus-scope.c     |  2 +-
+ src/core/manager.c        | 10 ++++++++++
+ src/core/manager.h        |  2 ++
+ src/core/mount.c          |  5 ++---
+ src/core/service.c        | 16 ++++++++--------
+ src/core/socket.c         |  7 +++----
+ src/core/swap.c           |  5 ++---
+ src/core/unit.c           |  8 +++++++-
+ src/core/unit.h           |  2 +-
+ src/test/test-watch-pid.c | 12 ++++++------
+ 11 files changed, 43 insertions(+), 28 deletions(-)
+
+diff --git a/src/core/cgroup.c b/src/core/cgroup.c
+index b7ed07e65b..76eafdc082 100644
+--- a/src/core/cgroup.c
++++ b/src/core/cgroup.c
+@@ -1926,7 +1926,7 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) {
+                 pid_t pid;
+ 
+                 while ((r = cg_read_pid(f, &pid)) > 0) {
+-                        r = unit_watch_pid(u, pid);
++                        r = unit_watch_pid(u, pid, false);
+                         if (r < 0 && ret >= 0)
+                                 ret = r;
+                 }
+diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
+index 6725f62794..0bbf64fff1 100644
+--- a/src/core/dbus-scope.c
++++ b/src/core/dbus-scope.c
+@@ -106,7 +106,7 @@ static int bus_scope_set_transient_property(
+                                 return r;
+ 
+                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+-                                r = unit_watch_pid(UNIT(s), pid);
++                                r = unit_watch_pid(UNIT(s), pid, false);
+                                 if (r < 0 && r != -EEXIST)
+                                         return r;
+                         }
+diff --git a/src/core/manager.c b/src/core/manager.c
+index c83e296cf3..0eae7d46fb 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -2044,6 +2044,16 @@ void manager_clear_jobs(Manager *m) {
+                 job_finish_and_invalidate(j, JOB_CANCELED, false, false);
+ }
+ 
++void manager_unwatch_pid(Manager *m, pid_t pid) {
++        assert(m);
++
++        /* First let's drop the unit keyed as "pid". */
++        (void) hashmap_remove(m->watch_pids, PID_TO_PTR(pid));
++
++        /* Then, let's also drop the array keyed by -pid. */
++        free(hashmap_remove(m->watch_pids, PID_TO_PTR(-pid)));
++}
++
+ static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
+         Manager *m = userdata;
+         Job *j;
+diff --git a/src/core/manager.h b/src/core/manager.h
+index c7f4d66ecd..fa47952d24 100644
+--- a/src/core/manager.h
++++ b/src/core/manager.h
+@@ -406,6 +406,8 @@ int manager_get_dump_string(Manager *m, char **ret);
+ 
+ void manager_clear_jobs(Manager *m);
+ 
++void manager_unwatch_pid(Manager *m, pid_t pid);
++
+ unsigned manager_dispatch_load_queue(Manager *m);
+ 
+ int manager_environment_add(Manager *m, char **minus, char **plus);
+diff --git a/src/core/mount.c b/src/core/mount.c
+index 2ac04e3874..5878814b1b 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -677,7 +677,7 @@ static int mount_coldplug(Unit *u) {
+             pid_is_unwaited(m->control_pid) &&
+             MOUNT_STATE_WITH_PROCESS(new_state)) {
+ 
+-                r = unit_watch_pid(UNIT(m), m->control_pid);
++                r = unit_watch_pid(UNIT(m), m->control_pid, false);
+                 if (r < 0)
+                         return r;
+ 
+@@ -781,9 +781,8 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
+         if (r < 0)
+                 return r;
+ 
+-        r = unit_watch_pid(UNIT(m), pid);
++        r = unit_watch_pid(UNIT(m), pid, true);
+         if (r < 0)
+-                /* FIXME: we need to do something here */
+                 return r;
+ 
+         *_pid = pid;
+diff --git a/src/core/service.c b/src/core/service.c
+index 614ba05d89..310838a5f6 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -974,7 +974,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
+         if (r < 0)
+                 return r;
+ 
+-        r = unit_watch_pid(UNIT(s), pid);
++        r = unit_watch_pid(UNIT(s), pid, false);
+         if (r < 0) /* FIXME: we need to do something here */
+                 return log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" for service: %m", pid);
+ 
+@@ -1004,7 +1004,7 @@ static void service_search_main_pid(Service *s) {
+         if (service_set_main_pid(s, pid) < 0)
+                 return;
+ 
+-        r = unit_watch_pid(UNIT(s), pid);
++        r = unit_watch_pid(UNIT(s), pid, false);
+         if (r < 0)
+                 /* FIXME: we need to do something here */
+                 log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" from: %m", pid);
+@@ -1135,7 +1135,7 @@ static int service_coldplug(Unit *u) {
+                     SERVICE_RUNNING, SERVICE_RELOAD,
+                     SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
+-                r = unit_watch_pid(UNIT(s), s->main_pid);
++                r = unit_watch_pid(UNIT(s), s->main_pid, false);
+                 if (r < 0)
+                         return r;
+         }
+@@ -1147,7 +1147,7 @@ static int service_coldplug(Unit *u) {
+                    SERVICE_RELOAD,
+                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
+-                r = unit_watch_pid(UNIT(s), s->control_pid);
++                r = unit_watch_pid(UNIT(s), s->control_pid, false);
+                 if (r < 0)
+                         return r;
+         }
+@@ -1545,8 +1545,8 @@ static int service_spawn(
+         s->exec_fd_event_source = TAKE_PTR(exec_fd_source);
+         s->exec_fd_hot = false;
+ 
+-        r = unit_watch_pid(UNIT(s), pid);
+-        if (r < 0) /* FIXME: we need to do something here */
++        r = unit_watch_pid(UNIT(s), pid, true);
++        if (r < 0)
+                 return r;
+ 
+         *_pid = pid;
+@@ -3643,7 +3643,7 @@ static void service_notify_message(
+                         }
+                         if (r > 0) {
+                                 service_set_main_pid(s, new_main_pid);
+-                                unit_watch_pid(UNIT(s), new_main_pid);
++                                unit_watch_pid(UNIT(s), new_main_pid, false);
+                                 notify_dbus = true;
+                         }
+                 }
+@@ -3858,7 +3858,7 @@ static void service_bus_name_owner_change(
+                         log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, name, pid);
+ 
+                         service_set_main_pid(s, pid);
+-                        unit_watch_pid(UNIT(s), pid);
++                        unit_watch_pid(UNIT(s), pid, false);
+                 }
+         }
+ }
+diff --git a/src/core/socket.c b/src/core/socket.c
+index d488c64e91..b034549634 100644
+--- a/src/core/socket.c
++++ b/src/core/socket.c
+@@ -1816,7 +1816,7 @@ static int socket_coldplug(Unit *u) {
+                    SOCKET_FINAL_SIGTERM,
+                    SOCKET_FINAL_SIGKILL)) {
+ 
+-                r = unit_watch_pid(UNIT(s), s->control_pid);
++                r = unit_watch_pid(UNIT(s), s->control_pid, false);
+                 if (r < 0)
+                         return r;
+ 
+@@ -1902,9 +1902,8 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
+         if (r < 0)
+                 return r;
+ 
+-        r = unit_watch_pid(UNIT(s), pid);
++        r = unit_watch_pid(UNIT(s), pid, true);
+         if (r < 0)
+-                /* FIXME: we need to do something here */
+                 return r;
+ 
+         *_pid = pid;
+@@ -1973,7 +1972,7 @@ static int socket_chown(Socket *s, pid_t *_pid) {
+                 _exit(EXIT_SUCCESS);
+         }
+ 
+-        r = unit_watch_pid(UNIT(s), pid);
++        r = unit_watch_pid(UNIT(s), pid, true);
+         if (r < 0)
+                 goto fail;
+ 
+diff --git a/src/core/swap.c b/src/core/swap.c
+index b644753a1c..e717dbb54a 100644
+--- a/src/core/swap.c
++++ b/src/core/swap.c
+@@ -531,7 +531,7 @@ static int swap_coldplug(Unit *u) {
+             pid_is_unwaited(s->control_pid) &&
+             SWAP_STATE_WITH_PROCESS(new_state)) {
+ 
+-                r = unit_watch_pid(UNIT(s), s->control_pid);
++                r = unit_watch_pid(UNIT(s), s->control_pid, false);
+                 if (r < 0)
+                         return r;
+ 
+@@ -636,9 +636,8 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
+         if (r < 0)
+                 goto fail;
+ 
+-        r = unit_watch_pid(UNIT(s), pid);
++        r = unit_watch_pid(UNIT(s), pid, true);
+         if (r < 0)
+-                /* FIXME: we need to do something here */
+                 goto fail;
+ 
+         *_pid = pid;
+diff --git a/src/core/unit.c b/src/core/unit.c
+index d298afb0d4..b0b1c77ef7 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2500,7 +2500,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
+         unit_add_to_gc_queue(u);
+ }
+ 
+-int unit_watch_pid(Unit *u, pid_t pid) {
++int unit_watch_pid(Unit *u, pid_t pid, bool exclusive) {
+         int r;
+ 
+         assert(u);
+@@ -2508,6 +2508,12 @@ int unit_watch_pid(Unit *u, pid_t pid) {
+ 
+         /* Watch a specific PID */
+ 
++        /* Caller might be sure that this PID belongs to this unit only. Let's take this
++         * opportunity to remove any stalled references to this PID as they can be created
++         * easily (when watching a process which is not our direct child). */
++        if (exclusive)
++                manager_unwatch_pid(u->manager, pid);
++
+         r = set_ensure_allocated(&u->pids, NULL);
+         if (r < 0)
+                 return r;
+diff --git a/src/core/unit.h b/src/core/unit.h
+index e1a60da244..68cc1869e4 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -655,7 +655,7 @@ typedef enum UnitNotifyFlags {
+ 
+ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags);
+ 
+-int unit_watch_pid(Unit *u, pid_t pid);
++int unit_watch_pid(Unit *u, pid_t pid, bool exclusive);
+ void unit_unwatch_pid(Unit *u, pid_t pid);
+ void unit_unwatch_all_pids(Unit *u);
+ 
+diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c
+index cb43b35bc5..8c70175aed 100644
+--- a/src/test/test-watch-pid.c
++++ b/src/test/test-watch-pid.c
+@@ -49,25 +49,25 @@ int main(int argc, char *argv[]) {
+         assert_se(hashmap_isempty(m->watch_pids));
+         assert_se(manager_get_unit_by_pid(m, 4711) == NULL);
+ 
+-        assert_se(unit_watch_pid(a, 4711) >= 0);
++        assert_se(unit_watch_pid(a, 4711, false) >= 0);
+         assert_se(manager_get_unit_by_pid(m, 4711) == a);
+ 
+-        assert_se(unit_watch_pid(a, 4711) >= 0);
++        assert_se(unit_watch_pid(a, 4711, false) >= 0);
+         assert_se(manager_get_unit_by_pid(m, 4711) == a);
+ 
+-        assert_se(unit_watch_pid(b, 4711) >= 0);
++        assert_se(unit_watch_pid(b, 4711, false) >= 0);
+         u = manager_get_unit_by_pid(m, 4711);
+         assert_se(u == a || u == b);
+ 
+-        assert_se(unit_watch_pid(b, 4711) >= 0);
++        assert_se(unit_watch_pid(b, 4711, false) >= 0);
+         u = manager_get_unit_by_pid(m, 4711);
+         assert_se(u == a || u == b);
+ 
+-        assert_se(unit_watch_pid(c, 4711) >= 0);
++        assert_se(unit_watch_pid(c, 4711, false) >= 0);
+         u = manager_get_unit_by_pid(m, 4711);
+         assert_se(u == a || u == b || u == c);
+ 
+-        assert_se(unit_watch_pid(c, 4711) >= 0);
++        assert_se(unit_watch_pid(c, 4711, false) >= 0);
+         u = manager_get_unit_by_pid(m, 4711);
+         assert_se(u == a || u == b || u == c);
+ 
diff --git a/SOURCES/0232-sd-bus-drop-two-inappropriate-empty-lines.patch b/SOURCES/0232-sd-bus-drop-two-inappropriate-empty-lines.patch
deleted file mode 100644
index 335c018..0000000
--- a/SOURCES/0232-sd-bus-drop-two-inappropriate-empty-lines.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From e81231e9a88ebc68c715010ce288c1d59c52e88f Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 18:18:18 +0100
-Subject: [PATCH] sd-bus: drop two inappropriate empty lines
-
-(cherry picked from commit 39feb2ce417e54cf9746e64b5dfd610cef6ac440)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/sd-bus.c | 2 --
- 1 file changed, 2 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index 55b008cc9f..01060d105c 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -2634,7 +2634,6 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) {
-                                 SD_BUS_ERROR_UNKNOWN_METHOD,
-                                  "Unknown method '%s' on interface '%s'.", m->member, m->interface);
-         }
--
-         if (r < 0)
-                 return r;
- 
-@@ -2758,7 +2757,6 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd
-                         return r;
- 
-                 *ret = TAKE_PTR(m);
--
-                 return 1;
-         }
- 
diff --git a/SOURCES/0233-core-only-watch-processes-when-it-s-really-necessary.patch b/SOURCES/0233-core-only-watch-processes-when-it-s-really-necessary.patch
new file mode 100644
index 0000000..058ff69
--- /dev/null
+++ b/SOURCES/0233-core-only-watch-processes-when-it-s-really-necessary.patch
@@ -0,0 +1,55 @@
+From 25b93538eba0275d35ef4b0792c2cd63d63d5e8d Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Tue, 19 Mar 2019 10:59:26 +0100
+Subject: [PATCH] core: only watch processes when it's really necessary
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If we know that main pid is our child then it's unnecessary to watch all
+other processes of a unit since in this case we will get SIGCHLD when the main
+process will exit and will act upon accordingly.
+
+So let's watch all processes only if the main process is not our child since in
+this case we need to detect when the cgroup will become empty in order to
+figure out when the service becomes dead. This is only needed by cgroupv1.
+
+Thanks Renaud Métrich for backporting this to RHEL.
+Resolves: #1744972
+---
+ src/core/service.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/src/core/service.c b/src/core/service.c
+index 310838a5f6..b1ec52d220 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -3410,8 +3410,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+                                 if (main_pid_good(s) <= 0)
+                                         service_enter_stop_post(s, f);
+ 
+-                                /* If there is still a service
+-                                 * process around, wait until
++                                /* If there is still a service process around, wait until
+                                  * that one quit, too */
+                                 break;
+ 
+@@ -3433,10 +3432,14 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+         if (notify_dbus)
+                 unit_add_to_dbus_queue(u);
+ 
+-        /* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to watch,
+-         * under the assumption that we'll sooner or later get a SIGCHLD for them, as the original process we watched
+-         * was probably the parent of them, and they are hence now our children. */
+-        (void) unit_enqueue_rewatch_pids(u);
++        /* We watch the main/control process otherwise we can't retrieve the unit they
++         * belong to with cgroupv1. But if they are not our direct child, we won't get a
++         * SIGCHLD for them. Therefore we need to look for others to watch so we can
++         * detect when the cgroup becomes empty. Note that the control process is always
++         * our child so it's pointless to watch all other processes. */
++        if (!control_pid_good(s))
++                if (!s->main_pid_known || s->main_pid_alien)
++                        (void) unit_enqueue_rewatch_pids(u);
+ }
+ 
+ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
diff --git a/SOURCES/0233-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch b/SOURCES/0233-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch
deleted file mode 100644
index 03ea861..0000000
--- a/SOURCES/0233-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From fb04f17617458d2d3d09e0bef29f1255d4d3500c Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 21:06:30 +0100
-Subject: [PATCH] sd-bus: initialize mutex after we allocated the wqueue
-
-That way the mutex doesn't have to be destroyed when we exit early due
-to OOM.
-
-(cherry picked from commit 2fe9a10d7695c4c3a748969a0d1662c624e50e5e)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/sd-bus.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index 01060d105c..e49d58137d 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -248,12 +248,12 @@ _public_ int sd_bus_new(sd_bus **ret) {
-         b->original_pid = getpid_cached();
-         b->n_groups = (size_t) -1;
- 
--        assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
--
-         /* We guarantee that wqueue always has space for at least one entry */
-         if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1))
-                 return -ENOMEM;
- 
-+        assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
-+
-         *ret = TAKE_PTR(b);
-         return 0;
- }
diff --git a/SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch b/SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch
new file mode 100644
index 0000000..a503b82
--- /dev/null
+++ b/SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch
@@ -0,0 +1,641 @@
+From a26f2b2732733aa361fec0a3a8f0ba377f48e75c Mon Sep 17 00:00:00 2001
+From: Anita Zhang <anitzhang@gmail.com>
+Date: Sun, 7 Oct 2018 20:28:36 -0700
+Subject: [PATCH] core: implement per unit journal rate limiting
+
+Add LogRateLimitIntervalSec= and LogRateLimitBurst= options for
+services. If provided, these values get passed to the journald
+client context, and those values are used in the rate limiting
+function in the journal over the the journald.conf values.
+
+Part of #10230
+
+(cherry picked from commit 90fc172e191f44979005a524521112f2bd1ff21b)
+
+Resolves: #1719577
+---
+ catalog/systemd.catalog.in                  |  3 +-
+ doc/TRANSIENT-SETTINGS.md                   |  2 +
+ man/journald.conf.xml                       |  8 +-
+ man/systemd.exec.xml                        | 16 ++++
+ src/core/dbus-execute.c                     |  8 ++
+ src/core/execute.c                          | 14 ++++
+ src/core/execute.h                          |  3 +
+ src/core/load-fragment-gperf.gperf.m4       |  2 +
+ src/core/unit.c                             | 92 +++++++++++++++++++++
+ src/core/unit.h                             |  2 +
+ src/journal/journald-context.c              | 50 ++++++++++-
+ src/journal/journald-context.h              |  3 +
+ src/journal/journald-rate-limit.c           | 38 ++++-----
+ src/journal/journald-rate-limit.h           |  4 +-
+ src/journal/journald-server.c               |  4 +-
+ src/shared/bus-unit-util.c                  |  8 ++
+ test/fuzz/fuzz-unit-file/directives.service |  2 +
+ 17 files changed, 231 insertions(+), 28 deletions(-)
+
+diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
+index f1bddc6f7d..8234e387cf 100644
+--- a/catalog/systemd.catalog.in
++++ b/catalog/systemd.catalog.in
+@@ -52,7 +52,8 @@ dropped, other services' messages are unaffected.
+ 
+ The limits controlling when messages are dropped may be configured
+ with RateLimitIntervalSec= and RateLimitBurst= in
+-/etc/systemd/journald.conf. See journald.conf(5) for details.
++/etc/systemd/journald.conf or LogRateLimitIntervalSec= and LogRateLimitBurst=
++in the unit file. See journald.conf(5) and systemd.exec(5) for details.
+ 
+ -- e9bf28e6e834481bb6f48f548ad13606
+ Subject: Journal messages have been missed
+diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md
+index ca9e8387b7..0ea444b133 100644
+--- a/doc/TRANSIENT-SETTINGS.md
++++ b/doc/TRANSIENT-SETTINGS.md
+@@ -135,6 +135,8 @@ All execution-related settings are available for transient units.
+ ✓ SyslogLevelPrefix=
+ ✓ LogLevelMax=
+ ✓ LogExtraFields=
++✓ LogRateLimitIntervalSec=
++✓ LogRateLimitBurst=
+ ✓ SecureBits=
+ ✓ CapabilityBoundingSet=
+ ✓ AmbientCapabilities=
+diff --git a/man/journald.conf.xml b/man/journald.conf.xml
+index ee8e8b7faf..b57a244b22 100644
+--- a/man/journald.conf.xml
++++ b/man/journald.conf.xml
+@@ -140,7 +140,13 @@
+         following units: <literal>s</literal>, <literal>min</literal>,
+         <literal>h</literal>, <literal>ms</literal>,
+         <literal>us</literal>. To turn off any kind of rate limiting,
+-        set either value to 0.</para></listitem>
++        set either value to 0.</para>
++
++        <para>If a service provides rate limits for itself through
++        <varname>LogRateLimitIntervalSec=</varname> and/or <varname>LogRateLimitBurst=</varname>
++        in <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
++        those values will override the settings specified here.</para>
++        </listitem>
+       </varlistentry>
+ 
+       <varlistentry>
+diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
+index 3bd790b485..737c52bcc4 100644
+--- a/man/systemd.exec.xml
++++ b/man/systemd.exec.xml
+@@ -1905,6 +1905,22 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
+         matching. Assign an empty string to reset the list.</para></listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><varname>LogRateLimitIntervalSec=</varname></term>
++        <term><varname>LogRateLimitBurst=</varname></term>
++
++        <listitem><para>Configures the rate limiting that is applied to messages generated by this unit. If, in the
++        time interval defined by <varname>LogRateLimitIntervalSec=</varname>, more messages than specified in
++        <varname>LogRateLimitBurst=</varname> are logged by a service, all further messages within the interval are
++        dropped until the interval is over. A message about the number of dropped messages is generated. The time
++        specification for <varname>LogRateLimitIntervalSec=</varname> may be specified in the following units: "s",
++        "min", "h", "ms", "us" (see
++        <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details).
++        The default settings are set by <varname>RateLimitIntervalSec=</varname> and <varname>RateLimitBurst=</varname>
++        configured in <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
++        </para></listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><varname>SyslogIdentifier=</varname></term>
+ 
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index c44970c10c..33a91c012e 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -718,6 +718,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
+         SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
++        SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_rate_limit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST),
++        SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_rate_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
+@@ -1073,6 +1075,12 @@ int bus_exec_context_set_transient_property(
+         if (streq(name, "CPUSchedulingPriority"))
+                 return bus_set_transient_sched_priority(u, name, &c->cpu_sched_priority, message, flags, error);
+ 
++        if (streq(name, "LogRateLimitIntervalUSec"))
++                return bus_set_transient_usec(u, name, &c->log_rate_limit_interval_usec, message, flags, error);
++
++        if (streq(name, "LogRateLimitBurst"))
++                return bus_set_transient_unsigned(u, name, &c->log_rate_limit_burst, message, flags, error);
++
+         if (streq(name, "Personality"))
+                 return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
+ 
+diff --git a/src/core/execute.c b/src/core/execute.c
+index c62f3cf849..8293c522bc 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -3693,6 +3693,9 @@ void exec_context_done(ExecContext *c) {
+ 
+         exec_context_free_log_extra_fields(c);
+ 
++        c->log_rate_limit_interval_usec = 0;
++        c->log_rate_limit_burst = 0;
++
+         c->stdin_data = mfree(c->stdin_data);
+         c->stdin_data_size = 0;
+ }
+@@ -4153,6 +4156,17 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
+                 fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t));
+         }
+ 
++        if (c->log_rate_limit_interval_usec > 0) {
++                char buf_timespan[FORMAT_TIMESPAN_MAX];
++
++                fprintf(f,
++                        "%sLogRateLimitIntervalSec: %s\n",
++                        prefix, format_timespan(buf_timespan, sizeof(buf_timespan), c->log_rate_limit_interval_usec, USEC_PER_SEC));
++        }
++
++        if (c->log_rate_limit_burst > 0)
++                fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_rate_limit_burst);
++
+         if (c->n_log_extra_fields > 0) {
+                 size_t j;
+ 
+diff --git a/src/core/execute.h b/src/core/execute.h
+index bff1634b88..8c91636adc 100644
+--- a/src/core/execute.h
++++ b/src/core/execute.h
+@@ -216,6 +216,9 @@ struct ExecContext {
+         struct iovec* log_extra_fields;
+         size_t n_log_extra_fields;
+ 
++        usec_t log_rate_limit_interval_usec;
++        unsigned log_rate_limit_burst;
++
+         bool cpu_sched_reset_on_fork;
+         bool non_blocking;
+         bool private_tmp;
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index 15fb47838c..1066bcfb8f 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -57,6 +57,8 @@ $1.SyslogFacility,               config_parse_log_facility,          0,
+ $1.SyslogLevel,                  config_parse_log_level,             0,                             offsetof($1, exec_context.syslog_priority)
+ $1.SyslogLevelPrefix,            config_parse_bool,                  0,                             offsetof($1, exec_context.syslog_level_prefix)
+ $1.LogLevelMax,                  config_parse_log_level,             0,                             offsetof($1, exec_context.log_level_max)
++$1.LogRateLimitIntervalSec,      config_parse_sec,                   0,                             offsetof($1, exec_context.log_rate_limit_interval_usec)
++$1.LogRateLimitBurst,            config_parse_unsigned,              0,                             offsetof($1, exec_context.log_rate_limit_burst)
+ $1.LogExtraFields,               config_parse_log_extra_fields,      0,                             offsetof($1, exec_context)
+ $1.Capabilities,                 config_parse_warn_compat,           DISABLED_LEGACY,               offsetof($1, exec_context)
+ $1.SecureBits,                   config_parse_exec_secure_bits,      0,                             offsetof($1, exec_context.secure_bits)
+diff --git a/src/core/unit.c b/src/core/unit.c
+index b0b1c77ef7..115739f4c6 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -3245,6 +3245,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
+         unit_serialize_item(u, f, "exported-invocation-id", yes_no(u->exported_invocation_id));
+         unit_serialize_item(u, f, "exported-log-level-max", yes_no(u->exported_log_level_max));
+         unit_serialize_item(u, f, "exported-log-extra-fields", yes_no(u->exported_log_extra_fields));
++        unit_serialize_item(u, f, "exported-log-rate-limit-interval", yes_no(u->exported_log_rate_limit_interval));
++        unit_serialize_item(u, f, "exported-log-rate-limit-burst", yes_no(u->exported_log_rate_limit_burst));
+ 
+         unit_serialize_item_format(u, f, "cpu-usage-base", "%" PRIu64, u->cpu_usage_base);
+         if (u->cpu_usage_last != NSEC_INFINITY)
+@@ -3508,6 +3510,26 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
+ 
+                         continue;
+ 
++                } else if (streq(l, "exported-log-rate-limit-interval")) {
++
++                        r = parse_boolean(v);
++                        if (r < 0)
++                                log_unit_debug(u, "Failed to parse exported log rate limit interval %s, ignoring.", v);
++                        else
++                                u->exported_log_rate_limit_interval = r;
++
++                        continue;
++
++                } else if (streq(l, "exported-log-rate-limit-burst")) {
++
++                        r = parse_boolean(v);
++                        if (r < 0)
++                                log_unit_debug(u, "Failed to parse exported log rate limit burst %s, ignoring.", v);
++                        else
++                                u->exported_log_rate_limit_burst = r;
++
++                        continue;
++
+                 } else if (STR_IN_SET(l, "cpu-usage-base", "cpuacct-usage-base")) {
+ 
+                         r = safe_atou64(v, &u->cpu_usage_base);
+@@ -5241,6 +5263,60 @@ fail:
+         return r;
+ }
+ 
++static int unit_export_log_rate_limit_interval(Unit *u, const ExecContext *c) {
++        _cleanup_free_ char *buf = NULL;
++        const char *p;
++        int r;
++
++        assert(u);
++        assert(c);
++
++        if (u->exported_log_rate_limit_interval)
++                return 0;
++
++        if (c->log_rate_limit_interval_usec == 0)
++                return 0;
++
++        p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id);
++
++        if (asprintf(&buf, "%" PRIu64, c->log_rate_limit_interval_usec) < 0)
++                return log_oom();
++
++        r = symlink_atomic(buf, p);
++        if (r < 0)
++                return log_unit_debug_errno(u, r, "Failed to create log rate limit interval symlink %s: %m", p);
++
++        u->exported_log_rate_limit_interval = true;
++        return 0;
++}
++
++static int unit_export_log_rate_limit_burst(Unit *u, const ExecContext *c) {
++        _cleanup_free_ char *buf = NULL;
++        const char *p;
++        int r;
++
++        assert(u);
++        assert(c);
++
++        if (u->exported_log_rate_limit_burst)
++                return 0;
++
++        if (c->log_rate_limit_burst == 0)
++                return 0;
++
++        p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id);
++
++        if (asprintf(&buf, "%u", c->log_rate_limit_burst) < 0)
++                return log_oom();
++
++        r = symlink_atomic(buf, p);
++        if (r < 0)
++                return log_unit_debug_errno(u, r, "Failed to create log rate limit burst symlink %s: %m", p);
++
++        u->exported_log_rate_limit_burst = true;
++        return 0;
++}
++
+ void unit_export_state_files(Unit *u) {
+         const ExecContext *c;
+ 
+@@ -5274,6 +5350,8 @@ void unit_export_state_files(Unit *u) {
+         if (c) {
+                 (void) unit_export_log_level_max(u, c);
+                 (void) unit_export_log_extra_fields(u, c);
++                (void) unit_export_log_rate_limit_interval(u, c);
++                (void) unit_export_log_rate_limit_burst(u, c);
+         }
+ }
+ 
+@@ -5310,6 +5388,20 @@ void unit_unlink_state_files(Unit *u) {
+ 
+                 u->exported_log_extra_fields = false;
+         }
++
++        if (u->exported_log_rate_limit_interval) {
++                p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id);
++                (void) unlink(p);
++
++                u->exported_log_rate_limit_interval = false;
++        }
++
++        if (u->exported_log_rate_limit_burst) {
++                p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id);
++                (void) unlink(p);
++
++                u->exported_log_rate_limit_burst = false;
++        }
+ }
+ 
+ int unit_prepare_exec(Unit *u) {
+diff --git a/src/core/unit.h b/src/core/unit.h
+index 68cc1869e4..99755823eb 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -349,6 +349,8 @@ typedef struct Unit {
+         bool exported_invocation_id:1;
+         bool exported_log_level_max:1;
+         bool exported_log_extra_fields:1;
++        bool exported_log_rate_limit_interval:1;
++        bool exported_log_rate_limit_burst:1;
+ 
+         /* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If
+          * == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */
+diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
+index dba3525ed8..c8e97e16de 100644
+--- a/src/journal/journald-context.c
++++ b/src/journal/journald-context.c
+@@ -140,6 +140,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) {
+         c->timestamp = USEC_INFINITY;
+         c->extra_fields_mtime = NSEC_INFINITY;
+         c->log_level_max = -1;
++        c->log_rate_limit_interval = s->rate_limit_interval;
++        c->log_rate_limit_burst = s->rate_limit_burst;
+ 
+         r = hashmap_put(s->client_contexts, PID_TO_PTR(pid), c);
+         if (r < 0) {
+@@ -151,7 +153,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) {
+         return 0;
+ }
+ 
+-static void client_context_reset(ClientContext *c) {
++static void client_context_reset(Server *s, ClientContext *c) {
++        assert(s);
+         assert(c);
+ 
+         c->timestamp = USEC_INFINITY;
+@@ -186,6 +189,9 @@ static void client_context_reset(ClientContext *c) {
+         c->extra_fields_mtime = NSEC_INFINITY;
+ 
+         c->log_level_max = -1;
++
++        c->log_rate_limit_interval = s->rate_limit_interval;
++        c->log_rate_limit_burst = s->rate_limit_burst;
+ }
+ 
+ static ClientContext* client_context_free(Server *s, ClientContext *c) {
+@@ -199,7 +205,7 @@ static ClientContext* client_context_free(Server *s, ClientContext *c) {
+         if (c->in_lru)
+                 assert_se(prioq_remove(s->client_contexts_lru, c, &c->lru_index) >= 0);
+ 
+-        client_context_reset(c);
++        client_context_reset(s, c);
+ 
+         return mfree(c);
+ }
+@@ -464,6 +470,42 @@ static int client_context_read_extra_fields(
+         return 0;
+ }
+ 
++static int client_context_read_log_rate_limit_interval(ClientContext *c) {
++        _cleanup_free_ char *value = NULL;
++        const char *p;
++        int r;
++
++        assert(c);
++
++        if (!c->unit)
++                return 0;
++
++        p = strjoina("/run/systemd/units/log-rate-limit-interval:", c->unit);
++        r = readlink_malloc(p, &value);
++        if (r < 0)
++                return r;
++
++        return safe_atou64(value, &c->log_rate_limit_interval);
++}
++
++static int client_context_read_log_rate_limit_burst(ClientContext *c) {
++        _cleanup_free_ char *value = NULL;
++        const char *p;
++        int r;
++
++        assert(c);
++
++        if (!c->unit)
++                return 0;
++
++        p = strjoina("/run/systemd/units/log-rate-limit-burst:", c->unit);
++        r = readlink_malloc(p, &value);
++        if (r < 0)
++                return r;
++
++        return safe_atou(value, &c->log_rate_limit_burst);
++}
++
+ static void client_context_really_refresh(
+                 Server *s,
+                 ClientContext *c,
+@@ -490,6 +532,8 @@ static void client_context_really_refresh(
+         (void) client_context_read_invocation_id(s, c);
+         (void) client_context_read_log_level_max(s, c);
+         (void) client_context_read_extra_fields(s, c);
++        (void) client_context_read_log_rate_limit_interval(c);
++        (void) client_context_read_log_rate_limit_burst(c);
+ 
+         c->timestamp = timestamp;
+ 
+@@ -520,7 +564,7 @@ void client_context_maybe_refresh(
+         /* If the data isn't pinned and if the cashed data is older than the upper limit, we flush it out
+          * entirely. This follows the logic that as long as an entry is pinned the PID reuse is unlikely. */
+         if (c->n_ref == 0 && c->timestamp + MAX_USEC < timestamp) {
+-                client_context_reset(c);
++                client_context_reset(s, c);
+                 goto refresh;
+         }
+ 
+diff --git a/src/journal/journald-context.h b/src/journal/journald-context.h
+index 9df3a38eff..5e19c71f14 100644
+--- a/src/journal/journald-context.h
++++ b/src/journal/journald-context.h
+@@ -49,6 +49,9 @@ struct ClientContext {
+         size_t extra_fields_n_iovec;
+         void *extra_fields_data;
+         nsec_t extra_fields_mtime;
++
++        usec_t log_rate_limit_interval;
++        unsigned log_rate_limit_burst;
+ };
+ 
+ int client_context_get(
+diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c
+index 6a8a36a736..539efb8669 100644
+--- a/src/journal/journald-rate-limit.c
++++ b/src/journal/journald-rate-limit.c
+@@ -39,6 +39,10 @@ struct JournalRateLimitGroup {
+         JournalRateLimit *parent;
+ 
+         char *id;
++
++        /* Interval is stored to keep track of when the group expires */
++        usec_t interval;
++
+         JournalRateLimitPool pools[POOLS_MAX];
+         uint64_t hash;
+ 
+@@ -47,8 +51,6 @@ struct JournalRateLimitGroup {
+ };
+ 
+ struct JournalRateLimit {
+-        usec_t interval;
+-        unsigned burst;
+ 
+         JournalRateLimitGroup* buckets[BUCKETS_MAX];
+         JournalRateLimitGroup *lru, *lru_tail;
+@@ -58,18 +60,13 @@ struct JournalRateLimit {
+         uint8_t hash_key[16];
+ };
+ 
+-JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
++JournalRateLimit *journal_rate_limit_new(void) {
+         JournalRateLimit *r;
+ 
+-        assert(interval > 0 || burst == 0);
+-
+         r = new0(JournalRateLimit, 1);
+         if (!r)
+                 return NULL;
+ 
+-        r->interval = interval;
+-        r->burst = burst;
+-
+         random_bytes(r->hash_key, sizeof(r->hash_key));
+ 
+         return r;
+@@ -109,7 +106,7 @@ _pure_ static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, us
+         assert(g);
+ 
+         for (i = 0; i < POOLS_MAX; i++)
+-                if (g->pools[i].begin + g->parent->interval >= ts)
++                if (g->pools[i].begin + g->interval >= ts)
+                         return false;
+ 
+         return true;
+@@ -126,7 +123,7 @@ static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) {
+                 journal_rate_limit_group_free(r->lru_tail);
+ }
+ 
+-static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
++static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t interval, usec_t ts) {
+         JournalRateLimitGroup *g;
+         struct siphash state;
+ 
+@@ -145,6 +142,8 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
+         string_hash_func(g->id, &state);
+         g->hash = siphash24_finalize(&state);
+ 
++        g->interval = interval;
++
+         journal_rate_limit_vacuum(r, ts);
+ 
+         LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g);
+@@ -189,7 +188,7 @@ static unsigned burst_modulate(unsigned burst, uint64_t available) {
+         return burst;
+ }
+ 
+-int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
++int journal_rate_limit_test(JournalRateLimit *r, const char *id, usec_t rl_interval, unsigned rl_burst, int priority, uint64_t available) {
+         uint64_t h;
+         JournalRateLimitGroup *g;
+         JournalRateLimitPool *p;
+@@ -209,11 +208,6 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
+         if (!r)
+                 return 1;
+ 
+-        if (r->interval == 0 || r->burst == 0)
+-                return 1;
+-
+-        burst = burst_modulate(r->burst, available);
+-
+         ts = now(CLOCK_MONOTONIC);
+ 
+         siphash24_init(&state, r->hash_key);
+@@ -226,10 +220,16 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
+                         break;
+ 
+         if (!g) {
+-                g = journal_rate_limit_group_new(r, id, ts);
++                g = journal_rate_limit_group_new(r, id, rl_interval, ts);
+                 if (!g)
+                         return -ENOMEM;
+-        }
++        } else
++                g->interval = rl_interval;
++
++        if (rl_interval == 0 || rl_burst == 0)
++                return 1;
++
++        burst = burst_modulate(rl_burst, available);
+ 
+         p = &g->pools[priority_map[priority]];
+ 
+@@ -240,7 +240,7 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
+                 return 1;
+         }
+ 
+-        if (p->begin + r->interval < ts) {
++        if (p->begin + rl_interval < ts) {
+                 unsigned s;
+ 
+                 s = p->suppressed;
+diff --git a/src/journal/journald-rate-limit.h b/src/journal/journald-rate-limit.h
+index 3a7f106de0..a2992800fe 100644
+--- a/src/journal/journald-rate-limit.h
++++ b/src/journal/journald-rate-limit.h
+@@ -5,6 +5,6 @@
+ 
+ typedef struct JournalRateLimit JournalRateLimit;
+ 
+-JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst);
++JournalRateLimit *journal_rate_limit_new(void);
+ void journal_rate_limit_free(JournalRateLimit *r);
+-int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available);
++int journal_rate_limit_test(JournalRateLimit *r, const char *id, usec_t rl_interval, unsigned rl_burst, int priority, uint64_t available);
+diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
+index 8de45552f6..0c983e102a 100644
+--- a/src/journal/journald-server.c
++++ b/src/journal/journald-server.c
+@@ -943,7 +943,7 @@ void server_dispatch_message(
+         if (c && c->unit) {
+                 (void) determine_space(s, &available, NULL);
+ 
+-                rl = journal_rate_limit_test(s->rate_limit, c->unit, priority & LOG_PRIMASK, available);
++                rl = journal_rate_limit_test(s->rate_limit, c->unit, c->log_rate_limit_interval, c->log_rate_limit_burst, priority & LOG_PRIMASK, available);
+                 if (rl == 0)
+                         return;
+ 
+@@ -1852,7 +1852,7 @@ int server_init(Server *s) {
+         if (!s->udev)
+                 return -ENOMEM;
+ 
+-        s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
++        s->rate_limit = journal_rate_limit_new();
+         if (!s->rate_limit)
+                 return -ENOMEM;
+ 
+diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
+index 3238b442c0..271cc054da 100644
+--- a/src/shared/bus-unit-util.c
++++ b/src/shared/bus-unit-util.c
+@@ -755,6 +755,14 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
+ 
+                 return bus_append_parse_nsec(m, field, eq);
+ 
++        if (STR_IN_SET(field, "LogRateLimitIntervalSec"))
++
++                return bus_append_parse_sec_rename(m, field, eq);
++
++        if (streq(field, "LogRateLimitBurst"))
++
++                return bus_append_safe_atou(m, field, eq);
++
+         if (streq(field, "MountFlags"))
+ 
+                 return bus_append_mount_propagation_flags_from_string(m, field, eq);
+diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
+index c2334d3b19..d8d1fc68b8 100644
+--- a/test/fuzz/fuzz-unit-file/directives.service
++++ b/test/fuzz/fuzz-unit-file/directives.service
+@@ -792,6 +792,8 @@ LineMax=
+ LockPersonality=
+ LogExtraFields=
+ LogLevelMax=
++LogRateLimitIntervalSec=
++LogRateLimitBurst=
+ LogsDirectory=
+ LogsDirectoryMode=
+ MACVLAN=
diff --git a/SOURCES/0234-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch b/SOURCES/0234-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch
deleted file mode 100644
index 732ad35..0000000
--- a/SOURCES/0234-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 51c839c733ff53061807d92326830b5fe8499041 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 21:07:42 +0100
-Subject: [PATCH] sd-bus: always go through sd_bus_unref() to free messages
-
-Don't try to be smart, don't bypass the ref counting logic if there's no
-real reason to.
-
-This matters if we want to tweak the ref counting logic later.
-
-(cherry picked from commit b41812d1e308de03c879cfca490105216d528c4b)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/bus-message.c | 12 +++++-------
- 1 file changed, 5 insertions(+), 7 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
-index 2ea3c5bba9..ac19cc04bf 100644
---- a/src/libsystemd/sd-bus/bus-message.c
-+++ b/src/libsystemd/sd-bus/bus-message.c
-@@ -138,8 +138,6 @@ static sd_bus_message* message_free(sd_bus_message *m) {
-         return mfree(m);
- }
- 
--DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, message_free);
--
- static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
-         void *op, *np;
-         size_t old_size, new_size, start;
-@@ -531,7 +529,7 @@ int bus_message_from_malloc(
-                 const char *label,
-                 sd_bus_message **ret) {
- 
--        _cleanup_(message_freep) sd_bus_message *m = NULL;
-+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
-         size_t sz;
-         int r;
- 
-@@ -651,7 +649,7 @@ _public_ int sd_bus_message_new_method_call(
-                 const char *interface,
-                 const char *member) {
- 
--        _cleanup_(message_freep) sd_bus_message *t = NULL;
-+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
-         int r;
- 
-         assert_return(bus, -ENOTCONN);
-@@ -696,7 +694,7 @@ static int message_new_reply(
-                 uint8_t type,
-                 sd_bus_message **m) {
- 
--        _cleanup_(message_freep) sd_bus_message *t = NULL;
-+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
-         uint64_t cookie;
-         int r;
- 
-@@ -747,7 +745,7 @@ _public_ int sd_bus_message_new_method_error(
-                 sd_bus_message **m,
-                 const sd_bus_error *e) {
- 
--        _cleanup_(message_freep) sd_bus_message *t = NULL;
-+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
-         int r;
- 
-         assert_return(sd_bus_error_is_set(e), -EINVAL);
-@@ -850,7 +848,7 @@ int bus_message_new_synthetic_error(
-                 const sd_bus_error *e,
-                 sd_bus_message **m) {
- 
--        _cleanup_(message_freep) sd_bus_message *t = NULL;
-+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
-         int r;
- 
-         assert(bus);
diff --git a/SOURCES/0235-bus-message-introduce-two-kinds-of-references-to-bus.patch b/SOURCES/0235-bus-message-introduce-two-kinds-of-references-to-bus.patch
deleted file mode 100644
index cf6db16..0000000
--- a/SOURCES/0235-bus-message-introduce-two-kinds-of-references-to-bus.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-From 02d55f8f5bfd38ed2958c7e55707cadb058071be Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 18:18:54 +0100
-Subject: [PATCH] bus-message: introduce two kinds of references to bus
- messages
-
-Before this commit bus messages had a single reference count: when it
-reached zero the message would be freed. This simple approach meant a
-cyclic dependency was typically seen: a message that was enqueued in a
-bus connection object would reference the bus connection object but also
-itself be referenced by the bus connection object. So far out strategy
-to avoid cases like this was: make sure to process the bus connection
-regularly so that messages don#t stay queued, and at exit flush/close
-the connection so that the message queued would be emptied, and thus the
-cyclic dependencies resolved. Im many cases this isn't done properly
-however.
-
-With this change, let's address the issue more systematically: let's
-break the reference cycle. Specifically, there are now two types of
-references to a bus message:
-
-1. A regular one, which keeps both the message and the bus object it is
-   associated with pinned.
-
-2. A "queue" reference, which is weaker: it pins the message, but not
-   the bus object it is associated with.
-
-The idea is then that regular user handling uses regular references, but
-when a message is enqueued on its connection, then this takes a "queue"
-reference instead. This then means that a queued message doesn't imply
-the connection itself remains pinned, only regular references to the
-connection or a message associated with it do. Thus, if we end up in the
-situation where a user allocates a bus and a message and enqueues the
-latter in the former and drops all refs to both, then this will detect
-this case and free both.
-
-Note that this scheme isn't perfect, it only covers references between
-messages and the busses they are associated with. If OTOH a bus message
-is enqueued on a different bus than it is associated with cyclic deps
-cannot be recognized with this simple algorithm, and thus if you enqueue
-a message associated with a bus A on a bus B, and another message
-associated with bus B on a bus A, a cyclic ref will be in effect and not
-be discovered. However, given that this is an exotic case (though one
-that happens, consider systemd-bus-stdio-bridge), it should be OK not to
-cover with this, and people have to explicit flush all queues on exit in
-that case.
-
-Note that this commit only establishes the separate reference counters
-per message. A follow-up commit will start making use of this from the
-bus connection object.
-
-(cherry picked from commit 1b3f9dd759ca0ea215e7b89f8ce66d1b724497b9)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/bus-message.c | 60 ++++++++++++++++++++++++++---
- src/libsystemd/sd-bus/bus-message.h | 14 ++++++-
- 2 files changed, 68 insertions(+), 6 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
-index ac19cc04bf..ce7e67ecf2 100644
---- a/src/libsystemd/sd-bus/bus-message.c
-+++ b/src/libsystemd/sd-bus/bus-message.c
-@@ -120,7 +120,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
- 
-         message_reset_parts(m);
- 
--        sd_bus_unref(m->bus);
-+        /* Note that we don't unref m->bus here. That's already done by sd_bus_message_unref() as each user
-+         * reference to the bus message also is considered a reference to the bus connection itself. */
- 
-         if (m->free_fds) {
-                 close_many(m->fds, m->n_fds);
-@@ -893,27 +894,76 @@ int bus_message_new_synthetic_error(
- }
- 
- _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
--
-         if (!m)
-                 return NULL;
- 
--        assert(m->n_ref > 0);
-+        /* We are fine if this message so far was either explicitly reffed or not reffed but queued into at
-+         * least one bus connection object. */
-+        assert(m->n_ref > 0 || m->n_queued > 0);
-+
-         m->n_ref++;
- 
-+        /* Each user reference to a bus message shall also be considered a ref on the bus */
-+        sd_bus_ref(m->bus);
-         return m;
- }
- 
- _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
--
-         if (!m)
-                 return NULL;
- 
-         assert(m->n_ref > 0);
-+
-+        sd_bus_unref(m->bus); /* Each regular ref is also a ref on the bus connection. Let's hence drop it
-+                               * here. Note we have to do this before decrementing our own n_ref here, since
-+                               * otherwise, if this message is currently queued sd_bus_unref() might call
-+                               * bus_message_unref_queued() for this which might then destroy the message
-+                               * while we are still processing it. */
-         m->n_ref--;
- 
--        if (m->n_ref > 0)
-+        if (m->n_ref > 0 || m->n_queued > 0)
-                 return NULL;
- 
-+        /* Unset the bus field if neither the user has a reference nor this message is queued. We are careful
-+         * to reset the field only after the last reference to the bus is dropped, after all we might keep
-+         * multiple references to the bus, once for each reference kept on outselves. */
-+        m->bus = NULL;
-+
-+        return message_free(m);
-+}
-+
-+sd_bus_message* bus_message_ref_queued(sd_bus_message *m, sd_bus *bus) {
-+        if (!m)
-+                return NULL;
-+
-+        /* If this is a different bus than the message is associated with, then implicitly turn this into a
-+         * regular reference. This means that you can create a memory leak by enqueuing a message generated
-+         * on one bus onto another at the same time as enqueueing a message from the second one on the first,
-+         * as we'll not detect the cyclic references there. */
-+        if (bus != m->bus)
-+                return sd_bus_message_ref(m);
-+
-+        assert(m->n_ref > 0 || m->n_queued > 0);
-+        m->n_queued++;
-+
-+        return m;
-+}
-+
-+sd_bus_message* bus_message_unref_queued(sd_bus_message *m, sd_bus *bus) {
-+        if (!m)
-+                return NULL;
-+
-+        if (bus != m->bus)
-+                return sd_bus_message_unref(m);
-+
-+        assert(m->n_queued > 0);
-+        m->n_queued--;
-+
-+        if (m->n_ref > 0 || m->n_queued > 0)
-+                return NULL;
-+
-+        m->bus = NULL;
-+
-         return message_free(m);
- }
- 
-diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
-index 97f6060e30..ded88005e2 100644
---- a/src/libsystemd/sd-bus/bus-message.h
-+++ b/src/libsystemd/sd-bus/bus-message.h
-@@ -51,7 +51,16 @@ struct bus_body_part {
- };
- 
- struct sd_bus_message {
--        unsigned n_ref;
-+        /* Caveat: a message can be referenced in two different ways: the main (user-facing) way will also
-+         * pin the bus connection object the message is associated with. The secondary way ("queued") is used
-+         * when a message is in the read or write queues of the bus connection object, which will not pin the
-+         * bus connection object. This is necessary so that we don't have to have a pair of cyclic references
-+         * between a message that is queued and its connection: as soon as a message is only referenced by
-+         * the connection (by means of being queued) and the connection itself has no other references it
-+         * will be freed. */
-+
-+        unsigned n_ref;     /* Counter of references that pin the connection */
-+        unsigned n_queued;  /* Counter of references that do not pin the connection */
- 
-         sd_bus *bus;
- 
-@@ -216,3 +225,6 @@ int bus_message_append_sender(sd_bus_message *m, const char *sender);
- 
- void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m);
- void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m);
-+
-+sd_bus_message* bus_message_ref_queued(sd_bus_message *m, sd_bus *bus);
-+sd_bus_message* bus_message_unref_queued(sd_bus_message *m, sd_bus *bus);
diff --git a/SOURCES/0235-path-stop-watching-path-specs-once-we-triggered-the-.patch b/SOURCES/0235-path-stop-watching-path-specs-once-we-triggered-the-.patch
new file mode 100644
index 0000000..c538f50
--- /dev/null
+++ b/SOURCES/0235-path-stop-watching-path-specs-once-we-triggered-the-.patch
@@ -0,0 +1,35 @@
+From 55d9d6dfb731d2f1c8c940fb8a7ea0af6c498c4c Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Mon, 9 Sep 2019 14:38:35 +0200
+Subject: [PATCH] path: stop watching path specs once we triggered the target
+ unit
+
+We start watching them again once we get a notification that triggered
+unit entered inactive or failed state.
+
+Fixes: #10503
+(cherry picked from commit 8fca6944c2ee20c63d62154c8badddc77170b176)
+
+Resolves: #1763161
+---
+ src/core/path.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/path.c b/src/core/path.c
+index 68b13b610a..5ef178a46b 100644
+--- a/src/core/path.c
++++ b/src/core/path.c
+@@ -478,11 +478,9 @@ static void path_enter_running(Path *p) {
+ 
+         p->inotify_triggered = false;
+ 
+-        r = path_watch(p);
+-        if (r < 0)
+-                goto fail;
+-
+         path_set_state(p, PATH_RUNNING);
++        path_unwatch(p);
++
+         return;
+ 
+ fail:
diff --git a/SOURCES/0236-journald-fixed-assertion-failure-when-system-journal.patch b/SOURCES/0236-journald-fixed-assertion-failure-when-system-journal.patch
new file mode 100644
index 0000000..25c91dd
--- /dev/null
+++ b/SOURCES/0236-journald-fixed-assertion-failure-when-system-journal.patch
@@ -0,0 +1,28 @@
+From 33aa231f5bf3335cdacfb38ffba757865019ce4d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Renaud=20M=C3=A9trich?=
+ <1163635+rmetrich@users.noreply.github.com>
+Date: Mon, 3 Sep 2018 05:42:39 +0200
+Subject: [PATCH] journald: fixed assertion failure when system journal
+ rotation fails (#9893)
+
+(cherry picked from commit fd790d6f09b10a87b007b71403cb018f18ff91c9)
+
+Resolves: #1763619
+---
+ src/journal/journald-server.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
+index 0c983e102a..6aecb67d6c 100644
+--- a/src/journal/journald-server.c
++++ b/src/journal/journald-server.c
+@@ -1041,7 +1041,8 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
+         r = 0;
+ 
+ finish:
+-        journal_file_post_change(s->system_journal);
++        if (s->system_journal)
++                journal_file_post_change(s->system_journal);
+ 
+         s->runtime_journal = journal_file_close(s->runtime_journal);
+ 
diff --git a/SOURCES/0236-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch b/SOURCES/0236-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch
deleted file mode 100644
index 2ce2ef3..0000000
--- a/SOURCES/0236-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From f16b5124274f35c475cb70fa936567877a4b74f9 Mon Sep 17 00:00:00 2001
-From: Jan Synacek <jsynacek@redhat.com>
-Date: Fri, 31 Jan 2020 11:34:45 +0100
-Subject: [PATCH] sd-bus: introduce API for re-enqueuing incoming messages
-
-When authorizing via PolicyKit we want to process incoming method calls
-twice: once to process and figure out that we need PK authentication,
-and a second time after we aquired PK authentication to actually execute
-the operation. With this new call sd_bus_enqueue_for_read() we have a
-way to put an incoming message back into the read queue for this
-purpose.
-
-This might have other uses too, for example debugging.
-Related: CVE-2020-1712
----
- src/libsystemd/libsystemd.sym  |  1 +
- src/libsystemd/sd-bus/sd-bus.c | 24 ++++++++++++++++++++++++
- src/systemd/sd-bus.h           |  1 +
- 3 files changed, 26 insertions(+)
-
-diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
-index 1eec17db50..e9972593a6 100644
---- a/src/libsystemd/libsystemd.sym
-+++ b/src/libsystemd/libsystemd.sym
-@@ -569,4 +569,5 @@ global:
-         sd_event_source_get_inotify_mask;
-         sd_event_source_set_destroy_callback;
-         sd_event_source_get_destroy_callback;
-+        sd_bus_enqueue_for_read;
- } LIBSYSTEMD_238;
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index e49d58137d..68ad6cbe89 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -4120,3 +4120,27 @@ _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) {
-         *ret = bus->wqueue_size;
-         return 0;
- }
-+
-+_public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) {
-+        int r;
-+
-+        assert_return(bus, -EINVAL);
-+        assert_return(bus = bus_resolve(bus), -ENOPKG);
-+        assert_return(m, -EINVAL);
-+        assert_return(m->sealed, -EINVAL);
-+        assert_return(!bus_pid_changed(bus), -ECHILD);
-+
-+        if (!BUS_IS_OPEN(bus->state))
-+                return -ENOTCONN;
-+
-+        /* Re-enqeue a message for reading. This is primarily useful for PolicyKit-style authentication,
-+         * where we want accept a message, then determine we need to interactively authenticate the user, and
-+         * when we have that process the message again. */
-+
-+        r = bus_rqueue_make_room(bus);
-+        if (r < 0)
-+                return r;
-+
-+        bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus);
-+        return 0;
-+}
-diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
-index 54c4b1ca83..9ba757b13d 100644
---- a/src/systemd/sd-bus.h
-+++ b/src/systemd/sd-bus.h
-@@ -193,6 +193,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r);
- int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r);
- int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec);
- int sd_bus_flush(sd_bus *bus);
-+int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m);
- 
- sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus);
- sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
diff --git a/SOURCES/0237-sd-event-add-sd_event_source_disable_unref-helper.patch b/SOURCES/0237-sd-event-add-sd_event_source_disable_unref-helper.patch
deleted file mode 100644
index 9ff72ce..0000000
--- a/SOURCES/0237-sd-event-add-sd_event_source_disable_unref-helper.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From 8e155b3dad29a96cd2586185c63604c42bc5690e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Wed, 8 May 2019 14:39:57 +0200
-Subject: [PATCH] sd-event: add sd_event_source_disable_unref() helper
-
-(cherry picked from commit afd15bbb4b6414b9356799c63029e36642dae8e4)
-Related: CVE-2020-1712
----
- man/rules/meson.build              |  4 +++-
- man/sd_event_source_unref.xml      | 30 +++++++++++++++++++-----------
- src/libsystemd/libsystemd.sym      |  1 +
- src/libsystemd/sd-event/sd-event.c |  6 ++++++
- src/systemd/sd-event.h             |  1 +
- 5 files changed, 30 insertions(+), 12 deletions(-)
-
-diff --git a/man/rules/meson.build b/man/rules/meson.build
-index 989d11c9b9..7ae94ea265 100644
---- a/man/rules/meson.build
-+++ b/man/rules/meson.build
-@@ -340,7 +340,9 @@ manpages = [
-  ['sd_event_source_set_userdata', '3', ['sd_event_source_get_userdata'], ''],
-  ['sd_event_source_unref',
-   '3',
--  ['sd_event_source_ref', 'sd_event_source_unrefp'],
-+  ['sd_event_source_disable_unref',
-+   'sd_event_source_ref',
-+   'sd_event_source_unrefp'],
-   ''],
-  ['sd_event_wait',
-   '3',
-diff --git a/man/sd_event_source_unref.xml b/man/sd_event_source_unref.xml
-index d1b83c57aa..af8fed33f2 100644
---- a/man/sd_event_source_unref.xml
-+++ b/man/sd_event_source_unref.xml
-@@ -22,6 +22,7 @@
-     <refname>sd_event_source_unref</refname>
-     <refname>sd_event_source_unrefp</refname>
-     <refname>sd_event_source_ref</refname>
-+    <refname>sd_event_source_disable_unref</refname>
- 
-     <refpurpose>Increase or decrease event source reference counters</refpurpose>
-   </refnamediv>
-@@ -45,6 +46,10 @@
-         <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
-       </funcprototype>
- 
-+      <funcprototype>
-+        <funcdef>sd_event_source* <function>sd_event_source_disable_unref</function></funcdef>
-+        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
-+      </funcprototype>
-     </funcsynopsis>
-   </refsynopsisdiv>
- 
-@@ -80,23 +85,26 @@
-     the passed event source object is
-     <constant>NULL</constant>.</para>
- 
--    <para>Note that event source objects stay alive and may be
--    dispatched as long as they have a reference counter greater than
--    zero. In order to drop a reference of an event source and make
--    sure the associated event source handler function is not called
--    anymore it is recommended to combine a call of
-+    <para>Note that event source objects stay alive and may be dispatched as long as they have a reference
-+    counter greater than zero. In order to drop a reference of an event source and make sure the associated
-+    event source handler function is not called anymore it is recommended to combine a call of
-     <function>sd_event_source_unref()</function> with a prior call to
--    <function>sd_event_source_set_enabled()</function> with
--    <constant>SD_EVENT_OFF</constant>.</para>
-+    <function>sd_event_source_set_enabled()</function> with <constant>SD_EVENT_OFF</constant> or call
-+    <function>sd_event_source_disable_unref()</function>, see below.</para>
-+
-+    <para><function>sd_event_source_disable_unref()</function> combines a call to
-+    <function>sd_event_source_set_enabled()</function> with <constant>SD_EVENT_OFF</constant> with
-+    <function>sd_event_source_unref()</function>. This ensures that the source is disabled before the local
-+    reference to it is lost. The <parameter>source</parameter> parameter is allowed to be
-+    <constant>NULL</constant>.</para>
-   </refsect1>
- 
-   <refsect1>
-     <title>Return Value</title>
- 
--    <para><function>sd_event_source_unref()</function> always returns
--    <constant>NULL</constant>.
--    <function>sd_event_source_ref()</function> always returns the
--    event source object passed in.</para>
-+    <para><function>sd_event_source_unref()</function> and
-+    <function>sd_event_source_disable_unref()</function> always return <constant>NULL</constant>.
-+    <function>sd_event_source_ref()</function> always returns the event source object passed in.</para>
-   </refsect1>
- 
-   <xi:include href="libsystemd-pkgconfig.xml" />
-diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
-index e9972593a6..778e88a16c 100644
---- a/src/libsystemd/libsystemd.sym
-+++ b/src/libsystemd/libsystemd.sym
-@@ -570,4 +570,5 @@ global:
-         sd_event_source_set_destroy_callback;
-         sd_event_source_get_destroy_callback;
-         sd_bus_enqueue_for_read;
-+        sd_event_source_disable_unref;
- } LIBSYSTEMD_238;
-diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
-index d53b9a7026..0d3bf5cbb6 100644
---- a/src/libsystemd/sd-event/sd-event.c
-+++ b/src/libsystemd/sd-event/sd-event.c
-@@ -580,6 +580,12 @@ _public_ sd_event* sd_event_unref(sd_event *e) {
-         return NULL;
- }
- 
-+_public_ sd_event_source* sd_event_source_disable_unref(sd_event_source *s) {
-+        if (s)
-+                (void) sd_event_source_set_enabled(s, SD_EVENT_OFF);
-+        return sd_event_source_unref(s);
-+}
-+
- static bool event_pid_changed(sd_event *e) {
-         assert(e);
- 
-diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
-index 7fcae4ac49..9876be01c6 100644
---- a/src/systemd/sd-event.h
-+++ b/src/systemd/sd-event.h
-@@ -113,6 +113,7 @@ int sd_event_get_iteration(sd_event *e, uint64_t *ret);
- 
- sd_event_source* sd_event_source_ref(sd_event_source *s);
- sd_event_source* sd_event_source_unref(sd_event_source *s);
-+sd_event_source* sd_event_source_disable_unref(sd_event_source *s);
- 
- sd_event *sd_event_source_get_event(sd_event_source *s);
- void* sd_event_source_get_userdata(sd_event_source *s);
diff --git a/SOURCES/0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch b/SOURCES/0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
new file mode 100644
index 0000000..4599b60
--- /dev/null
+++ b/SOURCES/0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
@@ -0,0 +1,29 @@
+From a7f18f9ef4abc7e0732d1710ead2a18a38c3ec6d Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Fri, 15 Mar 2019 10:05:33 +0100
+Subject: [PATCH] test: use PBKDF2 instead of Argon2 in cryptsetup...
+
+to reduce memory requirements for volume manipulation. Also,
+to further improve the test performance, reduce number of PBKDF
+iterations to 1000 (allowed minimum).
+
+(cherry picked from commit 5b69d297c153478f6f5e74ba66e1f4e5b6422baf)
+
+Related: #1761519
+---
+ test/TEST-02-CRYPTSETUP/test.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
+index 545602e17a..c38e56f72e 100755
+--- a/test/TEST-02-CRYPTSETUP/test.sh
++++ b/test/TEST-02-CRYPTSETUP/test.sh
+@@ -29,7 +29,7 @@ check_result_qemu() {
+ test_setup() {
+     create_empty_image
+     echo -n test >$TESTDIR/keyfile
+-    cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile
++    cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile
+     cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
+     mkfs.ext4 -L var /dev/mapper/varcrypt
+     mkdir -p $TESTDIR/root
diff --git a/SOURCES/0238-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch b/SOURCES/0238-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch
deleted file mode 100644
index 24c565a..0000000
--- a/SOURCES/0238-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From ae3cdcd5f8954d020a146c980ed064c21fd21239 Mon Sep 17 00:00:00 2001
-From: Jan Synacek <jsynacek@redhat.com>
-Date: Fri, 31 Jan 2020 15:17:25 +0100
-Subject: [PATCH] polkit: when authorizing via PK let's re-resolve
- callback/userdata instead of caching it
-
-Previously, when doing an async PK query we'd store the original
-callback/userdata pair and call it again after the PK request is
-complete. This is problematic, since PK queries might be slow and in the
-meantime the userdata might be released and re-acquired. Let's avoid
-this by always traversing through the message handlers so that we always
-re-resolve the callback and userdata pair and thus can be sure it's
-up-to-date and properly valid.
-
-Resolves: CVE-2020-1712
----
- src/shared/bus-util.c | 74 +++++++++++++++++++++++++++++--------------
- 1 file changed, 50 insertions(+), 24 deletions(-)
-
-diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
-index 2d908eb45c..5ed68429be 100644
---- a/src/shared/bus-util.c
-+++ b/src/shared/bus-util.c
-@@ -319,10 +319,10 @@ int bus_test_polkit(
- 
- typedef struct AsyncPolkitQuery {
-         sd_bus_message *request, *reply;
--        sd_bus_message_handler_t callback;
--        void *userdata;
-         sd_bus_slot *slot;
-+
-         Hashmap *registry;
-+        sd_event_source *defer_event_source;
- } AsyncPolkitQuery;
- 
- static void async_polkit_query_free(AsyncPolkitQuery *q) {
-@@ -338,9 +338,22 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
-         sd_bus_message_unref(q->request);
-         sd_bus_message_unref(q->reply);
- 
-+        sd_event_source_disable_unref(q->defer_event_source);
-         free(q);
- }
- 
-+static int async_polkit_defer(sd_event_source *s, void *userdata) {
-+        AsyncPolkitQuery *q = userdata;
-+
-+        assert(s);
-+
-+        /* This is called as idle event source after we processed the async polkit reply, hopefully after the
-+         * method call we re-enqueued has been properly processed. */
-+
-+        async_polkit_query_free(q);
-+        return 0;
-+}
-+
- static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
-         _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
-         AsyncPolkitQuery *q = userdata;
-@@ -349,19 +362,45 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e
-         assert(reply);
-         assert(q);
- 
-+        assert(q->slot);
-         q->slot = sd_bus_slot_unref(q->slot);
-+
-+        assert(!q->reply);
-         q->reply = sd_bus_message_ref(reply);
- 
-+        /* Now, let's dispatch the original message a second time be re-enqueing. This will then traverse the
-+         * whole message processing again, and thus re-validating and re-retrieving the "userdata" field
-+         * again.
-+         *
-+         * We install an idle event loop event to clean-up the PolicyKit request data when we are idle again,
-+         * i.e. after the second time the message is processed is complete. */
-+
-+        assert(!q->defer_event_source);
-+        r = sd_event_add_defer(sd_bus_get_event(sd_bus_message_get_bus(reply)), &q->defer_event_source, async_polkit_defer, q);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_priority(q->defer_event_source, SD_EVENT_PRIORITY_IDLE);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_ONESHOT);
-+        if (r < 0)
-+                goto fail;
-+
-         r = sd_bus_message_rewind(q->request, true);
--        if (r < 0) {
--                r = sd_bus_reply_method_errno(q->request, r, NULL);
--                goto finish;
--        }
-+        if (r < 0)
-+                goto fail;
- 
--        r = q->callback(q->request, q->userdata, &error_buffer);
--        r = bus_maybe_reply_error(q->request, r, &error_buffer);
-+        r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request);
-+        if (r < 0)
-+                goto fail;
- 
--finish:
-+        return 1;
-+
-+fail:
-+        log_debug_errno(r, "Processing asynchronous PolicyKit reply failed, ignoring: %m");
-+        (void) sd_bus_reply_method_errno(q->request, r, NULL);
-         async_polkit_query_free(q);
- 
-         return r;
-@@ -382,11 +421,9 @@ int bus_verify_polkit_async(
- #if ENABLE_POLKIT
-         _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
-         AsyncPolkitQuery *q;
--        const char *sender, **k, **v;
--        sd_bus_message_handler_t callback;
--        void *userdata;
-         int c;
- #endif
-+        const char *sender, **k, **v;
-         int r;
- 
-         assert(call);
-@@ -444,20 +481,11 @@ int bus_verify_polkit_async(
-         else if (r > 0)
-                 return 1;
- 
--#if ENABLE_POLKIT
--        if (sd_bus_get_current_message(call->bus) != call)
--                return -EINVAL;
--
--        callback = sd_bus_get_current_handler(call->bus);
--        if (!callback)
--                return -EINVAL;
--
--        userdata = sd_bus_get_current_userdata(call->bus);
--
-         sender = sd_bus_message_get_sender(call);
-         if (!sender)
-                 return -EBADMSG;
- 
-+#if ENABLE_POLKIT
-         c = sd_bus_message_get_allow_interactive_authorization(call);
-         if (c < 0)
-                 return c;
-@@ -509,8 +537,6 @@ int bus_verify_polkit_async(
-                 return -ENOMEM;
- 
-         q->request = sd_bus_message_ref(call);
--        q->callback = callback;
--        q->userdata = userdata;
- 
-         r = hashmap_put(*registry, call, q);
-         if (r < 0) {
diff --git a/SOURCES/0238-test-mask-several-unnecessary-services.patch b/SOURCES/0238-test-mask-several-unnecessary-services.patch
new file mode 100644
index 0000000..6ff56e8
--- /dev/null
+++ b/SOURCES/0238-test-mask-several-unnecessary-services.patch
@@ -0,0 +1,252 @@
+From c748b95f5a00b6d9c46026c3d251c40437e6b64a Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Thu, 1 Nov 2018 17:26:36 +0900
+Subject: [PATCH] test: mask several unnecessary services
+
+This may make CIs run faster.
+
+(cherry picked from commit 056ae88152a722bdbea54ff33db815d585c8b9c6)
+
+Related: #1761519
+---
+ test/TEST-02-CRYPTSETUP/test.sh    | 8 ++++++++
+ test/TEST-03-JOBS/test.sh          | 8 ++++++++
+ test/TEST-04-JOURNAL/test.sh       | 8 ++++++++
+ test/TEST-05-RLIMITS/test.sh       | 8 ++++++++
+ test/TEST-07-ISSUE-1981/test.sh    | 8 ++++++++
+ test/TEST-11-ISSUE-3166/test.sh    | 8 ++++++++
+ test/TEST-12-ISSUE-3171/test.sh    | 8 ++++++++
+ test/TEST-13-NSPAWN-SMOKE/test.sh  | 8 ++++++++
+ test/TEST-18-FAILUREACTION/test.sh | 7 +++++++
+ test/TEST-19-DELEGATE/test.sh      | 8 ++++++++
+ test/TEST-20-MAINPIDGAMES/test.sh  | 8 ++++++++
+ test/TEST-23-TYPE-EXEC/test.sh     | 8 ++++++++
+ 12 files changed, 95 insertions(+)
+
+diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
+index c38e56f72e..97eb2f409e 100755
+--- a/test/TEST-02-CRYPTSETUP/test.sh
++++ b/test/TEST-02-CRYPTSETUP/test.sh
+@@ -45,6 +45,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-03-JOBS/test.sh b/test/TEST-03-JOBS/test.sh
+index 08e5cfe6c8..93a387df59 100755
+--- a/test/TEST-03-JOBS/test.sh
++++ b/test/TEST-03-JOBS/test.sh
+@@ -19,6 +19,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh
+index 30e7b181b2..80e5fb0a73 100755
+--- a/test/TEST-04-JOURNAL/test.sh
++++ b/test/TEST-04-JOURNAL/test.sh
+@@ -18,6 +18,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-05-RLIMITS/test.sh b/test/TEST-05-RLIMITS/test.sh
+index a1b855c5fb..711f87f585 100755
+--- a/test/TEST-05-RLIMITS/test.sh
++++ b/test/TEST-05-RLIMITS/test.sh
+@@ -18,6 +18,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         cat >$initdir/etc/systemd/system.conf <<EOF
+ [Manager]
+ DefaultLimitNOFILE=10000:16384
+diff --git a/test/TEST-07-ISSUE-1981/test.sh b/test/TEST-07-ISSUE-1981/test.sh
+index 88d143e479..8d3ed04712 100755
+--- a/test/TEST-07-ISSUE-1981/test.sh
++++ b/test/TEST-07-ISSUE-1981/test.sh
+@@ -21,6 +21,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh
+index 8aae4d5ed9..e6e96101aa 100755
+--- a/test/TEST-11-ISSUE-3166/test.sh
++++ b/test/TEST-11-ISSUE-3166/test.sh
+@@ -20,6 +20,14 @@ test_setup() {
+         setup_basic_environment
+         dracut_install false touch
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
+index 559fa469cd..915cc21cd8 100755
+--- a/test/TEST-12-ISSUE-3171/test.sh
++++ b/test/TEST-12-ISSUE-3171/test.sh
+@@ -20,6 +20,14 @@ test_setup() {
+         setup_basic_environment
+         dracut_install cat mv stat nc
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
+index a676384bfc..cec59fa24d 100755
+--- a/test/TEST-13-NSPAWN-SMOKE/test.sh
++++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
+@@ -20,6 +20,14 @@ test_setup() {
+         setup_basic_environment
+         dracut_install busybox chmod rmdir unshare ip sysctl
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         cp create-busybox-container $initdir/
+ 
+         ./create-busybox-container $initdir/nc-container
+diff --git a/test/TEST-18-FAILUREACTION/test.sh b/test/TEST-18-FAILUREACTION/test.sh
+index e48ba9bac3..783b3aac6e 100755
+--- a/test/TEST-18-FAILUREACTION/test.sh
++++ b/test/TEST-18-FAILUREACTION/test.sh
+@@ -35,6 +35,13 @@ EOF
+     ) || return 1
+     setup_nspawn_root
+ 
++    # mask some services that we do not want to run in these tests
++    ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++    ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++    ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++    ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++
+     ddebug "umount $TESTDIR/root"
+     umount $TESTDIR/root
+ }
+diff --git a/test/TEST-19-DELEGATE/test.sh b/test/TEST-19-DELEGATE/test.sh
+index 841a29c06f..ef1d99932a 100755
+--- a/test/TEST-19-DELEGATE/test.sh
++++ b/test/TEST-19-DELEGATE/test.sh
+@@ -20,6 +20,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-20-MAINPIDGAMES/test.sh b/test/TEST-20-MAINPIDGAMES/test.sh
+index b14083a256..4ec8081478 100755
+--- a/test/TEST-20-MAINPIDGAMES/test.sh
++++ b/test/TEST-20-MAINPIDGAMES/test.sh
+@@ -17,6 +17,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
+diff --git a/test/TEST-23-TYPE-EXEC/test.sh b/test/TEST-23-TYPE-EXEC/test.sh
+index bdcea239a7..2e76451f5b 100755
+--- a/test/TEST-23-TYPE-EXEC/test.sh
++++ b/test/TEST-23-TYPE-EXEC/test.sh
+@@ -17,6 +17,14 @@ test_setup() {
+ 
+         setup_basic_environment
+ 
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
+         # setup the testsuite service
+         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
+ [Unit]
diff --git a/SOURCES/0239-sd-bus-use-queue-message-references-for-managing-r-w.patch b/SOURCES/0239-sd-bus-use-queue-message-references-for-managing-r-w.patch
deleted file mode 100644
index 10ff2cd..0000000
--- a/SOURCES/0239-sd-bus-use-queue-message-references-for-managing-r-w.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From ed560bc85cd2537dd083a8995b5d10f66f7a391f Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Jan 2019 18:31:59 +0100
-Subject: [PATCH] sd-bus: use "queue" message references for managing r/w
- message queues in connection objects
-
-Let's make use of the new concept the previous commit added.
-
-See: #4846
-(cherry picked from commit c1757a70eac0382c4837a3833d683919f6a48ed7)
-Related: CVE-2020-1712
----
- src/libsystemd/sd-bus/bus-socket.c |  6 ++-
- src/libsystemd/sd-bus/sd-bus.c     | 60 ++++++++++++++----------------
- 2 files changed, 32 insertions(+), 34 deletions(-)
-
-diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
-index 17cfa8e1fd..4a72795d2b 100644
---- a/src/libsystemd/sd-bus/bus-socket.c
-+++ b/src/libsystemd/sd-bus/bus-socket.c
-@@ -1116,8 +1116,10 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
-         bus->fds = NULL;
-         bus->n_fds = 0;
- 
--        if (t)
--                bus->rqueue[bus->rqueue_size++] = t;
-+        if (t) {
-+                bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(t, bus);
-+                sd_bus_message_unref(t);
-+        }
- 
-         return 1;
- }
-diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
-index 68ad6cbe89..a3509f7e89 100644
---- a/src/libsystemd/sd-bus/sd-bus.c
-+++ b/src/libsystemd/sd-bus/sd-bus.c
-@@ -148,13 +148,13 @@ static void bus_reset_queues(sd_bus *b) {
-         assert(b);
- 
-         while (b->rqueue_size > 0)
--                sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
-+                bus_message_unref_queued(b->rqueue[--b->rqueue_size], b);
- 
-         b->rqueue = mfree(b->rqueue);
-         b->rqueue_allocated = 0;
- 
-         while (b->wqueue_size > 0)
--                sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
-+                bus_message_unref_queued(b->wqueue[--b->wqueue_size], b);
- 
-         b->wqueue = mfree(b->wqueue);
-         b->wqueue_allocated = 0;
-@@ -493,7 +493,7 @@ static int synthesize_connected_signal(sd_bus *bus) {
- 
-         /* Insert at the very front */
-         memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size);
--        bus->rqueue[0] = TAKE_PTR(m);
-+        bus->rqueue[0] = bus_message_ref_queued(m, bus);
-         bus->rqueue_size++;
- 
-         return 0;
-@@ -1760,7 +1760,7 @@ static int dispatch_wqueue(sd_bus *bus) {
-                          * anyway. */
- 
-                         bus->wqueue_size--;
--                        sd_bus_message_unref(bus->wqueue[0]);
-+                        bus_message_unref_queued(bus->wqueue[0], bus);
-                         memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
-                         bus->windex = 0;
- 
-@@ -1789,6 +1789,15 @@ int bus_rqueue_make_room(sd_bus *bus) {
-         return 0;
- }
- 
-+static void rqueue_drop_one(sd_bus *bus, size_t i) {
-+        assert(bus);
-+        assert(i < bus->rqueue_size);
-+
-+        bus_message_unref_queued(bus->rqueue[i], bus);
-+        memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
-+        bus->rqueue_size--;
-+}
-+
- static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
-         int r, ret = 0;
- 
-@@ -1803,10 +1812,8 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd
-         for (;;) {
-                 if (bus->rqueue_size > 0) {
-                         /* Dispatch a queued message */
--
--                        *m = bus->rqueue[0];
--                        bus->rqueue_size--;
--                        memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
-+                        *m = sd_bus_message_ref(bus->rqueue[0]);
-+                        rqueue_drop_one(bus, 0);
-                         return 1;
-                 }
- 
-@@ -1884,7 +1891,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
-                          * of the wqueue array is always allocated so
-                          * that we always can remember how much was
-                          * written. */
--                        bus->wqueue[0] = sd_bus_message_ref(m);
-+                        bus->wqueue[0] = bus_message_ref_queued(m, bus);
-                         bus->wqueue_size = 1;
-                         bus->windex = idx;
-                 }
-@@ -1898,7 +1905,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
-                 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
-                         return -ENOMEM;
- 
--                bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
-+                bus->wqueue[bus->wqueue_size++] = bus_message_ref_queued(m, bus);
-         }
- 
- finish:
-@@ -2124,37 +2131,30 @@ _public_ int sd_bus_call(
-                 usec_t left;
- 
-                 while (i < bus->rqueue_size) {
--                        sd_bus_message *incoming = NULL;
-+                        _cleanup_(sd_bus_message_unrefp) sd_bus_message *incoming = NULL;
- 
--                        incoming = bus->rqueue[i];
-+                        incoming = sd_bus_message_ref(bus->rqueue[i]);
- 
-                         if (incoming->reply_cookie == cookie) {
-                                 /* Found a match! */
- 
--                                memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
--                                bus->rqueue_size--;
-+                                rqueue_drop_one(bus, i);
-                                 log_debug_bus_message(incoming);
- 
-                                 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
- 
-                                         if (incoming->n_fds <= 0 || bus->accept_fd) {
-                                                 if (reply)
--                                                        *reply = incoming;
--                                                else
--                                                        sd_bus_message_unref(incoming);
-+                                                        *reply = TAKE_PTR(incoming);
- 
-                                                 return 1;
-                                         }
- 
--                                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
--                                        sd_bus_message_unref(incoming);
--                                        return r;
-+                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
- 
--                                } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
--                                        r = sd_bus_error_copy(error, &incoming->error);
--                                        sd_bus_message_unref(incoming);
--                                        return r;
--                                } else {
-+                                } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
-+                                        return sd_bus_error_copy(error, &incoming->error);
-+                                else {
-                                         r = -EIO;
-                                         goto fail;
-                                 }
-@@ -2164,15 +2164,11 @@ _public_ int sd_bus_call(
-                                    incoming->sender &&
-                                    streq(bus->unique_name, incoming->sender)) {
- 
--                                memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
--                                bus->rqueue_size--;
-+                                rqueue_drop_one(bus, i);
- 
--                                /* Our own message? Somebody is trying
--                                 * to send its own client a message,
--                                 * let's not dead-lock, let's fail
--                                 * immediately. */
-+                                /* Our own message? Somebody is trying to send its own client a message,
-+                                 * let's not dead-lock, let's fail immediately. */
- 
--                                sd_bus_message_unref(incoming);
-                                 r = -ELOOP;
-                                 goto fail;
-                         }
diff --git a/SOURCES/0239-test-bump-the-second-partition-s-size-to-50M.patch b/SOURCES/0239-test-bump-the-second-partition-s-size-to-50M.patch
new file mode 100644
index 0000000..ff68908
--- /dev/null
+++ b/SOURCES/0239-test-bump-the-second-partition-s-size-to-50M.patch
@@ -0,0 +1,30 @@
+From 27d1acaa1d4c9299db461f0f1922c573be6a52c0 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <fsumsal@redhat.com>
+Date: Mon, 21 Oct 2019 18:39:39 +0200
+Subject: [PATCH] test: bump the second partition's size to 50M
+
+The former size (10M) caused systemd-journald to crash with SIGABRT when
+used on a LUKS2 partition, as the LUKS2 metadata consume a significant
+part of the 10M partition, thus leaving no space for the journal file
+itself (relevant for TEST-02-CRYPTSETUP). This change has been present
+in upstream for a while anyway.
+
+Related: #1761519
+rhel-only
+---
+ test/test-functions | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/test/test-functions b/test/test-functions
+index af9d16140f..fe25a501da 100644
+--- a/test/test-functions
++++ b/test/test-functions
+@@ -433,7 +433,7 @@ create_empty_image() {
+     [ -b "$LOOPDEV" ] || return 1
+     echo "LOOPDEV=$LOOPDEV" >> $STATEFILE
+     sfdisk "$LOOPDEV" <<EOF
+-,390M
++,350M
+ ,
+ EOF
+ 
diff --git a/SOURCES/0240-journal-do-not-trigger-assertion-when-journal_file_c.patch b/SOURCES/0240-journal-do-not-trigger-assertion-when-journal_file_c.patch
deleted file mode 100644
index 75f9aa1..0000000
--- a/SOURCES/0240-journal-do-not-trigger-assertion-when-journal_file_c.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 84e849bb006118bc24e8402754c6c5b624bc9efb Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Tue, 28 May 2019 12:40:17 +0900
-Subject: [PATCH] journal: do not trigger assertion when journal_file_close()
- get NULL
-
-We generally expect destructors to not complain if a NULL argument is passed.
-
-Closes #12400.
-
-(cherry picked from commit c377a6f3ad3d9bed4ce7e873e8e9ec6b1650c57d)
-(cherry picked from commit dc4c3a5aa35a5e88adcf210471d9460262c8c0d9)
-Resolves: #1807350
----
- src/journal/journal-file.c    | 3 ++-
- src/journal/journald-server.c | 7 ++-----
- 2 files changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
-index efc3ee052b..8249b11b23 100644
---- a/src/journal/journal-file.c
-+++ b/src/journal/journal-file.c
-@@ -335,7 +335,8 @@ bool journal_file_is_offlining(JournalFile *f) {
- }
- 
- JournalFile* journal_file_close(JournalFile *f) {
--        assert(f);
-+        if (!f)
-+                return NULL;
- 
- #if HAVE_GCRYPT
-         /* Write the final tag */
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index f2d2856e03..31a7b5ff03 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1906,11 +1906,8 @@ void server_done(Server *s) {
- 
-         client_context_flush_all(s);
- 
--        if (s->system_journal)
--                (void) journal_file_close(s->system_journal);
--
--        if (s->runtime_journal)
--                (void) journal_file_close(s->runtime_journal);
-+        (void) journal_file_close(s->system_journal);
-+        (void) journal_file_close(s->runtime_journal);
- 
-         ordered_hashmap_free_with_destructor(s->user_journals, journal_file_close);
- 
diff --git a/SOURCES/0240-shared-sleep-config-exclude-zram-devices-from-hibern.patch b/SOURCES/0240-shared-sleep-config-exclude-zram-devices-from-hibern.patch
new file mode 100644
index 0000000..667c909
--- /dev/null
+++ b/SOURCES/0240-shared-sleep-config-exclude-zram-devices-from-hibern.patch
@@ -0,0 +1,51 @@
+From 069cf14150b55e6580cf1d482709a0e48c36ee84 Mon Sep 17 00:00:00 2001
+From: Andrew Jorgensen <ajorgens@amazon.com>
+Date: Wed, 25 Jul 2018 08:06:57 -0700
+Subject: [PATCH] shared/sleep-config: exclude zram devices from hibernation
+ candidates
+
+On a host with sufficiently large zram but with no actual swap, logind will
+respond to CanHibernate() with yes. With this patch, it will correctly respond
+no, unless there are other swap devices to consider.
+
+(cherry picked from commit 411ae92b407bd7b4549b205ad754bcd0e3dfd81f)
+
+Resolves: #1763617
+---
+ src/shared/sleep-config.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
+index 9e4ce183d3..a1523e3f21 100644
+--- a/src/shared/sleep-config.c
++++ b/src/shared/sleep-config.c
+@@ -21,6 +21,7 @@
+ #include "log.h"
+ #include "macro.h"
+ #include "parse-util.h"
++#include "path-util.h"
+ #include "sleep-config.h"
+ #include "string-util.h"
+ #include "strv.h"
+@@ -201,9 +202,18 @@ int find_hibernate_location(char **device, char **type, size_t *size, size_t *us
+                         continue;
+                 }
+ 
+-                if (streq(type_field, "partition") && endswith(dev_field, "\\040(deleted)")) {
+-                        log_warning("Ignoring deleted swapfile '%s'.", dev_field);
+-                        continue;
++                if (streq(type_field, "partition")) {
++                        if (endswith(dev_field, "\\040(deleted)")) {
++                                log_warning("Ignoring deleted swapfile '%s'.", dev_field);
++                                continue;
++                        }
++
++                        const char *fn;
++                        fn = path_startswith(dev_field, "/dev/");
++                        if (fn && startswith(fn, "zram")) {
++                                log_debug("Ignoring compressed ram swap device '%s'.", dev_field);
++                                continue;
++                        }
+                 }
+                 if (device)
+                         *device = TAKE_PTR(dev_field);
diff --git a/SOURCES/0241-journal-use-cleanup-attribute-at-one-more-place.patch b/SOURCES/0241-journal-use-cleanup-attribute-at-one-more-place.patch
deleted file mode 100644
index c5ba94c..0000000
--- a/SOURCES/0241-journal-use-cleanup-attribute-at-one-more-place.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 8a9a0b62a58e1481b6a0f2e54b323b4eefadc4fd Mon Sep 17 00:00:00 2001
-From: Yu Watanabe <watanabe.yu+github@gmail.com>
-Date: Tue, 28 May 2019 18:07:01 +0900
-Subject: [PATCH] journal: use cleanup attribute at one more place
-
-(cherry picked from commit 627df1dc42b68a74b0882b06366d1185b1a34332)
-
-Conflicts:
-	src/journal/journald-server.c
-
-(cherry picked from commit ceacf935ac9f59bc08b5901f70f227958a2bcf52)
-Related: #1807350
----
- src/journal/journal-file.h    | 1 +
- src/journal/journald-server.c | 9 ++++-----
- 2 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
-index cd8a48a364..6a44fd39d2 100644
---- a/src/journal/journal-file.h
-+++ b/src/journal/journal-file.h
-@@ -144,6 +144,7 @@ int journal_file_open(
- int journal_file_set_offline(JournalFile *f, bool wait);
- bool journal_file_is_offlining(JournalFile *f);
- JournalFile* journal_file_close(JournalFile *j);
-+DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close);
- 
- int journal_file_open_reliably(
-                 const char *fname,
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index 31a7b5ff03..90c146dc67 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -253,8 +253,9 @@ static int open_journal(
-                 bool seal,
-                 JournalMetrics *metrics,
-                 JournalFile **ret) {
-+
-+        _cleanup_(journal_file_closep) JournalFile *f = NULL;
-         int r;
--        JournalFile *f;
- 
-         assert(s);
-         assert(fname);
-@@ -271,12 +272,10 @@ static int open_journal(
-                 return r;
- 
-         r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
--        if (r < 0) {
--                (void) journal_file_close(f);
-+        if (r < 0)
-                 return r;
--        }
- 
--        *ret = f;
-+        *ret = TAKE_PTR(f);
-         return r;
- }
- 
diff --git a/SOURCES/0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch b/SOURCES/0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch
new file mode 100644
index 0000000..5845313
--- /dev/null
+++ b/SOURCES/0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch
@@ -0,0 +1,45 @@
+From cc3c020a5f4fc577dbd2da769c22b77e37ae4e30 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Tue, 26 Feb 2019 17:33:27 +0100
+Subject: [PATCH] selinux: don't log SELINUX_INFO and SELINUX_WARNING messages
+ to audit
+
+Previously we logged even info message from libselinux as USER_AVC's to
+audit. For example, setting SELinux to permissive mode generated
+following audit message,
+
+time->Tue Feb 26 11:29:29 2019
+type=USER_AVC msg=audit(1551198569.423:334): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='avc:  received setenforce notice (enforcing=0)  exe="/usr/lib/systemd/systemd" sauid=0 hostname=? addr=? terminal=?'
+
+This is unnecessary and wrong at the same time. First, kernel already
+records audit event that SELinux was switched to permissive mode, also
+the type of the message really shouldn't be USER_AVC.
+
+Let's ignore SELINUX_WARNING and SELINUX_INFO and forward to audit only
+USER_AVC's and errors as these two libselinux message types have clear
+mapping to audit message types.
+
+(cherry picked from commit 6227fc14c48c4c17daed4b91f61cdd4aa375790a)
+
+Resolves: #1763612
+---
+ src/core/selinux-access.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
+index 39e994afd7..ada4f8705c 100644
+--- a/src/core/selinux-access.c
++++ b/src/core/selinux-access.c
+@@ -112,7 +112,11 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
+                 va_end(ap);
+ 
+                 if (r >= 0) {
+-                        audit_log_user_avc_message(fd, AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
++                        if (type == SELINUX_AVC)
++                                audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
++                        else if (type == SELINUX_ERROR)
++                                audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_SELINUX_ERR, buf, NULL, NULL, NULL, 0);
++
+                         return 0;
+                 }
+         }
diff --git a/SOURCES/0242-sd-device-introduce-log_device_-macros.patch b/SOURCES/0242-sd-device-introduce-log_device_-macros.patch
new file mode 100644
index 0000000..6b13e77
--- /dev/null
+++ b/SOURCES/0242-sd-device-introduce-log_device_-macros.patch
@@ -0,0 +1,47 @@
+From 0160499e86642f159a972be0196bf7c8a1d19ea8 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Mon, 22 Oct 2018 12:04:13 +0900
+Subject: [PATCH] sd-device: introduce log_device_*() macros
+
+(cherry picked from commit b0cba0ca526ed2d86e283a0fcfebdf0a4d4bea9b)
+
+Related: #1753369
+---
+ src/libsystemd/sd-device/device-util.h | 27 ++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h
+index 6dcd2645e6..448dfc63d7 100644
+--- a/src/libsystemd/sd-device/device-util.h
++++ b/src/libsystemd/sd-device/device-util.h
+@@ -33,3 +33,30 @@
+         for (device = sd_device_enumerator_get_subsystem_first(enumerator); \
+              device;                                                        \
+              device = sd_device_enumerator_get_subsystem_next(enumerator))
++
++#define log_device_full(device, level, error, ...)                      \
++        ({                                                              \
++                const char *_sysname = NULL, *_subsystem = NULL;        \
++                sd_device *_d = (device);                               \
++                int _level = (level), _error = (error);                 \
++                                                                        \
++                if (_d && _unlikely_(log_get_max_level() >= _level)) {  \
++                        (void) sd_device_get_sysname(_d, &_sysname);    \
++                        (void) sd_device_get_subsystem(_d, &_subsystem); \
++                }                                                       \
++                log_object_internal(_level, _error, __FILE__, __LINE__, __func__, \
++                                    _sysname ? "DEVICE=" : NULL, _sysname, \
++                                    _subsystem ? "SUBSYSTEM=" : NULL, _subsystem, ##__VA_ARGS__); \
++        })
++
++#define log_device_debug(link, ...)   log_device_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)
++#define log_device_info(link, ...)    log_device_full(link, LOG_INFO, 0, ##__VA_ARGS__)
++#define log_device_notice(link, ...)  log_device_full(link, LOG_NOTICE, 0, ##__VA_ARGS__)
++#define log_device_warning(link, ...) log_device_full(link, LOG_WARNING, 0, ##__VA_ARGS__)
++#define log_device_error(link, ...)   log_device_full(link, LOG_ERR, 0, ##__VA_ARGS__)
++
++#define log_device_debug_errno(link, error, ...)   log_device_full(link, LOG_DEBUG, error, ##__VA_ARGS__)
++#define log_device_info_errno(link, error, ...)    log_device_full(link, LOG_INFO, error, ##__VA_ARGS__)
++#define log_device_notice_errno(link, error, ...)  log_device_full(link, LOG_NOTICE, error, ##__VA_ARGS__)
++#define log_device_warning_errno(link, error, ...) log_device_full(link, LOG_WARNING, error, ##__VA_ARGS__)
++#define log_device_error_errno(link, error, ...)   log_device_full(link, LOG_ERR, error, ##__VA_ARGS__)
diff --git a/SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch b/SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch
new file mode 100644
index 0000000..0d32c08
--- /dev/null
+++ b/SOURCES/0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch
@@ -0,0 +1,505 @@
+From 080d3b14470f6ac59f4cfb97a4200ed18df5c260 Mon Sep 17 00:00:00 2001
+From: Fabian Henneke <fabian@henneke.me>
+Date: Wed, 21 Aug 2019 11:17:59 +0200
+Subject: [PATCH] udev: Add id program and rule for FIDO security tokens
+
+Add a fido_id program meant to be run for devices in the hidraw
+subsystem via an IMPORT directive. The program parses the HID report
+descriptor and assigns the ID_SECURITY_TOKEN environment variable if a
+declared usage matches the FIDO_CTAPHID_USAGE declared in the FIDO CTAP
+specification. This replaces the previous approach of whitelisting all
+known security token models manually.
+
+This commit is accompanied by a test suite and a fuzzer target for the
+descriptor parsing routine.
+
+Fixes: #11996.
+(cherry picked from commit d45ee2f31a8358db0accde2e7c81777cedadc3c2)
+
+Resolves: #1753369
+---
+ rules/60-fido-id.rules              |   7 ++
+ rules/meson.build                   |   1 +
+ src/fuzz/fuzz-fido-id-desc.c        |  23 +++++++
+ src/fuzz/fuzz-fido-id-desc.dict     |   6 ++
+ src/fuzz/meson.build                |   4 ++
+ src/test/meson.build                |   4 ++
+ src/test/test-fido-id-desc.c        |  85 +++++++++++++++++++++++
+ src/udev/fido_id/fido_id.c          | 103 ++++++++++++++++++++++++++++
+ src/udev/fido_id/fido_id_desc.c     |  92 +++++++++++++++++++++++++
+ src/udev/fido_id/fido_id_desc.h     |   8 +++
+ src/udev/meson.build                |   3 +
+ test/fuzz/fuzz-fido-id-desc/crash0  |   1 +
+ test/fuzz/fuzz-fido-id-desc/crash1  |   1 +
+ test/fuzz/fuzz-fido-id-desc/report0 | Bin 0 -> 71 bytes
+ test/fuzz/fuzz-fido-id-desc/report1 | Bin 0 -> 34 bytes
+ 15 files changed, 338 insertions(+)
+ create mode 100644 rules/60-fido-id.rules
+ create mode 100644 src/fuzz/fuzz-fido-id-desc.c
+ create mode 100644 src/fuzz/fuzz-fido-id-desc.dict
+ create mode 100644 src/test/test-fido-id-desc.c
+ create mode 100644 src/udev/fido_id/fido_id.c
+ create mode 100644 src/udev/fido_id/fido_id_desc.c
+ create mode 100644 src/udev/fido_id/fido_id_desc.h
+ create mode 100644 test/fuzz/fuzz-fido-id-desc/crash0
+ create mode 100644 test/fuzz/fuzz-fido-id-desc/crash1
+ create mode 100644 test/fuzz/fuzz-fido-id-desc/report0
+ create mode 100644 test/fuzz/fuzz-fido-id-desc/report1
+
+diff --git a/rules/60-fido-id.rules b/rules/60-fido-id.rules
+new file mode 100644
+index 0000000000..fcf5079704
+--- /dev/null
++++ b/rules/60-fido-id.rules
+@@ -0,0 +1,7 @@
++# do not edit this file, it will be overwritten on update
++
++ACTION=="remove", GOTO="fido_id_end"
++
++SUBSYSTEM=="hidraw", IMPORT{program}="fido_id"
++
++LABEL="fido_id_end"
+diff --git a/rules/meson.build b/rules/meson.build
+index b6aae596b6..6363f8bf2e 100644
+--- a/rules/meson.build
++++ b/rules/meson.build
+@@ -7,6 +7,7 @@ rules = files('''
+         60-cdrom_id.rules
+         60-drm.rules
+         60-evdev.rules
++        60-fido-id.rules
+         60-input-id.rules
+         60-persistent-alsa.rules
+         60-persistent-input.rules
+diff --git a/src/fuzz/fuzz-fido-id-desc.c b/src/fuzz/fuzz-fido-id-desc.c
+new file mode 100644
+index 0000000000..cf98dee044
+--- /dev/null
++++ b/src/fuzz/fuzz-fido-id-desc.c
+@@ -0,0 +1,23 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include <linux/hid.h>
++#include <stdbool.h>
++#include <stdint.h>
++#include <stdlib.h>
++
++#include "fido_id/fido_id_desc.h"
++#include "fuzz.h"
++#include "log.h"
++
++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
++        /* We don't want to fill the logs with messages about parse errors.
++         * Disable most logging if not running standalone */
++        if (!getenv("SYSTEMD_LOG_LEVEL"))
++                log_set_max_level(LOG_CRIT);
++
++        if (size > HID_MAX_DESCRIPTOR_SIZE)
++                return 0;
++        (void) is_fido_security_token_desc(data, size);
++
++        return 0;
++}
+diff --git a/src/fuzz/fuzz-fido-id-desc.dict b/src/fuzz/fuzz-fido-id-desc.dict
+new file mode 100644
+index 0000000000..d2d2679e18
+--- /dev/null
++++ b/src/fuzz/fuzz-fido-id-desc.dict
+@@ -0,0 +1,6 @@
++"\xfe"
++"\x00"
++"\x01"
++"\xf1"
++"\xd0"
++"\xf1\xd0\x00\x01"
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index 1dbe28e57e..483a952421 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -47,4 +47,8 @@ fuzzers += [
+          [libsystemd_journal_remote,
+           libshared],
+          []],
++        [['src/fuzz/fuzz-fido-id-desc.c',
++          'src/udev/fido_id/fido_id_desc.c'],
++         [],
++         []]
+ ]
+diff --git a/src/test/meson.build b/src/test/meson.build
+index 0998f59897..4259421f98 100644
+--- a/src/test/meson.build
++++ b/src/test/meson.build
+@@ -663,6 +663,10 @@ tests += [
+         [['src/test/test-bus-util.c'],
+          [],
+          []],
++        [['src/test/test-fido-id-desc.c',
++          'src/udev/fido_id/fido_id_desc.c'],
++         [],
++         []],
+ ]
+ 
+ ############################################################
+diff --git a/src/test/test-fido-id-desc.c b/src/test/test-fido-id-desc.c
+new file mode 100644
+index 0000000000..cf55dd3266
+--- /dev/null
++++ b/src/test/test-fido-id-desc.c
+@@ -0,0 +1,85 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include <stdint.h>
++#include <stdlib.h>
++
++#include "fido_id/fido_id_desc.h"
++#include "macro.h"
++
++static void test_is_fido_security_token_desc__fido(void) {
++        static const uint8_t FIDO_HID_DESC_1[] = {
++                0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
++                0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
++                0x40, 0x91, 0x02, 0xc0,
++        };
++        assert_se(is_fido_security_token_desc(FIDO_HID_DESC_1, sizeof(FIDO_HID_DESC_1)) > 0);
++
++        static const uint8_t FIDO_HID_DESC_2[] = {
++                0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25,
++                0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05,
++                0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 0x91,
++                0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, 0x00, 0x29, 0x65,
++                0x81, 0x00, 0x09, 0x03, 0x75, 0x08, 0x95, 0x08, 0xb1, 0x02, 0xc0,
++                0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
++                0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
++                0x40, 0x91, 0x02, 0xc0,
++        };
++        assert_se(is_fido_security_token_desc(FIDO_HID_DESC_2, sizeof(FIDO_HID_DESC_2)) > 0);
++}
++
++static void test_is_fido_security_token_desc__non_fido(void) {
++        /* Wrong usage page */
++        static const uint8_t NON_FIDO_HID_DESC_1[] = {
++                0x06, 0xd0, 0xf0, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
++                0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
++                0x40, 0x91, 0x02, 0xc0,
++        };
++        assert_se(is_fido_security_token_desc(NON_FIDO_HID_DESC_1, sizeof(NON_FIDO_HID_DESC_1)) == 0);
++
++        /* Wrong usage */
++        static const uint8_t NON_FIDO_HID_DESC_2[] = {
++                0x06, 0xd0, 0xf1, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
++                0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
++                0x40, 0x91, 0x02, 0xc0,
++        };
++        assert_se(is_fido_security_token_desc(NON_FIDO_HID_DESC_2, sizeof(NON_FIDO_HID_DESC_2)) == 0);
++
++        static const uint8_t NON_FIDO_HID_DESC_3[] = {
++                0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25,
++                0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05,
++                0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 0x91,
++                0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, 0x00, 0x29, 0x65,
++                0x81, 0x00, 0x09, 0x03, 0x75, 0x08, 0x95, 0x08, 0xb1, 0x02, 0xc0,
++        };
++        assert_se(is_fido_security_token_desc(NON_FIDO_HID_DESC_3, sizeof(NON_FIDO_HID_DESC_3)) == 0);
++}
++
++static void test_is_fido_security_token_desc__invalid(void) {
++        /* Size coded on 1 byte, but no byte given */
++        static const uint8_t INVALID_HID_DESC_1[] = { 0x01 };
++        assert_se(is_fido_security_token_desc(INVALID_HID_DESC_1, sizeof(INVALID_HID_DESC_1)) < 0);
++
++        /* Size coded on 2 bytes, but only 1 byte given */
++        static const uint8_t INVALID_HID_DESC_2[] = { 0x02, 0x01 };
++        assert_se(is_fido_security_token_desc(INVALID_HID_DESC_2, sizeof(INVALID_HID_DESC_2)) < 0);
++
++        /* Size coded on 4 bytes, but only 3 bytes given */
++        static const uint8_t INVALID_HID_DESC_3[] = { 0x03, 0x01, 0x02, 0x03 };
++        assert_se(is_fido_security_token_desc(INVALID_HID_DESC_3, sizeof(INVALID_HID_DESC_3)) < 0);
++
++        /* Long item without a size byte */
++        static const uint8_t INVALID_HID_DESC_4[] = { 0xfe };
++        assert_se(is_fido_security_token_desc(INVALID_HID_DESC_4, sizeof(INVALID_HID_DESC_4)) < 0);
++
++        /* Usage pages are coded on at most 2 bytes */
++        static const uint8_t INVALID_HID_DESC_5[] = { 0x07, 0x01, 0x02, 0x03, 0x04 };
++        assert_se(is_fido_security_token_desc(INVALID_HID_DESC_5, sizeof(INVALID_HID_DESC_5)) < 0);
++}
++
++int main(int argc, char *argv[]) {
++        test_is_fido_security_token_desc__fido();
++        test_is_fido_security_token_desc__non_fido();
++        test_is_fido_security_token_desc__invalid();
++
++        return EXIT_SUCCESS;
++}
+diff --git a/src/udev/fido_id/fido_id.c b/src/udev/fido_id/fido_id.c
+new file mode 100644
+index 0000000000..7e1cc804f2
+--- /dev/null
++++ b/src/udev/fido_id/fido_id.c
+@@ -0,0 +1,103 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++/*
++ * Identifies FIDO CTAP1 ("U2F")/CTAP2 security tokens based on the usage declared in their report
++ * descriptor and outputs suitable environment variables.
++ *
++ * Inspired by Andrew Lutomirski's 'u2f-hidraw-policy.c'
++ */
++
++#include <errno.h>
++#include <fcntl.h>
++#include <linux/hid.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <unistd.h>
++
++#include "sd-device.h"
++
++#include "device-internal.h"
++#include "device-private.h"
++#include "device-util.h"
++#include "fd-util.h"
++#include "fido_id_desc.h"
++#include "log.h"
++#include "macro.h"
++#include "path-util.h"
++#include "string-util.h"
++#include "udev-util.h"
++
++static int run(int argc, char **argv) {
++        _cleanup_(sd_device_unrefp) struct sd_device *device = NULL;
++        _cleanup_free_ char *desc_path = NULL;
++        _cleanup_close_ int fd = -1;
++
++        struct sd_device *hid_device;
++        const char *sys_path;
++        uint8_t desc[HID_MAX_DESCRIPTOR_SIZE];
++        ssize_t desc_len;
++
++        int r;
++
++        log_set_target(LOG_TARGET_AUTO);
++        udev_parse_config();
++        log_parse_environment();
++        log_open();
++
++        if (argc > 2)
++                return log_error_errno(EINVAL, "Usage: %s [SYSFS_PATH]", program_invocation_short_name);
++
++        if (argc == 1) {
++                r = device_new_from_strv(&device, environ);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to get current device from environment: %m");
++        } else {
++                r = sd_device_new_from_syspath(&device, argv[1]);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to get device from syspath: %m");
++        }
++
++        r = sd_device_get_parent(device, &hid_device);
++        if (r < 0)
++                return log_device_error_errno(device, r, "Failed to get parent HID device: %m");
++
++        r = sd_device_get_syspath(hid_device, &sys_path);
++        if (r < 0)
++                return log_device_error_errno(hid_device, r, "Failed to get syspath for HID device: %m");
++
++        desc_path = path_join(NULL, sys_path, "report_descriptor");
++        if (!desc_path)
++                return log_oom();
++
++        fd = open(desc_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
++        if (fd < 0)
++                return log_device_error_errno(hid_device, errno,
++                                              "Failed to open report descriptor at '%s': %m", desc_path);
++
++        desc_len = read(fd, desc, sizeof(desc));
++        if (desc_len < 0)
++                return log_device_error_errno(hid_device, errno,
++                                              "Failed to read report descriptor at '%s': %m", desc_path);
++        if (desc_len == 0)
++                return log_device_debug_errno(hid_device, EINVAL,
++                                              "Empty report descriptor at '%s'.", desc_path);
++
++        r = is_fido_security_token_desc(desc, desc_len);
++        if (r < 0)
++                return log_device_debug_errno(hid_device, r,
++                                              "Failed to parse report descriptor at '%s'.", desc_path);
++        if (r > 0) {
++                printf("ID_FIDO_TOKEN=1\n");
++                printf("ID_SECURITY_TOKEN=1\n");
++        }
++
++        return 0;
++}
++
++int main(int argc, char *argv[]) {
++    int r;
++
++    r = run(argc, argv);
++
++    return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
++}
+diff --git a/src/udev/fido_id/fido_id_desc.c b/src/udev/fido_id/fido_id_desc.c
+new file mode 100644
+index 0000000000..bbfcf93709
+--- /dev/null
++++ b/src/udev/fido_id/fido_id_desc.c
+@@ -0,0 +1,92 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++/* Inspired by Andrew Lutomirski's 'u2f-hidraw-policy.c' */
++
++#include <errno.h>
++#include <stdbool.h>
++#include <stddef.h>
++#include <stdint.h>
++
++#include "fido_id_desc.h"
++
++#define HID_RPTDESC_FIRST_BYTE_LONG_ITEM 0xfeu
++#define HID_RPTDESC_TYPE_GLOBAL 0x1u
++#define HID_RPTDESC_TYPE_LOCAL 0x2u
++#define HID_RPTDESC_TAG_USAGE_PAGE 0x0u
++#define HID_RPTDESC_TAG_USAGE 0x0u
++
++/*
++ * HID usage for FIDO CTAP1 ("U2F") and CTAP2 security tokens.
++ * https://fidoalliance.org/specs/fido-u2f-v1.0-ps-20141009/fido-u2f-u2f_hid.h-v1.0-ps-20141009.txt
++ * https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#usb-discovery
++ * https://www.usb.org/sites/default/files/hutrr48.pdf
++ */
++#define FIDO_FULL_USAGE_CTAPHID 0xf1d00001u
++
++/*
++ * Parses a HID report descriptor and identifies FIDO CTAP1 ("U2F")/CTAP2 security tokens based on their
++ * declared usage.
++ * A positive return value indicates that the report descriptor belongs to a FIDO security token.
++ * https://www.usb.org/sites/default/files/documents/hid1_11.pdf (Section 6.2.2)
++ */
++int is_fido_security_token_desc(const uint8_t *desc, size_t desc_len) {
++        uint32_t usage = 0;
++
++        for (size_t pos = 0; pos < desc_len; ) {
++                uint8_t tag, type, size_code;
++                size_t size;
++                uint32_t value;
++
++                /* Report descriptors consists of short items (1-5 bytes) and long items (3-258 bytes). */
++                if (desc[pos] == HID_RPTDESC_FIRST_BYTE_LONG_ITEM) {
++                        /* No long items are defined in the spec; skip them.
++                         * The length of the data in a long item is contained in the byte after the long
++                         * item tag. The header consists of three bytes: special long item tag, length,
++                         * actual tag. */
++                        if (pos + 1 >= desc_len)
++                                return -EINVAL;
++                        pos += desc[pos + 1] + 3;
++                        continue;
++                }
++
++                /* The first byte of a short item encodes tag, type and size. */
++                tag = desc[pos] >> 4;          /* Bits 7 to 4 */
++                type = (desc[pos] >> 2) & 0x3; /* Bits 3 and 2 */
++                size_code = desc[pos] & 0x3;   /* Bits 1 and 0 */
++                /* Size is coded as follows:
++                 * 0 -> 0 bytes, 1 -> 1 byte, 2 -> 2 bytes, 3 -> 4 bytes
++                 */
++                size = size_code < 3 ? size_code : 4;
++                /* Consume header byte. */
++                pos++;
++
++                /* Extract the item value coded on size bytes. */
++                if (pos + size > desc_len)
++                        return -EINVAL;
++                value = 0;
++                for (size_t i = 0; i < size; i++)
++                        value |= (uint32_t) desc[pos + i] << (8 * i);
++                /* Consume value bytes. */
++                pos += size;
++
++                if (type == HID_RPTDESC_TYPE_GLOBAL && tag == HID_RPTDESC_TAG_USAGE_PAGE) {
++                        /* A usage page is a 16 bit value coded on at most 16 bits. */
++                        if (size > 2)
++                                return -EINVAL;
++                        /* A usage page sets the upper 16 bits of a following usage. */
++                        usage = (value & 0x0000ffffu) << 16;
++                }
++
++                if (type == HID_RPTDESC_TYPE_LOCAL && tag == HID_RPTDESC_TAG_USAGE) {
++                        /* A usage is a 32 bit value, but is prepended with the current usage page if
++                         * coded on less than 4 bytes (that is, at most 2 bytes). */
++                        if (size == 4)
++                                usage = value;
++                        else
++                                usage = (usage & 0xffff0000u) | (value & 0x0000ffffu);
++                        if (usage == FIDO_FULL_USAGE_CTAPHID)
++                                return 1;
++                }
++        }
++
++        return 0;
++}
+diff --git a/src/udev/fido_id/fido_id_desc.h b/src/udev/fido_id/fido_id_desc.h
+new file mode 100644
+index 0000000000..c813a3a454
+--- /dev/null
++++ b/src/udev/fido_id/fido_id_desc.h
+@@ -0,0 +1,8 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#pragma once
++
++#include <stddef.h>
++#include <stdint.h>
++
++int is_fido_security_token_desc(const uint8_t *desc, size_t desc_len);
+diff --git a/src/udev/meson.build b/src/udev/meson.build
+index 3bcd2bd3d7..5931a6da7d 100644
+--- a/src/udev/meson.build
++++ b/src/udev/meson.build
+@@ -160,6 +160,9 @@ libudev_core = static_library(
+ foreach prog : [['ata_id/ata_id.c'],
+                 ['cdrom_id/cdrom_id.c'],
+                 ['collect/collect.c'],
++                ['fido_id/fido_id.c',
++                 'fido_id/fido_id_desc.c',
++                 'fido_id/fido_id_desc.h'],
+                 ['scsi_id/scsi_id.c',
+                  'scsi_id/scsi_id.h',
+                  'scsi_id/scsi_serial.c',
+diff --git a/test/fuzz/fuzz-fido-id-desc/crash0 b/test/fuzz/fuzz-fido-id-desc/crash0
+new file mode 100644
+index 0000000000..e066656502
+--- /dev/null
++++ b/test/fuzz/fuzz-fido-id-desc/crash0
+@@ -0,0 +1 @@
++�
+\ No newline at end of file
+diff --git a/test/fuzz/fuzz-fido-id-desc/crash1 b/test/fuzz/fuzz-fido-id-desc/crash1
+new file mode 100644
+index 0000000000..aef3e18335
+--- /dev/null
++++ b/test/fuzz/fuzz-fido-id-desc/crash1
+@@ -0,0 +1 @@
++������
+\ No newline at end of file
+diff --git a/test/fuzz/fuzz-fido-id-desc/report0 b/test/fuzz/fuzz-fido-id-desc/report0
+new file mode 100644
+index 0000000000000000000000000000000000000000..48757cba682ffddd5a1ddd8988bb8bcdc7db0a7a
+GIT binary patch
+literal 71
+zcmZQ&<YZgO$jUDHK=ZjMgDPVw<5Z4Drm2jj9F2@qSxXsNIV2f1Sto)-m?tt$Wh><X
+Xs!9c_XV6S-WZ+~j<(SH`k?8;c6l@Pq
+
+literal 0
+HcmV?d00001
+
+diff --git a/test/fuzz/fuzz-fido-id-desc/report1 b/test/fuzz/fuzz-fido-id-desc/report1
+new file mode 100644
+index 0000000000000000000000000000000000000000..b70b7fb871aeccf4074ccbd20e3cdbaca42e23b3
+GIT binary patch
+literal 34
+icmZR(@R5^oAtR@PD1+L6hEk5H4vkElig3<ErUL+_0SUDL
+
+literal 0
+HcmV?d00001
+
diff --git a/SOURCES/0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch b/SOURCES/0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
new file mode 100644
index 0000000..9977fa0
--- /dev/null
+++ b/SOURCES/0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
@@ -0,0 +1,33 @@
+From c3be943b30689f77ded9f431fdafb666769aea89 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Aug 2019 19:00:34 +0200
+Subject: [PATCH] shared/but-util: drop trusted annotation from
+ bus_open_system_watch_bind_with_description()
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1746057
+
+This only affects systemd-resolved. bus_open_system_watch_bind_with_description()
+is also used in timesyncd, but it has no methods, only read-only properties, and
+in networkd, but it annotates all methods with SD_BUS_VTABLE_UNPRIVILEGED and does
+polkit checks.
+
+Resolves: #1746857
+---
+ src/shared/bus-util.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
+index a4f2deba31..302dbb4c2e 100644
+--- a/src/shared/bus-util.c
++++ b/src/shared/bus-util.c
+@@ -1699,10 +1699,6 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
+         if (r < 0)
+                 return r;
+ 
+-        r = sd_bus_set_trusted(bus, true);
+-        if (r < 0)
+-                return r;
+-
+         r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
+         if (r < 0)
+                 return r;
diff --git a/SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch b/SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch
new file mode 100644
index 0000000..bdb144e
--- /dev/null
+++ b/SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch
@@ -0,0 +1,50 @@
+From 7e0f9a0cd4053fcc713a99ada3d0d50793b83564 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Aug 2019 19:00:50 +0200
+Subject: [PATCH] sd-bus: adjust indentation of comments
+
+Related: #1746857
+---
+ src/libsystemd/sd-bus/sd-bus.c | 3 +--
+ src/shared/bus-util.c          | 7 ++++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 3583e24e64..1c9e967ae0 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -1341,8 +1341,7 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip
+         b->bus_client = true;
+         b->is_user = true;
+ 
+-        /* We don't do any per-method access control on the user
+-         * bus. */
++        /* We don't do any per-method access control on the user bus. */
+         b->trusted = true;
+         b->is_local = true;
+ 
+diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
+index 302dbb4c2e..2d908eb45c 100644
+--- a/src/shared/bus-util.c
++++ b/src/shared/bus-util.c
+@@ -1675,7 +1675,8 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
+ 
+         assert(ret);
+ 
+-        /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */
++        /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal
++         * turned on. */
+ 
+         r = sd_bus_new(&bus);
+         if (r < 0)
+@@ -1890,8 +1891,8 @@ int bus_reply_pair_array(sd_bus_message *m, char **l) {
+ 
+         assert(m);
+ 
+-        /* Reply to the specified message with a message containing a dictionary put together from the specified
+-         * strv */
++        /* Reply to the specified message with a message containing a dictionary put together from the
++         * specified strv */
+ 
+         r = sd_bus_message_new_method_return(m, &reply);
+         if (r < 0)
diff --git a/SOURCES/0246-resolved-do-not-run-loop-twice.patch b/SOURCES/0246-resolved-do-not-run-loop-twice.patch
new file mode 100644
index 0000000..70fdf78
--- /dev/null
+++ b/SOURCES/0246-resolved-do-not-run-loop-twice.patch
@@ -0,0 +1,46 @@
+From d95afbca80cf52f0bc84b2e1b4af6aadda007138 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Aug 2019 19:02:53 +0200
+Subject: [PATCH] resolved: do not run loop twice
+
+This doesn't matter much, but let's just do the loop once and allocate
+the populate the result set on the fly. If we find an error, it'll get
+cleaned up automatically.
+
+Related: #1746857
+---
+ src/resolve/resolved-link-bus.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
+index b1581740d8..46d2b11636 100644
+--- a/src/resolve/resolved-link-bus.c
++++ b/src/resolve/resolved-link-bus.c
+@@ -492,6 +492,10 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
+         if (r < 0)
+                 return r;
+ 
++        ns = set_new(&dns_name_hash_ops);
++        if (!ns)
++                return -ENOMEM;
++
+         r = sd_bus_message_read_strv(message, &ntas);
+         if (r < 0)
+                 return r;
+@@ -501,14 +505,9 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
+                 if (r < 0)
+                         return r;
+                 if (r == 0)
+-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i);
+-        }
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
++                                                 "Invalid negative trust anchor domain: %s", *i);
+ 
+-        ns = set_new(&dns_name_hash_ops);
+-        if (!ns)
+-                return -ENOMEM;
+-
+-        STRV_FOREACH(i, ntas) {
+                 r = set_put_strdup(ns, *i);
+                 if (r < 0)
+                         return r;
diff --git a/SOURCES/0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch b/SOURCES/0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
new file mode 100644
index 0000000..5e2b359
--- /dev/null
+++ b/SOURCES/0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
@@ -0,0 +1,347 @@
+From ddd08e75b1e7fa1f6dfef3d30a0c1ef8c63e4d07 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Aug 2019 19:25:05 +0200
+Subject: [PATCH] resolved: allow access to Set*Link and Revert methods through
+ polkit
+
+This matches what is done in networkd very closely. In fact even the
+policy descriptions are all identical (with s/network/resolve), except
+for the last one:
+resolved has org.freedesktop.resolve1.revert while
+networkd has org.freedesktop.network1.revert-ntp and
+org.freedesktop.network1.revert-dns so the description is a bit different.
+
+Conflicts:
+	src/resolve/resolved-bus.c
+	src/resolve/resolved-link-bus.c
+
+Related: #1746857
+---
+ src/resolve/org.freedesktop.resolve1.policy | 99 +++++++++++++++++++++
+ src/resolve/resolved-bus.c                  | 22 ++---
+ src/resolve/resolved-link-bus.c             | 97 +++++++++++++++++---
+ 3 files changed, 197 insertions(+), 21 deletions(-)
+
+diff --git a/src/resolve/org.freedesktop.resolve1.policy b/src/resolve/org.freedesktop.resolve1.policy
+index b65ba3e56a..592c4eb8b0 100644
+--- a/src/resolve/org.freedesktop.resolve1.policy
++++ b/src/resolve/org.freedesktop.resolve1.policy
+@@ -40,4 +40,103 @@
+                 <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
+         </action>
+ 
++        <action id="org.freedesktop.resolve1.set-dns-servers">
++                <description gettext-domain="systemd">Set DNS servers</description>
++                <message gettext-domain="systemd">Authentication is required to set DNS servers.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-domains">
++                <description gettext-domain="systemd">Set domains</description>
++                <message gettext-domain="systemd">Authentication is required to set domains.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-default-route">
++                <description gettext-domain="systemd">Set default route</description>
++                <message gettext-domain="systemd">Authentication is required to set default route.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-llmnr">
++                <description gettext-domain="systemd">Enable/disable LLMNR</description>
++                <message gettext-domain="systemd">Authentication is required to enable or disable LLMNR.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-mdns">
++                <description gettext-domain="systemd">Enable/disable multicast DNS</description>
++                <message gettext-domain="systemd">Authentication is required to enable or disable multicast DNS.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-dns-over-tls">
++                <description gettext-domain="systemd">Enable/disable DNS over TLS</description>
++                <message gettext-domain="systemd">Authentication is required to enable or disable DNS over TLS.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-dnssec">
++                <description gettext-domain="systemd">Enable/disable DNSSEC</description>
++                <message gettext-domain="systemd">Authentication is required to enable or disable DNSSEC.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.set-dnssec-negative-trust-anchors">
++                <description gettext-domain="systemd">Set DNSSEC Negative Trust Anchors</description>
++                <message gettext-domain="systemd">Authentication is required to set DNSSEC Negative Trust Anchros.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
++        <action id="org.freedesktop.resolve1.revert">
++                <description gettext-domain="systemd">Revert name resolution settings</description>
++                <message gettext-domain="systemd">Authentication is required to revert name resolution settings.</message>
++                <defaults>
++                        <allow_any>auth_admin</allow_any>
++                        <allow_inactive>auth_admin</allow_inactive>
++                        <allow_active>auth_admin_keep</allow_active>
++                </defaults>
++                <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
++        </action>
++
+ </policyconfig>
+diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
+index da0a909dd6..4d6cc4fd48 100644
+--- a/src/resolve/resolved-bus.c
++++ b/src/resolve/resolved-bus.c
+@@ -1848,18 +1848,18 @@ static const sd_bus_vtable resolve_vtable[] = {
+         SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
+-        SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
+-        SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, 0),
+-        SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, 0),
++        SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
+-        SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
+-        SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0),
+-        SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0),
+-        SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0),
+-        SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, 0),
+-        SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0),
+-        SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0),
+-        SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0),
++        SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, SD_BUS_VTABLE_UNPRIVILEGED),
+ 
+         SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED),
+         SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED),
+diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
+index 46d2b11636..bf3e42264e 100644
+--- a/src/resolve/resolved-link-bus.c
++++ b/src/resolve/resolved-link-bus.c
+@@ -1,5 +1,9 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
++#include <net/if.h>
++#include <netinet/in.h>
++#include <sys/capability.h>
++
+ #include "alloc-util.h"
+ #include "bus-common-errors.h"
+ #include "bus-util.h"
+@@ -9,6 +13,7 @@
+ #include "resolved-link-bus.h"
+ #include "resolved-resolv-conf.h"
+ #include "strv.h"
++#include "user-util.h"
+ 
+ static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
+ static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
+@@ -235,6 +240,15 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
+         if (r < 0)
+                 return r;
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-dns-servers",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         dns_server_mark_all(l->dns_servers);
+ 
+         for (i = 0; i < n; i++) {
+@@ -298,12 +312,21 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
+                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
+         }
+ 
+-        dns_search_domain_mark_all(l->search_domains);
+-
+         r = sd_bus_message_rewind(message, false);
+         if (r < 0)
+                 return r;
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-domains",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
++        dns_search_domain_mark_all(l->search_domains);
++
+         for (;;) {
+                 DnsSearchDomain *d;
+                 const char *name;
+@@ -371,6 +394,15 @@ int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_er
+                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr);
+         }
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-llmnr",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         l->llmnr_support = mode;
+         link_allocate_scopes(l);
+         link_add_rrs(l, false);
+@@ -405,6 +437,15 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err
+                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns);
+         }
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-mdns",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         l->mdns_support = mode;
+         link_allocate_scopes(l);
+         link_add_rrs(l, false);
+@@ -439,6 +480,15 @@ int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd
+                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls);
+         }
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-dns-over-tls",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         link_set_dns_over_tls_mode(l, mode);
+ 
+         (void) link_save_user(l);
+@@ -471,6 +521,15 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
+                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec);
+         }
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-dnssec",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         link_set_dnssec_mode(l, mode);
+ 
+         (void) link_save_user(l);
+@@ -513,6 +572,15 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
+                         return r;
+         }
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.set-dnssec-negative-trust-anchors",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         set_free_free(l->dnssec_negative_trust_anchors);
+         l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
+ 
+@@ -532,6 +600,15 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error
+         if (r < 0)
+                 return r;
+ 
++        r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
++                                    "org.freedesktop.resolve1.revert",
++                                    NULL, true, UID_INVALID,
++                                    &l->manager->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         link_flush_settings(l);
+         link_allocate_scopes(l);
+         link_add_rrs(l, false);
+@@ -556,14 +633,14 @@ const sd_bus_vtable link_vtable[] = {
+         SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
+         SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
+ 
+-        SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0),
+-        SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0),
+-        SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
+-        SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
+-        SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, 0),
+-        SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
+-        SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, 0),
+-        SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, 0),
++        SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
++        SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED),
+ 
+         SD_BUS_VTABLE_END
+ };
diff --git a/SOURCES/0248-resolved-query-polkit-only-after-parsing-the-data.patch b/SOURCES/0248-resolved-query-polkit-only-after-parsing-the-data.patch
new file mode 100644
index 0000000..eac8530
--- /dev/null
+++ b/SOURCES/0248-resolved-query-polkit-only-after-parsing-the-data.patch
@@ -0,0 +1,48 @@
+From 7b00cae817e54ee3398ad3b42ec69a3b63676562 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 27 Aug 2019 19:28:19 +0200
+Subject: [PATCH] resolved: query polkit only after parsing the data
+
+That's what we do everywhere else because it leads to nicer user experience.
+
+Related: #1746857
+---
+ src/resolve/resolved-bus.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
+index 4d6cc4fd48..3f6a6f9e12 100644
+--- a/src/resolve/resolved-bus.c
++++ b/src/resolve/resolved-bus.c
+@@ -1632,15 +1632,6 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
+         if (m->mdns_support != RESOLVE_SUPPORT_YES)
+                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled");
+ 
+-        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
+-                                    "org.freedesktop.resolve1.register-service",
+-                                    NULL, false, UID_INVALID,
+-                                    &m->polkit_registry, error);
+-        if (r < 0)
+-                return r;
+-        if (r == 0)
+-                return 1; /* Polkit will call us back */
+-
+         service = new0(DnssdService, 1);
+         if (!service)
+                 return log_oom();
+@@ -1765,6 +1756,15 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
+         if (r < 0)
+                 return r;
+ 
++        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
++                                    "org.freedesktop.resolve1.register-service",
++                                    NULL, false, UID_INVALID,
++                                    &m->polkit_registry, error);
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return 1; /* Polkit will call us back */
++
+         r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops);
+         if (r < 0)
+                 return r;
diff --git a/SOURCES/0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch b/SOURCES/0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
new file mode 100644
index 0000000..932a2fc
--- /dev/null
+++ b/SOURCES/0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
@@ -0,0 +1,48 @@
+From 4d2145e3edd6ba6ac2e52a232fa5059ecdacaead Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Mon, 24 Dec 2018 00:29:56 +0100
+Subject: [PATCH] journal: rely on _cleanup_free_ to free a temporary string
+ used in client_context_read_cgroup
+
+Closes https://github.com/systemd/systemd/issues/11253.
+
+(cherry picked from commit ef30f7cac18a810814ada7e6a68a31d48cc9fccd)
+
+Resolves: #1764560
+---
+ src/journal/journald-context.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
+index c8e97e16de..3a768094d9 100644
+--- a/src/journal/journald-context.c
++++ b/src/journal/journald-context.c
+@@ -282,7 +282,7 @@ static int client_context_read_label(
+ }
+ 
+ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *unit_id) {
+-        char *t = NULL;
++        _cleanup_free_ char *t = NULL;
+         int r;
+ 
+         assert(c);
+@@ -290,7 +290,6 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
+         /* Try to acquire the current cgroup path */
+         r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t);
+         if (r < 0 || empty_or_root(t)) {
+-
+                 /* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted()
+                  * failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup
+                  * on cgroupsv1 and we want to be able to map log messages from them too. */
+@@ -304,10 +303,8 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
+         }
+ 
+         /* Let's shortcut this if the cgroup path didn't change */
+-        if (streq_ptr(c->cgroup, t)) {
+-                free(t);
++        if (streq_ptr(c->cgroup, t))
+                 return 0;
+-        }
+ 
+         free_and_replace(c->cgroup, t);
+ 
diff --git a/SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch b/SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch
new file mode 100644
index 0000000..4b03b91
--- /dev/null
+++ b/SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch
@@ -0,0 +1,90 @@
+From 76176de0889c3e8b9b3a176da24e4f8dbbd380a3 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Wed, 2 Oct 2019 11:59:41 +0200
+Subject: [PATCH] basic/user-util: allow dots in user names
+
+(based on commit 1a29610f5fa1bcb2eeb37d2c6b79d8d1a6dbb865)
+
+Resolves: #1717603
+---
+ src/basic/user-util.c     | 9 ++++++---
+ src/test/test-user-util.c | 8 ++++----
+ 2 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/src/basic/user-util.c b/src/basic/user-util.c
+index c533f67025..d92969c966 100644
+--- a/src/basic/user-util.c
++++ b/src/basic/user-util.c
+@@ -575,11 +575,14 @@ bool valid_user_group_name(const char *u) {
+         /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
+          * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
+          *
+-         * - We don't allow any dots (this would break chown syntax which permits dots as user/group name separator)
+          * - We require that names fit into the appropriate utmp field
+          * - We don't allow empty user names
+          *
+          * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
++         *
++         * jsynacek: We now allow dots in user names. The checks are not exhaustive as user names like "..." are allowed
++         * and valid according to POSIX, but can't be created using useradd. However, ".user" can be created. Let's not
++         * complicate the code by adding additional checks for weird corner cases like these,  as they don't really matter here.
+          */
+ 
+         if (isempty(u))
+@@ -587,14 +590,14 @@ bool valid_user_group_name(const char *u) {
+ 
+         if (!(u[0] >= 'a' && u[0] <= 'z') &&
+             !(u[0] >= 'A' && u[0] <= 'Z') &&
+-            u[0] != '_')
++            u[0] != '_' && u[0] != '.')
+                 return false;
+ 
+         for (i = u+1; *i; i++) {
+                 if (!(*i >= 'a' && *i <= 'z') &&
+                     !(*i >= 'A' && *i <= 'Z') &&
+                     !(*i >= '0' && *i <= '9') &&
+-                    !IN_SET(*i, '_', '-'))
++                    !IN_SET(*i, '_', '-', '.'))
+                         return false;
+         }
+ 
+diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
+index c1428fab02..9114d30b8c 100644
+--- a/src/test/test-user-util.c
++++ b/src/test/test-user-util.c
+@@ -71,8 +71,6 @@ static void test_valid_user_group_name(void) {
+         assert_se(!valid_user_group_name("-1"));
+         assert_se(!valid_user_group_name("-kkk"));
+         assert_se(!valid_user_group_name("rööt"));
+-        assert_se(!valid_user_group_name("."));
+-        assert_se(!valid_user_group_name("eff.eff"));
+         assert_se(!valid_user_group_name("foo\nbar"));
+         assert_se(!valid_user_group_name("0123456789012345678901234567890123456789"));
+         assert_se(!valid_user_group_name_or_id("aaa:bbb"));
+@@ -83,6 +81,8 @@ static void test_valid_user_group_name(void) {
+         assert_se(valid_user_group_name("_kkk"));
+         assert_se(valid_user_group_name("kkk-"));
+         assert_se(valid_user_group_name("kk-k"));
++        assert_se(valid_user_group_name(".moo"));
++        assert_se(valid_user_group_name("eff.eff"));
+ 
+         assert_se(valid_user_group_name("some5"));
+         assert_se(!valid_user_group_name("5some"));
+@@ -102,8 +102,6 @@ static void test_valid_user_group_name_or_id(void) {
+         assert_se(!valid_user_group_name_or_id("-1"));
+         assert_se(!valid_user_group_name_or_id("-kkk"));
+         assert_se(!valid_user_group_name_or_id("rööt"));
+-        assert_se(!valid_user_group_name_or_id("."));
+-        assert_se(!valid_user_group_name_or_id("eff.eff"));
+         assert_se(!valid_user_group_name_or_id("foo\nbar"));
+         assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789"));
+         assert_se(!valid_user_group_name_or_id("aaa:bbb"));
+@@ -114,6 +112,8 @@ static void test_valid_user_group_name_or_id(void) {
+         assert_se(valid_user_group_name_or_id("_kkk"));
+         assert_se(valid_user_group_name_or_id("kkk-"));
+         assert_se(valid_user_group_name_or_id("kk-k"));
++        assert_se(valid_user_group_name_or_id(".moo"));
++        assert_se(valid_user_group_name_or_id("eff.eff"));
+ 
+         assert_se(valid_user_group_name_or_id("some5"));
+         assert_se(!valid_user_group_name_or_id("5some"));
diff --git a/SOURCES/0251-sd-bus-bump-message-queue-size-again.patch b/SOURCES/0251-sd-bus-bump-message-queue-size-again.patch
new file mode 100644
index 0000000..5fd7ade
--- /dev/null
+++ b/SOURCES/0251-sd-bus-bump-message-queue-size-again.patch
@@ -0,0 +1,29 @@
+From 62623bafd9ce4842122ddeda83f9527e43b9a21f Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 8 Nov 2019 14:54:30 +0100
+Subject: [PATCH] sd-bus: bump message queue size again
+
+Simliarly to issue #4068, the current limit turns out to be too small for a
+big storage setup that uses many small disks. Let's bump it further.
+
+(cherry picked from commit 83a32ea7b03d6707b8e5bb90a0b3a6eb868ef633)
+Resolves: #1770189
+---
+ src/libsystemd/sd-bus/bus-internal.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
+index 90e6028983..5d773b14c4 100644
+--- a/src/libsystemd/sd-bus/bus-internal.h
++++ b/src/libsystemd/sd-bus/bus-internal.h
+@@ -328,8 +328,8 @@ struct sd_bus {
+  * with enough entropy yet and might delay the boot */
+ #define BUS_AUTH_TIMEOUT ((usec_t) DEFAULT_TIMEOUT_USEC)
+ 
+-#define BUS_WQUEUE_MAX (192*1024)
+-#define BUS_RQUEUE_MAX (192*1024)
++#define BUS_WQUEUE_MAX (384*1024)
++#define BUS_RQUEUE_MAX (384*1024)
+ 
+ #define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
+ #define BUS_AUTH_SIZE_MAX (64*1024)
diff --git a/SOURCES/0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch b/SOURCES/0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch
new file mode 100644
index 0000000..532dd60
--- /dev/null
+++ b/SOURCES/0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch
@@ -0,0 +1,109 @@
+From 18a45cf91dbdd075fb55d752f959e84d36f3ab3b Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 7 Sep 2018 06:13:17 +0000
+Subject: [PATCH] tests: put fuzz_journald_processing_function in a .c file
+
+(cherry picked from commit 231dca5579cfba6175d19eee5347d693893fb5aa)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald.c | 30 ++++++++++++++++++++++++++++++
+ src/fuzz/fuzz-journald.h | 24 ++----------------------
+ src/fuzz/meson.build     |  6 ++++--
+ 3 files changed, 36 insertions(+), 24 deletions(-)
+ create mode 100644 src/fuzz/fuzz-journald.c
+
+diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
+new file mode 100644
+index 0000000000..f271d7f2fe
+--- /dev/null
++++ b/src/fuzz/fuzz-journald.c
+@@ -0,0 +1,30 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include "alloc-util.h"
++#include "fuzz-journald.h"
++#include "journald-server.h"
++#include "sd-event.h"
++
++void fuzz_journald_processing_function(
++                const uint8_t *data,
++                size_t size,
++                void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
++        ) {
++        Server s = {};
++        char *label = NULL;
++        size_t label_len = 0;
++        struct ucred *ucred = NULL;
++        struct timeval *tv = NULL;
++
++        if (size == 0)
++                return;
++
++        assert_se(sd_event_default(&s.event) >= 0);
++        s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
++        s.buffer = memdup_suffix0(data, size);
++        assert_se(s.buffer);
++        s.buffer_size = size + 1;
++        s.storage = STORAGE_NONE;
++        (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
++        server_done(&s);
++}
+diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h
+index e66ef54c9b..e9d32a74aa 100644
+--- a/src/fuzz/fuzz-journald.h
++++ b/src/fuzz/fuzz-journald.h
+@@ -1,30 +1,10 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ #pragma once
+ 
+-#include "alloc-util.h"
+ #include "journald-server.h"
+-#include "sd-event.h"
+ 
+-static void fuzz_journald_processing_function(
++void fuzz_journald_processing_function(
+                 const uint8_t *data,
+                 size_t size,
+                 void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
+-        ) {
+-        Server s = {};
+-        char *label = NULL;
+-        size_t label_len = 0;
+-        struct ucred *ucred = NULL;
+-        struct timeval *tv = NULL;
+-
+-        if (size == 0)
+-                return;
+-
+-        assert_se(sd_event_default(&s.event) >= 0);
+-        s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
+-        s.buffer = memdup_suffix0(data, size);
+-        assert_se(s.buffer);
+-        s.buffer_size = size + 1;
+-        s.storage = STORAGE_NONE;
+-        (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
+-        server_done(&s);
+-}
++);
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index 483a952421..1f8631bcc0 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -33,12 +33,14 @@ fuzzers += [
+           libshared],
+          [libmount]],
+ 
+-        [['src/fuzz/fuzz-journald-native.c'],
++        [['src/fuzz/fuzz-journald-native.c',
++          'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+           libshared],
+          [libselinux]],
+ 
+-        [['src/fuzz/fuzz-journald-syslog.c'],
++        [['src/fuzz/fuzz-journald-syslog.c',
++          'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+           libshared],
+          [libselinux]],
diff --git a/SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch b/SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch
new file mode 100644
index 0000000..6e01bbf
--- /dev/null
+++ b/SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch
@@ -0,0 +1,129 @@
+From e7e70f575840cd021f6429f264911ae0cbff9741 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Thu, 15 Nov 2018 17:52:57 +0100
+Subject: [PATCH] tests: add a fuzzer for dev_kmsg_record
+
+(cherry picked from commit 8857fb9beb9dcb95a6ce1be14dc94c4dc4cd3ea3)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-kmsg.c                 | 29 +++++++++++++++++++
+ src/fuzz/meson.build                          |  5 ++++
+ src/journal/journald-kmsg.c                   |  2 +-
+ src/journal/journald-kmsg.h                   |  2 ++
+ test/fuzz/fuzz-journald-kmsg/basic            |  1 +
+ test/fuzz/fuzz-journald-kmsg/dev-null         |  2 ++
+ test/fuzz/fuzz-journald-kmsg/loopback         |  2 ++
+ .../fuzz-journald-kmsg/subsystem-loopback     |  2 ++
+ 8 files changed, 44 insertions(+), 1 deletion(-)
+ create mode 100644 src/fuzz/fuzz-journald-kmsg.c
+ create mode 100644 test/fuzz/fuzz-journald-kmsg/basic
+ create mode 100644 test/fuzz/fuzz-journald-kmsg/dev-null
+ create mode 100644 test/fuzz/fuzz-journald-kmsg/loopback
+ create mode 100644 test/fuzz/fuzz-journald-kmsg/subsystem-loopback
+
+diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
+new file mode 100644
+index 0000000000..5d99d244b5
+--- /dev/null
++++ b/src/fuzz/fuzz-journald-kmsg.c
+@@ -0,0 +1,29 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include "fuzz.h"
++#include "journald-kmsg.h"
++
++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
++        Server s = {};
++        _cleanup_free_ char *buffer = NULL;
++
++        if (size == 0)
++                return 0;
++
++        s = (Server) {
++                .native_fd = -1,
++                .stdout_fd = -1,
++                .dev_kmsg_fd = -1,
++                .audit_fd = -1,
++                .hostname_fd = -1,
++                .notify_fd = -1,
++                .storage = STORAGE_NONE,
++        };
++        assert_se(sd_event_default(&s.event) >= 0);
++        buffer = memdup(data, size);
++        assert_se(buffer);
++        dev_kmsg_record(&s, buffer, size);
++        server_done(&s);
++
++        return 0;
++}
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index 1f8631bcc0..0520e448a9 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -33,6 +33,11 @@ fuzzers += [
+           libshared],
+          [libmount]],
+ 
++        [['src/fuzz/fuzz-journald-kmsg.c'],
++         [libjournal_core,
++          libshared],
++         [libselinux]],
++
+         [['src/fuzz/fuzz-journald-native.c',
+           'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
+index 7644bebfc8..0cdf1c4794 100644
+--- a/src/journal/journald-kmsg.c
++++ b/src/journal/journald-kmsg.c
+@@ -93,7 +93,7 @@ static bool is_us(const char *identifier, const char *pid) {
+                streq(identifier, program_invocation_short_name);
+ }
+ 
+-static void dev_kmsg_record(Server *s, char *p, size_t l) {
++void dev_kmsg_record(Server *s, char *p, size_t l) {
+ 
+         _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL;
+         struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
+diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h
+index bff24ac310..2326bc8c93 100644
+--- a/src/journal/journald-kmsg.h
++++ b/src/journal/journald-kmsg.h
+@@ -9,3 +9,5 @@ int server_flush_dev_kmsg(Server *s);
+ void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred);
+ 
+ int server_open_kernel_seqnum(Server *s);
++
++void dev_kmsg_record(Server *s, char *p, size_t l);
+diff --git a/test/fuzz/fuzz-journald-kmsg/basic b/test/fuzz/fuzz-journald-kmsg/basic
+new file mode 100644
+index 0000000000..1299cd0869
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-kmsg/basic
+@@ -0,0 +1 @@
++29,456,292891883,-;systemd[1]: Reexecuting.
+diff --git a/test/fuzz/fuzz-journald-kmsg/dev-null b/test/fuzz/fuzz-journald-kmsg/dev-null
+new file mode 100644
+index 0000000000..de039588b5
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-kmsg/dev-null
+@@ -0,0 +1,2 @@
++12,460,1322026586,-;hey
++ DEVICE=c1:3
+diff --git a/test/fuzz/fuzz-journald-kmsg/loopback b/test/fuzz/fuzz-journald-kmsg/loopback
+new file mode 100644
+index 0000000000..ca320177b7
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-kmsg/loopback
+@@ -0,0 +1,2 @@
++12,460,1322026586,-;hey
++ DEVICE=n1
+diff --git a/test/fuzz/fuzz-journald-kmsg/subsystem-loopback b/test/fuzz/fuzz-journald-kmsg/subsystem-loopback
+new file mode 100644
+index 0000000000..af9c0d91e5
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-kmsg/subsystem-loopback
+@@ -0,0 +1,2 @@
++12,460,1322026586,-;hey
++ DEVICE=+net:lo
diff --git a/SOURCES/0254-basic-remove-an-assertion-from-cunescape_one.patch b/SOURCES/0254-basic-remove-an-assertion-from-cunescape_one.patch
new file mode 100644
index 0000000..ec38ffc
--- /dev/null
+++ b/SOURCES/0254-basic-remove-an-assertion-from-cunescape_one.patch
@@ -0,0 +1,30 @@
+From 43d72623fdfca8500c8c89a4b5023e35a3f0b259 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 07:05:29 +0100
+Subject: [PATCH] basic: remove an assertion from cunescape_one
+
+The function takes a pointer to a random block of memory and
+the length of that block. It shouldn't crash every time it sees
+a zero byte at the beginning there.
+
+This should help the dev-kmsg fuzzer to keep going.
+
+(cherry picked from commit 8dc4de966ce6d32470aaff30ed054f6a2688d6d7)
+
+Resolves: #1764560
+---
+ src/basic/escape.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/basic/escape.c b/src/basic/escape.c
+index 5004763d97..5f715156fb 100644
+--- a/src/basic/escape.c
++++ b/src/basic/escape.c
+@@ -106,7 +106,6 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
+         int r = 1;
+ 
+         assert(p);
+-        assert(*p);
+         assert(ret);
+ 
+         /* Unescapes C style. Returns the unescaped character in ret.
diff --git a/SOURCES/0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch b/SOURCES/0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch
new file mode 100644
index 0000000..28a0b3e
--- /dev/null
+++ b/SOURCES/0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch
@@ -0,0 +1,25 @@
+From f00d221d5dc92a530e260db5f44fa57653f03e8b Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 07:11:06 +0100
+Subject: [PATCH] journal: fix an off-by-one error in dev_kmsg_record
+
+(cherry picked from commit 080d112caa0dc948555a69a008c1caf4d5d41ed6)
+
+Resolves: #1764560
+---
+ src/journal/journald-kmsg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
+index 0cdf1c4794..726c006ce1 100644
+--- a/src/journal/journald-kmsg.c
++++ b/src/journal/journald-kmsg.c
+@@ -239,7 +239,7 @@ void dev_kmsg_record(Server *s, char *p, size_t l) {
+                         ll = udev_device_get_devlinks_list_entry(ud);
+                         udev_list_entry_foreach(ll, ll) {
+ 
+-                                if (j > N_IOVEC_UDEV_FIELDS)
++                                if (j >= N_IOVEC_UDEV_FIELDS)
+                                         break;
+ 
+                                 g = udev_list_entry_get_name(ll);
diff --git a/SOURCES/0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch b/SOURCES/0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch
new file mode 100644
index 0000000..14c1223
--- /dev/null
+++ b/SOURCES/0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch
@@ -0,0 +1,25 @@
+From 4caa887ae8eabc087d6f9f2b233c96c220de8b02 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 07:20:44 +0100
+Subject: [PATCH] tests: add a reproducer for a memory leak fixed in
+ 30eddcd51b8a472e05d3b8d1 in August
+
+(cherry picked from commit 1dd485b700fe9ad94d7a780f14fcf18a4738ace4)
+
+Resolves: #1764560
+---
+ ...leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 | Bin 0 -> 1847 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ create mode 100644 test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43
+
+diff --git a/test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 b/test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43
+new file mode 100644
+index 0000000000000000000000000000000000000000..424ae5cb010aa519758e6af90cc981795b68d3fd
+GIT binary patch
+literal 1847
+zcmXps(lIeJ&@nVNGBPkSGqo_&(Y4M<t>jX0aSiiycD2<{NiEaQE6vG)izFLb8I!<a
+b7zLvtFd70lLcjrs_^9w`2#kin;0*x)kUJOk
+
+literal 0
+HcmV?d00001
+
diff --git a/SOURCES/0257-tests-add-a-reproducer-for-a-heap-buffer-overflow-fi.patch b/SOURCES/0257-tests-add-a-reproducer-for-a-heap-buffer-overflow-fi.patch
new file mode 100644
index 0000000..ee63a32
--- /dev/null
+++ b/SOURCES/0257-tests-add-a-reproducer-for-a-heap-buffer-overflow-fi.patch
@@ -0,0 +1,25 @@
+From 375fd5f8b3c6fb0f7c29ceb166f70bfd45314e04 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 07:33:02 +0100
+Subject: [PATCH] tests: add a reproducer for a heap-buffer-overflow fixed in
+ 937b1171378bc1000a
+
+(cherry picked from commit f7a6b40187a98751a9ab6867e8b52e4e6f1dad5c)
+
+Resolves: #1764560
+---
+ ...crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 | Bin 0 -> 112 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ create mode 100644 test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963
+
+diff --git a/test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 b/test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963
+new file mode 100644
+index 0000000000000000000000000000000000000000..19887a1fec9fc29b1f7da8a2d1c5ea5054f2bc02
+GIT binary patch
+literal 112
+zcmXpq)Zrxx80r}680lCOP-~&{)k?wIfGehgOM!tQroxI#0Z63Aa4DF?03ibx03hxS
+A82|tP
+
+literal 0
+HcmV?d00001
+
diff --git a/SOURCES/0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch b/SOURCES/0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch
new file mode 100644
index 0000000..3ffa913
--- /dev/null
+++ b/SOURCES/0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch
@@ -0,0 +1,44 @@
+From af471e7402a70b670cd50e45c6139a0ac50a74bd Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 09:23:53 +0100
+Subject: [PATCH] test: initialize syslog_fd in fuzz-journald-kmsg too
+
+This is a follow-up to 8857fb9beb9dcb that prevents the fuzzer from crashing with
+```
+==220==ERROR: AddressSanitizer: ABRT on unknown address 0x0000000000dc (pc 0x7ff4953c8428 bp 0x7ffcf66ec290 sp 0x7ffcf66ec128 T0)
+SCARINESS: 10 (signal)
+    #0 0x7ff4953c8427 in gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35427)
+    #1 0x7ff4953ca029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029)
+    #2 0x7ff49666503a in log_assert_failed_realm /work/build/../../src/systemd/src/basic/log.c:805:9
+    #3 0x7ff496614ecf in safe_close /work/build/../../src/systemd/src/basic/fd-util.c:66:17
+    #4 0x548806 in server_done /work/build/../../src/systemd/src/journal/journald-server.c:2064:9
+    #5 0x5349fa in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-journald-kmsg.c:26:9
+    #6 0x592755 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:571:15
+    #7 0x590627 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:480:3
+    #8 0x594432 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:708:19
+    #9 0x5973c6 in fuzzer::Fuzzer::Loop(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, fuzzer::fuzzer_allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) /src/libfuzzer/FuzzerLoop.cpp:839:5
+    #10 0x574541 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6
+    #11 0x5675fc in main /src/libfuzzer/FuzzerMain.cpp:20:10
+    #12 0x7ff4953b382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
+    #13 0x420f58 in _start (/out/fuzz-journald-kmsg+0x420f58)
+```
+
+(cherry picked from commit cc55ac0171a2493768c021faa356513642797e7f)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-kmsg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
+index 5d99d244b5..e2611c6d45 100644
+--- a/src/fuzz/fuzz-journald-kmsg.c
++++ b/src/fuzz/fuzz-journald-kmsg.c
+@@ -11,6 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+                 return 0;
+ 
+         s = (Server) {
++                .syslog_fd = -1,
+                 .native_fd = -1,
+                 .stdout_fd = -1,
+                 .dev_kmsg_fd = -1,
diff --git a/SOURCES/0259-tests-add-a-fuzzer-for-process_audit_string.patch b/SOURCES/0259-tests-add-a-fuzzer-for-process_audit_string.patch
new file mode 100644
index 0000000..d6ea02d
--- /dev/null
+++ b/SOURCES/0259-tests-add-a-fuzzer-for-process_audit_string.patch
@@ -0,0 +1,99 @@
+From f991a9c7644f3fb5155ff823600ba5a6ea403dc4 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 21:23:56 +0100
+Subject: [PATCH] tests: add a fuzzer for process_audit_string
+
+(cherry picked from commit 090a20cfaf3d5439fa39c5d8df473b0cfef181dd)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-audit.c      | 27 +++++++++++++++++++++++++++
+ src/fuzz/meson.build                |  5 +++++
+ src/journal/journald-audit.c        |  2 +-
+ src/journal/journald-audit.h        |  2 ++
+ test/fuzz/fuzz-journald-audit/basic |  1 +
+ 5 files changed, 36 insertions(+), 1 deletion(-)
+ create mode 100644 src/fuzz/fuzz-journald-audit.c
+ create mode 100644 test/fuzz/fuzz-journald-audit/basic
+
+diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c
+new file mode 100644
+index 0000000000..fe401c0d98
+--- /dev/null
++++ b/src/fuzz/fuzz-journald-audit.c
+@@ -0,0 +1,27 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include "fuzz.h"
++#include "journald-audit.h"
++
++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
++        Server s;
++        _cleanup_free_ char *buffer = NULL;
++
++        s = (Server) {
++                .syslog_fd = -1,
++                .native_fd = -1,
++                .stdout_fd = -1,
++                .dev_kmsg_fd = -1,
++                .audit_fd = -1,
++                .hostname_fd = -1,
++                .notify_fd = -1,
++                .storage = STORAGE_NONE,
++        };
++        assert_se(sd_event_default(&s.event) >= 0);
++        buffer = memdup_suffix0(data, size);
++        assert_se(buffer);
++        process_audit_string(&s, 0, buffer, size);
++        server_done(&s);
++
++        return 0;
++}
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index 0520e448a9..5548da3822 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -33,6 +33,11 @@ fuzzers += [
+           libshared],
+          [libmount]],
+ 
++        [['src/fuzz/fuzz-journald-audit.c'],
++         [libjournal_core,
++          libshared],
++         [libselinux]],
++
+         [['src/fuzz/fuzz-journald-kmsg.c'],
+          [libjournal_core,
+           libshared],
+diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
+index 87726684af..7810a0139a 100644
+--- a/src/journal/journald-audit.c
++++ b/src/journal/journald-audit.c
+@@ -313,7 +313,7 @@ static int map_all_fields(
+         }
+ }
+ 
+-static void process_audit_string(Server *s, int type, const char *data, size_t size) {
++void process_audit_string(Server *s, int type, const char *data, size_t size) {
+         size_t n_iov_allocated = 0, n_iov = 0, z;
+         _cleanup_free_ struct iovec *iov = NULL;
+         uint64_t seconds, msec, id;
+diff --git a/src/journal/journald-audit.h b/src/journal/journald-audit.h
+index 57bb1711c9..7766618c98 100644
+--- a/src/journal/journald-audit.h
++++ b/src/journal/journald-audit.h
+@@ -6,4 +6,6 @@
+ 
+ void server_process_audit_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const union sockaddr_union *sa, socklen_t salen);
+ 
++void process_audit_string(Server *s, int type, const char *data, size_t size);
++
+ int server_open_audit(Server*s);
+diff --git a/test/fuzz/fuzz-journald-audit/basic b/test/fuzz/fuzz-journald-audit/basic
+new file mode 100644
+index 0000000000..d1ce8cc5f0
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-audit/basic
+@@ -0,0 +1 @@
++audit(1542398162.211:744): pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success'
+\ No newline at end of file
diff --git a/SOURCES/0260-journald-check-whether-sscanf-has-changed-the-value-.patch b/SOURCES/0260-journald-check-whether-sscanf-has-changed-the-value-.patch
new file mode 100644
index 0000000..29ce46f
--- /dev/null
+++ b/SOURCES/0260-journald-check-whether-sscanf-has-changed-the-value-.patch
@@ -0,0 +1,47 @@
+From bef599d1a0e41afe4b6f1d6dfb6fbc86896ab8c5 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 16 Nov 2018 23:32:31 +0100
+Subject: [PATCH] journald: check whether sscanf has changed the value
+ corresponding to %n
+
+It's possible for sscanf to receive strings containing all three fields
+and not matching the template at the same time. When this happens the
+value of k doesn't change, which basically means that process_audit_string
+tries to access memory randomly. Sometimes it works and sometimes it doesn't :-)
+
+See also https://bugzilla.redhat.com/show_bug.cgi?id=1059314.
+
+(cherry picked from commit 1dab14aba749b9c5ab8176c5730107b70834240b)
+
+Resolves: #1764560
+---
+ src/journal/journald-audit.c        | 3 ++-
+ test/fuzz/fuzz-journald-audit/crash | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+ create mode 100644 test/fuzz/fuzz-journald-audit/crash
+
+diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
+index 7810a0139a..0fd6ab2a84 100644
+--- a/src/journal/journald-audit.c
++++ b/src/journal/journald-audit.c
+@@ -341,11 +341,12 @@ void process_audit_string(Server *s, int type, const char *data, size_t size) {
+         if (!p)
+                 return;
+ 
++        k = 0;
+         if (sscanf(p, "(%" PRIu64 ".%" PRIu64 ":%" PRIu64 "):%n",
+                    &seconds,
+                    &msec,
+                    &id,
+-                   &k) != 3)
++                   &k) != 3 || k == 0)
+                 return;
+ 
+         p += k;
+diff --git a/test/fuzz/fuzz-journald-audit/crash b/test/fuzz/fuzz-journald-audit/crash
+new file mode 100644
+index 0000000000..91bd85ca6e
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-audit/crash
+@@ -0,0 +1 @@
++audit(1542398162.211:744) pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success'
diff --git a/SOURCES/0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch b/SOURCES/0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch
new file mode 100644
index 0000000..f4a5225
--- /dev/null
+++ b/SOURCES/0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch
@@ -0,0 +1,172 @@
+From b276c85200786add6c86b6c1fedc888c71ffe5db Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Sat, 17 Nov 2018 13:01:09 +0100
+Subject: [PATCH] tests: introduce dummy_server_init and use it in all journald
+ fuzzers
+
+(cherry picked from commit ed62712dc6fb236845c489a7f386c7aff0ec31d6)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-audit.c | 18 +++---------------
+ src/fuzz/fuzz-journald-kmsg.c  | 20 ++++----------------
+ src/fuzz/fuzz-journald.c       | 26 +++++++++++++++++++-------
+ src/fuzz/fuzz-journald.h       |  2 ++
+ src/fuzz/meson.build           |  6 ++++--
+ 5 files changed, 32 insertions(+), 40 deletions(-)
+
+diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c
+index fe401c0d98..3f3ce7e8ee 100644
+--- a/src/fuzz/fuzz-journald-audit.c
++++ b/src/fuzz/fuzz-journald-audit.c
+@@ -1,26 +1,14 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include "fuzz.h"
++#include "fuzz-journald.h"
+ #include "journald-audit.h"
+ 
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+         Server s;
+-        _cleanup_free_ char *buffer = NULL;
+ 
+-        s = (Server) {
+-                .syslog_fd = -1,
+-                .native_fd = -1,
+-                .stdout_fd = -1,
+-                .dev_kmsg_fd = -1,
+-                .audit_fd = -1,
+-                .hostname_fd = -1,
+-                .notify_fd = -1,
+-                .storage = STORAGE_NONE,
+-        };
+-        assert_se(sd_event_default(&s.event) >= 0);
+-        buffer = memdup_suffix0(data, size);
+-        assert_se(buffer);
+-        process_audit_string(&s, 0, buffer, size);
++        dummy_server_init(&s, data, size);
++        process_audit_string(&s, 0, s.buffer, size);
+         server_done(&s);
+ 
+         return 0;
+diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
+index e2611c6d45..f7426c8400 100644
+--- a/src/fuzz/fuzz-journald-kmsg.c
++++ b/src/fuzz/fuzz-journald-kmsg.c
+@@ -1,29 +1,17 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include "fuzz.h"
++#include "fuzz-journald.h"
+ #include "journald-kmsg.h"
+ 
+ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+-        Server s = {};
+-        _cleanup_free_ char *buffer = NULL;
++        Server s;
+ 
+         if (size == 0)
+                 return 0;
+ 
+-        s = (Server) {
+-                .syslog_fd = -1,
+-                .native_fd = -1,
+-                .stdout_fd = -1,
+-                .dev_kmsg_fd = -1,
+-                .audit_fd = -1,
+-                .hostname_fd = -1,
+-                .notify_fd = -1,
+-                .storage = STORAGE_NONE,
+-        };
+-        assert_se(sd_event_default(&s.event) >= 0);
+-        buffer = memdup(data, size);
+-        assert_se(buffer);
+-        dev_kmsg_record(&s, buffer, size);
++        dummy_server_init(&s, data, size);
++        dev_kmsg_record(&s, s.buffer, size);
+         server_done(&s);
+ 
+         return 0;
+diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
+index f271d7f2fe..0659b92ba3 100644
+--- a/src/fuzz/fuzz-journald.c
++++ b/src/fuzz/fuzz-journald.c
+@@ -5,12 +5,29 @@
+ #include "journald-server.h"
+ #include "sd-event.h"
+ 
++void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
++        *s = (Server) {
++                .syslog_fd = -1,
++                .native_fd = -1,
++                .stdout_fd = -1,
++                .dev_kmsg_fd = -1,
++                .audit_fd = -1,
++                .hostname_fd = -1,
++                .notify_fd = -1,
++                .storage = STORAGE_NONE,
++        };
++        assert_se(sd_event_default(&s->event) >= 0);
++        s->buffer = memdup_suffix0(buffer, size);
++        assert_se(s->buffer);
++        s->buffer_size = size + 1;
++}
++
+ void fuzz_journald_processing_function(
+                 const uint8_t *data,
+                 size_t size,
+                 void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
+         ) {
+-        Server s = {};
++        Server s;
+         char *label = NULL;
+         size_t label_len = 0;
+         struct ucred *ucred = NULL;
+@@ -19,12 +36,7 @@ void fuzz_journald_processing_function(
+         if (size == 0)
+                 return;
+ 
+-        assert_se(sd_event_default(&s.event) >= 0);
+-        s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
+-        s.buffer = memdup_suffix0(data, size);
+-        assert_se(s.buffer);
+-        s.buffer_size = size + 1;
+-        s.storage = STORAGE_NONE;
++        dummy_server_init(&s, data, size);
+         (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
+         server_done(&s);
+ }
+diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h
+index e9d32a74aa..77e3b0c064 100644
+--- a/src/fuzz/fuzz-journald.h
++++ b/src/fuzz/fuzz-journald.h
+@@ -3,6 +3,8 @@
+ 
+ #include "journald-server.h"
+ 
++void dummy_server_init(Server *s, const uint8_t *buffer, size_t size);
++
+ void fuzz_journald_processing_function(
+                 const uint8_t *data,
+                 size_t size,
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index 5548da3822..897c02e4ae 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -33,12 +33,14 @@ fuzzers += [
+           libshared],
+          [libmount]],
+ 
+-        [['src/fuzz/fuzz-journald-audit.c'],
++        [['src/fuzz/fuzz-journald-audit.c',
++          'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+           libshared],
+          [libselinux]],
+ 
+-        [['src/fuzz/fuzz-journald-kmsg.c'],
++        [['src/fuzz/fuzz-journald-kmsg.c',
++          'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+           libshared],
+          [libselinux]],
diff --git a/SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch b/SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch
new file mode 100644
index 0000000..03ff6e8
--- /dev/null
+++ b/SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch
@@ -0,0 +1,148 @@
+From e7077e3a551a3faedfcc3d007de6a72fb5e1df62 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Tue, 20 Nov 2018 01:20:32 +0100
+Subject: [PATCH] tests: add a fuzzer for journald streams
+
+(cherry picked from commit 9541f5ff5c637bb1b3e3c69706cb73e68ff06813)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-stream.c      | 35 ++++++++++++++++++++++++++++
+ src/fuzz/fuzz-journald.c             | 10 +++++---
+ src/fuzz/meson.build                 |  6 +++++
+ src/journal/journald-stream.c        |  4 ++--
+ src/journal/journald-stream.h        |  2 ++
+ test/fuzz/fuzz-journald-stream/basic |  8 +++++++
+ 6 files changed, 60 insertions(+), 5 deletions(-)
+ create mode 100644 src/fuzz/fuzz-journald-stream.c
+ create mode 100644 test/fuzz/fuzz-journald-stream/basic
+
+diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c
+new file mode 100644
+index 0000000000..247c0889bc
+--- /dev/null
++++ b/src/fuzz/fuzz-journald-stream.c
+@@ -0,0 +1,35 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include <linux/sockios.h>
++
++#include "fd-util.h"
++#include "fuzz.h"
++#include "fuzz-journald.h"
++#include "journald-stream.h"
++
++static int stream_fds[2] = { -1, -1 };
++
++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
++        Server s;
++        StdoutStream *stream;
++        int v;
++
++        if (size == 0)
++                return 0;
++
++        if (!getenv("SYSTEMD_LOG_LEVEL"))
++                log_set_max_level(LOG_CRIT);
++
++        assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, stream_fds) >= 0);
++        dummy_server_init(&s, NULL, 0);
++        assert_se(stdout_stream_install(&s, stream_fds[0], &stream) >= 0);
++        assert_se(write(stream_fds[1], data, size) == (ssize_t) size);
++        while (ioctl(stream_fds[0], SIOCINQ, &v) == 0 && v)
++                sd_event_run(s.event, (uint64_t) -1);
++        if (s.n_stdout_streams)
++                stdout_stream_destroy(stream);
++        server_done(&s);
++        stream_fds[1] = safe_close(stream_fds[1]);
++
++        return 0;
++}
+diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
+index 0659b92ba3..950e885cae 100644
+--- a/src/fuzz/fuzz-journald.c
++++ b/src/fuzz/fuzz-journald.c
+@@ -15,11 +15,15 @@ void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
+                 .hostname_fd = -1,
+                 .notify_fd = -1,
+                 .storage = STORAGE_NONE,
++                .line_max = 64,
+         };
+         assert_se(sd_event_default(&s->event) >= 0);
+-        s->buffer = memdup_suffix0(buffer, size);
+-        assert_se(s->buffer);
+-        s->buffer_size = size + 1;
++
++        if (buffer) {
++                s->buffer = memdup_suffix0(buffer, size);
++                assert_se(s->buffer);
++                s->buffer_size = size + 1;
++        }
+ }
+ 
+ void fuzz_journald_processing_function(
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index 897c02e4ae..eea9117360 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -51,6 +51,12 @@ fuzzers += [
+           libshared],
+          [libselinux]],
+ 
++        [['src/fuzz/fuzz-journald-stream.c',
++          'src/fuzz/fuzz-journald.c'],
++         [libjournal_core,
++          libshared],
++         [libselinux]],
++
+         [['src/fuzz/fuzz-journald-syslog.c',
+           'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
+index dbf3503a82..6f8a4011ff 100644
+--- a/src/journal/journald-stream.c
++++ b/src/journal/journald-stream.c
+@@ -125,7 +125,7 @@ void stdout_stream_free(StdoutStream *s) {
+ 
+ DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
+ 
+-static void stdout_stream_destroy(StdoutStream *s) {
++void stdout_stream_destroy(StdoutStream *s) {
+         if (!s)
+                 return;
+ 
+@@ -534,7 +534,7 @@ terminate:
+         return 0;
+ }
+ 
+-static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
++int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
+         _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
+         sd_id128_t id;
+         int r;
+diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h
+index bc5622ab3b..487376e763 100644
+--- a/src/journal/journald-stream.h
++++ b/src/journal/journald-stream.h
+@@ -10,4 +10,6 @@ int server_open_stdout_socket(Server *s);
+ int server_restore_streams(Server *s, FDSet *fds);
+ 
+ void stdout_stream_free(StdoutStream *s);
++int stdout_stream_install(Server *s, int fd, StdoutStream **ret);
++void stdout_stream_destroy(StdoutStream *s);
+ void stdout_stream_send_notify(StdoutStream *s);
+diff --git a/test/fuzz/fuzz-journald-stream/basic b/test/fuzz/fuzz-journald-stream/basic
+new file mode 100644
+index 0000000000..a088f1a539
+--- /dev/null
++++ b/test/fuzz/fuzz-journald-stream/basic
+@@ -0,0 +1,8 @@
++
++
++6
++1
++0
++0
++0
++hey
+\ No newline at end of file
diff --git a/SOURCES/0263-tests-add-a-fuzzer-for-server_process_native_file.patch b/SOURCES/0263-tests-add-a-fuzzer-for-server_process_native_file.patch
new file mode 100644
index 0000000..500af37
--- /dev/null
+++ b/SOURCES/0263-tests-add-a-fuzzer-for-server_process_native_file.patch
@@ -0,0 +1,96 @@
+From 76e2fa8ed4bbee7c625e3b790f2e38a59fffd93d Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 23 Nov 2018 00:27:19 +0100
+Subject: [PATCH] tests: add a fuzzer for server_process_native_file
+
+(cherry picked from commit a4aa59bae206eebb4703b291147144def5d4bb3e)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-native-fd.c      |  47 ++++++++++++++++++++++++
+ src/fuzz/meson.build                    |   6 +++
+ test/fuzz/fuzz-journald-native-fd/basic | Bin 0 -> 34 bytes
+ 3 files changed, 53 insertions(+)
+ create mode 100644 src/fuzz/fuzz-journald-native-fd.c
+ create mode 100644 test/fuzz/fuzz-journald-native-fd/basic
+
+diff --git a/src/fuzz/fuzz-journald-native-fd.c b/src/fuzz/fuzz-journald-native-fd.c
+new file mode 100644
+index 0000000000..95415d9f85
+--- /dev/null
++++ b/src/fuzz/fuzz-journald-native-fd.c
+@@ -0,0 +1,47 @@
++/* SPDX-License-Identifier: LGPL-2.1+ */
++
++#include "fd-util.h"
++#include "fileio.h"
++#include "fs-util.h"
++#include "fuzz.h"
++#include "fuzz-journald.h"
++#include "journald-native.h"
++#include "memfd-util.h"
++#include "process-util.h"
++
++int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
++        Server s;
++        _cleanup_close_ int sealed_fd = -1, unsealed_fd = -1;
++        _cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX";
++        char *label = NULL;
++        size_t label_len = 0;
++        struct ucred ucred;
++        struct timeval *tv = NULL;
++
++        if (!getenv("SYSTEMD_LOG_LEVEL"))
++                log_set_max_level(LOG_CRIT);
++
++        dummy_server_init(&s, NULL, 0);
++
++        sealed_fd = memfd_new(NULL);
++        assert_se(sealed_fd >= 0);
++        assert_se(write(sealed_fd, data, size) == (ssize_t) size);
++        assert_se(memfd_set_sealed(sealed_fd) >= 0);
++        assert_se(lseek(sealed_fd, 0, SEEK_SET) == 0);
++        ucred = (struct ucred) {
++                .pid = getpid_cached(),
++                .uid = geteuid(),
++                .gid = getegid(),
++        };
++        server_process_native_file(&s, sealed_fd, &ucred, tv, label, label_len);
++
++        unsealed_fd = mkostemp_safe(name);
++        assert_se(unsealed_fd >= 0);
++        assert_se(write(unsealed_fd, data, size) == (ssize_t) size);
++        assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0);
++        server_process_native_file(&s, unsealed_fd, &ucred, tv, label, label_len);
++
++        server_done(&s);
++
++        return 0;
++}
+diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
+index eea9117360..5315d2771c 100644
+--- a/src/fuzz/meson.build
++++ b/src/fuzz/meson.build
+@@ -51,6 +51,12 @@ fuzzers += [
+           libshared],
+          [libselinux]],
+ 
++        [['src/fuzz/fuzz-journald-native-fd.c',
++          'src/fuzz/fuzz-journald.c'],
++         [libjournal_core,
++          libshared],
++         [libselinux]],
++
+         [['src/fuzz/fuzz-journald-stream.c',
+           'src/fuzz/fuzz-journald.c'],
+          [libjournal_core,
+diff --git a/test/fuzz/fuzz-journald-native-fd/basic b/test/fuzz/fuzz-journald-native-fd/basic
+new file mode 100644
+index 0000000000000000000000000000000000000000..65f89705a655618851c0e446efaa5c633adf425f
+GIT binary patch
+literal 34
+kcmeZu4Gwm6cjaPXfB;7>M@KGyCofm$koW*k7h3}^0B8*cRR910
+
+literal 0
+HcmV?d00001
+
diff --git a/SOURCES/0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch b/SOURCES/0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch
new file mode 100644
index 0000000..798aa6c
--- /dev/null
+++ b/SOURCES/0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch
@@ -0,0 +1,47 @@
+From 2d197adc6d7109d5901401a90288530582f3f991 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 26 Feb 2019 13:00:35 +0100
+Subject: [PATCH] fuzz-journal-stream: avoid assertion failure on samples which
+ don't fit in pipe
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11587.
+We had a sample which was large enough that write(2) failed to push all the
+data into the pipe, and an assert failed. The code could be changed to use
+a loop, but then we'd need to interleave writes and sd_event_run (to process
+the journal). I don't think the complexity is worth it — fuzzing works best
+if the sample is not too huge anyway. So let's just reject samples above 64k,
+and tell oss-fuzz about this limit.
+
+(cherry picked from commit eafadd069c4e30ed62173123326a7237448615d1)
+
+Resolves: #1764560
+---
+ src/fuzz/fuzz-journald-stream.c       | 2 +-
+ src/fuzz/fuzz-journald-stream.options | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+ create mode 100644 src/fuzz/fuzz-journald-stream.options
+
+diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c
+index 247c0889bc..693b197d3a 100644
+--- a/src/fuzz/fuzz-journald-stream.c
++++ b/src/fuzz/fuzz-journald-stream.c
+@@ -14,7 +14,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+         StdoutStream *stream;
+         int v;
+ 
+-        if (size == 0)
++        if (size == 0 || size > 65536)
+                 return 0;
+ 
+         if (!getenv("SYSTEMD_LOG_LEVEL"))
+diff --git a/src/fuzz/fuzz-journald-stream.options b/src/fuzz/fuzz-journald-stream.options
+new file mode 100644
+index 0000000000..678d526b1e
+--- /dev/null
++++ b/src/fuzz/fuzz-journald-stream.options
+@@ -0,0 +1,2 @@
++[libfuzzer]
++max_len = 65536
diff --git a/SOURCES/0265-journald-take-leading-spaces-into-account-in-syslog_.patch b/SOURCES/0265-journald-take-leading-spaces-into-account-in-syslog_.patch
new file mode 100644
index 0000000..25b1d95
--- /dev/null
+++ b/SOURCES/0265-journald-take-leading-spaces-into-account-in-syslog_.patch
@@ -0,0 +1,45 @@
+From 3521217c88b364e2c5b10a1e35d3c036b1ecba64 Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Fri, 10 Aug 2018 12:55:09 +0000
+Subject: [PATCH] journald: take leading spaces into account in
+ syslog_parse_identifier
+
+This is a kind of follow-up to e88baee88fad8bc59d3 which should finally fix
+the issue which that commit was supposed to fix.
+
+(cherry picked from commit 937b1171378bc1000a34fcdfe9534d898227e35f)
+
+Resolves: #1764560
+---
+ src/journal/journald-syslog.c     | 3 ++-
+ src/journal/test-journal-syslog.c | 2 ++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
+index e0b55cc566..ae966763a0 100644
+--- a/src/journal/journald-syslog.c
++++ b/src/journal/journald-syslog.c
+@@ -223,8 +223,9 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
+         if (p[e] != '\0' && strchr(WHITESPACE, p[e]))
+                 e++;
+ 
++        l = (p - *buf) + e;
+         *buf = p + e;
+-        return e;
++        return l;
+ }
+ 
+ static void syslog_skip_date(char **buf) {
+diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
+index 120477cc9f..415b9d23ca 100644
+--- a/src/journal/test-journal-syslog.c
++++ b/src/journal/test-journal-syslog.c
+@@ -41,6 +41,8 @@ int main(void) {
+         test_syslog_parse_identifier("  ", NULL, NULL, "  ", 0);
+         test_syslog_parse_identifier(":", "", NULL, "", 1);
+         test_syslog_parse_identifier(":  ", "", NULL, " ", 2);
++        test_syslog_parse_identifier(" :", "", NULL, "", 2);
++        test_syslog_parse_identifier("   pidu:", "pidu", NULL, "", 8);
+         test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5);
+         test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
+         test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
diff --git a/SOURCES/0266-Add-a-warning-about-the-difference-in-permissions-be.patch b/SOURCES/0266-Add-a-warning-about-the-difference-in-permissions-be.patch
new file mode 100644
index 0000000..8b0bd5c
--- /dev/null
+++ b/SOURCES/0266-Add-a-warning-about-the-difference-in-permissions-be.patch
@@ -0,0 +1,43 @@
+From 5df63c2ddf93bab5e7f13e09dfb1f97a011b3451 Mon Sep 17 00:00:00 2001
+From: Taro Yamada <archer_ame@yahoo.co.jp>
+Date: Sun, 27 Jan 2019 13:50:04 +0900
+Subject: [PATCH] Add a warning about the difference in permissions between
+ existing directories and unit settings.
+
+To follows the intent of 30c81ce, this change does not execute chmod() and just add warnings.
+
+(cherry picked from commit 6cff72eb0a18d8547f005a481cd0622d3bc78483)
+
+Related: #1778384
+---
+ src/core/execute.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index 8293c522bc..9ddba00421 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -2099,8 +2099,21 @@ static int setup_exec_directory(
+                         r = mkdir_label(p, context->directories[type].mode);
+                         if (r < 0 && r != -EEXIST)
+                                 goto fail;
+-                        if (r == -EEXIST && !context->dynamic_user)
+-                                continue;
++                        if (r == -EEXIST) {
++                                struct stat st;
++
++                                if (stat(p, &st) < 0) {
++                                        r = -errno;
++                                        goto fail;
++                                }
++                                if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
++                                        log_warning("%s \'%s\' already exists but the mode is different. "
++                                                    "(filesystem: %o %sMode: %o)",
++                                                    exec_directory_type_to_string(type), *rt,
++                                                    st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
++                                if (!context->dynamic_user)
++                                        continue;
++                        }
+                 }
+ 
+                 /* Don't change the owner of the configuration directory, as in the common case it is not written to by
diff --git a/SOURCES/0267-execute-remove-one-redundant-comparison-check.patch b/SOURCES/0267-execute-remove-one-redundant-comparison-check.patch
new file mode 100644
index 0000000..8101159
--- /dev/null
+++ b/SOURCES/0267-execute-remove-one-redundant-comparison-check.patch
@@ -0,0 +1,32 @@
+From 81ca39b7b38ef1d44cc146efe75bef412e7c4c97 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 14 Mar 2019 17:01:46 +0100
+Subject: [PATCH] execute: remove one redundant comparison check
+
+(cherry picked from commit d484580ca6f0e79abe6f3f5c677323a22d9e22d7)
+
+Related: #1778384
+---
+ src/core/execute.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index 9ddba00421..46aa733937 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -2097,11 +2097,12 @@ static int setup_exec_directory(
+                         }
+                 } else {
+                         r = mkdir_label(p, context->directories[type].mode);
+-                        if (r < 0 && r != -EEXIST)
+-                                goto fail;
+-                        if (r == -EEXIST) {
++                        if (r < 0) {
+                                 struct stat st;
+ 
++                                if (r != -EEXIST)
++                                        goto fail;
++
+                                 if (stat(p, &st) < 0) {
+                                         r = -errno;
+                                         goto fail;
diff --git a/SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch b/SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch
new file mode 100644
index 0000000..faaef74
--- /dev/null
+++ b/SOURCES/0268-core-change-ownership-mode-of-the-execution-director.patch
@@ -0,0 +1,88 @@
+From 789806ac06bb13d1b579fef47dbb85f224b6dbb1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 14 Mar 2019 17:19:30 +0100
+Subject: [PATCH] core: change ownership/mode of the execution directories also
+ for static users
+
+It's probably unexpected if we do a recursive chown() when dynamic users
+are used but not on static users.
+
+hence, let's tweak the logic slightly, and recursively chown in both
+cases, except when operating on the configuration directory.
+
+Fixes: #11842
+(cherry picked from commit 206e9864de460dd79d9edd7bedb47dee168765e1)
+
+Resolves: #1778384
+---
+ src/core/execute.c | 47 +++++++++++++++++++++++++---------------------
+ 1 file changed, 26 insertions(+), 21 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index 46aa733937..c42300a41e 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -2090,37 +2090,42 @@ static int setup_exec_directory(
+                         if (r < 0)
+                                 goto fail;
+ 
+-                        /* Lock down the access mode */
+-                        if (chmod(pp, context->directories[type].mode) < 0) {
+-                                r = -errno;
+-                                goto fail;
+-                        }
+                 } else {
+                         r = mkdir_label(p, context->directories[type].mode);
+                         if (r < 0) {
+-                                struct stat st;
+-
+                                 if (r != -EEXIST)
+                                         goto fail;
+ 
+-                                if (stat(p, &st) < 0) {
+-                                        r = -errno;
+-                                        goto fail;
+-                                }
+-                                if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
+-                                        log_warning("%s \'%s\' already exists but the mode is different. "
+-                                                    "(filesystem: %o %sMode: %o)",
+-                                                    exec_directory_type_to_string(type), *rt,
+-                                                    st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
+-                                if (!context->dynamic_user)
++                                if (type == EXEC_DIRECTORY_CONFIGURATION) {
++                                        struct stat st;
++
++                                        /* Don't change the owner/access mode of the configuration directory,
++                                         * as in the common case it is not written to by a service, and shall
++                                         * not be writable. */
++
++                                        if (stat(p, &st) < 0) {
++                                                r = -errno;
++                                                goto fail;
++                                        }
++
++                                        /* Still complain if the access mode doesn't match */
++                                        if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
++                                                log_warning("%s \'%s\' already exists but the mode is different. "
++                                                            "(File system: %o %sMode: %o)",
++                                                            exec_directory_type_to_string(type), *rt,
++                                                            st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
++
+                                         continue;
++                                }
+                         }
+                 }
+ 
+-                /* Don't change the owner of the configuration directory, as in the common case it is not written to by
+-                 * a service, and shall not be writable. */
+-                if (type == EXEC_DIRECTORY_CONFIGURATION)
+-                        continue;
++                /* Lock down the access mode (we use chmod_and_chown() to make this idempotent. We don't
++                 * specifiy UID/GID here, so that path_chown_recursive() can optimize things depending on the
++                 * current UID/GID ownership.) */
++                r = chmod_and_chown(pp ?: p, context->directories[type].mode, UID_INVALID, GID_INVALID);
++                if (r < 0)
++                        goto fail;
+ 
+                 /* Then, change the ownership of the whole tree, if necessary */
+                 r = path_chown_recursive(pp ?: p, uid, gid);
diff --git a/SOURCES/0269-core-dbus-execute-remove-unnecessary-initialization.patch b/SOURCES/0269-core-dbus-execute-remove-unnecessary-initialization.patch
new file mode 100644
index 0000000..e46f256
--- /dev/null
+++ b/SOURCES/0269-core-dbus-execute-remove-unnecessary-initialization.patch
@@ -0,0 +1,25 @@
+From 5d7e8cb0e12e4642a760cf00cbb6caf4c07b9cd9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Sun, 19 May 2019 16:05:02 +0200
+Subject: [PATCH] core/dbus-execute: remove unnecessary initialization
+
+(cherry picked from commit bd0abfaea1514bdd7cb60228d7a3f94c17ba916d)
+
+Related: #1734787
+---
+ src/core/dbus-execute.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index 33a91c012e..5379545d57 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -1552,7 +1552,7 @@ int bus_exec_context_set_transient_property(
+ #endif
+         if (streq(name, "CPUAffinity")) {
+                 const void *a;
+-                size_t n = 0;
++                size_t n;
+ 
+                 r = sd_bus_message_read_array(message, 'y', &a, &n);
+                 if (r < 0)
diff --git a/SOURCES/0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch b/SOURCES/0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch
new file mode 100644
index 0000000..5babb33
--- /dev/null
+++ b/SOURCES/0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch
@@ -0,0 +1,215 @@
+From 46b4d26c54a773f7da350e89562039ccc5157a8f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Sun, 19 May 2019 18:02:38 +0200
+Subject: [PATCH] shared/cpu-set-util: move the part to print cpu-set into a
+ separate function
+
+Also avoid unnecessary asprintf() when we can write to the output area
+directly.
+
+(cherry picked from commit a832893f9c4f0a0329768e90f67e2fa24bb0008e)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c     | 21 +++++++++++++++++++++
+ src/basic/cpu-set-util.h     |  1 +
+ src/core/dbus-execute.c      | 29 +++++------------------------
+ src/test/test-cpu-set-util.c | 29 +++++++++++++++++++++++++++++
+ 4 files changed, 56 insertions(+), 24 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index b1c927bcb8..8f24a2601a 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -5,6 +5,7 @@
+ 
+ #include <errno.h>
+ #include <stddef.h>
++#include <stdio.h>
+ #include <syslog.h>
+ 
+ #include "alloc-util.h"
+@@ -15,6 +16,26 @@
+ #include "parse-util.h"
+ #include "string-util.h"
+ 
++char* cpu_set_to_string(const cpu_set_t *set, size_t setsize) {
++        _cleanup_free_ char *str = NULL;
++        size_t allocated = 0, len = 0;
++        int i, r;
++
++        for (i = 0; (size_t) i < setsize * 8; i++) {
++                if (!CPU_ISSET_S(i, setsize, set))
++                        continue;
++
++                if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int)))
++                        return NULL;
++
++                r = sprintf(str + len, len > 0 ? " %d" : "%d", i);
++                assert_se(r > 0);
++                len += r;
++        }
++
++        return TAKE_PTR(str) ?: strdup("");
++}
++
+ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+         cpu_set_t *c;
+         unsigned n = 1024;
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index 88470fe15a..3c546beb55 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -26,6 +26,7 @@ static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) {
+ 
+ cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+ 
++char* cpu_set_to_string(const cpu_set_t *set, size_t setsize);
+ int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue);
+ 
+ static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) {
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index 5379545d57..d9f4445745 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -1565,32 +1565,13 @@ int bus_exec_context_set_transient_property(
+                                 unit_write_settingf(u, flags, name, "%s=", name);
+                         } else {
+                                 _cleanup_free_ char *str = NULL;
+-                                size_t allocated = 0, len = 0, i, ncpus;
++                                size_t ncpus;
+ 
+-                                ncpus = CPU_SIZE_TO_NUM(n);
+-
+-                                for (i = 0; i < ncpus; i++) {
+-                                        _cleanup_free_ char *p = NULL;
+-                                        size_t add;
+-
+-                                        if (!CPU_ISSET_S(i, n, (cpu_set_t*) a))
+-                                                continue;
+-
+-                                        r = asprintf(&p, "%zu", i);
+-                                        if (r < 0)
+-                                                return -ENOMEM;
+-
+-                                        add = strlen(p);
+-
+-                                        if (!GREEDY_REALLOC(str, allocated, len + add + 2))
+-                                                return -ENOMEM;
+-
+-                                        strcpy(mempcpy(str + len, p, add), " ");
+-                                        len += add + 1;
+-                                }
++                                str = cpu_set_to_string(a, n);
++                                if (!str)
++                                        return -ENOMEM;
+ 
+-                                if (len != 0)
+-                                        str[len - 1] = '\0';
++                                ncpus = CPU_SIZE_TO_NUM(n);
+ 
+                                 if (!c->cpuset || c->cpuset_ncpus < ncpus) {
+                                         cpu_set_t *cpuset;
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index c9272459b4..ff5edb2a69 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -6,6 +6,7 @@
+ 
+ static void test_parse_cpu_set(void) {
+         cpu_set_t *c = NULL;
++        _cleanup_free_ char *str = NULL;
+         int ncpus;
+         int cpu;
+ 
+@@ -15,6 +16,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
+         assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
+         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
++
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* A more interesting range */
+@@ -25,6 +30,9 @@ static void test_parse_cpu_set(void) {
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Quoted strings */
+@@ -33,6 +41,9 @@ static void test_parse_cpu_set(void) {
+         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Use commas as separators */
+@@ -43,6 +54,9 @@ static void test_parse_cpu_set(void) {
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Commas with spaces (and trailing comma, space) */
+@@ -51,6 +65,9 @@ static void test_parse_cpu_set(void) {
+         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
+         for (cpu = 0; cpu < 8; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Ranges */
+@@ -61,6 +78,9 @@ static void test_parse_cpu_set(void) {
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Ranges with trailing comma, space */
+@@ -71,6 +91,9 @@ static void test_parse_cpu_set(void) {
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Negative range (returns empty cpu_set) */
+@@ -85,6 +108,9 @@ static void test_parse_cpu_set(void) {
+         assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
+         for (cpu = 0; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Mix ranges and individual CPUs */
+@@ -95,6 +121,9 @@ static void test_parse_cpu_set(void) {
+         assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
+         for (cpu = 4; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
+         c = cpu_set_mfree(c);
+ 
+         /* Garbage */
diff --git a/SOURCES/0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch b/SOURCES/0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch
new file mode 100644
index 0000000..8d393c5
--- /dev/null
+++ b/SOURCES/0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch
@@ -0,0 +1,29 @@
+From d6935e61de30967aa82b7722f36193ba782b75e4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Sun, 19 May 2019 18:08:39 +0200
+Subject: [PATCH] shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM()
+
+(cherry picked from commit b12ef7141648be40fd8c4b0209a742f2151736d9)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.h | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index 3c546beb55..20612a8876 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -9,12 +9,6 @@
+ 
+ #include "macro.h"
+ 
+-#ifdef __NCPUBITS
+-#define CPU_SIZE_TO_NUM(n) ((n) * __NCPUBITS)
+-#else
+-#define CPU_SIZE_TO_NUM(n) ((n) * sizeof(cpu_set_t) * 8)
+-#endif
+-
+ DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
+ #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
+ 
diff --git a/SOURCES/0272-Rework-cpu-affinity-parsing.patch b/SOURCES/0272-Rework-cpu-affinity-parsing.patch
new file mode 100644
index 0000000..f6001e5
--- /dev/null
+++ b/SOURCES/0272-Rework-cpu-affinity-parsing.patch
@@ -0,0 +1,932 @@
+From 61e5aed87f1b82a51c6ea8ccde96805cb63e5b15 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 21 May 2019 08:45:19 +0200
+Subject: [PATCH] Rework cpu affinity parsing
+
+The CPU_SET_S api is pretty bad. In particular, it has a parameter for the size
+of the array, but operations which take two (CPU_EQUAL_S) or even three arrays
+(CPU_{AND,OR,XOR}_S) still take just one size. This means that all arrays must
+be of the same size, or buffer overruns will occur. This is exactly what our
+code would do, if it received an array of unexpected size over the network.
+("Unexpected" here means anything different from what cpu_set_malloc() detects
+as the "right" size.)
+
+Let's rework this, and store the size in bytes of the allocated storage area.
+
+The code will now parse any number up to 8191, independently of what the current
+kernel supports. This matches the kernel maximum setting for any architecture,
+to make things more portable.
+
+Fixes #12605.
+
+(cherry picked from commit 0985c7c4e22c8dbbea4398cf3453da45ebf63800)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c     | 133 +++++++++++++++++++++-----
+ src/basic/cpu-set-util.h     |  47 ++++++---
+ src/core/dbus-execute.c      |  35 ++-----
+ src/core/execute.c           |  12 +--
+ src/core/execute.h           |   4 +-
+ src/core/load-fragment.c     |  31 +-----
+ src/core/main.c              |  14 +--
+ src/nspawn/nspawn-settings.c |  33 +------
+ src/nspawn/nspawn-settings.h |   4 +-
+ src/nspawn/nspawn.c          |  29 +++---
+ src/shared/bus-unit-util.c   |   4 +-
+ src/test/test-cpu-set-util.c | 179 +++++++++++++++++++----------------
+ src/test/test-sizeof.c       |   3 +
+ 13 files changed, 286 insertions(+), 242 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index 8f24a2601a..fe440f6381 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -15,14 +15,15 @@
+ #include "macro.h"
+ #include "parse-util.h"
+ #include "string-util.h"
++#include "util.h"
+ 
+-char* cpu_set_to_string(const cpu_set_t *set, size_t setsize) {
++char* cpu_set_to_string(const CPUSet *a) {
+         _cleanup_free_ char *str = NULL;
+         size_t allocated = 0, len = 0;
+         int i, r;
+ 
+-        for (i = 0; (size_t) i < setsize * 8; i++) {
+-                if (!CPU_ISSET_S(i, setsize, set))
++        for (i = 0; (size_t) i < a->allocated * 8; i++) {
++                if (!CPU_ISSET_S(i, a->allocated, a->set))
+                         continue;
+ 
+                 if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int)))
+@@ -65,24 +66,74 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+         }
+ }
+ 
+-int parse_cpu_set_internal(
++static int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
++        size_t need;
++
++        assert(cpu_set);
++
++        need = CPU_ALLOC_SIZE(ncpus);
++        if (need > cpu_set->allocated) {
++                cpu_set_t *t;
++
++                t = realloc(cpu_set->set, need);
++                if (!t)
++                        return -ENOMEM;
++
++                memzero((uint8_t*) t + cpu_set->allocated, need - cpu_set->allocated);
++
++                cpu_set->set = t;
++                cpu_set->allocated = need;
++        }
++
++        return 0;
++}
++
++static int cpu_set_add(CPUSet *cpu_set, unsigned cpu) {
++        int r;
++
++        if (cpu >= 8192)
++                /* As of kernel 5.1, CONFIG_NR_CPUS can be set to 8192 on PowerPC */
++                return -ERANGE;
++
++        r = cpu_set_realloc(cpu_set, cpu + 1);
++        if (r < 0)
++                return r;
++
++        CPU_SET_S(cpu, cpu_set->allocated, cpu_set->set);
++        return 0;
++}
++
++int cpu_set_add_all(CPUSet *a, const CPUSet *b) {
++        int r;
++
++        /* Do this backwards, so if we fail, we fail before changing anything. */
++        for (unsigned cpu_p1 = b->allocated * 8; cpu_p1 > 0; cpu_p1--)
++                if (CPU_ISSET_S(cpu_p1 - 1, b->allocated, b->set)) {
++                        r = cpu_set_add(a, cpu_p1 - 1);
++                        if (r < 0)
++                                return r;
++                }
++
++        return 0;
++}
++
++int parse_cpu_set_full(
+                 const char *rvalue,
+-                cpu_set_t **cpu_set,
++                CPUSet *cpu_set,
+                 bool warn,
+                 const char *unit,
+                 const char *filename,
+                 unsigned line,
+                 const char *lvalue) {
+ 
+-        _cleanup_cpu_free_ cpu_set_t *c = NULL;
++        _cleanup_(cpu_set_reset) CPUSet c = {};
+         const char *p = rvalue;
+-        unsigned ncpus = 0;
+ 
+-        assert(rvalue);
++        assert(p);
+ 
+         for (;;) {
+                 _cleanup_free_ char *word = NULL;
+-                unsigned cpu, cpu_lower, cpu_upper;
++                unsigned cpu_lower, cpu_upper;
+                 int r;
+ 
+                 r = extract_first_word(&p, &word, WHITESPACE ",", EXTRACT_QUOTES);
+@@ -93,31 +144,63 @@ int parse_cpu_set_internal(
+                 if (r == 0)
+                         break;
+ 
+-                if (!c) {
+-                        c = cpu_set_malloc(&ncpus);
+-                        if (!c)
+-                                return warn ? log_oom() : -ENOMEM;
+-                }
+-
+                 r = parse_range(word, &cpu_lower, &cpu_upper);
+                 if (r < 0)
+                         return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word) : r;
+-                if (cpu_lower >= ncpus || cpu_upper >= ncpus)
+-                        return warn ? log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus) : -EINVAL;
+ 
+                 if (cpu_lower > cpu_upper) {
+                         if (warn)
+-                                log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring", word, cpu_lower, cpu_upper);
+-                        continue;
++                                log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring.",
++                                           word, cpu_lower, cpu_upper);
++
++                        /* Make sure something is allocated, to distinguish this from the empty case */
++                        r = cpu_set_realloc(&c, 1);
++                        if (r < 0)
++                                return r;
+                 }
+ 
+-                for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
+-                        CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
++                for (unsigned cpu_p1 = MIN(cpu_upper, UINT_MAX-1) + 1; cpu_p1 > cpu_lower; cpu_p1--) {
++                        r = cpu_set_add(&c, cpu_p1 - 1);
++                        if (r < 0)
++                                return warn ? log_syntax(unit, LOG_ERR, filename, line, r,
++                                                         "Cannot add CPU %u to set: %m", cpu_p1 - 1) : r;
++                }
+         }
+ 
+-        /* On success, sets *cpu_set and returns ncpus for the system. */
+-        if (c)
+-                *cpu_set = TAKE_PTR(c);
++        /* On success, transfer ownership to the output variable */
++        *cpu_set = c;
++        c = (CPUSet) {};
++
++        return 0;
++}
++
++int parse_cpu_set_extend(
++                const char *rvalue,
++                CPUSet *old,
++                bool warn,
++                const char *unit,
++                const char *filename,
++                unsigned line,
++                const char *lvalue) {
++
++        _cleanup_(cpu_set_reset) CPUSet cpuset = {};
++        int r;
++
++        r = parse_cpu_set_full(rvalue, &cpuset, true, unit, filename, line, lvalue);
++        if (r < 0)
++                return r;
++
++        if (!cpuset.set) {
++                /* An empty assignment resets the CPU list */
++                cpu_set_reset(old);
++                return 0;
++        }
++
++        if (!old->set) {
++                *old = cpuset;
++                cpuset = (CPUSet) {};
++                return 0;
++        }
+ 
+-        return (int) ncpus;
++        return cpu_set_add_all(old, &cpuset);
+ }
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index 20612a8876..eb31b362fe 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -12,23 +12,40 @@
+ DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
+ #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
+ 
+-static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) {
+-        if (p)
+-                CPU_FREE(p);
+-        return NULL;
+-}
+-
+ cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+ 
+-char* cpu_set_to_string(const cpu_set_t *set, size_t setsize);
+-int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue);
+-
+-static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) {
+-        assert(lvalue);
+-
+-        return parse_cpu_set_internal(rvalue, cpu_set, true, unit, filename, line, lvalue);
++/* This wraps the libc interface with a variable to keep the allocated size. */
++typedef struct CPUSet {
++        cpu_set_t *set;
++        size_t allocated; /* in bytes */
++} CPUSet;
++
++static inline void cpu_set_reset(CPUSet *a) {
++        assert((a->allocated > 0) == !!a->set);
++        if (a->set)
++                CPU_FREE(a->set);
++        *a = (CPUSet) {};
+ }
+ 
+-static inline int parse_cpu_set(const char *rvalue, cpu_set_t **cpu_set){
+-        return parse_cpu_set_internal(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
++int cpu_set_add_all(CPUSet *a, const CPUSet *b);
++
++char* cpu_set_to_string(const CPUSet *a);
++int parse_cpu_set_full(
++                const char *rvalue,
++                CPUSet *cpu_set,
++                bool warn,
++                const char *unit,
++                const char *filename, unsigned line,
++                const char *lvalue);
++int parse_cpu_set_extend(
++                const char *rvalue,
++                CPUSet *old,
++                bool warn,
++                const char *unit,
++                const char *filename,
++                unsigned line,
++                const char *lvalue);
++
++static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){
++        return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
+ }
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index d9f4445745..08946627e3 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -220,7 +220,7 @@ static int property_get_cpu_affinity(
+         assert(reply);
+         assert(c);
+ 
+-        return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
++        return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated);
+ }
+ 
+ static int property_get_timer_slack_nsec(
+@@ -1560,37 +1560,22 @@ int bus_exec_context_set_transient_property(
+ 
+                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                         if (n == 0) {
+-                                c->cpuset = cpu_set_mfree(c->cpuset);
+-                                c->cpuset_ncpus = 0;
++                                cpu_set_reset(&c->cpu_set);
+                                 unit_write_settingf(u, flags, name, "%s=", name);
+                         } else {
+                                 _cleanup_free_ char *str = NULL;
+-                                size_t ncpus;
++                                const CPUSet set = {(cpu_set_t*) a, n};
+ 
+-                                str = cpu_set_to_string(a, n);
++                                str = cpu_set_to_string(&set);
+                                 if (!str)
+                                         return -ENOMEM;
+ 
+-                                ncpus = CPU_SIZE_TO_NUM(n);
+-
+-                                if (!c->cpuset || c->cpuset_ncpus < ncpus) {
+-                                        cpu_set_t *cpuset;
+-
+-                                        cpuset = CPU_ALLOC(ncpus);
+-                                        if (!cpuset)
+-                                                return -ENOMEM;
+-
+-                                        CPU_ZERO_S(n, cpuset);
+-                                        if (c->cpuset) {
+-                                                CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, (cpu_set_t*) a);
+-                                                CPU_FREE(c->cpuset);
+-                                        } else
+-                                                CPU_OR_S(n, cpuset, cpuset, (cpu_set_t*) a);
+-
+-                                        c->cpuset = cpuset;
+-                                        c->cpuset_ncpus = ncpus;
+-                                } else
+-                                        CPU_OR_S(n, c->cpuset, c->cpuset, (cpu_set_t*) a);
++                                /* We forego any optimizations here, and always create the structure using
++                                 * cpu_set_add_all(), because we don't want to care if the existing size we
++                                 * got over dbus is appropriate. */
++                                r = cpu_set_add_all(&c->cpu_set, &set);
++                                if (r < 0)
++                                        return r;
+ 
+                                 unit_write_settingf(u, flags, name, "%s=%s", name, str);
+                         }
+diff --git a/src/core/execute.c b/src/core/execute.c
+index c42300a41e..22e5825905 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -2991,8 +2991,8 @@ static int exec_child(
+                 }
+         }
+ 
+-        if (context->cpuset)
+-                if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
++        if (context->cpu_set.set)
++                if (sched_setaffinity(0, context->cpu_set.allocated, context->cpu_set.set) < 0) {
+                         *exit_status = EXIT_CPUAFFINITY;
+                         return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m");
+                 }
+@@ -3694,7 +3694,7 @@ void exec_context_done(ExecContext *c) {
+         c->temporary_filesystems = NULL;
+         c->n_temporary_filesystems = 0;
+ 
+-        c->cpuset = cpu_set_mfree(c->cpuset);
++        cpu_set_reset(&c->cpu_set);
+ 
+         c->utmp_id = mfree(c->utmp_id);
+         c->selinux_context = mfree(c->selinux_context);
+@@ -4097,10 +4097,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
+                         prefix, yes_no(c->cpu_sched_reset_on_fork));
+         }
+ 
+-        if (c->cpuset) {
++        if (c->cpu_set.set) {
+                 fprintf(f, "%sCPUAffinity:", prefix);
+-                for (i = 0; i < c->cpuset_ncpus; i++)
+-                        if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
++                for (i = 0; i < c->cpu_set.allocated * 8; i++)
++                        if (CPU_ISSET_S(i, c->cpu_set.allocated, c->cpu_set.set))
+                                 fprintf(f, " %u", i);
+                 fputs("\n", f);
+         }
+diff --git a/src/core/execute.h b/src/core/execute.h
+index 8c91636adc..e1e7a494cd 100644
+--- a/src/core/execute.h
++++ b/src/core/execute.h
+@@ -14,6 +14,7 @@ typedef struct Manager Manager;
+ #include <sys/capability.h>
+ 
+ #include "cgroup-util.h"
++#include "cpu-set-util.h"
+ #include "fdset.h"
+ #include "list.h"
+ #include "missing.h"
+@@ -148,8 +149,7 @@ struct ExecContext {
+         int cpu_sched_policy;
+         int cpu_sched_priority;
+ 
+-        cpu_set_t *cpuset;
+-        unsigned cpuset_ncpus;
++        CPUSet cpu_set;
+ 
+         ExecInput std_input;
+         ExecOutput std_output;
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index d9a5094aa0..34ae834188 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -1211,42 +1211,13 @@ int config_parse_exec_cpu_affinity(const char *unit,
+                                    void *userdata) {
+ 
+         ExecContext *c = data;
+-        _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
+-        int ncpus;
+ 
+         assert(filename);
+         assert(lvalue);
+         assert(rvalue);
+         assert(data);
+ 
+-        ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue);
+-        if (ncpus < 0)
+-                return ncpus;
+-
+-        if (ncpus == 0) {
+-                /* An empty assignment resets the CPU list */
+-                c->cpuset = cpu_set_mfree(c->cpuset);
+-                c->cpuset_ncpus = 0;
+-                return 0;
+-        }
+-
+-        if (!c->cpuset) {
+-                c->cpuset = TAKE_PTR(cpuset);
+-                c->cpuset_ncpus = (unsigned) ncpus;
+-                return 0;
+-        }
+-
+-        if (c->cpuset_ncpus < (unsigned) ncpus) {
+-                CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, cpuset);
+-                CPU_FREE(c->cpuset);
+-                c->cpuset = TAKE_PTR(cpuset);
+-                c->cpuset_ncpus = (unsigned) ncpus;
+-                return 0;
+-        }
+-
+-        CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), c->cpuset, c->cpuset, cpuset);
+-
+-        return 0;
++        return parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue);
+ }
+ 
+ int config_parse_capability_set(
+diff --git a/src/core/main.c b/src/core/main.c
+index af7b26d6f1..e62b2756ee 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -537,16 +537,18 @@ static int config_parse_cpu_affinity2(
+                 void *data,
+                 void *userdata) {
+ 
+-        _cleanup_cpu_free_ cpu_set_t *c = NULL;
+-        int ncpus;
++        _cleanup_(cpu_set_reset) CPUSet c = {};
++        int r;
+ 
+-        ncpus = parse_cpu_set_and_warn(rvalue, &c, unit, filename, line, lvalue);
+-        if (ncpus < 0)
+-                return ncpus;
++        r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue);
++        if (r < 0)
++                return r;
+ 
+-        if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
++        if (sched_setaffinity(0, c.allocated, c.set) < 0)
+                 log_warning_errno(errno, "Failed to set CPU affinity: %m");
+ 
++        // FIXME: parsing and execution should be seperated.
++
+         return 0;
+ }
+ 
+diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c
+index 62a3486952..21c24a1111 100644
+--- a/src/nspawn/nspawn-settings.c
++++ b/src/nspawn/nspawn-settings.c
+@@ -85,7 +85,7 @@ Settings* settings_free(Settings *s) {
+         strv_free(s->syscall_blacklist);
+         rlimit_free_all(s->rlimit);
+         free(s->hostname);
+-        s->cpuset = cpu_set_mfree(s->cpuset);
++        cpu_set_reset(&s->cpu_set);
+ 
+         strv_free(s->network_interfaces);
+         strv_free(s->network_macvlan);
+@@ -687,41 +687,12 @@ int config_parse_cpu_affinity(
+                 void *data,
+                 void *userdata) {
+ 
+-        _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
+         Settings *settings = data;
+-        int ncpus;
+ 
+         assert(rvalue);
+         assert(settings);
+ 
+-        ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue);
+-        if (ncpus < 0)
+-                return ncpus;
+-
+-        if (ncpus == 0) {
+-                /* An empty assignment resets the CPU list */
+-                settings->cpuset = cpu_set_mfree(settings->cpuset);
+-                settings->cpuset_ncpus = 0;
+-                return 0;
+-        }
+-
+-        if (!settings->cpuset) {
+-                settings->cpuset = TAKE_PTR(cpuset);
+-                settings->cpuset_ncpus = (unsigned) ncpus;
+-                return 0;
+-        }
+-
+-        if (settings->cpuset_ncpus < (unsigned) ncpus) {
+-                CPU_OR_S(CPU_ALLOC_SIZE(settings->cpuset_ncpus), cpuset, settings->cpuset, cpuset);
+-                CPU_FREE(settings->cpuset);
+-                settings->cpuset = TAKE_PTR(cpuset);
+-                settings->cpuset_ncpus = (unsigned) ncpus;
+-                return 0;
+-        }
+-
+-        CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), settings->cpuset, settings->cpuset, cpuset);
+-
+-        return 0;
++        return parse_cpu_set_extend(rvalue, &settings->cpu_set, true, unit, filename, line, lvalue);
+ }
+ 
+ DEFINE_CONFIG_PARSE_ENUM(config_parse_resolv_conf, resolv_conf_mode, ResolvConfMode, "Failed to parse resolv.conf mode");
+diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h
+index d522f3cb36..da863ef11c 100644
+--- a/src/nspawn/nspawn-settings.h
++++ b/src/nspawn/nspawn-settings.h
+@@ -7,6 +7,7 @@
+ #include "sd-id128.h"
+ 
+ #include "conf-parser.h"
++#include "cpu-set-util.h"
+ #include "macro.h"
+ #include "nspawn-expose-ports.h"
+ #include "nspawn-mount.h"
+@@ -123,8 +124,7 @@ typedef struct Settings {
+         int no_new_privileges;
+         int oom_score_adjust;
+         bool oom_score_adjust_set;
+-        cpu_set_t *cpuset;
+-        unsigned cpuset_ncpus;
++        CPUSet cpu_set;
+         ResolvConfMode resolv_conf;
+         LinkJournal link_journal;
+         bool link_journal_try;
+diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
+index b40411dcd0..08255b5724 100644
+--- a/src/nspawn/nspawn.c
++++ b/src/nspawn/nspawn.c
+@@ -199,8 +199,7 @@ static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {};
+ static bool arg_no_new_privileges = false;
+ static int arg_oom_score_adjust = 0;
+ static bool arg_oom_score_adjust_set = false;
+-static cpu_set_t *arg_cpuset = NULL;
+-static unsigned arg_cpuset_ncpus = 0;
++static CPUSet arg_cpu_set = {};
+ static ResolvConfMode arg_resolv_conf = RESOLV_CONF_AUTO;
+ static TimezoneMode arg_timezone = TIMEZONE_AUTO;
+ 
+@@ -1186,17 +1185,14 @@ static int parse_argv(int argc, char *argv[]) {
+                         break;
+ 
+                 case ARG_CPU_AFFINITY: {
+-                        _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
++                        CPUSet cpuset;
+ 
+                         r = parse_cpu_set(optarg, &cpuset);
+                         if (r < 0)
+-                                return log_error_errno(r, "Failed to parse CPU affinity mask: %s", optarg);
++                                return log_error_errno(r, "Failed to parse CPU affinity mask %s: %m", optarg);
+ 
+-                        if (arg_cpuset)
+-                                CPU_FREE(arg_cpuset);
+-
+-                        arg_cpuset = TAKE_PTR(cpuset);
+-                        arg_cpuset_ncpus = r;
++                        cpu_set_reset(&arg_cpu_set);
++                        arg_cpu_set = cpuset;
+                         arg_settings_mask |= SETTING_CPU_AFFINITY;
+                         break;
+                 }
+@@ -2631,8 +2627,8 @@ static int inner_child(
+                         return log_error_errno(r, "Failed to adjust OOM score: %m");
+         }
+ 
+-        if (arg_cpuset)
+-                if (sched_setaffinity(0, CPU_ALLOC_SIZE(arg_cpuset_ncpus), arg_cpuset) < 0)
++        if (arg_cpu_set.set)
++                if (sched_setaffinity(0, arg_cpu_set.allocated, arg_cpu_set.set) < 0)
+                         return log_error_errno(errno, "Failed to set CPU affinity: %m");
+ 
+         r = drop_capabilities();
+@@ -3494,15 +3490,14 @@ static int merge_settings(Settings *settings, const char *path) {
+         }
+ 
+         if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 &&
+-            settings->cpuset) {
++            settings->cpu_set.set) {
+ 
+                 if (!arg_settings_trusted)
+                         log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", path);
+                 else {
+-                        if (arg_cpuset)
+-                                CPU_FREE(arg_cpuset);
+-                        arg_cpuset = TAKE_PTR(settings->cpuset);
+-                        arg_cpuset_ncpus = settings->cpuset_ncpus;
++                        cpu_set_reset(&arg_cpu_set);
++                        arg_cpu_set = settings->cpu_set;
++                        settings->cpu_set = (CPUSet) {};
+                 }
+         }
+ 
+@@ -4600,7 +4595,7 @@ finish:
+         rlimit_free_all(arg_rlimit);
+         strv_free(arg_syscall_whitelist);
+         strv_free(arg_syscall_blacklist);
+-        arg_cpuset = cpu_set_mfree(arg_cpuset);
++        cpu_set_reset(&arg_cpu_set);
+ 
+         return r < 0 ? EXIT_FAILURE : ret;
+ }
+diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
+index 271cc054da..75b4aace84 100644
+--- a/src/shared/bus-unit-util.c
++++ b/src/shared/bus-unit-util.c
+@@ -932,13 +932,13 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
+         }
+ 
+         if (streq(field, "CPUAffinity")) {
+-                _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
++                _cleanup_(cpu_set_reset) CPUSet cpuset = {};
+ 
+                 r = parse_cpu_set(eq, &cpuset);
+                 if (r < 0)
+                         return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
+ 
+-                return bus_append_byte_array(m, field, cpuset, CPU_ALLOC_SIZE(r));
++                return bus_append_byte_array(m, field, cpuset.set, cpuset.allocated);
+         }
+ 
+         if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) {
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index ff5edb2a69..b9ec29af66 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -1,154 +1,171 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
++#include <errno.h>
++
+ #include "alloc-util.h"
+ #include "cpu-set-util.h"
+ #include "macro.h"
+ 
+ static void test_parse_cpu_set(void) {
+-        cpu_set_t *c = NULL;
++        CPUSet c = {};
+         _cleanup_free_ char *str = NULL;
+-        int ncpus;
+         int cpu;
+ 
+         /* Simple range (from CPUAffinity example) */
+-        ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
+-
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++        assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.set);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_ISSET_S(1, c.allocated, c.set));
++        assert_se(CPU_ISSET_S(2, c.allocated, c.set));
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
++
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* A more interesting range */
+-        ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
++        assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+         for (cpu = 8; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Quoted strings */
+-        ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
++        assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
+         for (cpu = 8; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Use commas as separators */
+-        ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
++        assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+         for (cpu = 8; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Commas with spaces (and trailing comma, space) */
+-        ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
++        assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 8; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Ranges */
+-        ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
++        assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+         for (cpu = 8; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Ranges with trailing comma, space */
+-        ncpus = parse_cpu_set_and_warn("0-3  8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
++        assert_se(parse_cpu_set_full("0-3  8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+         for (cpu = 8; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Negative range (returns empty cpu_set) */
+-        ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
+-        c = cpu_set_mfree(c);
++        assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
++        cpu_set_reset(&c);
+ 
+         /* Overlapping ranges */
+-        ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
++        assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
+         for (cpu = 0; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Mix ranges and individual CPUs */
+-        ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus >= 1024);
+-        assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
+-        assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
++        assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
++        assert_se(CPU_ISSET_S(0, c.allocated, c.set));
++        assert_se(CPU_ISSET_S(1, c.allocated, c.set));
+         for (cpu = 4; cpu < 12; cpu++)
+-                assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
+-        assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
++                assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++        assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+-        c = cpu_set_mfree(c);
++        cpu_set_reset(&c);
+ 
+         /* Garbage */
+-        ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus < 0);
+-        assert_se(!c);
++        assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
++        assert_se(!c.set);
++        assert_se(c.allocated == 0);
+ 
+         /* Range with garbage */
+-        ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus < 0);
+-        assert_se(!c);
++        assert_se(parse_cpu_set_full("0-3 8-garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
++        assert_se(!c.set);
++        assert_se(c.allocated == 0);
+ 
+         /* Empty string */
+-        c = NULL;
+-        ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus == 0);  /* empty string returns 0 */
+-        assert_se(!c);
++        assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
++        assert_se(!c.set);                /* empty string returns NULL */
++        assert_se(c.allocated == 0);
+ 
+         /* Runaway quoted string */
+-        ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
+-        assert_se(ncpus < 0);
+-        assert_se(!c);
++        assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
++        assert_se(!c.set);
++        assert_se(c.allocated == 0);
++
++        /* Maximum allocation */
++        assert_se(parse_cpu_set_full("8000-8191", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 192);
++        assert_se(str = cpu_set_to_string(&c));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
++        cpu_set_reset(&c);
+ }
+ 
+ int main(int argc, char *argv[]) {
++        log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
++        log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
++        log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
++        log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
++        log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
++        log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
++        log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
++
+         test_parse_cpu_set();
+ 
+         return 0;
+diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c
+index 7a1e496ed2..396e68f35f 100644
+--- a/src/test/test-sizeof.c
++++ b/src/test/test-sizeof.c
+@@ -1,5 +1,6 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
++#include <sched.h>
+ #include <stdio.h>
+ #include <string.h>
+ 
+@@ -64,6 +65,8 @@ int main(void) {
+         info(uid_t);
+         info(gid_t);
+ 
++        info(__cpu_mask);
++
+         info(enum Enum);
+         info(enum BigEnum);
+         info(enum BigEnum2);
diff --git a/SOURCES/0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch b/SOURCES/0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch
new file mode 100644
index 0000000..43f5d04
--- /dev/null
+++ b/SOURCES/0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch
@@ -0,0 +1,125 @@
+From 42032749e61076b3d9e5004432073c2a5ea737ce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 28 May 2019 21:28:31 +0200
+Subject: [PATCH] Move cpus_in_affinity_mask() to cpu-set-util.[ch]
+
+It just seems to fit better there and it's always better to have things
+in shared/ rather than basic/.
+
+(cherry picked from commit f44b3035d4a698aa0ce08a552199b54d43de3d85)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c  | 34 ++++++++++++++++++++++++++++++++++
+ src/basic/cpu-set-util.h  |  2 ++
+ src/basic/process-util.c  |  5 ++---
+ src/shared/condition.c    |  1 +
+ src/test/test-condition.c |  1 +
+ 5 files changed, 40 insertions(+), 3 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index fe440f6381..1803539ac6 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -204,3 +204,37 @@ int parse_cpu_set_extend(
+ 
+         return cpu_set_add_all(old, &cpuset);
+ }
++
++int cpus_in_affinity_mask(void) {
++        size_t n = 16;
++        int r;
++
++        for (;;) {
++                cpu_set_t *c;
++
++                c = CPU_ALLOC(n);
++                if (!c)
++                        return -ENOMEM;
++
++                if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) {
++                        int k;
++
++                        k = CPU_COUNT_S(CPU_ALLOC_SIZE(n), c);
++                        CPU_FREE(c);
++
++                        if (k <= 0)
++                                return -EINVAL;
++
++                        return k;
++                }
++
++                r = -errno;
++                CPU_FREE(c);
++
++                if (r != -EINVAL)
++                        return r;
++                if (n > SIZE_MAX/2)
++                        return -ENOMEM;
++                n *= 2;
++        }
++}
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index eb31b362fe..9b026aca09 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -49,3 +49,5 @@ int parse_cpu_set_extend(
+ static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){
+         return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
+ }
++
++int cpus_in_affinity_mask(void);
+diff --git a/src/basic/process-util.c b/src/basic/process-util.c
+index 6dbeee9dda..0a4a747ba4 100644
+--- a/src/basic/process-util.c
++++ b/src/basic/process-util.c
+@@ -4,7 +4,6 @@
+ #include <errno.h>
+ #include <limits.h>
+ #include <linux/oom.h>
+-#include <sched.h>
+ #include <signal.h>
+ #include <stdbool.h>
+ #include <stdio.h>
+@@ -1474,7 +1473,7 @@ static const char *const ioprio_class_table[] = {
+         [IOPRIO_CLASS_NONE] = "none",
+         [IOPRIO_CLASS_RT] = "realtime",
+         [IOPRIO_CLASS_BE] = "best-effort",
+-        [IOPRIO_CLASS_IDLE] = "idle"
++        [IOPRIO_CLASS_IDLE] = "idle",
+ };
+ 
+ DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_N_CLASSES);
+@@ -1495,7 +1494,7 @@ static const char* const sched_policy_table[] = {
+         [SCHED_BATCH] = "batch",
+         [SCHED_IDLE] = "idle",
+         [SCHED_FIFO] = "fifo",
+-        [SCHED_RR] = "rr"
++        [SCHED_RR] = "rr",
+ };
+ 
+ DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
+diff --git a/src/shared/condition.c b/src/shared/condition.c
+index 2969a89b4e..b829f0528c 100644
+--- a/src/shared/condition.c
++++ b/src/shared/condition.c
+@@ -21,6 +21,7 @@
+ #include "cap-list.h"
+ #include "cgroup-util.h"
+ #include "condition.h"
++#include "cpu-set-util.h"
+ #include "efivars.h"
+ #include "extract-word.h"
+ #include "fd-util.h"
+diff --git a/src/test/test-condition.c b/src/test/test-condition.c
+index 7ce6ee80ea..24395dafc6 100644
+--- a/src/test/test-condition.c
++++ b/src/test/test-condition.c
+@@ -13,6 +13,7 @@
+ #include "audit-util.h"
+ #include "cgroup-util.h"
+ #include "condition.h"
++#include "cpu-set-util.h"
+ #include "efivars.h"
+ #include "hostname-util.h"
+ #include "id128-util.h"
diff --git a/SOURCES/0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch b/SOURCES/0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch
new file mode 100644
index 0000000..026cee1
--- /dev/null
+++ b/SOURCES/0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch
@@ -0,0 +1,40 @@
+From a1ed6bfc5a8c40377b9f1cab1acc3c67a9529427 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 21 May 2019 09:01:34 +0200
+Subject: [PATCH] test-cpu-set-util: add simple test for
+ cpus_in_affinity_mask()
+
+(cherry picked from commit 9d1345f0657c707df89b41b2738776efb40aec8e)
+
+Related: #1734787
+---
+ src/test/test-cpu-set-util.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index b9ec29af66..e87e0ca6e6 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -157,6 +157,14 @@ static void test_parse_cpu_set(void) {
+         cpu_set_reset(&c);
+ }
+ 
++static void test_cpus_in_affinity_mask(void) {
++        int r;
++
++        r = cpus_in_affinity_mask();
++        assert(r > 0);
++        log_info("cpus_in_affinity_mask: %d", r);
++}
++
+ int main(int argc, char *argv[]) {
+         log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
+         log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
+@@ -167,6 +175,7 @@ int main(int argc, char *argv[]) {
+         log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
+ 
+         test_parse_cpu_set();
++        test_cpus_in_affinity_mask();
+ 
+         return 0;
+ }
diff --git a/SOURCES/0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch b/SOURCES/0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch
new file mode 100644
index 0000000..cce5c67
--- /dev/null
+++ b/SOURCES/0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch
@@ -0,0 +1,63 @@
+From 69541e93c45efb7ee15d7584c3aa70c3ff0b2200 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 24 May 2019 08:50:41 +0200
+Subject: [PATCH] test-cpu-set-util: add a smoke test for
+ test_parse_cpu_set_extend()
+
+(cherry picked from commit b54d7241f25b859c6c008e516c2131c39902e6e4)
+
+Related: #1734787
+---
+ src/test/test-cpu-set-util.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index e87e0ca6e6..81f67647e8 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -11,6 +11,8 @@ static void test_parse_cpu_set(void) {
+         _cleanup_free_ char *str = NULL;
+         int cpu;
+ 
++        log_info("/* %s */", __func__);
++
+         /* Simple range (from CPUAffinity example) */
+         assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.set);
+@@ -157,6 +159,28 @@ static void test_parse_cpu_set(void) {
+         cpu_set_reset(&c);
+ }
+ 
++static void test_parse_cpu_set_extend(void) {
++        CPUSet c = {};
++        _cleanup_free_ char *s1 = NULL, *s2 = NULL;
++
++        log_info("/* %s */", __func__);
++
++        assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
++        assert_se(s1 = cpu_set_to_string(&c));
++        log_info("cpu_set_to_string: %s", s1);
++
++        assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
++        assert_se(s2 = cpu_set_to_string(&c));
++        log_info("cpu_set_to_string: %s", s2);
++
++        assert_se(parse_cpu_set_extend("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
++        assert_se(!c.set);
++        assert_se(c.allocated == 0);
++        log_info("cpu_set_to_string: (null)");
++}
++
+ static void test_cpus_in_affinity_mask(void) {
+         int r;
+ 
+@@ -175,6 +199,7 @@ int main(int argc, char *argv[]) {
+         log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
+ 
+         test_parse_cpu_set();
++        test_parse_cpu_set_extend();
+         test_cpus_in_affinity_mask();
+ 
+         return 0;
diff --git a/SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch b/SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch
new file mode 100644
index 0000000..948c139
--- /dev/null
+++ b/SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch
@@ -0,0 +1,148 @@
+From 8bf8409c6e08f5aef35d1976e172b3f61b651c8d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 24 May 2019 08:35:51 +0200
+Subject: [PATCH] pid1: parse CPUAffinity= in incremental fashion
+
+This makes the handling of this option match what we do in unit files. I think
+consistency is important here. (As it happens, it is the only option in
+system.conf that is "non-atomic", i.e. where there's a list of things which can
+be split over multiple assignments. All other options are single-valued, so
+there's no issue of how to handle multiple assignments.)
+
+(cherry picked from commit 61fbbac1d517a0b3498a689c736c6ca918497904)
+
+Related: #1734787
+---
+ man/systemd-system.conf.xml | 13 ++++++++-----
+ man/systemd.exec.xml        |  2 +-
+ src/core/main.c             | 36 ++++++++++++++++++++++++++----------
+ 3 files changed, 35 insertions(+), 16 deletions(-)
+
+diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
+index 085086200a..ab23779ec0 100644
+--- a/man/systemd-system.conf.xml
++++ b/man/systemd-system.conf.xml
+@@ -99,11 +99,14 @@
+       <varlistentry>
+         <term><varname>CPUAffinity=</varname></term>
+ 
+-        <listitem><para>Configures the initial CPU affinity for the
+-        init process. Takes a list of CPU indices or ranges separated
+-        by either whitespace or commas. CPU ranges are specified by
+-        the lower and upper CPU indices separated by a
+-        dash.</para></listitem>
++        <listitem><para>Configures the CPU affinity for the service manager as well as the default CPU
++        affinity for all forked off processes. Takes a list of CPU indices or ranges separated by either
++        whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a
++        dash. This option may be specified more than once, in which case the specified CPU affinity masks are
++        merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have
++        no effect. Individual services may override the CPU affinity for their processes with the
++        <varname>CPUAffinity=</varname> setting in unit files, see
++        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
+       </varlistentry>
+ 
+       <varlistentry>
+diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
+index 737c52bcc4..342b8385bc 100644
+--- a/man/systemd.exec.xml
++++ b/man/systemd.exec.xml
+@@ -703,7 +703,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
+ 
+         <listitem><para>Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges
+         separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated
+-        by a dash.  This option may be specified more than once, in which case the specified CPU affinity masks are
++        by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
+         merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no
+         effect. See
+         <citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+diff --git a/src/core/main.c b/src/core/main.c
+index e62b2756ee..bc1db2af7b 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -127,6 +127,7 @@ static bool arg_default_tasks_accounting = true;
+ static uint64_t arg_default_tasks_max = UINT64_MAX;
+ static sd_id128_t arg_machine_id = {};
+ static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
++static CPUSet arg_cpu_affinity = {};
+ 
+ _noreturn_ static void freeze_or_reboot(void) {
+ 
+@@ -537,17 +538,11 @@ static int config_parse_cpu_affinity2(
+                 void *data,
+                 void *userdata) {
+ 
+-        _cleanup_(cpu_set_reset) CPUSet c = {};
+-        int r;
+-
+-        r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue);
+-        if (r < 0)
+-                return r;
++        CPUSet *affinity = data;
+ 
+-        if (sched_setaffinity(0, c.allocated, c.set) < 0)
+-                log_warning_errno(errno, "Failed to set CPU affinity: %m");
++        assert(affinity);
+ 
+-        // FIXME: parsing and execution should be seperated.
++        (void) parse_cpu_set_extend(rvalue, affinity, true, unit, filename, line, lvalue);
+ 
+         return 0;
+ }
+@@ -655,7 +650,7 @@ static int parse_config_file(void) {
+                 { "Manager", "CrashShell",                config_parse_bool,             0, &arg_crash_shell                       },
+                 { "Manager", "CrashReboot",               config_parse_bool,             0, &arg_crash_reboot                      },
+                 { "Manager", "ShowStatus",                config_parse_show_status,      0, &arg_show_status                       },
+-                { "Manager", "CPUAffinity",               config_parse_cpu_affinity2,    0, NULL                                   },
++                { "Manager", "CPUAffinity",               config_parse_cpu_affinity2,    0, &arg_cpu_affinity                      },
+                 { "Manager", "JoinControllers",           config_parse_join_controllers, 0, &arg_join_controllers                  },
+                 { "Manager", "RuntimeWatchdogSec",        config_parse_sec,              0, &arg_runtime_watchdog                  },
+                 { "Manager", "ShutdownWatchdogSec",       config_parse_sec,              0, &arg_shutdown_watchdog                 },
+@@ -1483,6 +1478,21 @@ static void initialize_coredump(bool skip_setup) {
+ #endif
+ }
+ 
++static void update_cpu_affinity(bool skip_setup) {
++        _cleanup_free_ char *mask = NULL;
++
++        if (skip_setup || !arg_cpu_affinity.set)
++                return;
++
++        assert(arg_cpu_affinity.allocated > 0);
++
++        mask = cpu_set_to_string(&arg_cpu_affinity);
++        log_debug("Setting CPU affinity to %s.", strnull(mask));
++
++        if (sched_setaffinity(0, arg_cpu_affinity.allocated, arg_cpu_affinity.set) < 0)
++                log_warning_errno(errno, "Failed to set CPU affinity: %m");
++}
++
+ static void do_reexecute(
+                 int argc,
+                 char *argv[],
+@@ -1655,6 +1665,8 @@ static int invoke_main_loop(
+ 
+                         set_manager_defaults(m);
+ 
++                        update_cpu_affinity(false);
++
+                         if (saved_log_level >= 0)
+                                 manager_override_log_level(m, saved_log_level);
+                         if (saved_log_target >= 0)
+@@ -1813,6 +1825,8 @@ static int initialize_runtime(
+         if (arg_action != ACTION_RUN)
+                 return 0;
+ 
++        update_cpu_affinity(skip_setup);
++
+         if (arg_system) {
+                 /* Make sure we leave a core dump without panicing the kernel. */
+                 install_crash_handler();
+@@ -1947,6 +1961,8 @@ static void free_arguments(void) {
+         arg_join_controllers = strv_free_free(arg_join_controllers);
+         arg_default_environment = strv_free(arg_default_environment);
+         arg_syscall_archs = set_free(arg_syscall_archs);
++
++        cpu_set_reset(&arg_cpu_affinity);
+ }
+ 
+ static int load_configuration(int argc, char **argv, const char **ret_error_message) {
diff --git a/SOURCES/0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch b/SOURCES/0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch
new file mode 100644
index 0000000..bb8d822
--- /dev/null
+++ b/SOURCES/0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch
@@ -0,0 +1,86 @@
+From f71f3271fa149d2b5f022830d43071d97b022b38 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 24 May 2019 08:59:23 +0200
+Subject: [PATCH] pid1: don't reset setting from /proc/cmdline upon restart
+
+We have settings which may be set on the kernel command line, and also
+in /proc/cmdline (for pid1). The settings in /proc/cmdline have higher priority
+of course. When a reload was done, we'd reload just the configuration file,
+losing the overrides.
+
+So read /proc/cmdline again during reload.
+
+Also, when initially reading the configuration file when program starts,
+don't treat any errors as fatal. The configuration done in there doesn't
+seem important enough to refuse boot.
+
+(cherry picked from commit 470a5e6dcec4637439ae953002127af214d396ac)
+
+Related: #1734787
+---
+ src/core/main.c | 26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index bc1db2af7b..9a9f145080 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -129,6 +129,8 @@ static sd_id128_t arg_machine_id = {};
+ static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
+ static CPUSet arg_cpu_affinity = {};
+ 
++static int parse_configuration(void);
++
+ _noreturn_ static void freeze_or_reboot(void) {
+ 
+         if (arg_crash_reboot) {
+@@ -1659,9 +1661,7 @@ static int invoke_main_loop(
+                         saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
+                         saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
+ 
+-                        r = parse_config_file();
+-                        if (r < 0)
+-                                log_warning_errno(r, "Failed to parse config file, ignoring: %m");
++                        (void) parse_configuration();
+ 
+                         set_manager_defaults(m);
+ 
+@@ -1965,18 +1965,14 @@ static void free_arguments(void) {
+         cpu_set_reset(&arg_cpu_affinity);
+ }
+ 
+-static int load_configuration(int argc, char **argv, const char **ret_error_message) {
++static int parse_configuration(void) {
+         int r;
+ 
+-        assert(ret_error_message);
+-
+         arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+ 
+         r = parse_config_file();
+-        if (r < 0) {
+-                *ret_error_message = "Failed to parse config file";
+-                return r;
+-        }
++        if (r < 0)
++                log_warning_errno(r, "Failed to parse config file, ignoring: %m");
+ 
+         if (arg_system) {
+                 r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
+@@ -1987,6 +1983,16 @@ static int load_configuration(int argc, char **argv, const char **ret_error_mess
+         /* Note that this also parses bits from the kernel command line, including "debug". */
+         log_parse_environment();
+ 
++        return 0;
++}
++
++static int load_configuration(int argc, char **argv, const char **ret_error_message) {
++        int r;
++
++        assert(ret_error_message);
++
++        (void) parse_configuration();
++
+         r = parse_argv(argc, argv);
+         if (r < 0) {
+                 *ret_error_message = "Failed to parse commandline arguments";
diff --git a/SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch b/SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch
new file mode 100644
index 0000000..1b941cc
--- /dev/null
+++ b/SOURCES/0278-pid1-when-reloading-configuration-forget-old-setting.patch
@@ -0,0 +1,208 @@
+From 0387294ba41ceaf80c79621409aab9508732bda0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Fri, 24 May 2019 09:41:44 +0200
+Subject: [PATCH] pid1: when reloading configuration, forget old settings
+
+If we had a configuration setting from a configuration file, and it was
+removed, we'd still remember the old value, because there's was no mechanism to
+"reset" everything, just to assign new values.
+
+Note that the effect of this is limited. For settings that have an "ongoing" effect,
+like systemd.confirm_spawn, the new value is simply used. But some settings can only
+be set at start.
+
+In particular, CPUAffinity= will be updated if set to a new value, but if
+CPUAffinity= is fully removed, it will not be reset, simply because we don't
+know what to reset it to. We might have inherited a setting, or we might have
+set it ourselves. In principle we could remember the "original" value that was
+set when we were executed, but propagate this over reloads and reexecs, but
+that would be a lot of work for little gain. So this corner case of removal of
+CPUAffinity= is not handled fully, and a reboot is needed to execute the
+change. As a work-around, a full mask of CPUAffinity=0-8191 can be specified.
+
+(cherry picked from commit fb39af4ce42d7ef9af63009f271f404038703704)
+
+Related: #1734787
+---
+ src/core/main.c | 139 +++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 95 insertions(+), 44 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 9a9f145080..c74dc641c1 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -88,46 +88,52 @@ static enum {
+         ACTION_DUMP_CONFIGURATION_ITEMS,
+         ACTION_DUMP_BUS_PROPERTIES,
+ } arg_action = ACTION_RUN;
+-static char *arg_default_unit = NULL;
+-static bool arg_system = false;
+-static bool arg_dump_core = true;
+-static int arg_crash_chvt = -1;
+-static bool arg_crash_shell = false;
+-static bool arg_crash_reboot = false;
+-static char *arg_confirm_spawn = NULL;
+-static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
+-static bool arg_switched_root = false;
+-static bool arg_no_pager = false;
+-static bool arg_service_watchdogs = true;
++
++/* Those variables are initalized to 0 automatically, so we avoid uninitialized memory access.
++ * Real defaults are assigned in reset_arguments() below. */
++static char *arg_default_unit;
++static bool arg_system;
++static bool arg_dump_core;
++static int arg_crash_chvt;
++static bool arg_crash_shell;
++static bool arg_crash_reboot;
++static char *arg_confirm_spawn;
++static ShowStatus arg_show_status;
++static bool arg_switched_root;
++static bool arg_no_pager;
++static bool arg_service_watchdogs;
+ static char ***arg_join_controllers = NULL;
+-static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
+-static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
+-static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
+-static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
+-static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
+-static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
+-static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
+-static usec_t arg_runtime_watchdog = 0;
+-static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
+-static char *arg_watchdog_device = NULL;
+-static char **arg_default_environment = NULL;
+-static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
+-static uint64_t arg_capability_bounding_set = CAP_ALL;
+-static bool arg_no_new_privs = false;
+-static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
+-static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
+-static Set* arg_syscall_archs = NULL;
+-static FILE* arg_serialization = NULL;
+-static bool arg_default_cpu_accounting = false;
+-static bool arg_default_io_accounting = false;
+-static bool arg_default_ip_accounting = false;
+-static bool arg_default_blockio_accounting = false;
+-static bool arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
+-static bool arg_default_tasks_accounting = true;
+-static uint64_t arg_default_tasks_max = UINT64_MAX;
+-static sd_id128_t arg_machine_id = {};
+-static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
+-static CPUSet arg_cpu_affinity = {};
++static ExecOutput arg_default_std_output;
++static ExecOutput arg_default_std_error;
++static usec_t arg_default_restart_usec;
++static usec_t arg_default_timeout_start_usec;
++static usec_t arg_default_timeout_stop_usec;
++static usec_t arg_default_timeout_abort_usec;
++static bool arg_default_timeout_abort_set;
++static usec_t arg_default_start_limit_interval;
++static unsigned arg_default_start_limit_burst;
++static usec_t arg_runtime_watchdog;
++static usec_t arg_shutdown_watchdog;
++static char *arg_early_core_pattern;
++static char *arg_watchdog_device;
++static char **arg_default_environment;
++static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
++static uint64_t arg_capability_bounding_set;
++static bool arg_no_new_privs;
++static nsec_t arg_timer_slack_nsec;
++static usec_t arg_default_timer_accuracy_usec;
++static Set* arg_syscall_archs;
++static FILE* arg_serialization;
++static int arg_default_cpu_accounting;
++static bool arg_default_io_accounting;
++static bool arg_default_ip_accounting;
++static bool arg_default_blockio_accounting;
++static bool arg_default_memory_accounting;
++static bool arg_default_tasks_accounting;
++static uint64_t arg_default_tasks_max;
++static sd_id128_t arg_machine_id;
++static EmergencyAction arg_cad_burst_action;
++static CPUSet arg_cpu_affinity;
+ 
+ static int parse_configuration(void);
+ 
+@@ -1951,17 +1957,59 @@ static int do_queue_default_job(
+         return 0;
+ }
+ 
+-static void free_arguments(void) {
+-
+-        /* Frees all arg_* variables, with the exception of arg_serialization */
+-        rlimit_free_all(arg_default_rlimit);
++static void reset_arguments(void) {
++        /* Frees/resets arg_* variables, with a few exceptions commented below. */
+ 
+         arg_default_unit = mfree(arg_default_unit);
++
++        /* arg_system — ignore */
++
++        arg_dump_core = true;
++        arg_crash_chvt = -1;
++        arg_crash_shell = false;
++        arg_crash_reboot = false;
+         arg_confirm_spawn = mfree(arg_confirm_spawn);
+         arg_join_controllers = strv_free_free(arg_join_controllers);
++        arg_show_status = _SHOW_STATUS_UNSET;
++        arg_switched_root = false;
++        arg_no_pager = false;
++        arg_service_watchdogs = true;
++        arg_default_std_output = EXEC_OUTPUT_JOURNAL;
++        arg_default_std_error = EXEC_OUTPUT_INHERIT;
++        arg_default_restart_usec = DEFAULT_RESTART_USEC;
++        arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
++        arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
++        arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC;
++        arg_default_timeout_abort_set = false;
++        arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
++        arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
++        arg_runtime_watchdog = 0;
++        arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
++        arg_early_core_pattern = NULL;
++        arg_watchdog_device = NULL;
++
+         arg_default_environment = strv_free(arg_default_environment);
++        rlimit_free_all(arg_default_rlimit);
++
++        arg_capability_bounding_set = CAP_ALL;
++        arg_no_new_privs = false;
++        arg_timer_slack_nsec = NSEC_INFINITY;
++        arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
++
+         arg_syscall_archs = set_free(arg_syscall_archs);
+ 
++        /* arg_serialization — ignore */
++
++        arg_default_cpu_accounting = -1;
++        arg_default_io_accounting = false;
++        arg_default_ip_accounting = false;
++        arg_default_blockio_accounting = false;
++        arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
++        arg_default_tasks_accounting = true;
++        arg_default_tasks_max = UINT64_MAX;
++        arg_machine_id = (sd_id128_t) {};
++        arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
++
+         cpu_set_reset(&arg_cpu_affinity);
+ }
+ 
+@@ -1970,6 +2018,9 @@ static int parse_configuration(void) {
+ 
+         arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+ 
++        /* Assign configuration defaults */
++        reset_arguments();
++
+         r = parse_config_file();
+         if (r < 0)
+                 log_warning_errno(r, "Failed to parse config file, ignoring: %m");
+@@ -2460,7 +2511,7 @@ finish:
+                 m = manager_free(m);
+         }
+ 
+-        free_arguments();
++        reset_arguments();
+         mac_selinux_finish();
+ 
+         if (reexecute)
diff --git a/SOURCES/0279-test-execute-use-CPUSet-too.patch b/SOURCES/0279-test-execute-use-CPUSet-too.patch
new file mode 100644
index 0000000..2332226
--- /dev/null
+++ b/SOURCES/0279-test-execute-use-CPUSet-too.patch
@@ -0,0 +1,114 @@
+From 5e6b616ed2708391752ba8c45f183ceb38573d7d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 28 May 2019 21:38:41 +0200
+Subject: [PATCH] test-execute: use CPUSet too
+
+cpu_set_malloc() was the last user. It doesn't seem useful to keep
+it just to save the allocation of a few hundred bytes in a test, so
+it is dropped and a fixed maximum is allocated (1024 bytes).
+
+(cherry picked from commit 167a776dbe9d033523bd6881e5a695f2155dc321)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c | 31 +------------------------------
+ src/basic/cpu-set-util.h |  3 +--
+ src/test/test-execute.c  | 13 ++++++-------
+ 3 files changed, 8 insertions(+), 39 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index 1803539ac6..c297eab032 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -37,36 +37,7 @@ char* cpu_set_to_string(const CPUSet *a) {
+         return TAKE_PTR(str) ?: strdup("");
+ }
+ 
+-cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+-        cpu_set_t *c;
+-        unsigned n = 1024;
+-
+-        /* Allocates the cpuset in the right size */
+-
+-        for (;;) {
+-                c = CPU_ALLOC(n);
+-                if (!c)
+-                        return NULL;
+-
+-                if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) {
+-                        CPU_ZERO_S(CPU_ALLOC_SIZE(n), c);
+-
+-                        if (ncpus)
+-                                *ncpus = n;
+-
+-                        return c;
+-                }
+-
+-                CPU_FREE(c);
+-
+-                if (errno != EINVAL)
+-                        return NULL;
+-
+-                n *= 2;
+-        }
+-}
+-
+-static int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
++int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
+         size_t need;
+ 
+         assert(cpu_set);
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index 9b026aca09..b54e737110 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -12,8 +12,6 @@
+ DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
+ #define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
+ 
+-cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+-
+ /* This wraps the libc interface with a variable to keep the allocated size. */
+ typedef struct CPUSet {
+         cpu_set_t *set;
+@@ -30,6 +28,7 @@ static inline void cpu_set_reset(CPUSet *a) {
+ int cpu_set_add_all(CPUSet *a, const CPUSet *b);
+ 
+ char* cpu_set_to_string(const CPUSet *a);
++int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus);
+ int parse_cpu_set_full(
+                 const char *rvalue,
+                 CPUSet *cpu_set,
+diff --git a/src/test/test-execute.c b/src/test/test-execute.c
+index fa8efdddd2..6c22995b1e 100644
+--- a/src/test/test-execute.c
++++ b/src/test/test-execute.c
+@@ -144,13 +144,12 @@ static void test_exec_bindpaths(Manager *m) {
+ }
+ 
+ static void test_exec_cpuaffinity(Manager *m) {
+-        _cleanup_cpu_free_ cpu_set_t *c = NULL;
+-        unsigned n;
++        _cleanup_(cpu_set_reset) CPUSet c = {};
+ 
+-        assert_se(c = cpu_set_malloc(&n));
+-        assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0);
++        assert_se(cpu_set_realloc(&c, 8192) >= 0); /* just allocate the maximum possible size */
++        assert_se(sched_getaffinity(0, c.allocated, c.set) >= 0);
+ 
+-        if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n), c) == 0) {
++        if (!CPU_ISSET_S(0, c.allocated, c.set)) {
+                 log_notice("Cannot use CPU 0, skipping %s", __func__);
+                 return;
+         }
+@@ -158,8 +157,8 @@ static void test_exec_cpuaffinity(Manager *m) {
+         test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED);
+         test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED);
+ 
+-        if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n), c) == 0 ||
+-            CPU_ISSET_S(2, CPU_ALLOC_SIZE(n), c) == 0) {
++        if (!CPU_ISSET_S(1, c.allocated, c.set) ||
++            !CPU_ISSET_S(2, c.allocated, c.set)) {
+                 log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__);
+                 return;
+         }
diff --git a/SOURCES/0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch b/SOURCES/0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch
new file mode 100644
index 0000000..21bf12e
--- /dev/null
+++ b/SOURCES/0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch
@@ -0,0 +1,26 @@
+From 7aa32093c3dfc4bf7298f02be553e95c40d7c211 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 28 May 2019 21:40:10 +0200
+Subject: [PATCH] shared/cpu-set-util: drop now-unused cleanup function
+
+(cherry picked from commit cb0d3acf55ef335001cac5dd9c335ec5e75e9b56)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index b54e737110..68a73bf9f7 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -9,9 +9,6 @@
+ 
+ #include "macro.h"
+ 
+-DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
+-#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
+-
+ /* This wraps the libc interface with a variable to keep the allocated size. */
+ typedef struct CPUSet {
+         cpu_set_t *set;
diff --git a/SOURCES/0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch b/SOURCES/0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch
new file mode 100644
index 0000000..d09f290
--- /dev/null
+++ b/SOURCES/0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch
@@ -0,0 +1,126 @@
+From daa0243fda679c8af723648b8b1e501fc55b0ada Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Wed, 22 May 2019 13:55:49 +0200
+Subject: [PATCH] shared/cpu-set-util: make transfer of cpu_set_t over bus
+ endian safe
+
+(cherry picked from commit c367f996f5f091a63f812f0140b304c649be77fc)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c   | 38 ++++++++++++++++++++++++++++++++++++++
+ src/basic/cpu-set-util.h   |  3 +++
+ src/core/dbus-execute.c    |  6 +++++-
+ src/shared/bus-unit-util.c |  8 +++++++-
+ 4 files changed, 53 insertions(+), 2 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index c297eab032..74e35e57dd 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -209,3 +209,41 @@ int cpus_in_affinity_mask(void) {
+                 n *= 2;
+         }
+ }
++
++int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated) {
++        uint8_t *out;
++
++        assert(set);
++        assert(ret);
++
++        out = new0(uint8_t, set->allocated);
++        if (!out)
++                return -ENOMEM;
++
++        for (unsigned cpu = 0; cpu < set->allocated * 8; cpu++)
++                if (CPU_ISSET_S(cpu, set->allocated, set->set))
++                        out[cpu / 8] |= 1u << (cpu % 8);
++
++        *ret = out;
++        *allocated = set->allocated;
++        return 0;
++}
++
++int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
++        _cleanup_(cpu_set_reset) CPUSet s = {};
++        int r;
++
++        assert(bits);
++        assert(set);
++
++        for (unsigned cpu = size * 8; cpu > 0; cpu--)
++                if (bits[(cpu - 1) / 8] & (1u << ((cpu - 1) % 8))) {
++                        r = cpu_set_add(&s, cpu - 1);
++                        if (r < 0)
++                                return r;
++                }
++
++        *set = s;
++        s = (CPUSet) {};
++        return 0;
++}
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index 68a73bf9f7..415c6ca295 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -46,4 +46,7 @@ static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){
+         return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
+ }
+ 
++int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated);
++int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set);
++
+ int cpus_in_affinity_mask(void);
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index 08946627e3..50ea71a281 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -1553,18 +1553,22 @@ int bus_exec_context_set_transient_property(
+         if (streq(name, "CPUAffinity")) {
+                 const void *a;
+                 size_t n;
++                _cleanup_(cpu_set_reset) CPUSet set = {};
+ 
+                 r = sd_bus_message_read_array(message, 'y', &a, &n);
+                 if (r < 0)
+                         return r;
+ 
++                r = cpu_set_from_dbus(a, n, &set);
++                if (r < 0)
++                        return r;
++
+                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                         if (n == 0) {
+                                 cpu_set_reset(&c->cpu_set);
+                                 unit_write_settingf(u, flags, name, "%s=", name);
+                         } else {
+                                 _cleanup_free_ char *str = NULL;
+-                                const CPUSet set = {(cpu_set_t*) a, n};
+ 
+                                 str = cpu_set_to_string(&set);
+                                 if (!str)
+diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
+index 75b4aace84..ec8732c226 100644
+--- a/src/shared/bus-unit-util.c
++++ b/src/shared/bus-unit-util.c
+@@ -933,12 +933,18 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
+ 
+         if (streq(field, "CPUAffinity")) {
+                 _cleanup_(cpu_set_reset) CPUSet cpuset = {};
++                _cleanup_free_ uint8_t *array = NULL;
++                size_t allocated;
+ 
+                 r = parse_cpu_set(eq, &cpuset);
+                 if (r < 0)
+                         return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
+ 
+-                return bus_append_byte_array(m, field, cpuset.set, cpuset.allocated);
++                r = cpu_set_to_dbus(&cpuset, &array, &allocated);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to serialize CPUAffinity: %m");
++
++                return bus_append_byte_array(m, field, array, allocated);
+         }
+ 
+         if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) {
diff --git a/SOURCES/0282-test-cpu-set-util-add-test-for-dbus-conversions.patch b/SOURCES/0282-test-cpu-set-util-add-test-for-dbus-conversions.patch
new file mode 100644
index 0000000..f6e259a
--- /dev/null
+++ b/SOURCES/0282-test-cpu-set-util-add-test-for-dbus-conversions.patch
@@ -0,0 +1,61 @@
+From fd65eadbbcc068171ee9164610fd1c2016b3bf59 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Wed, 29 May 2019 09:44:16 +0200
+Subject: [PATCH] test-cpu-set-util: add test for dbus conversions
+
+(cherry picked from commit 1bf0d6c28f8c884e187c7dacc1a969c0763ff4e3)
+
+Related: #1734787
+---
+ src/test/test-cpu-set-util.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index 81f67647e8..cae51ad7d9 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -181,6 +181,36 @@ static void test_parse_cpu_set_extend(void) {
+         log_info("cpu_set_to_string: (null)");
+ }
+ 
++static void test_cpu_set_to_from_dbus(void) {
++        _cleanup_(cpu_set_reset) CPUSet c = {}, c2 = {};
++        _cleanup_free_ char *s = NULL;
++
++        log_info("/* %s */", __func__);
++
++        assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
++        assert_se(s = cpu_set_to_string(&c));
++        log_info("cpu_set_to_string: %s", s);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 104);
++
++        _cleanup_free_ uint8_t *array = NULL;
++        size_t allocated;
++        static const char expected[32] =
++                "\x0A\x01\x00\x00\x00\x00\x00\x00\x00\x00"
++                "\x00\x00\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
++                "\xFF\xFF\xFF\xFF\xFF\x01";
++
++        assert_se(cpu_set_to_dbus(&c, &array, &allocated) == 0);
++        assert_se(array);
++        assert_se(allocated == c.allocated);
++
++        assert(memcmp(array, expected, sizeof expected) == 0);
++
++        assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
++        assert_se(c2.set);
++        assert_se(c2.allocated == c.allocated);
++        assert_se(memcmp(c.set, c2.set, c.allocated) == 0);
++}
++
+ static void test_cpus_in_affinity_mask(void) {
+         int r;
+ 
+@@ -201,6 +231,7 @@ int main(int argc, char *argv[]) {
+         test_parse_cpu_set();
+         test_parse_cpu_set_extend();
+         test_cpus_in_affinity_mask();
++        test_cpu_set_to_from_dbus();
+ 
+         return 0;
+ }
diff --git a/SOURCES/0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch b/SOURCES/0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch
new file mode 100644
index 0000000..d49553f
--- /dev/null
+++ b/SOURCES/0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch
@@ -0,0 +1,203 @@
+From 93777a6dd8c12d5cba094694bf7ed6e8c06c2d6d Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Thu, 23 May 2019 14:27:18 +0200
+Subject: [PATCH] shared/cpu-set-util: introduce cpu_set_to_range()
+
+(cherry picked from commit 71b28519b55b496237146f9bcb5a627455f15f7e)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c     | 37 ++++++++++++++++++++++++++
+ src/basic/cpu-set-util.h     |  2 ++
+ src/test/test-cpu-set-util.c | 50 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 89 insertions(+)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index 74e35e57dd..bff39ec143 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -37,6 +37,43 @@ char* cpu_set_to_string(const CPUSet *a) {
+         return TAKE_PTR(str) ?: strdup("");
+ }
+ 
++char *cpu_set_to_range_string(const CPUSet *set) {
++        unsigned range_start = 0, range_end;
++        _cleanup_free_ char *str = NULL;
++        size_t allocated = 0, len = 0;
++        bool in_range = false;
++        int r;
++
++        for (unsigned i = 0; i < set->allocated * 8; i++)
++                if (CPU_ISSET_S(i, set->allocated, set->set)) {
++                        if (in_range)
++                                range_end++;
++                        else {
++                                range_start = range_end = i;
++                                in_range = true;
++                        }
++                } else if (in_range) {
++                        in_range = false;
++
++                        if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
++                                return NULL;
++
++                        r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
++                        assert_se(r > 0);
++                        len += r;
++                }
++
++        if (in_range) {
++                if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
++                        return NULL;
++
++                r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
++                assert_se(r > 0);
++        }
++
++        return TAKE_PTR(str) ?: strdup("");
++}
++
+ int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
+         size_t need;
+ 
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index 415c6ca295..ec640b2ec9 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -25,7 +25,9 @@ static inline void cpu_set_reset(CPUSet *a) {
+ int cpu_set_add_all(CPUSet *a, const CPUSet *b);
+ 
+ char* cpu_set_to_string(const CPUSet *a);
++char *cpu_set_to_range_string(const CPUSet *a);
+ int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus);
++
+ int parse_cpu_set_full(
+                 const char *rvalue,
+                 CPUSet *cpu_set,
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index cae51ad7d9..0d2741cd43 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -4,6 +4,7 @@
+ 
+ #include "alloc-util.h"
+ #include "cpu-set-util.h"
++#include "string-util.h"
+ #include "macro.h"
+ 
+ static void test_parse_cpu_set(void) {
+@@ -13,6 +14,22 @@ static void test_parse_cpu_set(void) {
+ 
+         log_info("/* %s */", __func__);
+ 
++        /* Single value */
++        assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(c.set);
++        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(CPU_ISSET_S(0, c.allocated, c.set));
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
++
++        assert_se(str = cpu_set_to_string(&c));
++        log_info("cpu_set_to_string: %s", str);
++        str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "0-0"));
++        str = mfree(str);
++        cpu_set_reset(&c);
++
+         /* Simple range (from CPUAffinity example) */
+         assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.set);
+@@ -24,6 +41,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "1-2"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* A more interesting range */
+@@ -34,9 +55,14 @@ static void test_parse_cpu_set(void) {
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "0-3 8-11"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* Quoted strings */
+@@ -48,6 +74,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "8-11"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* Use commas as separators */
+@@ -72,6 +102,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "0-7"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* Ranges */
+@@ -98,6 +132,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "0-3 8-11"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* Negative range (returns empty cpu_set) */
+@@ -115,6 +153,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "0-11"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* Mix ranges and individual CPUs */
+@@ -128,6 +170,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "0-1 4-11"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ 
+         /* Garbage */
+@@ -156,6 +202,10 @@ static void test_parse_cpu_set(void) {
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
++        assert_se(str = cpu_set_to_range_string(&c));
++        log_info("cpu_set_to_range_string: %s", str);
++        assert_se(streq(str, "8000-8191"));
++        str = mfree(str);
+         cpu_set_reset(&c);
+ }
+ 
diff --git a/SOURCES/0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch b/SOURCES/0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch
new file mode 100644
index 0000000..44d35dd
--- /dev/null
+++ b/SOURCES/0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch
@@ -0,0 +1,53 @@
+From fb1244ef318e9f54628a7c13db9e2ffbc712dd38 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Wed, 22 May 2019 17:14:21 +0200
+Subject: [PATCH] systemctl: present CPUAffinity mask as a list of CPU index
+ ranges
+
+(cherry picked from commit a047f4f10ed2f922d6079c033d24a443b0e95f38)
+
+Related: #1734787
+---
+ src/systemctl/systemctl.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index f072ad0c31..0154b300a3 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -30,6 +30,7 @@
+ #include "cgroup-show.h"
+ #include "cgroup-util.h"
+ #include "copy.h"
++#include "cpu-set-util.h"
+ #include "dropin.h"
+ #include "efivars.h"
+ #include "env-util.h"
+@@ -4876,6 +4877,27 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
+ 
+                         print_prop(name, "%s", h);
+ 
++                        return 1;
++                } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "CPUAffinity")) {
++                        _cleanup_free_ char *affinity = NULL;
++                        _cleanup_(cpu_set_reset) CPUSet set = {};
++                        const void *a;
++                        size_t n;
++
++                        r = sd_bus_message_read_array(m, 'y', &a, &n);
++                        if (r < 0)
++                                return bus_log_parse_error(r);
++
++                        r = cpu_set_from_dbus(a, n, &set);
++                        if (r < 0)
++                                return log_error_errno(r, "Failed to deserialize CPUAffinity: %m");
++
++                        affinity = cpu_set_to_range_string(&set);
++                        if (!affinity)
++                                return log_oom();
++
++                        print_prop(name, "%s", affinity);
++
+                         return 1;
+                 }
+ 
diff --git a/SOURCES/0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch b/SOURCES/0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch
new file mode 100644
index 0000000..5f34600
--- /dev/null
+++ b/SOURCES/0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch
@@ -0,0 +1,77 @@
+From cabd9055d0d745f7de9625dec6c623d363dd3aa6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Wed, 29 May 2019 10:17:43 +0200
+Subject: [PATCH] shared/cpu-set-util: only force range printing one time
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The idea is to have at least one range to make the new format clearly
+distinguishable from the old. But it is enough to just do it once.
+In particular, in case the affinity would be specified like 0, 2, 4, 6…,
+this gives much shorter output.
+
+(cherry picked from commit 1f57a176af5152d05719bf43740e87a47e37af50)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c     | 10 ++++++++--
+ src/test/test-cpu-set-util.c |  7 ++++---
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index bff39ec143..5024290557 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -58,7 +58,10 @@ char *cpu_set_to_range_string(const CPUSet *set) {
+                         if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
+                                 return NULL;
+ 
+-                        r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
++                        if (range_end > range_start || len == 0)
++                                r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
++                        else
++                                r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
+                         assert_se(r > 0);
+                         len += r;
+                 }
+@@ -67,7 +70,10 @@ char *cpu_set_to_range_string(const CPUSet *set) {
+                 if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
+                         return NULL;
+ 
+-                r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
++                if (range_end > range_start || len == 0)
++                        r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
++                else
++                        r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
+                 assert_se(r > 0);
+         }
+ 
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index 0d2741cd43..995b981d25 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -31,19 +31,20 @@ static void test_parse_cpu_set(void) {
+         cpu_set_reset(&c);
+ 
+         /* Simple range (from CPUAffinity example) */
+-        assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.set);
+         assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+         assert_se(CPU_ISSET_S(1, c.allocated, c.set));
+         assert_se(CPU_ISSET_S(2, c.allocated, c.set));
+-        assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
++        assert_se(CPU_ISSET_S(4, c.allocated, c.set));
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
+ 
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+         assert_se(str = cpu_set_to_range_string(&c));
+         log_info("cpu_set_to_range_string: %s", str);
+-        assert_se(streq(str, "1-2"));
++        assert_se(streq(str, "1-2 4"));
+         str = mfree(str);
+         cpu_set_reset(&c);
+ 
diff --git a/SOURCES/0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch b/SOURCES/0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch
new file mode 100644
index 0000000..050478a
--- /dev/null
+++ b/SOURCES/0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch
@@ -0,0 +1,36 @@
+From b90f935f8d2268522480a7c12f7e2213a7a5e19d Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Fri, 31 May 2019 18:02:20 +0200
+Subject: [PATCH] execute: dump CPUAffinity as a range string instead of a list
+ of CPUs
+
+We do this already when printing the property in systemctl so be
+consistent and do the same for systemd-analyze dump.
+
+(cherry picked from commit e7fca352ba43988682a927de6b1f629b3f10a415)
+
+Related: #1734787
+---
+ src/core/execute.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index 22e5825905..bc26aa66e7 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -4098,11 +4098,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
+         }
+ 
+         if (c->cpu_set.set) {
+-                fprintf(f, "%sCPUAffinity:", prefix);
+-                for (i = 0; i < c->cpu_set.allocated * 8; i++)
+-                        if (CPU_ISSET_S(i, c->cpu_set.allocated, c->cpu_set.set))
+-                                fprintf(f, " %u", i);
+-                fputs("\n", f);
++                _cleanup_free_ char *affinity = NULL;
++
++                affinity = cpu_set_to_range_string(&c->cpu_set);
++                fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity);
+         }
+ 
+         if (c->timer_slack_nsec != NSEC_INFINITY)
diff --git a/SOURCES/0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch b/SOURCES/0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch
new file mode 100644
index 0000000..0b2bec0
--- /dev/null
+++ b/SOURCES/0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch
@@ -0,0 +1,95 @@
+From 35894625624f0e8c7d3ca2c200861005c7ad4435 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Mon, 3 Jun 2019 10:12:35 +0200
+Subject: [PATCH] cpu-set-util: use %d-%d format in  cpu_set_to_range_string()
+ only for actual ranges
+
+(cherry picked from commit 71923237b18df35401626993d8a285cd998be78d)
+
+Related: #1734787
+---
+ src/basic/cpu-set-util.c     |  4 ++--
+ src/test/test-cpu-set-util.c | 16 +++++++++-------
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index 5024290557..103b9703b3 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -58,7 +58,7 @@ char *cpu_set_to_range_string(const CPUSet *set) {
+                         if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
+                                 return NULL;
+ 
+-                        if (range_end > range_start || len == 0)
++                        if (range_end > range_start)
+                                 r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
+                         else
+                                 r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
+@@ -70,7 +70,7 @@ char *cpu_set_to_range_string(const CPUSet *set) {
+                 if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
+                         return NULL;
+ 
+-                if (range_end > range_start || len == 0)
++                if (range_end > range_start)
+                         r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
+                 else
+                         r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index 995b981d25..9522582891 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -26,7 +26,7 @@ static void test_parse_cpu_set(void) {
+         str = mfree(str);
+         assert_se(str = cpu_set_to_range_string(&c));
+         log_info("cpu_set_to_range_string: %s", str);
+-        assert_se(streq(str, "0-0"));
++        assert_se(streq(str, "0"));
+         str = mfree(str);
+         cpu_set_reset(&c);
+ 
+@@ -95,17 +95,19 @@ static void test_parse_cpu_set(void) {
+         cpu_set_reset(&c);
+ 
+         /* Commas with spaces (and trailing comma, space) */
+-        assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+-        assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
++        assert_se(CPU_COUNT_S(c.allocated, c.set) == 9);
+         for (cpu = 0; cpu < 8; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
++
++        assert_se(CPU_ISSET_S(63, c.allocated, c.set));
+         assert_se(str = cpu_set_to_string(&c));
+         log_info("cpu_set_to_string: %s", str);
+         str = mfree(str);
+         assert_se(str = cpu_set_to_range_string(&c));
+         log_info("cpu_set_to_range_string: %s", str);
+-        assert_se(streq(str, "0-7"));
++        assert_se(streq(str, "0-7 63"));
+         str = mfree(str);
+         cpu_set_reset(&c);
+ 
+@@ -161,11 +163,11 @@ static void test_parse_cpu_set(void) {
+         cpu_set_reset(&c);
+ 
+         /* Mix ranges and individual CPUs */
+-        assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
++        assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
+         assert_se(CPU_ISSET_S(0, c.allocated, c.set));
+-        assert_se(CPU_ISSET_S(1, c.allocated, c.set));
++        assert_se(CPU_ISSET_S(2, c.allocated, c.set));
+         for (cpu = 4; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+         assert_se(str = cpu_set_to_string(&c));
+@@ -173,7 +175,7 @@ static void test_parse_cpu_set(void) {
+         str = mfree(str);
+         assert_se(str = cpu_set_to_range_string(&c));
+         log_info("cpu_set_to_range_string: %s", str);
+-        assert_se(streq(str, "0-1 4-11"));
++        assert_se(streq(str, "0 2 4-11"));
+         str = mfree(str);
+         cpu_set_reset(&c);
+ 
diff --git a/SOURCES/0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch b/SOURCES/0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch
new file mode 100644
index 0000000..bcfd3a3
--- /dev/null
+++ b/SOURCES/0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch
@@ -0,0 +1,779 @@
+From a735699a8287c19e043b7d2fe9a387a3938e1e2f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
+Date: Mon, 18 Nov 2019 12:50:11 +0100
+Subject: [PATCH] core: introduce NUMAPolicy and NUMAMask options
+
+Make possible to set NUMA allocation policy for manager. Manager's
+policy is by default inherited to all forked off processes. However, it
+is possible to override the policy on per-service basis. Currently we
+support, these policies: default, prefer, bind, interleave, local.
+See man 2 set_mempolicy for details on each policy.
+
+Overall NUMA policy actually consists of two parts. Policy itself and
+bitmask representing NUMA nodes where is policy effective. Node mask can
+be specified using related option, NUMAMask. Default mask can be
+overwritten on per-service level.
+
+(cherry-picked from commit fe9c54b2188e6cd23262a319f96b13215f2c5e9c)
+
+Resolves: #1734787
+---
+ man/systemd-system.conf.xml           | 19 ++++++
+ man/systemd.exec.xml                  | 28 +++++++++
+ meson.build                           |  4 ++
+ src/basic/cpu-set-util.c              | 91 +++++++++++++++++++++++++++
+ src/basic/cpu-set-util.h              | 28 +++++++++
+ src/basic/exit-status.c               |  3 +
+ src/basic/exit-status.h               |  1 +
+ src/basic/missing_syscall.h           | 43 +++++++++++++
+ src/core/dbus-execute.c               | 65 ++++++++++++++++++-
+ src/core/execute.c                    | 20 ++++++
+ src/core/execute.h                    |  1 +
+ src/core/load-fragment-gperf.gperf.m4 |  2 +
+ src/core/load-fragment.c              | 28 +++++++++
+ src/core/load-fragment.h              |  2 +
+ src/core/main.c                       | 27 ++++++++
+ src/core/system.conf.in               |  2 +
+ src/shared/bus-unit-util.c            | 28 +++++++++
+ src/systemctl/systemctl.c             | 18 +++++-
+ 18 files changed, 405 insertions(+), 5 deletions(-)
+
+diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
+index ab23779ec0..988c4e7665 100644
+--- a/man/systemd-system.conf.xml
++++ b/man/systemd-system.conf.xml
+@@ -132,6 +132,25 @@
+         anymore.</para></listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><varname>NUMAPolicy=</varname></term>
++
++        <listitem><para>Configures the NUMA memory policy for the service manager and the default NUMA memory policy
++        for all forked off processes. Individual services may override the default policy with the
++        <varname>NUMAPolicy=</varname> setting in unit files, see
++        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
++      </varlistentry>
++
++      <varlistentry>
++        <term><varname>NUMAMask=</varname></term>
++
++        <listitem><para>Configures the NUMA node mask that will be associated with the selected NUMA policy. Note that
++        <option>default</option> and <option>local</option> NUMA policies don't require explicit NUMA node mask and
++        value of the option can be empty. Similarly to <varname>NUMAPolicy=</varname>, value can be overriden
++        by individual services in unit files, see
++        <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><varname>RuntimeWatchdogSec=</varname></term>
+         <term><varname>ShutdownWatchdogSec=</varname></term>
+diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
+index 342b8385bc..87fb8b34f4 100644
+--- a/man/systemd.exec.xml
++++ b/man/systemd.exec.xml
+@@ -710,6 +710,28 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
+         details.</para></listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><varname>NUMAPolicy=</varname></term>
++
++        <listitem><para>Controls the NUMA memory policy of the executed processes. Takes a policy type, one of:
++        <option>default</option>, <option>preferred</option>, <option>bind</option>, <option>interleave</option> and
++        <option>local</option>. A list of NUMA nodes that should be associated with the policy must be specified
++        in <varname>NUMAMask=</varname>. For more details on each policy please see,
++        <citerefentry><refentrytitle>set_mempolicy</refentrytitle><manvolnum>2</manvolnum></citerefentry>. For overall
++        overview of NUMA support in Linux see,
++        <citerefentry><refentrytitle>numa</refentrytitle><manvolnum>7</manvolnum></citerefentry>
++        </para></listitem>
++      </varlistentry>
++
++      <varlistentry>
++        <term><varname>NUMAMask=</varname></term>
++
++        <listitem><para>Controls the NUMA node list which will be applied alongside with selected NUMA policy.
++        Takes a list of NUMA nodes and has the same syntax as a list of CPUs for <varname>CPUAffinity=</varname>
++        option. Note that the list of NUMA nodes is not required for <option>default</option> and <option>local</option>
++        policies and for <option>preferred</option> policy we expect a single NUMA node.</para></listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><varname>IOSchedulingClass=</varname></term>
+ 
+@@ -2709,6 +2731,12 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
+             <entry><constant>EXIT_CONFIGURATION_DIRECTORY</constant></entry>
+             <entry>Failed to set up unit's configuration directory. See <varname>ConfigurationDirectory=</varname> above.</entry>
+           </row>
++          <row>
++            <entry>242</entry>
++            <entry><constant>EXIT_NUMA_POLICY</constant></entry>
++            <entry>Failed to set up unit's NUMA memory policy. See <varname>NUMAPolicy=</varname> and <varname>NUMAMask=</varname>above.</entry>
++          </row>
++
+         </tbody>
+       </tgroup>
+     </table>
+diff --git a/meson.build b/meson.build
+index 613a5133b6..fe82ca4ac2 100644
+--- a/meson.build
++++ b/meson.build
+@@ -501,6 +501,10 @@ foreach ident : [
+                                  #include <unistd.h>'''],
+         ['explicit_bzero' ,   '''#include <string.h>'''],
+         ['reallocarray',      '''#include <malloc.h>'''],
++        ['set_mempolicy',     '''#include <stdlib.h>
++                                 #include <unistd.h>'''],
++        ['get_mempolicy',     '''#include <stdlib.h>
++                                 #include <unistd.h>'''],
+ ]
+ 
+         have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
+diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
+index 103b9703b3..36cb017ae7 100644
+--- a/src/basic/cpu-set-util.c
++++ b/src/basic/cpu-set-util.c
+@@ -10,11 +10,17 @@
+ 
+ #include "alloc-util.h"
+ #include "cpu-set-util.h"
++#include "dirent-util.h"
+ #include "extract-word.h"
++#include "fd-util.h"
+ #include "log.h"
+ #include "macro.h"
++#include "missing.h"
+ #include "parse-util.h"
++#include "stat-util.h"
+ #include "string-util.h"
++#include "string-table.h"
++#include "strv.h"
+ #include "util.h"
+ 
+ char* cpu_set_to_string(const CPUSet *a) {
+@@ -290,3 +296,88 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
+         s = (CPUSet) {};
+         return 0;
+ }
++
++bool numa_policy_is_valid(const NUMAPolicy *policy) {
++        assert(policy);
++
++        if (!mpol_is_valid(numa_policy_get_type(policy)))
++                return false;
++
++        if (!policy->nodes.set &&
++            !IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED))
++                return false;
++
++        if (policy->nodes.set &&
++            numa_policy_get_type(policy) == MPOL_PREFERRED &&
++            CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1)
++                return false;
++
++        return true;
++}
++
++static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) {
++        unsigned node, bits = 0, ulong_bits;
++        _cleanup_free_ unsigned long *out = NULL;
++
++        assert(policy);
++        assert(ret_maxnode);
++        assert(ret_nodes);
++
++        if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) ||
++            (numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) {
++                *ret_nodes = NULL;
++                *ret_maxnode = 0;
++                return 0;
++        }
++
++        bits = policy->nodes.allocated * 8;
++        ulong_bits = sizeof(unsigned long) * 8;
++
++        out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long)));
++        if (!out)
++                return -ENOMEM;
++
++        /* We don't make any assumptions about internal type libc is using to store NUMA node mask.
++           Hence we need to convert the node mask to the representation expected by set_mempolicy() */
++        for (node = 0; node < bits; node++)
++                if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set))
++                        out[node / ulong_bits] |= 1ul << (node % ulong_bits);
++
++        *ret_nodes = TAKE_PTR(out);
++        *ret_maxnode = bits + 1;
++        return 0;
++}
++
++int apply_numa_policy(const NUMAPolicy *policy) {
++        int r;
++        _cleanup_free_ unsigned long *nodes = NULL;
++        unsigned long maxnode;
++
++        assert(policy);
++
++        if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS)
++                return -EOPNOTSUPP;
++
++        if (!numa_policy_is_valid(policy))
++                return -EINVAL;
++
++        r = numa_policy_to_mempolicy(policy, &maxnode, &nodes);
++        if (r < 0)
++                return r;
++
++        r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode);
++        if (r < 0)
++                return -errno;
++
++        return 0;
++}
++
++static const char* const mpol_table[] = {
++        [MPOL_DEFAULT]    = "default",
++        [MPOL_PREFERRED]  = "preferred",
++        [MPOL_BIND]       = "bind",
++        [MPOL_INTERLEAVE] = "interleave",
++        [MPOL_LOCAL]      = "local",
++};
++
++DEFINE_STRING_TABLE_LOOKUP(mpol, int);
+diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
+index ec640b2ec9..295028cb54 100644
+--- a/src/basic/cpu-set-util.h
++++ b/src/basic/cpu-set-util.h
+@@ -8,6 +8,7 @@
+ #include <sched.h>
+ 
+ #include "macro.h"
++#include "missing.h"
+ 
+ /* This wraps the libc interface with a variable to keep the allocated size. */
+ typedef struct CPUSet {
+@@ -52,3 +53,30 @@ int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated);
+ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set);
+ 
+ int cpus_in_affinity_mask(void);
++
++static inline bool mpol_is_valid(int t) {
++        return t >= MPOL_DEFAULT && t <= MPOL_LOCAL;
++}
++
++typedef struct NUMAPolicy {
++        /* Always use numa_policy_get_type() to read the value */
++        int type;
++        CPUSet nodes;
++} NUMAPolicy;
++
++bool numa_policy_is_valid(const NUMAPolicy *p);
++
++static inline int numa_policy_get_type(const NUMAPolicy *p) {
++        return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type;
++}
++
++static inline void numa_policy_reset(NUMAPolicy *p) {
++        assert(p);
++        cpu_set_reset(&p->nodes);
++        p->type = -1;
++}
++
++int apply_numa_policy(const NUMAPolicy *policy);
++
++const char* mpol_to_string(int i) _const_;
++int mpol_from_string(const char *s) _pure_;
+diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c
+index 21af8c4c71..0a7a53b73d 100644
+--- a/src/basic/exit-status.c
++++ b/src/basic/exit-status.c
+@@ -155,6 +155,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) {
+ 
+                 case EXIT_CONFIGURATION_DIRECTORY:
+                         return "CONFIGURATION_DIRECTORY";
++
++                case EXIT_NUMA_POLICY:
++                        return "NUMA_POLICY";
+                 }
+         }
+ 
+diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h
+index c41e8b82c3..dc284aacb1 100644
+--- a/src/basic/exit-status.h
++++ b/src/basic/exit-status.h
+@@ -69,6 +69,7 @@ enum {
+         EXIT_CACHE_DIRECTORY,
+         EXIT_LOGS_DIRECTORY, /* 240 */
+         EXIT_CONFIGURATION_DIRECTORY,
++        EXIT_NUMA_POLICY,
+ };
+ 
+ typedef enum ExitStatusLevel {
+diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
+index 93c60458bf..014dd2b326 100644
+--- a/src/basic/missing_syscall.h
++++ b/src/basic/missing_syscall.h
+@@ -428,3 +428,46 @@ static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flag
+ 
+ #  define statx missing_statx
+ #endif
++
++#if !HAVE_SET_MEMPOLICY
++
++enum {
++        MPOL_DEFAULT,
++        MPOL_PREFERRED,
++        MPOL_BIND,
++        MPOL_INTERLEAVE,
++        MPOL_LOCAL,
++};
++
++static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask,
++                           unsigned long maxnode) {
++        long i;
++#  ifdef __NR_set_mempolicy
++        i = syscall(__NR_set_mempolicy, mode, nodemask, maxnode);
++#  else
++        errno = ENOSYS;
++        i = -1;
++#  endif
++        return i;
++}
++
++#  define set_mempolicy missing_set_mempolicy
++#endif
++
++
++#if !HAVE_GET_MEMPOLICY
++static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
++                           unsigned long maxnode, void *addr,
++                           unsigned long flags) {
++        long i;
++#  ifdef __NR_get_mempolicy
++        i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
++#  else
++        errno = ENOSYS;
++        i = -1;
++#  endif
++        return i;
++}
++
++#define get_mempolicy missing_get_mempolicy
++#endif
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index 50ea71a281..198f149210 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -223,6 +223,48 @@ static int property_get_cpu_affinity(
+         return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated);
+ }
+ 
++static int property_get_numa_mask(
++                sd_bus *bus,
++                const char *path,
++                const char *interface,
++                const char *property,
++                sd_bus_message *reply,
++                void *userdata,
++                sd_bus_error *error) {
++
++        ExecContext *c = userdata;
++        _cleanup_free_ uint8_t *array = NULL;
++        size_t allocated;
++
++        assert(bus);
++        assert(reply);
++        assert(c);
++
++        (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated);
++
++        return sd_bus_message_append_array(reply, 'y', array, allocated);
++}
++
++static int property_get_numa_policy(
++                sd_bus *bus,
++                const char *path,
++                const char *interface,
++                const char *property,
++                sd_bus_message *reply,
++                void *userdata,
++                sd_bus_error *error) {
++        ExecContext *c = userdata;
++        int32_t policy;
++
++        assert(bus);
++        assert(reply);
++        assert(c);
++
++        policy = numa_policy_get_type(&c->numa_policy);
++
++        return sd_bus_message_append_basic(reply, 'i', &policy);
++}
++
+ static int property_get_timer_slack_nsec(
+                 sd_bus *bus,
+                 const char *path,
+@@ -698,6 +740,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
+         SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
++        SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
++        SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
+@@ -1550,9 +1594,10 @@ int bus_exec_context_set_transient_property(
+                 return 1;
+         }
+ #endif
+-        if (streq(name, "CPUAffinity")) {
++        if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
+                 const void *a;
+                 size_t n;
++                bool affinity = streq(name, "CPUAffinity");
+                 _cleanup_(cpu_set_reset) CPUSet set = {};
+ 
+                 r = sd_bus_message_read_array(message, 'y', &a, &n);
+@@ -1565,7 +1610,7 @@ int bus_exec_context_set_transient_property(
+ 
+                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                         if (n == 0) {
+-                                cpu_set_reset(&c->cpu_set);
++                                cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes);
+                                 unit_write_settingf(u, flags, name, "%s=", name);
+                         } else {
+                                 _cleanup_free_ char *str = NULL;
+@@ -1577,7 +1622,7 @@ int bus_exec_context_set_transient_property(
+                                 /* We forego any optimizations here, and always create the structure using
+                                  * cpu_set_add_all(), because we don't want to care if the existing size we
+                                  * got over dbus is appropriate. */
+-                                r = cpu_set_add_all(&c->cpu_set, &set);
++                                r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set);
+                                 if (r < 0)
+                                         return r;
+ 
+@@ -1587,6 +1632,20 @@ int bus_exec_context_set_transient_property(
+ 
+                 return 1;
+ 
++        } else if (streq(name, "NUMAPolicy")) {
++                int32_t type;
++
++                r = sd_bus_message_read(message, "i", &type);
++                if (r < 0)
++                        return r;
++
++                if (!mpol_is_valid(type))
++                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
++
++                if (!UNIT_WRITE_FLAGS_NOOP(flags))
++                        c->numa_policy.type = type;
++
++                return 1;
+         } else if (streq(name, "IOSchedulingClass")) {
+                 int32_t q;
+ 
+diff --git a/src/core/execute.c b/src/core/execute.c
+index bc26aa66e7..56aa89e1ec 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -2997,6 +2997,16 @@ static int exec_child(
+                         return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m");
+                 }
+ 
++        if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) {
++                r = apply_numa_policy(&context->numa_policy);
++                if (r == -EOPNOTSUPP)
++                        log_unit_debug_errno(unit, r, "NUMA support not available, ignoring.");
++                else if (r < 0) {
++                        *exit_status = EXIT_NUMA_POLICY;
++                        return log_unit_error_errno(unit, r, "Failed to set NUMA memory policy: %m");
++                }
++        }
++
+         if (context->ioprio_set)
+                 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
+                         *exit_status = EXIT_IOPRIO;
+@@ -3651,6 +3661,7 @@ void exec_context_init(ExecContext *c) {
+         assert_cc(NAMESPACE_FLAGS_INITIAL != NAMESPACE_FLAGS_ALL);
+         c->restrict_namespaces = NAMESPACE_FLAGS_INITIAL;
+         c->log_level_max = -1;
++        numa_policy_reset(&c->numa_policy);
+ }
+ 
+ void exec_context_done(ExecContext *c) {
+@@ -3695,6 +3706,7 @@ void exec_context_done(ExecContext *c) {
+         c->n_temporary_filesystems = 0;
+ 
+         cpu_set_reset(&c->cpu_set);
++        numa_policy_reset(&c->numa_policy);
+ 
+         c->utmp_id = mfree(c->utmp_id);
+         c->selinux_context = mfree(c->selinux_context);
+@@ -4104,6 +4116,14 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
+                 fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity);
+         }
+ 
++        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
++                _cleanup_free_ char *nodes = NULL;
++
++                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
++                fprintf(f, "%sNUMAPolicy: %s\n", prefix, mpol_to_string(numa_policy_get_type(&c->numa_policy)));
++                fprintf(f, "%sNUMAMask: %s\n", prefix, strnull(nodes));
++        }
++
+         if (c->timer_slack_nsec != NSEC_INFINITY)
+                 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
+ 
+diff --git a/src/core/execute.h b/src/core/execute.h
+index e1e7a494cd..b2eb55f8f5 100644
+--- a/src/core/execute.h
++++ b/src/core/execute.h
+@@ -150,6 +150,7 @@ struct ExecContext {
+         int cpu_sched_priority;
+ 
+         CPUSet cpu_set;
++        NUMAPolicy numa_policy;
+ 
+         ExecInput std_input;
+         ExecOutput std_output;
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index 1066bcfb8f..cdf4d14c4e 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -36,6 +36,8 @@ $1.CPUSchedulingPolicy,          config_parse_exec_cpu_sched_policy, 0,
+ $1.CPUSchedulingPriority,        config_parse_exec_cpu_sched_prio,   0,                             offsetof($1, exec_context)
+ $1.CPUSchedulingResetOnFork,     config_parse_bool,                  0,                             offsetof($1, exec_context.cpu_sched_reset_on_fork)
+ $1.CPUAffinity,                  config_parse_exec_cpu_affinity,     0,                             offsetof($1, exec_context)
++$1.NUMAPolicy,                   config_parse_numa_policy,           0,                             offsetof($1, exec_context.numa_policy.type)
++$1.NUMAMask,                     config_parse_numa_mask,             0,                             offsetof($1, exec_context.numa_policy)
+ $1.UMask,                        config_parse_mode,                  0,                             offsetof($1, exec_context.umask)
+ $1.Environment,                  config_parse_environ,               0,                             offsetof($1, exec_context.environment)
+ $1.EnvironmentFile,              config_parse_unit_env_file,         0,                             offsetof($1, exec_context.environment_files)
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index 34ae834188..35dd595098 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -93,6 +93,7 @@ DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint
+ DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight");
+ DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares");
+ DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag");
++DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_numa_policy, mpol, int, -1, "Invalid NUMA policy type");
+ 
+ int config_parse_unit_deps(
+                 const char *unit,
+@@ -1159,6 +1160,33 @@ int config_parse_exec_cpu_sched_policy(const char *unit,
+         return 0;
+ }
+ 
++int config_parse_numa_mask(const char *unit,
++                           const char *filename,
++                           unsigned line,
++                           const char *section,
++                           unsigned section_line,
++                           const char *lvalue,
++                           int ltype,
++                           const char *rvalue,
++                           void *data,
++                           void *userdata) {
++        int r;
++        NUMAPolicy *p = data;
++
++        assert(filename);
++        assert(lvalue);
++        assert(rvalue);
++        assert(data);
++
++        r = parse_cpu_set_extend(rvalue, &p->nodes, true, unit, filename, line, lvalue);
++        if (r < 0) {
++                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NUMA node mask, ignoring: %s", rvalue);
++                return 0;
++        }
++
++        return r;
++}
++
+ int config_parse_exec_cpu_sched_prio(const char *unit,
+                                      const char *filename,
+                                      unsigned line,
+diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
+index dad281ef72..f2ca1b8ee7 100644
+--- a/src/core/load-fragment.h
++++ b/src/core/load-fragment.h
+@@ -102,6 +102,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_job_timeout_sec);
+ CONFIG_PARSER_PROTOTYPE(config_parse_job_running_timeout_sec);
+ CONFIG_PARSER_PROTOTYPE(config_parse_log_extra_fields);
+ CONFIG_PARSER_PROTOTYPE(config_parse_collect_mode);
++CONFIG_PARSER_PROTOTYPE(config_parse_numa_policy);
++CONFIG_PARSER_PROTOTYPE(config_parse_numa_mask);
+ 
+ /* gperf prototypes */
+ const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
+diff --git a/src/core/main.c b/src/core/main.c
+index c74dc641c1..83f9dd5878 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -134,6 +134,7 @@ static uint64_t arg_default_tasks_max;
+ static sd_id128_t arg_machine_id;
+ static EmergencyAction arg_cad_burst_action;
+ static CPUSet arg_cpu_affinity;
++static NUMAPolicy arg_numa_policy;
+ 
+ static int parse_configuration(void);
+ 
+@@ -660,6 +661,8 @@ static int parse_config_file(void) {
+                 { "Manager", "ShowStatus",                config_parse_show_status,      0, &arg_show_status                       },
+                 { "Manager", "CPUAffinity",               config_parse_cpu_affinity2,    0, &arg_cpu_affinity                      },
+                 { "Manager", "JoinControllers",           config_parse_join_controllers, 0, &arg_join_controllers                  },
++                { "Manager", "NUMAPolicy",                config_parse_numa_policy,      0, &arg_numa_policy.type                  },
++                { "Manager", "NUMAMask",                  config_parse_numa_mask,        0, &arg_numa_policy                       },
+                 { "Manager", "RuntimeWatchdogSec",        config_parse_sec,              0, &arg_runtime_watchdog                  },
+                 { "Manager", "ShutdownWatchdogSec",       config_parse_sec,              0, &arg_shutdown_watchdog                 },
+                 { "Manager", "WatchdogDevice",            config_parse_path,             0, &arg_watchdog_device                   },
+@@ -1501,6 +1504,27 @@ static void update_cpu_affinity(bool skip_setup) {
+                 log_warning_errno(errno, "Failed to set CPU affinity: %m");
+ }
+ 
++static void update_numa_policy(bool skip_setup) {
++        int r;
++        _cleanup_free_ char *nodes = NULL;
++        const char * policy = NULL;
++
++        if (skip_setup || !mpol_is_valid(numa_policy_get_type(&arg_numa_policy)))
++                return;
++
++        if (DEBUG_LOGGING) {
++                policy = mpol_to_string(numa_policy_get_type(&arg_numa_policy));
++                nodes = cpu_set_to_range_string(&arg_numa_policy.nodes);
++                log_debug("Setting NUMA policy to %s, with nodes %s.", strnull(policy), strnull(nodes));
++        }
++
++        r = apply_numa_policy(&arg_numa_policy);
++        if (r == -EOPNOTSUPP)
++                log_debug_errno(r, "NUMA support not available, ignoring.");
++        else if (r < 0)
++                log_warning_errno(r, "Failed to set NUMA memory policy: %m");
++}
++
+ static void do_reexecute(
+                 int argc,
+                 char *argv[],
+@@ -1672,6 +1696,7 @@ static int invoke_main_loop(
+                         set_manager_defaults(m);
+ 
+                         update_cpu_affinity(false);
++                        update_numa_policy(false);
+ 
+                         if (saved_log_level >= 0)
+                                 manager_override_log_level(m, saved_log_level);
+@@ -1832,6 +1857,7 @@ static int initialize_runtime(
+                 return 0;
+ 
+         update_cpu_affinity(skip_setup);
++        update_numa_policy(skip_setup);
+ 
+         if (arg_system) {
+                 /* Make sure we leave a core dump without panicing the kernel. */
+@@ -2011,6 +2037,7 @@ static void reset_arguments(void) {
+         arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
+ 
+         cpu_set_reset(&arg_cpu_affinity);
++        numa_policy_reset(&arg_numa_policy);
+ }
+ 
+ static int parse_configuration(void) {
+diff --git a/src/core/system.conf.in b/src/core/system.conf.in
+index 653ec6b8c9..0d93fbf147 100644
+--- a/src/core/system.conf.in
++++ b/src/core/system.conf.in
+@@ -24,6 +24,8 @@
+ #CtrlAltDelBurstAction=reboot-force
+ #CPUAffinity=1 2
+ #JoinControllers=cpu,cpuacct net_cls,net_prio
++#NUMAPolicy=default
++#NUMAMask=
+ #RuntimeWatchdogSec=0
+ #ShutdownWatchdogSec=10min
+ #CapabilityBoundingSet=
+diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
+index ec8732c226..055edd6e22 100644
+--- a/src/shared/bus-unit-util.c
++++ b/src/shared/bus-unit-util.c
+@@ -947,6 +947,34 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
+                 return bus_append_byte_array(m, field, array, allocated);
+         }
+ 
++        if (streq(field, "NUMAPolicy")) {
++                r = mpol_from_string(eq);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
++
++                r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t) r);
++                if (r < 0)
++                        return bus_log_create_error(r);
++
++                return 1;
++        }
++
++        if (streq(field, "NUMAMask")) {
++                _cleanup_(cpu_set_reset) CPUSet nodes = {};
++                _cleanup_free_ uint8_t *array = NULL;
++                size_t allocated;
++
++                r = parse_cpu_set(eq, &nodes);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
++
++                r = cpu_set_to_dbus(&nodes, &array, &allocated);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to serialize NUMAMask: %m");
++
++                return bus_append_byte_array(m, field, array, allocated);
++        }
++
+         if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) {
+                 int whitelist = 1;
+                 const char *p = eq;
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 0154b300a3..7274921e6d 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -4573,6 +4573,20 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
+ 
+         switch (bus_type) {
+ 
++        case SD_BUS_TYPE_INT32:
++                if (streq(name, "NUMAPolicy")) {
++                        int32_t i;
++
++                        r = sd_bus_message_read_basic(m, bus_type, &i);
++                        if (r < 0)
++                                return r;
++
++                        print_prop(name, "%s", strna(mpol_to_string(i)));
++
++                        return 1;
++                }
++                break;
++
+         case SD_BUS_TYPE_STRUCT:
+ 
+                 if (contents[0] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
+@@ -4878,7 +4892,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
+                         print_prop(name, "%s", h);
+ 
+                         return 1;
+-                } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "CPUAffinity")) {
++                } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
+                         _cleanup_free_ char *affinity = NULL;
+                         _cleanup_(cpu_set_reset) CPUSet set = {};
+                         const void *a;
+@@ -4890,7 +4904,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
+ 
+                         r = cpu_set_from_dbus(a, n, &set);
+                         if (r < 0)
+-                                return log_error_errno(r, "Failed to deserialize CPUAffinity: %m");
++                                return log_error_errno(r, "Failed to deserialize %s: %m", name);
+ 
+                         affinity = cpu_set_to_range_string(&set);
+                         if (!affinity)
diff --git a/SOURCES/0289-core-disable-CPUAccounting-by-default.patch b/SOURCES/0289-core-disable-CPUAccounting-by-default.patch
new file mode 100644
index 0000000..d250c03
--- /dev/null
+++ b/SOURCES/0289-core-disable-CPUAccounting-by-default.patch
@@ -0,0 +1,25 @@
+From b47f26558e5234ec8cf2ecc3674c94a87f20ec69 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
+Date: Thu, 28 Nov 2019 15:47:43 +0100
+Subject: [PATCH] core: disable CPUAccounting by default
+
+Related: #1734787
+
+[RHEL-only]
+---
+ src/core/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 83f9dd5878..c83249a8dc 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -2026,7 +2026,7 @@ static void reset_arguments(void) {
+ 
+         /* arg_serialization — ignore */
+ 
+-        arg_default_cpu_accounting = -1;
++        arg_default_cpu_accounting = 0;
+         arg_default_io_accounting = false;
+         arg_default_ip_accounting = false;
+         arg_default_blockio_accounting = false;
diff --git a/SOURCES/0290-set-kptr_restrict-1.patch b/SOURCES/0290-set-kptr_restrict-1.patch
new file mode 100644
index 0000000..5005756
--- /dev/null
+++ b/SOURCES/0290-set-kptr_restrict-1.patch
@@ -0,0 +1,24 @@
+From cf1a9df1171273fc1ed3f977b5ec52aba27674bf Mon Sep 17 00:00:00 2001
+From: David Tardon <dtardon@redhat.com>
+Date: Tue, 3 Dec 2019 14:04:00 +0100
+Subject: [PATCH] set kptr_restrict=1
+
+Resolves: #1689346
+---
+ sysctl.d/50-default.conf | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
+index e263cf0628..e0afc9c702 100644
+--- a/sysctl.d/50-default.conf
++++ b/sysctl.d/50-default.conf
+@@ -21,6 +21,9 @@ kernel.sysrq = 16
+ # Append the PID to the core filename
+ kernel.core_uses_pid = 1
+ 
++# https://bugzilla.redhat.com/show_bug.cgi?id=1689346
++kernel.kptr_restrict = 1
++
+ # Source route verification
+ net.ipv4.conf.all.rp_filter = 1
+ 
diff --git a/SOURCES/0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch b/SOURCES/0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch
new file mode 100644
index 0000000..48f41cf
--- /dev/null
+++ b/SOURCES/0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch
@@ -0,0 +1,34 @@
+From 40612e4e7690c613cba7ac87b9d782724e623a39 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
+Date: Wed, 27 Nov 2019 14:27:58 +0100
+Subject: [PATCH] cryptsetup: reduce the chance that we will be OOM killed
+
+cryptsetup introduced optional locking scheme that should serialize
+unlocking keyslots which use memory hard key derivation
+function (argon2). Using the serialization should prevent OOM situation
+in early boot while unlocking encrypted volumes.
+
+(cherry picked from commit 408c81f62454684dfbff1c95ce3210d06f256e58)
+
+Resolves: #1696602
+---
+ src/cryptsetup/cryptsetup.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index 4e1b3eff19..9071126c2e 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -656,6 +656,12 @@ int main(int argc, char *argv[]) {
+                 if (arg_discards)
+                         flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
+ 
++#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
++                /* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
++                /* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
++                flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
++#endif
++
+                 if (arg_timeout == USEC_INFINITY)
+                         until = 0;
+                 else
diff --git a/SOURCES/0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch b/SOURCES/0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
new file mode 100644
index 0000000..4bfb5ef
--- /dev/null
+++ b/SOURCES/0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
@@ -0,0 +1,136 @@
+From cb084637ba1c8558f1538ce300c5520a6764dc76 Mon Sep 17 00:00:00 2001
+From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
+Date: Mon, 28 Oct 2019 19:35:24 +0900
+Subject: [PATCH] core, job: fix breakage of ordering dependencies by systemctl
+ reload command
+
+Currently, systemctl reload command breaks ordering dependencies if it's
+executed when its target service unit is in activating state.
+
+For example, prepare A.service, B.service and C.target as follows:
+
+    # systemctl cat A.service B.service C.target
+    # /etc/systemd/system/A.service
+    [Unit]
+    Description=A
+
+    [Service]
+    Type=oneshot
+    ExecStart=/usr/bin/echo A1
+    ExecStart=/usr/bin/sleep 60
+    ExecStart=/usr/bin/echo A2
+    ExecReload=/usr/bin/echo A reloaded
+    RemainAfterExit=yes
+
+    # /etc/systemd/system/B.service
+    [Unit]
+    Description=B
+    After=A.service
+
+    [Service]
+    Type=oneshot
+    ExecStart=/usr/bin/echo B
+    RemainAfterExit=yes
+
+    # /etc/systemd/system/C.target
+    [Unit]
+    Description=C
+    Wants=A.service B.service
+
+Start them.
+
+    # systemctl daemon-reload
+    # systemctl start C.target
+
+Then, we have:
+
+    # LANG=C journalctl --no-pager -u A.service -u B.service -u C.target -b
+    -- Logs begin at Mon 2019-09-09 00:25:06 EDT, end at Thu 2019-10-24 22:28:47 EDT. --
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: Starting A...
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Child 967 belongs to A.service.
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/sleep 60
+    Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/sleep as 968
+    Oct 24 22:27:47 localhost.localdomain systemd[968]: A.service: Executing: /usr/bin/sleep 60
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Trying to enqueue job A.service/reload/replace
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Merged into running job, re-running: A.service/reload as 1288
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Enqueued job A.service/reload as 1288
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Unit cannot be reloaded because it is inactive.
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Job 1288 A.service/reload finished, result=invalid
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Passing 0 fds to service
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: About to execute: /usr/bin/echo B
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Forked /usr/bin/echo as 970
+    Oct 24 22:27:52 localhost.localdomain systemd[970]: B.service: Executing: /usr/bin/echo B
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Failed to send unit change signal for B.service: Connection reset by peer
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed dead -> start
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: Starting B...
+    Oct 24 22:27:52 localhost.localdomain echo[970]: B
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Child 970 belongs to B.service.
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Main process exited, code=exited, status=0/SUCCESS
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed start -> exited
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Job 1371 B.service/start finished, result=done
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: Started B.
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Job 1287 C.target/start finished, result=done
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: Reached target C.
+    Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Failed to send unit change signal for C.target: Connection reset by peer
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 968 belongs to A.service.
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/echo A2
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/echo as 972
+    Oct 24 22:28:47 localhost.localdomain systemd[972]: A.service: Executing: /usr/bin/echo A2
+    Oct 24 22:28:47 localhost.localdomain echo[972]: A2
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 972 belongs to A.service.
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
+    Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Changed start -> exited
+
+The issue occurs not only in reload command, i.e.:
+
+  - reload
+  - try-restart
+  - reload-or-restart
+  - reload-or-try-restart commands
+
+The cause of this issue is that job_type_collapse() doesn't take care of the
+activating state.
+
+Fixes: #10464
+(cherry picked from commit d1559793df555212271e490a4a72f55826caf5b4)
+
+Resolves: #1766417
+---
+ src/core/job.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index 8552ffb704..769ed6d603 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -403,21 +403,21 @@ JobType job_type_collapse(JobType t, Unit *u) {
+ 
+         case JOB_TRY_RESTART:
+                 s = unit_active_state(u);
+-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
++                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
+                         return JOB_NOP;
+ 
+                 return JOB_RESTART;
+ 
+         case JOB_TRY_RELOAD:
+                 s = unit_active_state(u);
+-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
++                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
+                         return JOB_NOP;
+ 
+                 return JOB_RELOAD;
+ 
+         case JOB_RELOAD_OR_START:
+                 s = unit_active_state(u);
+-                if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
++                if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
+                         return JOB_START;
+ 
+                 return JOB_RELOAD;
diff --git a/SOURCES/0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch b/SOURCES/0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch
new file mode 100644
index 0000000..fb40563
--- /dev/null
+++ b/SOURCES/0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch
@@ -0,0 +1,149 @@
+From 613a02b7d67864af1860e9137e2ee101d603463e Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Thu, 25 Apr 2019 12:19:16 +0200
+Subject: [PATCH] debug-generator: enable custom systemd.debug_shell tty
+
+(cherry picked from commit 93912e872fb14e9c372e090409e429084a6450f5)
+
+Resolves: #1723722
+---
+ man/custom-entities.ent.in            |  1 +
+ man/systemd-debug-generator.xml       | 13 ++++++---
+ meson.build                           |  1 +
+ src/debug-generator/debug-generator.c | 41 +++++++++++++++++++++------
+ 4 files changed, 43 insertions(+), 13 deletions(-)
+
+diff --git a/man/custom-entities.ent.in b/man/custom-entities.ent.in
+index e2bd44e5e7..85805777a0 100644
+--- a/man/custom-entities.ent.in
++++ b/man/custom-entities.ent.in
+@@ -8,3 +8,4 @@
+ <!ENTITY CERTIFICATE_ROOT @CERTIFICATE_ROOT@>
+ <!ENTITY MEMORY_ACCOUNTING_DEFAULT @MEMORY_ACCOUNTING_DEFAULT_YES_NO@>
+ <!ENTITY KILL_USER_PROCESSES @KILL_USER_PROCESSES_YES_NO@>
++<!ENTITY DEBUGTTY @DEBUGTTY@>
+diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
+index fa88e8ac01..25d8b1a873 100644
+--- a/man/systemd-debug-generator.xml
++++ b/man/systemd-debug-generator.xml
+@@ -1,6 +1,10 @@
+ <?xml version="1.0"?>
+ <!--*-nxml-*-->
+-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
++<!ENTITY % entities SYSTEM "custom-entities.ent" >
++%entities;
++]>
+ <!--
+   SPDX-License-Identifier: LGPL-2.1+
+ -->
+@@ -57,9 +61,10 @@
+     <option>rd.systemd.debug_shell</option> option is
+     specified, the debug shell service
+     <literal>debug-shell.service</literal> is pulled into the boot
+-    transaction. It will spawn a debug shell on tty9 during early
+-    system startup. Note that the shell may also be turned on
+-    persistently by enabling it with
++    transaction and a debug shell will be spawned during early boot.
++    By default, <filename>&DEBUGTTY;</filename> is used, but a specific tty can also be set,
++    either with or without the <filename>/dev/</filename> prefix.
++    Note that the shell may also be turned on persistently by enabling it with
+     <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+     <command>enable</command> command.
+     <option>rd.systemd.debug_shell=</option> is honored only by initial
+diff --git a/meson.build b/meson.build
+index fe82ca4ac2..70811c29cf 100644
+--- a/meson.build
++++ b/meson.build
+@@ -768,6 +768,7 @@ conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
+ 
+ substs.set('SUSHELL', get_option('debug-shell'))
+ substs.set('DEBUGTTY', get_option('debug-tty'))
++conf.set_quoted('DEBUGTTY', get_option('debug-tty'))
+ 
+ enable_debug_hashmap = false
+ enable_debug_mmap_cache = false
+diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
+index 800d31cebe..ddef385833 100644
+--- a/src/debug-generator/debug-generator.c
++++ b/src/debug-generator/debug-generator.c
+@@ -1,8 +1,11 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include "alloc-util.h"
++#include "dropin.h"
++#include "generator.h"
+ #include "mkdir.h"
+ #include "parse-util.h"
++#include "path-util.h"
+ #include "proc-cmdline.h"
+ #include "special.h"
+ #include "string-util.h"
+@@ -14,7 +17,7 @@ static char *arg_default_unit = NULL;
+ static const char *arg_dest = "/tmp";
+ static char **arg_mask = NULL;
+ static char **arg_wants = NULL;
+-static bool arg_debug_shell = false;
++static char *arg_debug_shell = NULL;
+ 
+ static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
+         int r;
+@@ -50,15 +53,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
+                         return log_oom();
+ 
+         } else if (proc_cmdline_key_streq(key, "systemd.debug_shell")) {
++                const char *t = NULL;
+ 
+-                if (value) {
+-                        r = parse_boolean(value);
+-                        if (r < 0)
+-                                log_error("Failed to parse systemd.debug_shell= argument '%s', ignoring.", value);
+-                        else
+-                                arg_debug_shell = r;
+-                } else
+-                        arg_debug_shell = true;
++                r = value ? parse_boolean(value) : 1;
++                if (r < 0)
++                        t = skip_dev_prefix(value);
++                else if (r > 0)
++                        t = skip_dev_prefix(DEBUGTTY);
++
++                if (free_and_strdup(&arg_debug_shell, t) < 0)
++                        return log_oom();
+ 
+         } else if (streq(key, "systemd.unit")) {
+ 
+@@ -136,6 +140,23 @@ static int generate_wants_symlinks(void) {
+         return r;
+ }
+ 
++static void install_debug_shell_dropin(const char *dir) {
++        int r;
++
++        if (streq(arg_debug_shell, skip_dev_prefix(DEBUGTTY)))
++                return;
++
++        r = write_drop_in_format(dir, "debug-shell.service", 50, "tty",
++                        "[Unit]\n"
++                        "Description=Early root shell on /dev/%s FOR DEBUGGING ONLY\n"
++                        "ConditionPathExists=\n"
++                        "[Service]\n"
++                        "TTYPath=/dev/%s",
++                        arg_debug_shell, arg_debug_shell);
++        if (r < 0)
++                log_warning_errno(r, "Failed to write drop-in for debug-shell.service, ignoring: %m");
++}
++
+ int main(int argc, char *argv[]) {
+         int r, q;
+ 
+@@ -164,6 +185,8 @@ int main(int argc, char *argv[]) {
+                         r = log_oom();
+                         goto finish;
+                 }
++
++                install_debug_shell_dropin(arg_dest);
+         }
+ 
+         r = generate_mask_symlinks();
diff --git a/SOURCES/0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch b/SOURCES/0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch
new file mode 100644
index 0000000..490a14f
--- /dev/null
+++ b/SOURCES/0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch
@@ -0,0 +1,118 @@
+From f4344bb4055cab8dc3bbe82a7f3d97fc6fabcb7e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 4 Jun 2019 09:19:04 +0200
+Subject: [PATCH] test-cpu-set-util: fix comparison for allocation size
+
+On i386, __cpu_mask is 4 bytes, so we'd check if c.allocated >= 0, and
+gcc would warn about a bogus comparison. Let's round up.
+
+Fixes #12726.
+
+(cherry picked from commit a299ce058b41b21c87f36e77e2c563b0ddd1be0d)
+
+Related: #1734787
+---
+ src/test/test-cpu-set-util.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index 9522582891..3456add989 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -17,7 +17,7 @@ static void test_parse_cpu_set(void) {
+         /* Single value */
+         assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.set);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_ISSET_S(0, c.allocated, c.set));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
+ 
+@@ -33,7 +33,7 @@ static void test_parse_cpu_set(void) {
+         /* Simple range (from CPUAffinity example) */
+         assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+         assert_se(c.set);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_ISSET_S(1, c.allocated, c.set));
+         assert_se(CPU_ISSET_S(2, c.allocated, c.set));
+         assert_se(CPU_ISSET_S(4, c.allocated, c.set));
+@@ -50,7 +50,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* A more interesting range */
+         assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -68,7 +68,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Quoted strings */
+         assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
+         for (cpu = 8; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -83,7 +83,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Use commas as separators */
+         assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -96,7 +96,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Commas with spaces (and trailing comma, space) */
+         assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 9);
+         for (cpu = 0; cpu < 8; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -113,7 +113,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Ranges */
+         assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -126,7 +126,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Ranges with trailing comma, space */
+         assert_se(parse_cpu_set_full("0-3  8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
+         for (cpu = 0; cpu < 4; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -143,13 +143,13 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Negative range (returns empty cpu_set) */
+         assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
+         cpu_set_reset(&c);
+ 
+         /* Overlapping ranges */
+         assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
+         for (cpu = 0; cpu < 12; cpu++)
+                 assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+@@ -164,7 +164,7 @@ static void test_parse_cpu_set(void) {
+ 
+         /* Mix ranges and individual CPUs */
+         assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+-        assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
++        assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
+         assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
+         assert_se(CPU_ISSET_S(0, c.allocated, c.set));
+         assert_se(CPU_ISSET_S(2, c.allocated, c.set));
diff --git a/SOURCES/0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch b/SOURCES/0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch
new file mode 100644
index 0000000..cbb8483
--- /dev/null
+++ b/SOURCES/0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch
@@ -0,0 +1,30 @@
+From 3cf9361996b796eae0bda12aec8c92ddae1d5d48 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Tue, 4 Jun 2019 09:40:38 +0200
+Subject: [PATCH] test-cpu-set-util: fix allocation size check on i386
+
+We get just 28 bytes not 32 as on 64-bit architectures (__cpu_set_t is 4 bytes,
+we need at least 26, so 28 satisfies the constraints).
+
+(cherry picked from commit 64412970ac0d4b6f5c4bbd8816edc9bff9eab2de)
+
+Related: #1734787
+---
+ src/test/test-cpu-set-util.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
+index 3456add989..136eaca82d 100644
+--- a/src/test/test-cpu-set-util.c
++++ b/src/test/test-cpu-set-util.c
+@@ -256,7 +256,9 @@ static void test_cpu_set_to_from_dbus(void) {
+         assert_se(array);
+         assert_se(allocated == c.allocated);
+ 
+-        assert(memcmp(array, expected, sizeof expected) == 0);
++        assert_se(allocated <= sizeof expected);
++        assert_se(allocated >= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
++        assert(memcmp(array, expected, allocated) == 0);
+ 
+         assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
+         assert_se(c2.set);
diff --git a/SOURCES/0296-catalog-fix-name-of-variable.patch b/SOURCES/0296-catalog-fix-name-of-variable.patch
new file mode 100644
index 0000000..1e752eb
--- /dev/null
+++ b/SOURCES/0296-catalog-fix-name-of-variable.patch
@@ -0,0 +1,531 @@
+From c3513c7bcc27210c89edad1740e1190e693df86f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Mon, 15 Oct 2018 22:41:49 +0200
+Subject: [PATCH] catalog: fix name of variable
+
+All the messages would (literally) say "The start-up result is RESULT."
+because @RESULT@ was not defined.
+
+Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1639482
+and the first part of #8005.
+
+Fixup for 646cc98dc81c4d0edbc1b57e7bca0f474b47e270.
+
+(cherry picked from commit 65d51875c2a7b27b61de090f1bd6311b0cef2016)
+
+Resolves: #1677768
+---
+ catalog/systemd.be.catalog.in       | 6 +++---
+ catalog/systemd.be@latin.catalog.in | 6 +++---
+ catalog/systemd.bg.catalog.in       | 6 +++---
+ catalog/systemd.catalog.in          | 6 +++---
+ catalog/systemd.da.catalog.in       | 6 +++---
+ catalog/systemd.fr.catalog.in       | 6 +++---
+ catalog/systemd.hr.catalog.in       | 6 +++---
+ catalog/systemd.hu.catalog.in       | 6 +++---
+ catalog/systemd.it.catalog.in       | 6 +++---
+ catalog/systemd.ko.catalog.in       | 6 +++---
+ catalog/systemd.pl.catalog.in       | 6 +++---
+ catalog/systemd.pt_BR.catalog.in    | 6 +++---
+ catalog/systemd.ru.catalog.in       | 6 +++---
+ catalog/systemd.sr.catalog.in       | 6 +++---
+ catalog/systemd.zh_CN.catalog.in    | 6 +++---
+ catalog/systemd.zh_TW.catalog.in    | 6 +++---
+ 16 files changed, 48 insertions(+), 48 deletions(-)
+
+diff --git a/catalog/systemd.be.catalog.in b/catalog/systemd.be.catalog.in
+index 5011ea268d..2c59898683 100644
+--- a/catalog/systemd.be.catalog.in
++++ b/catalog/systemd.be.catalog.in
+@@ -175,7 +175,7 @@ Support: %SUPPORT_URL%
+ 
+ Працэс запуску юніта @UNIT@ завершаны.
+ 
+-Вынік: @RESULT@.
++Вынік: @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Юніт @UNIT@ спыняецца
+@@ -198,7 +198,7 @@ Support: %SUPPORT_URL%
+ 
+ Збой юніта @UNIT@.
+ 
+-Вынік: @RESULT@.
++Вынік: @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Юніт @UNIT@ перачытвае сваю канфігурацыю
+@@ -214,7 +214,7 @@ Support: %SUPPORT_URL%
+ 
+ Юніт @UNIT@ перачытаў сваю канфігурацыю.
+ 
+-Вынік: @RESULT@.
++Вынік: @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Працэс @EXECUTABLE@ не можа быць выкананы
+diff --git a/catalog/systemd.be@latin.catalog.in b/catalog/systemd.be@latin.catalog.in
+index 6a8b092669..1d024fea12 100644
+--- a/catalog/systemd.be@latin.catalog.in
++++ b/catalog/systemd.be@latin.catalog.in
+@@ -178,7 +178,7 @@ Support: %SUPPORT_URL%
+ 
+ Praces zapusku junita @UNIT@ zavieršany.
+ 
+-Vynik: @RESULT@.
++Vynik: @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Junit @UNIT@ spyniajecca
+@@ -201,7 +201,7 @@ Support: %SUPPORT_URL%
+ 
+ Zboj junita @UNIT@.
+ 
+-Vynik: @RESULT@.
++Vynik: @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Junit @UNIT@ pieračytvaje svaju kanfihuracyju
+@@ -217,7 +217,7 @@ Support: %SUPPORT_URL%
+ 
+ Junit @UNIT@ pieračytaŭ svaju kanfihuracyju.
+ 
+-Vynik: @RESULT@.
++Vynik: @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Praces @EXECUTABLE@ nie moža być vykanany
+diff --git a/catalog/systemd.bg.catalog.in b/catalog/systemd.bg.catalog.in
+index 64d616f381..41f7b21bce 100644
+--- a/catalog/systemd.bg.catalog.in
++++ b/catalog/systemd.bg.catalog.in
+@@ -178,7 +178,7 @@ Support: %SUPPORT_URL%
+ 
+ Стартирането на модул „@UNIT@“ завърши.
+ 
+-Резултатът е: @RESULT@
++Резултатът е: @JOB_RESULT@
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Модул „@UNIT@“ се спира
+@@ -201,7 +201,7 @@ Support: %SUPPORT_URL%
+ 
+ Модулът „@UNIT@“ не успя да стартира.
+ 
+-Резултатът е: @RESULT@
++Резултатът е: @JOB_RESULT@
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Модулът „@UNIT@“ започна презареждане на настройките си
+@@ -217,7 +217,7 @@ Support: %SUPPORT_URL%
+ 
+ Модулът „@UNIT@“ завърши презареждането на настройките си.
+ 
+-Резултатът e: @RESULT@
++Резултатът e: @JOB_RESULT@
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Програмата „@EXECUTABLE@“ не успя да се стартира
+diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
+index 8234e387cf..49a45890f6 100644
+--- a/catalog/systemd.catalog.in
++++ b/catalog/systemd.catalog.in
+@@ -202,7 +202,7 @@ Support: %SUPPORT_URL%
+ 
+ Unit @UNIT@ has finished starting up.
+ 
+-The start-up result is @RESULT@.
++The start-up result is @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Unit @UNIT@ has begun shutting down
+@@ -225,7 +225,7 @@ Support: %SUPPORT_URL%
+ 
+ Unit @UNIT@ has failed.
+ 
+-The result is @RESULT@.
++The result is @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Unit @UNIT@ has begun reloading its configuration
+@@ -241,7 +241,7 @@ Support: %SUPPORT_URL%
+ 
+ Unit @UNIT@ has finished reloading its configuration
+ 
+-The result is @RESULT@.
++The result is @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Process @EXECUTABLE@ could not be executed
+diff --git a/catalog/systemd.da.catalog.in b/catalog/systemd.da.catalog.in
+index 4e2bec8a0f..aecfafa05f 100644
+--- a/catalog/systemd.da.catalog.in
++++ b/catalog/systemd.da.catalog.in
+@@ -159,7 +159,7 @@ Support: %SUPPORT_URL%
+ 
+ Enhed @UNIT@ er færdig med at starte op.
+ 
+-Resultat for opstart er @RESULT@.
++Resultat for opstart er @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Enhed @UNIT@ har påbegyndt nedlukning
+@@ -182,7 +182,7 @@ Support: %SUPPORT_URL%
+ 
+ Enhed @UNIT@ har fejlet.
+ 
+-Resultatet er @RESULT@
++Resultatet er @JOB_RESULT@
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Enhed @UNIT@ har påbegyndt genindlæsning af sin konfiguration
+@@ -198,7 +198,7 @@ Support: %SUPPORT_URL%
+ 
+ Enhed @UNIT@ er færdig med at genindlæse sin konfiguration
+ 
+-Resultatet er: @RESULT@.
++Resultatet er: @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Process @EXECUTABLE@ kunne ikke eksekveres
+diff --git a/catalog/systemd.fr.catalog.in b/catalog/systemd.fr.catalog.in
+index 156b1a37dc..13edd083cb 100644
+--- a/catalog/systemd.fr.catalog.in
++++ b/catalog/systemd.fr.catalog.in
+@@ -191,7 +191,7 @@ Subject: L'unité (unit) @UNIT@ a terminé son démarrage
+ Defined-By: systemd
+ Support: %SUPPORT_URL%
+ 
+-L'unité (unit) @UNIT@ a terminé son démarrage, avec le résultat @RESULT@.
++L'unité (unit) @UNIT@ a terminé son démarrage, avec le résultat @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: L'unité (unit) @UNIT@ a commencé à s'arrêter
+@@ -212,7 +212,7 @@ Subject: L'unité (unit) @UNIT@ a échoué
+ Defined-By: systemd
+ Support: %SUPPORT_URL%
+ 
+-L'unité (unit) @UNIT@ a échoué, avec le résultat @RESULT@.
++L'unité (unit) @UNIT@ a échoué, avec le résultat @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: L'unité (unit) @UNIT@ a commencé à recharger sa configuration
+@@ -227,7 +227,7 @@ Defined-By: systemd
+ Support: %SUPPORT_URL%
+ 
+ L'unité (unit) @UNIT@ a terminé de recharger configuration,
+-avec le résultat @RESULT@.
++avec le résultat @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Le processus @EXECUTABLE@ n'a pas pu être exécuté
+diff --git a/catalog/systemd.hr.catalog.in b/catalog/systemd.hr.catalog.in
+index c4808b4c7d..4526ae2a8c 100644
+--- a/catalog/systemd.hr.catalog.in
++++ b/catalog/systemd.hr.catalog.in
+@@ -173,7 +173,7 @@ Support: %SUPPORT_URL%
+ 
+ Jedinica @UNIT@ je završila pokretanje.
+ 
+-Rezultat pokretanja je @RESULT@.
++Rezultat pokretanja je @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Jedinica @UNIT@ je započela isključivanje
+@@ -196,7 +196,7 @@ Support: %SUPPORT_URL%
+ 
+ Jedinica @UNIT@ nije uspjela.
+ 
+-Rezultat je @RESULT@.
++Rezultat je @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Jedinica @UNIT@ je započela ponovno učitavati podešavanja
+@@ -212,7 +212,7 @@ Support: %SUPPORT_URL%
+ 
+ Jedinica @UNIT@ je završila ponovno učitavati podešavanja
+ 
+-Rezultat je @RESULT@.
++Rezultat je @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Proces @EXECUTABLE@ se ne može pokrenuti
+diff --git a/catalog/systemd.hu.catalog.in b/catalog/systemd.hu.catalog.in
+index 6c6d7e7934..5565b80b2a 100644
+--- a/catalog/systemd.hu.catalog.in
++++ b/catalog/systemd.hu.catalog.in
+@@ -161,7 +161,7 @@ Support: %SUPPORT_URL%
+ 
+ A(z) @UNIT@ egység befejezte az indulást
+ 
+-Az indítás eredménye: @RESULT@.
++Az indítás eredménye: @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: A(z) @UNIT@ egység megkezdte a leállást
+@@ -184,7 +184,7 @@ Support: %SUPPORT_URL%
+ 
+ A(z) @UNIT@ egység hibát jelzett.
+ 
+-Az eredmény: @RESULT@.
++Az eredmény: @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: A(z) @UNIT@ egység megkezdte a beállításainak újratöltését
+@@ -200,7 +200,7 @@ Support: %SUPPORT_URL%
+ 
+ A(z) @UNIT@ egység befejezte a beállításainak újratöltését.
+ 
+-Az eredmény: @RESULT@.
++Az eredmény: @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: A folyamat végrehajtása sikertelen: @EXECUTABLE@
+diff --git a/catalog/systemd.it.catalog.in b/catalog/systemd.it.catalog.in
+index 4fd1f2a933..8ce4fa5d92 100644
+--- a/catalog/systemd.it.catalog.in
++++ b/catalog/systemd.it.catalog.in
+@@ -191,7 +191,7 @@ Support: %SUPPORT_URL%
+ 
+ L'unità @UNIT@ ha terminato la fase di avvio.
+ 
+-La fase di avvio è @RESULT@.
++La fase di avvio è @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: L'unità @UNIT@ inizia la fase di spegnimento
+@@ -214,7 +214,7 @@ Support: %SUPPORT_URL%
+ 
+ L'unità @UNIT@ è fallita.
+ 
+-Il risultato è @RESULT@.
++Il risultato è @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: L'unità @UNIT@ inizia a caricare la propria configurazione
+@@ -230,7 +230,7 @@ Support: %SUPPORT_URL%
+ 
+ L'unità @UNIT@ è terminata ricaricando la propria configurazione
+ 
+-Il risultato è @RESULT@.
++Il risultato è @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Il processo @EXECUTABLE@ non può essere eseguito
+diff --git a/catalog/systemd.ko.catalog.in b/catalog/systemd.ko.catalog.in
+index fc0faad02c..59fbde8b62 100644
+--- a/catalog/systemd.ko.catalog.in
++++ b/catalog/systemd.ko.catalog.in
+@@ -182,7 +182,7 @@ Support: %SUPPORT_URL%
+ 
+ @UNIT@ 유닛 시동을 마쳤습니다.
+ 
+-시동 결과는 @RESULT@ 입니다.
++시동 결과는 @JOB_RESULT@ 입니다.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: @UNIT@ 유닛 끝내기 동작 시작
+@@ -205,7 +205,7 @@ Support: %SUPPORT_URL%
+ 
+ @UNIT@ 유닛 동작에 실패했습니다.
+ 
+-결과는 @RESULT@ 입니다.
++결과는 @JOB_RESULT@ 입니다.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: @UNIT@ 유닛 설정 다시 읽기 시작
+@@ -221,7 +221,7 @@ Support: %SUPPORT_URL%
+ 
+ @UNIT@ 유닛의 설정 다시 읽기 동작을 끝냈습니다.
+ 
+-결과는 @RESULT@ 입니다.
++결과는 @JOB_RESULT@ 입니다.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: @EXECUTABLE@ 프로세스 시작할 수 없음
+diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in
+index 998894bd0a..b73f56ca11 100644
+--- a/catalog/systemd.pl.catalog.in
++++ b/catalog/systemd.pl.catalog.in
+@@ -201,7 +201,7 @@ Support: %SUPPORT_URL%
+ 
+ Jednostka @UNIT@ ukończyła uruchamianie.
+ 
+-Wynik uruchamiania: @RESULT@.
++Wynik uruchamiania: @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Rozpoczęto wyłączanie jednostki @UNIT@
+@@ -224,7 +224,7 @@ Support: %SUPPORT_URL%
+ 
+ Jednostka @UNIT@ się nie powiodła.
+ 
+-Wynik: @RESULT@.
++Wynik: @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Rozpoczęto ponowne wczytywanie konfiguracji jednostki @UNIT@
+@@ -240,7 +240,7 @@ Support: %SUPPORT_URL%
+ 
+ Jednostka @UNIT@ ukończyła ponowne wczytywanie swojej konfiguracji.
+ 
+-Wynik: @RESULT@.
++Wynik: @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Nie można wykonać procesu @EXECUTABLE@
+diff --git a/catalog/systemd.pt_BR.catalog.in b/catalog/systemd.pt_BR.catalog.in
+index db1cb03198..edaefb7164 100644
+--- a/catalog/systemd.pt_BR.catalog.in
++++ b/catalog/systemd.pt_BR.catalog.in
+@@ -162,7 +162,7 @@ Support: %SUPPORT_URL%
+ 
+ A unidade @UNIT@ concluiu a inicialização.
+ 
+-The start-up result is @RESULT@.
++The start-up result is @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Unidade @UNIT@ sendo desligado
+@@ -185,7 +185,7 @@ Support: %SUPPORT_URL%
+ 
+ A unidade @UNIT@ falhou.
+ 
+-O resultado é @RESULT@.
++O resultado é @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Unidade @UNIT@ iniciou recarregamento de sua configuração
+@@ -201,7 +201,7 @@ Support: %SUPPORT_URL%
+ 
+ A unidade @UNIT@ concluiu o recarregamento de sua configuração.
+ 
+-O resultado é @RESULT@.
++O resultado é @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Processo @EXECUTABLE@ não pôde ser executado
+diff --git a/catalog/systemd.ru.catalog.in b/catalog/systemd.ru.catalog.in
+index 645edaa922..ccdc685037 100644
+--- a/catalog/systemd.ru.catalog.in
++++ b/catalog/systemd.ru.catalog.in
+@@ -227,7 +227,7 @@ Support: %SUPPORT_URL%
+ 
+ Процесс запуска юнита @UNIT@ был завершен.
+ 
+-Результат: @RESULT@.
++Результат: @JOB_RESULT@.
+ 
+ # Subject: Unit @UNIT@ has begun shutting down
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+@@ -253,7 +253,7 @@ Support: %SUPPORT_URL%
+ 
+ Произошел сбой юнита @UNIT@.
+ 
+-Результат: @RESULT@.
++Результат: @JOB_RESULT@.
+ 
+ # Subject: Unit @UNIT@ has begun with reloading its configuration
+ -- d34d037fff1847e6ae669a370e694725
+@@ -271,7 +271,7 @@ Support: %SUPPORT_URL%
+ 
+ Юнит @UNIT@ завершил процесс перечитывания своей конфигурации.
+ 
+-Результат: @RESULT@.
++Результат: @JOB_RESULT@.
+ 
+ # Subject: Process @EXECUTABLE@ could not be executed
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+diff --git a/catalog/systemd.sr.catalog.in b/catalog/systemd.sr.catalog.in
+index f5746715a4..7cb6546d43 100644
+--- a/catalog/systemd.sr.catalog.in
++++ b/catalog/systemd.sr.catalog.in
+@@ -158,7 +158,7 @@ Support: %SUPPORT_URL%
+ 
+ Јединица @UNIT@ је завршила са покретањем.
+ 
+-Исход покретања је @RESULT@.
++Исход покретања је @JOB_RESULT@.
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: Јединица @UNIT@ је почела са гашењем
+@@ -181,7 +181,7 @@ Support: %SUPPORT_URL%
+ 
+ Јединица @UNIT@ је пукла.
+ 
+-Исход је @RESULT@.
++Исход је @JOB_RESULT@.
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: Јединица @UNIT@ је почела са поновним учитавањем свог подешавања
+@@ -197,7 +197,7 @@ Support: %SUPPORT_URL%
+ 
+ Јединица @UNIT@ је завршила са поновним учитавањем свог подешавања
+ 
+-Исход је @RESULT@.
++Исход је @JOB_RESULT@.
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: Процес @EXECUTABLE@ није могао бити извршен
+diff --git a/catalog/systemd.zh_CN.catalog.in b/catalog/systemd.zh_CN.catalog.in
+index fa58448acf..d6ac2592b8 100644
+--- a/catalog/systemd.zh_CN.catalog.in
++++ b/catalog/systemd.zh_CN.catalog.in
+@@ -156,7 +156,7 @@ Support: %SUPPORT_URL%
+ 
+ @UNIT@ 单元已结束启动。
+ 
+-启动结果为“@RESULT@”。
++启动结果为“@JOB_RESULT@”。
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: @UNIT@ 单元已开始停止操作
+@@ -179,7 +179,7 @@ Support: %SUPPORT_URL%
+ 
+ @UNIT@ 单元已失败。
+ 
+-结果为“@RESULT@”。
++结果为“@JOB_RESULT@”。
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: @UNIT@ 单元已开始重新载入其配置
+@@ -195,7 +195,7 @@ Support: %SUPPORT_URL%
+ 
+ @UNIT@ 单元已结束配置重载入操作。
+ 
+-结果为“@RESULT@”。
++结果为“@JOB_RESULT@”。
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: 进程 @EXECUTABLE@ 无法执行
+diff --git a/catalog/systemd.zh_TW.catalog.in b/catalog/systemd.zh_TW.catalog.in
+index 17bd2bc9af..a468c2f6bf 100644
+--- a/catalog/systemd.zh_TW.catalog.in
++++ b/catalog/systemd.zh_TW.catalog.in
+@@ -160,7 +160,7 @@ Support: %SUPPORT_URL%
+ 
+ 單位 @UNIT@ 啟動已結束。
+ 
+-啟動結果為 @RESULT@。
++啟動結果為 @JOB_RESULT@。
+ 
+ -- de5b426a63be47a7b6ac3eaac82e2f6f
+ Subject: 單位 @UNIT@ 已開始關閉
+@@ -183,7 +183,7 @@ Support: %SUPPORT_URL%
+ 
+ 單位 @UNIT@ 已失敗。
+ 
+-結果為 @RESULT@。
++結果為 @JOB_RESULT@。
+ 
+ -- d34d037fff1847e6ae669a370e694725
+ Subject: 單位 @UNIT@ 已開始重新載入其設定
+@@ -199,7 +199,7 @@ Support: %SUPPORT_URL%
+ 
+ 單位 @UNIT@ 已結束重新載入其設定
+ 
+-結果為 @RESULT@。
++結果為 @JOB_RESULT@。
+ 
+ -- 641257651c1b4ec9a8624d7a40a9e1e7
+ Subject: 行程 @EXECUTABLE@ 無法執行
diff --git a/SOURCES/0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch b/SOURCES/0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch
new file mode 100644
index 0000000..8e99e2f
--- /dev/null
+++ b/SOURCES/0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch
@@ -0,0 +1,273 @@
+From 0f7a4f49a7ce95e87061afe03ac40662a1eb0e2d Mon Sep 17 00:00:00 2001
+From: shinygold <10763595+shinygold@users.noreply.github.com>
+Date: Tue, 16 Jul 2019 13:06:16 +0200
+Subject: [PATCH] cryptsetup: add keyfile-timeout to allow a keydev timeout and
+ allow to fallback to a password if it fails.
+
+(cherry picked from commit 50d2eba27b9bfc77ef6b40e5721713846815418b)
+
+Resolves: #1763155
+---
+ src/cryptsetup/cryptsetup-generator.c | 119 ++++++++++++++++++--------
+ src/cryptsetup/cryptsetup.c           |   5 +-
+ 2 files changed, 89 insertions(+), 35 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 52c1262728..1e8e3ba00d 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -40,10 +40,39 @@ 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, *name_escaped = NULL;
++static int split_keyspec(const char *keyspec, char **keyfile, char **keydev) {
++        _cleanup_free_ char *kfile = NULL, *kdev = NULL;
++        char *c;
++
++        assert(keyspec);
++        assert(keyfile);
++        assert(keydev);
++
++        c = strrchr(keyspec, ':');
++        if (c) {
++                kfile = strndup(keyspec, c-keyspec);
++                kdev = strdup(c + 1);
++                if (!*kfile || !*kdev)
++                        return log_oom();
++        } else {
++                /* No keydev specified */
++                kfile = strdup(keyspec);
++                kdev = NULL;
++                if (!*kfile)
++                        return log_oom();
++        }
++
++        *keyfile = TAKE_PTR(kfile);
++        *keydev = TAKE_PTR(kdev);
++
++        return 0;
++}
++
++static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **mount) {
++        _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
+         _cleanup_fclose_ FILE *f = NULL;
+         int r;
++        usec_t timeout_us;
+ 
+         assert(name);
+         assert(keydev);
+@@ -88,7 +117,25 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
+                 "[Mount]\n"
+                 "What=%s\n"
+                 "Where=%s\n"
+-                "Options=ro\n", what, where);
++                "Options=ro%s\n", what, where, canfail ? ",nofail" : "");
++
++        if (keydev_timeout) {
++                r = parse_sec_fix_0(keydev_timeout, &timeout_us);
++                if (r >= 0) {
++                        r = unit_name_from_path(what, ".device", &device_unit);
++                        if (r < 0)
++                                return log_error_errno(r, "Failed to generate unit name: %m");
++
++                        r = write_drop_in_format(arg_dest, device_unit, 90, "device-timeout",
++                                "# Automatically generated by systemd-cryptsetup-generator \n\n"
++                                "[Unit]\nJobRunningTimeoutSec=%s", keydev_timeout);
++                        if (r < 0)
++                                return log_error_errno(r, "Failed to write device drop-in: %m");
++
++                } else
++                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", keydev_timeout);
++
++        }
+ 
+         r = fflush_and_check(f);
+         if (r < 0)
+@@ -103,16 +150,17 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
+ static int create_disk(
+                 const char *name,
+                 const char *device,
+-                const char *keydev,
+                 const char *password,
++                const char *keydev,
+                 const char *options) {
+ 
+         _cleanup_free_ char *n = NULL, *d = NULL, *u = NULL, *e = NULL,
+-                *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL, *keydev_mount = NULL;
++                *keydev_mount = NULL, *keyfile_timeout_value = NULL, *password_escaped = NULL,
++                *filtered = NULL, *u_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL;
+         _cleanup_fclose_ FILE *f = NULL;
+         const char *dmname;
+         bool noauto, nofail, tmp, swap, netdev;
+-        int r;
++        int r, keyfile_can_timeout;
+ 
+         assert(name);
+         assert(device);
+@@ -123,6 +171,10 @@ static int create_disk(
+         swap = fstab_test_option(options, "swap\0");
+         netdev = fstab_test_option(options, "_netdev\0");
+ 
++        keyfile_can_timeout = fstab_filter_options(options, "keyfile-timeout\0", NULL, &keyfile_timeout_value, NULL);
++        if (keyfile_can_timeout < 0)
++                return log_error_errno(keyfile_can_timeout, "Failed to parse keyfile-timeout= option value: %m");
++
+         if (tmp && swap) {
+                 log_error("Device '%s' cannot be both 'tmp' and 'swap'. Ignoring.", name);
+                 return -EINVAL;
+@@ -152,12 +204,6 @@ static int create_disk(
+         if (r < 0)
+                 return log_error_errno(r, "Failed to generate unit name: %m");
+ 
+-        if (password) {
+-                password_escaped = specifier_escape(password);
+-                if (!password_escaped)
+-                        return log_oom();
+-        }
+-
+         if (keydev && !password) {
+                 log_error("Key device is specified, but path to the password file is missing.");
+                 return -EINVAL;
+@@ -178,10 +224,16 @@ static int create_disk(
+                 "After=%s\n",
+                 netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
+ 
++        if (password) {
++                password_escaped = specifier_escape(password);
++                if (!password_escaped)
++                        return log_oom();
++        }
++
+         if (keydev) {
+                 _cleanup_free_ char *unit = NULL, *p = NULL;
+ 
+-                r = generate_keydev_mount(name, keydev, &unit, &keydev_mount);
++                r = generate_keydev_mount(name, keydev, keyfile_timeout_value, keyfile_can_timeout > 0, &unit, &keydev_mount);
+                 if (r < 0)
+                         return log_error_errno(r, "Failed to generate keydev mount unit: %m");
+ 
+@@ -190,6 +242,12 @@ static int create_disk(
+                         return log_oom();
+ 
+                 free_and_replace(password_escaped, p);
++
++                fprintf(f, "After=%s\n", unit);
++                if (keyfile_can_timeout > 0)
++                        fprintf(f, "Wants=%s\n", unit);
++                else
++                        fprintf(f, "Requires=%s\n", unit);
+         }
+ 
+         if (!nofail)
+@@ -197,7 +255,7 @@ static int create_disk(
+                         "Before=%s\n",
+                         netdev ? "remote-cryptsetup.target" : "cryptsetup.target");
+ 
+-        if (password) {
++        if (password && !keydev) {
+                 if (STR_IN_SET(password, "/dev/urandom", "/dev/random", "/dev/hw_random"))
+                         fputs("After=systemd-random-seed.service\n", f);
+                 else if (!STR_IN_SET(password, "-", "none")) {
+@@ -271,7 +329,7 @@ static int create_disk(
+ 
+         if (keydev)
+                 fprintf(f,
+-                        "ExecStartPost=" UMOUNT_PATH " %s\n\n",
++                        "ExecStartPost=-" UMOUNT_PATH " %s\n\n",
+                         keydev_mount);
+ 
+         r = fflush_and_check(f);
+@@ -394,7 +452,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
+         } else if (streq(key, "luks.key")) {
+                 size_t n;
+                 _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+-                char *c;
+                 const char *keyspec;
+ 
+                 if (proc_cmdline_value_missing(key, value))
+@@ -421,23 +478,13 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
+                         return log_oom();
+ 
+                 keyspec = value + n + 1;
+-                c = strrchr(keyspec, ':');
+-                if (c) {
+-                         *c = '\0';
+-                        keyfile = strdup(keyspec);
+-                        keydev = strdup(c + 1);
+-
+-                        if (!keyfile || !keydev)
+-                                return log_oom();
+-                } else {
+-                        /* No keydev specified */
+-                        keyfile = strdup(keyspec);
+-                        if (!keyfile)
+-                                return log_oom();
+-                }
++                r = split_keyspec(keyspec, &keyfile, &keydev);
++                if (r < 0)
++                        return r;
+ 
+                 free_and_replace(d->keyfile, keyfile);
+                 free_and_replace(d->keydev, keydev);
++
+         } else if (streq(key, "luks.name")) {
+ 
+                 if (proc_cmdline_value_missing(key, value))
+@@ -485,7 +532,7 @@ static int add_crypttab_devices(void) {
+                 int r, k;
+                 char line[LINE_MAX], *l, *uuid;
+                 crypto_device *d = NULL;
+-                _cleanup_free_ char *name = NULL, *device = NULL, *keyfile = NULL, *options = NULL;
++                _cleanup_free_ char *name = NULL, *device = NULL, *keydev = NULL, *keyfile = NULL, *keyspec = NULL, *options = NULL;
+ 
+                 if (!fgets(line, sizeof(line), f))
+                         break;
+@@ -496,7 +543,7 @@ static int add_crypttab_devices(void) {
+                 if (IN_SET(*l, 0, '#'))
+                         continue;
+ 
+-                k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyfile, &options);
++                k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyspec, &options);
+                 if (k < 2 || k > 4) {
+                         log_error("Failed to parse /etc/crypttab:%u, ignoring.", crypttab_line);
+                         continue;
+@@ -515,7 +562,11 @@ static int add_crypttab_devices(void) {
+                         continue;
+                 }
+ 
+-                r = create_disk(name, device, NULL, keyfile, (d && d->options) ? d->options : options);
++                r = split_keyspec(keyspec, &keyfile, &keydev);
++                if (r < 0)
++                        return r;
++
++                r = create_disk(name, device, keyfile, keydev, (d && d->options) ? d->options : options);
+                 if (r < 0)
+                         return r;
+ 
+@@ -555,7 +606,7 @@ static int add_proc_cmdline_devices(void) {
+                 else
+                         options = "timeout=0";
+ 
+-                r = create_disk(d->name, device, d->keydev, d->keyfile ?: arg_default_keyfile, options);
++                r = create_disk(d->name, device, d->keyfile ?: arg_default_keyfile, d->keydev, options);
+                 if (r < 0)
+                         return r;
+         }
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index 9071126c2e..0881aea915 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -69,7 +69,10 @@ static int parse_one_option(const char *option) {
+         assert(option);
+ 
+         /* Handled outside of this tool */
+-        if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev"))
++        if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev", "keyfile-timeout"))
++                return 0;
++
++        if (startswith(option, "keyfile-timeout="))
+                 return 0;
+ 
+         if ((val = startswith(option, "cipher="))) {
diff --git a/SOURCES/0298-cryptsetup-add-documentation-for-keyfile-timeout.patch b/SOURCES/0298-cryptsetup-add-documentation-for-keyfile-timeout.patch
new file mode 100644
index 0000000..c43658a
--- /dev/null
+++ b/SOURCES/0298-cryptsetup-add-documentation-for-keyfile-timeout.patch
@@ -0,0 +1,44 @@
+From fdb86185b56619c59602c6546fd0710eec4a6e85 Mon Sep 17 00:00:00 2001
+From: shinygold <10763595+shinygold@users.noreply.github.com>
+Date: Tue, 16 Jul 2019 13:05:34 +0200
+Subject: [PATCH] cryptsetup: add documentation for keyfile-timeout
+
+(cherry picked from commit 4e1334512debb27f4a0c4a6da237a4b8d59fea08)
+
+Related: #1763155
+---
+ man/crypttab.xml | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/man/crypttab.xml b/man/crypttab.xml
+index 3574ce00da..6074315980 100644
+--- a/man/crypttab.xml
++++ b/man/crypttab.xml
+@@ -150,6 +150,17 @@
+         sequential order.</para></listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><option>keyfile-timeout=</option></term>
++
++        <listitem><para> Specifies the timeout for the device on
++        which the key file resides and falls back to a password if
++        it could not be mounted. See
++        <citerefentry><refentrytitle>systemd-cryptsetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
++        for key files on external devices.
++        </para></listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><option>luks</option></term>
+ 
+@@ -417,7 +428,8 @@
+       <programlisting>luks       UUID=2505567a-9e27-4efe-a4d5-15ad146c258b
+ swap       /dev/sda7       /dev/urandom       swap
+ truecrypt  /dev/sda2       /etc/container_password  tcrypt
+-hidden     /mnt/tc_hidden  /dev/null    tcrypt-hidden,tcrypt-keyfile=/etc/keyfile</programlisting>
++hidden     /mnt/tc_hidden  /dev/null    tcrypt-hidden,tcrypt-keyfile=/etc/keyfile
++external   /dev/sda3       keyfile:LABEL=keydev keyfile-timeout=10s</programlisting>
+     </example>
+   </refsect1>
+ 
diff --git a/SOURCES/0299-cryptsetup-use-unabbrieviated-variable-names.patch b/SOURCES/0299-cryptsetup-use-unabbrieviated-variable-names.patch
new file mode 100644
index 0000000..be86edd
--- /dev/null
+++ b/SOURCES/0299-cryptsetup-use-unabbrieviated-variable-names.patch
@@ -0,0 +1,63 @@
+From 0577d8378645c1ecd909b74403cefe31ed569398 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Thu, 1 Aug 2019 08:13:13 +0200
+Subject: [PATCH] cryptsetup: use unabbrieviated variable names
+
+Now that "ret_" has been added to the output variables, we can name
+the internal variables without artificial abbrevs.
+
+(cherry picked from commit 5d2100dc4c32abbce4109e75cbfbbef6e1b2b7b1)
+
+Related: #1763155
+---
+ src/cryptsetup/cryptsetup-generator.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 1e8e3ba00d..7b234e37be 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -40,30 +40,30 @@ static Hashmap *arg_disks = NULL;
+ static char *arg_default_options = NULL;
+ static char *arg_default_keyfile = NULL;
+ 
+-static int split_keyspec(const char *keyspec, char **keyfile, char **keydev) {
+-        _cleanup_free_ char *kfile = NULL, *kdev = NULL;
+-        char *c;
++static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_keydev) {
++        _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
++        const char *c;
+ 
+         assert(keyspec);
+-        assert(keyfile);
+-        assert(keydev);
++        assert(ret_keyfile);
++        assert(ret_keydev);
+ 
+         c = strrchr(keyspec, ':');
+         if (c) {
+-                kfile = strndup(keyspec, c-keyspec);
+-                kdev = strdup(c + 1);
+-                if (!*kfile || !*kdev)
++                keyfile = strndup(keyspec, c-keyspec);
++                keydev = strdup(c + 1);
++                if (!keyfile || !keydev)
+                         return log_oom();
+         } else {
+                 /* No keydev specified */
+-                kfile = strdup(keyspec);
+-                kdev = NULL;
+-                if (!*kfile)
++                keyfile = strdup(keyspec);
++                keydev = NULL;
++                if (!keyfile)
+                         return log_oom();
+         }
+ 
+-        *keyfile = TAKE_PTR(kfile);
+-        *keydev = TAKE_PTR(kdev);
++        *ret_keyfile = TAKE_PTR(keyfile);
++        *ret_keydev = TAKE_PTR(keydev);
+ 
+         return 0;
+ }
diff --git a/SOURCES/0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch b/SOURCES/0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch
new file mode 100644
index 0000000..7154dca
--- /dev/null
+++ b/SOURCES/0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch
@@ -0,0 +1,37 @@
+From 5cdb2b0b2a0f8f89f97053b0633b8419506d4e28 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Thu, 1 Aug 2019 08:15:43 +0200
+Subject: [PATCH] cryptsetup: don't assert on variable which is optional
+
+https://github.com/systemd/systemd/commit/50d2eba27b9bfc77ef6b40e5721713846815418b#commitcomment-34519739
+
+In add_crypttab_devices() split_keyspec is called on the keyfile argument,
+which may be NULL.
+
+(cherry picked from commit fef716b28be6e866b8afe995805d5ebe2af6bbfa)
+
+Related: #1763155
+---
+ src/cryptsetup/cryptsetup-generator.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 7b234e37be..a09983b576 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -44,10 +44,14 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
+         _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+         const char *c;
+ 
+-        assert(keyspec);
+         assert(ret_keyfile);
+         assert(ret_keydev);
+ 
++        if (!keyspec) {
++                *ret_keyfile = *ret_keydev = NULL;
++                return 0;
++        }
++
+         c = strrchr(keyspec, ':');
+         if (c) {
+                 keyfile = strndup(keyspec, c-keyspec);
diff --git a/SOURCES/0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch b/SOURCES/0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch
new file mode 100644
index 0000000..0f394ac
--- /dev/null
+++ b/SOURCES/0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch
@@ -0,0 +1,100 @@
+From 9040e15cd3cba546b47aeae0ea133afa1a6ad292 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Wed, 13 Nov 2019 10:32:30 +0100
+Subject: [PATCH] cryptsetup-generator: guess whether the keyfile argument is
+ two items or one
+
+Fixes #13615.
+
+See the inline comment for documentation.
+
+(cherry picked from commit 32c6237a7c2e697d2fc4f3403319db16858fb8e3)
+
+Related: #1763155
+---
+ src/cryptsetup/cryptsetup-generator.c | 45 ++++++++++++++++++---------
+ 1 file changed, 30 insertions(+), 15 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index a09983b576..4117930925 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -54,17 +54,36 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
+ 
+         c = strrchr(keyspec, ':');
+         if (c) {
+-                keyfile = strndup(keyspec, c-keyspec);
+-                keydev = strdup(c + 1);
+-                if (!keyfile || !keydev)
++                /* The keydev part has to be either an absolute path to device node (/dev/something,
++                 * /dev/foo/something, or even possibly /dev/foo/something:part), or a fstab device
++                 * specification starting with LABEL= or similar. The keyfile part has the same syntax.
++                 *
++                 * Let's try to guess if the second part looks like a keydev specification, or just part of a
++                 * filename with a colon. fstab_node_to_udev_node() will convert the fstab device syntax to
++                 * an absolute path. If we didn't get an absolute path, assume that it is just part of the
++                 * first keyfile argument. */
++
++                keydev = fstab_node_to_udev_node(c + 1);
++                if (!keydev)
+                         return log_oom();
+-        } else {
++
++                if (path_is_absolute(keydev))
++                        keyfile = strndup(keyspec, c-keyspec);
++                else {
++                        log_debug("Keyspec argument contains a colon, but \"%s\" doesn't look like a device specification.\n"
++                                  "Assuming that \"%s\" is a single device specification.",
++                                  c + 1, keyspec);
++                        keydev = mfree(keydev);
++                        c = NULL;
++                }
++        }
++
++        if (!c)
+                 /* No keydev specified */
+                 keyfile = strdup(keyspec);
+-                keydev = NULL;
+-                if (!keyfile)
+-                        return log_oom();
+-        }
++
++        if (!keyfile)
++                return log_oom();
+ 
+         *ret_keyfile = TAKE_PTR(keyfile);
+         *ret_keydev = TAKE_PTR(keydev);
+@@ -73,7 +92,7 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
+ }
+ 
+ static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **mount) {
+-        _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
++        _cleanup_free_ char *u = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
+         _cleanup_fclose_ FILE *f = NULL;
+         int r;
+         usec_t timeout_us;
+@@ -111,22 +130,18 @@ static int generate_keydev_mount(const char *name, const char *keydev, const cha
+         if (r < 0)
+                 return r;
+ 
+-        what = fstab_node_to_udev_node(keydev);
+-        if (!what)
+-                return -ENOMEM;
+-
+         fprintf(f,
+                 "[Unit]\n"
+                 "DefaultDependencies=no\n\n"
+                 "[Mount]\n"
+                 "What=%s\n"
+                 "Where=%s\n"
+-                "Options=ro%s\n", what, where, canfail ? ",nofail" : "");
++                "Options=ro%s\n", keydev, where, canfail ? ",nofail" : "");
+ 
+         if (keydev_timeout) {
+                 r = parse_sec_fix_0(keydev_timeout, &timeout_us);
+                 if (r >= 0) {
+-                        r = unit_name_from_path(what, ".device", &device_unit);
++                        r = unit_name_from_path(keydev, ".device", &device_unit);
+                         if (r < 0)
+                                 return log_error_errno(r, "Failed to generate unit name: %m");
+ 
diff --git a/SOURCES/0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch b/SOURCES/0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch
new file mode 100644
index 0000000..f7c2454
--- /dev/null
+++ b/SOURCES/0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch
@@ -0,0 +1,46 @@
+From 05e184dea3f0182e5787812adfd52b68cff9418d Mon Sep 17 00:00:00 2001
+From: Jan Janssen <medhefgo@web.de>
+Date: Mon, 25 Jun 2018 20:33:31 +0200
+Subject: [PATCH] crypt-util: Translate libcryptsetup log level instead of
+ using log_debug()
+
+This makes sure that errors reported by libcryptsetup are shown to the
+user instead of getting swallowed up by log_debug().
+
+(cherry picked from commit aa2cc005d77890b07e8c579f25e1333ff8ba8dac)
+
+Resolves: #1776408
+---
+ src/basic/crypt-util.c | 20 +++++++++++++++++++-
+ 1 file changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/src/basic/crypt-util.c b/src/basic/crypt-util.c
+index b181ba3ba0..20bdc5489e 100644
+--- a/src/basic/crypt-util.c
++++ b/src/basic/crypt-util.c
+@@ -5,6 +5,24 @@
+ #include "log.h"
+ 
+ void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
+-        log_debug("%s", msg);
++        switch (level) {
++        case CRYPT_LOG_NORMAL:
++                level = LOG_NOTICE;
++                break;
++        case CRYPT_LOG_ERROR:
++                level = LOG_ERR;
++                break;
++        case CRYPT_LOG_VERBOSE:
++                level = LOG_INFO;
++                break;
++        case CRYPT_LOG_DEBUG:
++                level = LOG_DEBUG;
++                break;
++        default:
++                log_error("Unknown libcryptsetup log level: %d", level);
++                level = LOG_ERR;
++        }
++
++        log_full(level, "%s", msg);
+ }
+ #endif
diff --git a/SOURCES/0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch b/SOURCES/0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch
new file mode 100644
index 0000000..e8f6f83
--- /dev/null
+++ b/SOURCES/0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch
@@ -0,0 +1,25 @@
+From ea0c4c31f6dff7d01e585bd8d5f962b373844544 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Mon, 21 Jan 2019 20:13:11 +0100
+Subject: [PATCH] cryptsetup: add some commenting about EAGAIN generation
+
+(cherry picked from commit b7a0fead10959b03a1fa642a5ae7aca3a6a3dee9)
+
+Related: #1776408
+---
+ src/cryptsetup/cryptsetup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index 0881aea915..f2b2557497 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -455,7 +455,7 @@ static int attach_tcrypt(
+                 r = read_one_line_file(key_file, &passphrase);
+                 if (r < 0) {
+                         log_error_errno(r, "Failed to read password file '%s': %m", key_file);
+-                        return -EAGAIN;
++                        return -EAGAIN; /* log with the actual error, but return EAGAIN */
+                 }
+ 
+                 params.passphrase = passphrase;
diff --git a/SOURCES/0304-cryptsetup-downgrade-a-log-message-we-ignore.patch b/SOURCES/0304-cryptsetup-downgrade-a-log-message-we-ignore.patch
new file mode 100644
index 0000000..cd853ee
--- /dev/null
+++ b/SOURCES/0304-cryptsetup-downgrade-a-log-message-we-ignore.patch
@@ -0,0 +1,25 @@
+From 3bbacfb22a9266769a41dee6f8f594fbeb6287fc Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Mon, 21 Jan 2019 20:19:57 +0100
+Subject: [PATCH] cryptsetup: downgrade a log message we ignore
+
+(cherry picked from commit 44ce4255147ab308c1f13580147c693204c322e8)
+
+Related: #1776408
+---
+ src/cryptsetup/cryptsetup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index f2b2557497..53fe04a73f 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -621,7 +621,7 @@ int main(int argc, char *argv[]) {
+                     !streq(argv[4], "none")) {
+ 
+                         if (!path_is_absolute(argv[4]))
+-                                log_error("Password file path '%s' is not absolute. Ignoring.", argv[4]);
++                                log_warning("Password file path '%s' is not absolute. Ignoring.", argv[4]);
+                         else
+                                 key_file = argv[4];
+                 }
diff --git a/SOURCES/0305-cryptsetup-rework-how-we-log-about-activation-failur.patch b/SOURCES/0305-cryptsetup-rework-how-we-log-about-activation-failur.patch
new file mode 100644
index 0000000..5b357c3
--- /dev/null
+++ b/SOURCES/0305-cryptsetup-rework-how-we-log-about-activation-failur.patch
@@ -0,0 +1,102 @@
+From 966ecf0011a02c7823083a7868b8589fdf850be8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Mon, 21 Jan 2019 20:20:35 +0100
+Subject: [PATCH] cryptsetup: rework how we log about activation failures
+
+First of all let's always log where the errors happen, and not in an
+upper stackframe, in all cases. Previously we'd do this somethis one way
+and sometimes another, which resulted in sometimes duplicate logging and
+sometimes none.
+
+When we cannot activate something due to bad password the kernel gives
+us EPERM. Let's uniformly return this EAGAIN, so tha the next password
+is tried. (previously this was done in most cases but not in all)
+
+When we get EPERM let's also explicitly indicate that this probably
+means the password is simply wrong.
+
+Fixes: #11498
+(cherry picked from commit 6f177c7dc092eb68762b4533d41b14244adb2a73)
+
+Related: #1776408
+---
+ src/cryptsetup/cryptsetup.c | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index 53fe04a73f..33c215eaa1 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -469,10 +469,15 @@ static int attach_tcrypt(
+                         log_error("Failed to activate using password file '%s'.", key_file);
+                         return -EAGAIN;
+                 }
+-                return r;
++
++                return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", crypt_get_device_name(cd));
+         }
+ 
+-        return crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
++        r = crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
++        if (r < 0)
++                return log_error_errno(r, "Failed to activate tcrypt device %s: %m", crypt_get_device_name(cd));
++
++        return 0;
+ }
+ 
+ static int attach_luks_or_plain(struct crypt_device *cd,
+@@ -549,22 +554,30 @@ static int attach_luks_or_plain(struct crypt_device *cd,
+ 
+         if (key_file) {
+                 r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags);
+-                if (r < 0) {
+-                        log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
+-                        return -EAGAIN;
++                if (r == -EPERM) {
++                        log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file);
++                        return -EAGAIN; /* Log actual error, but return EAGAIN */
+                 }
++                if (r < 0)
++                        return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
+         } else {
+                 char **p;
+ 
++                r = -EINVAL;
+                 STRV_FOREACH(p, passwords) {
+                         if (pass_volume_key)
+                                 r = crypt_activate_by_volume_key(cd, name, *p, arg_key_size, flags);
+                         else
+                                 r = crypt_activate_by_passphrase(cd, name, arg_key_slot, *p, strlen(*p), flags);
+-
+                         if (r >= 0)
+                                 break;
+                 }
++                if (r == -EPERM) {
++                        log_error_errno(r, "Failed to activate with specified passphrase. (Passphrase incorrect?)");
++                        return -EAGAIN; /* log actual error, but return EAGAIN */
++                }
++                if (r < 0)
++                        return log_error_errno(r, "Failed to activate with specified passphrase: %m");
+         }
+ 
+         return r;
+@@ -726,16 +739,11 @@ int main(int argc, char *argv[]) {
+                                                          flags);
+                         if (r >= 0)
+                                 break;
+-                        if (r == -EAGAIN) {
+-                                key_file = NULL;
+-                                continue;
+-                        }
+-                        if (r != -EPERM) {
+-                                log_error_errno(r, "Failed to activate: %m");
++                        if (r != -EAGAIN)
+                                 goto finish;
+-                        }
+ 
+-                        log_warning("Invalid passphrase.");
++                        /* Passphrase not correct? Let's try again! */
++                        key_file = NULL;
+                 }
+ 
+                 if (arg_tries != 0 && tries >= arg_tries) {
diff --git a/SOURCES/0306-rules-reintroduce-60-alias-kmsg.rules.patch b/SOURCES/0306-rules-reintroduce-60-alias-kmsg.rules.patch
new file mode 100644
index 0000000..2451c00
--- /dev/null
+++ b/SOURCES/0306-rules-reintroduce-60-alias-kmsg.rules.patch
@@ -0,0 +1,41 @@
+From b7f9d757dd6f276203b8b04f0c0ba1c61bcf8937 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Wed, 18 Dec 2019 09:41:29 +0100
+Subject: [PATCH] rules: reintroduce 60-alias-kmsg.rules
+
+Resolves:#1739353
+rhel-only
+---
+ rules/60-alias-kmsg.rules | 10 ++++++++++
+ rules/meson.build         |  1 +
+ 2 files changed, 11 insertions(+)
+ create mode 100644 rules/60-alias-kmsg.rules
+
+diff --git a/rules/60-alias-kmsg.rules b/rules/60-alias-kmsg.rules
+new file mode 100644
+index 0000000000..9c7236a730
+--- /dev/null
++++ b/rules/60-alias-kmsg.rules
+@@ -0,0 +1,10 @@
++SUBSYSTEM!="block", GOTO="log_end"
++KERNEL=="loop*|ram*", GOTO="log_end"
++ACTION=="remove", GOTO="log_end"
++ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="log_end"
++ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="log_end"
++
++IMPORT{cmdline}="udev.alias"
++ENV{udev.alias}=="1", RUN+="/bin/sh -c 'echo udev-alias: $name \($links\) > /dev/kmsg'"
++
++LABEL="log_end"
+diff --git a/rules/meson.build b/rules/meson.build
+index 6363f8bf2e..7b5b2472de 100644
+--- a/rules/meson.build
++++ b/rules/meson.build
+@@ -3,6 +3,7 @@
+ rules = files('''
+         40-redhat.rules
+         40-elevator.rules
++        60-alias-kmsg.rules
+         60-block.rules
+         60-cdrom_id.rules
+         60-drm.rules
diff --git a/SOURCES/0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch b/SOURCES/0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch
new file mode 100644
index 0000000..65374a7
--- /dev/null
+++ b/SOURCES/0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch
@@ -0,0 +1,49 @@
+From 1d8e642b0b67f07b0bf469c25126b878380bae6a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 18:13:03 +0100
+Subject: [PATCH] sd-bus: make rqueue/wqueue sizes of type size_t
+
+Let's do this like we usually do and size arrays with size_t.
+
+We already do this for the "allocated" counter correctly, and externally
+we expose the queue sizes as uint64_t anyway, hence there's really no
+point in usigned "unsigned" internally.
+
+(cherry picked from commit 143d4e045a798ccc87889b2a8a60d7fbe44be441)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/bus-internal.h | 4 ++--
+ src/libsystemd/sd-bus/sd-bus.c       | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
+index 5d773b14c4..06bd7862cb 100644
+--- a/src/libsystemd/sd-bus/bus-internal.h
++++ b/src/libsystemd/sd-bus/bus-internal.h
+@@ -221,11 +221,11 @@ struct sd_bus {
+         size_t rbuffer_size;
+ 
+         sd_bus_message **rqueue;
+-        unsigned rqueue_size;
++        size_t rqueue_size;
+         size_t rqueue_allocated;
+ 
+         sd_bus_message **wqueue;
+-        unsigned wqueue_size;
++        size_t wqueue_size;
+         size_t windex;
+         size_t wqueue_allocated;
+ 
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 1c9e967ae0..64026f7ee1 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -2080,7 +2080,7 @@ _public_ int sd_bus_call(
+         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
+         usec_t timeout;
+         uint64_t cookie;
+-        unsigned i;
++        size_t i;
+         int r;
+ 
+         bus_assert_return(m, -EINVAL, error);
diff --git a/SOURCES/0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch b/SOURCES/0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch
new file mode 100644
index 0000000..89004d8
--- /dev/null
+++ b/SOURCES/0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch
@@ -0,0 +1,51 @@
+From 9c23ceef0a08ffdf4aed7a96ec440e1b110568ac Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 18:14:17 +0100
+Subject: [PATCH] sd-bus: reorder bus ref and bus message ref handling
+
+Let's always place handling of these references together, so that all
+reference counting during allocation is at a single place.
+
+(cherry picked from commit e593b6a87a335267e5f7238b14683b7f840a01a3)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/bus-message.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
+index 19cb2b9a97..e9cdf46c91 100644
+--- a/src/libsystemd/sd-bus/bus-message.c
++++ b/src/libsystemd/sd-bus/bus-message.c
+@@ -461,7 +461,6 @@ int bus_message_from_header(
+         if (!m)
+                 return -ENOMEM;
+ 
+-        m->n_ref = 1;
+         m->sealed = true;
+         m->header = header;
+         m->header_accessible = header_accessible;
+@@ -515,7 +514,9 @@ int bus_message_from_header(
+                 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+         }
+ 
++        m->n_ref = 1;
+         m->bus = sd_bus_ref(bus);
++
+         *ret = TAKE_PTR(m);
+ 
+         return 0;
+@@ -588,13 +589,13 @@ _public_ int sd_bus_message_new(
+                 return -ENOMEM;
+ 
+         t->n_ref = 1;
++        t->bus = sd_bus_ref(bus);
+         t->header = (struct bus_header*) ((uint8_t*) t + ALIGN(sizeof(struct sd_bus_message)));
+         t->header->endian = BUS_NATIVE_ENDIAN;
+         t->header->type = type;
+         t->header->version = bus->message_version;
+         t->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING);
+         t->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(t);
+-        t->bus = sd_bus_ref(bus);
+ 
+         if (bus->allow_interactive_authorization)
+                 t->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
diff --git a/SOURCES/0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch b/SOURCES/0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch
new file mode 100644
index 0000000..9c7b804
--- /dev/null
+++ b/SOURCES/0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch
@@ -0,0 +1,32 @@
+From 19a9c67b79ebb9a65bc2aec8d8f2799262ef0cb2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 18:15:37 +0100
+Subject: [PATCH] sd-bus: make sure dispatch_rqueue() initializes return
+ parameter on all types of success
+
+Let's make sure our own code follows coding style and initializes all
+return values on all types of success (and leaves it uninitialized in
+all types of failure).
+
+(cherry picked from commit c0bc4ec5cc17ac61773d1e9362b0ffa8382c1ff1)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/sd-bus.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 64026f7ee1..55b008cc9f 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -1814,8 +1814,10 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd
+                 r = bus_read_message(bus, hint_priority, priority);
+                 if (r < 0)
+                         return r;
+-                if (r == 0)
++                if (r == 0) {
++                        *m = NULL;
+                         return ret;
++                }
+ 
+                 ret = 1;
+         }
diff --git a/SOURCES/0310-sd-bus-drop-two-inappropriate-empty-lines.patch b/SOURCES/0310-sd-bus-drop-two-inappropriate-empty-lines.patch
new file mode 100644
index 0000000..da2330b
--- /dev/null
+++ b/SOURCES/0310-sd-bus-drop-two-inappropriate-empty-lines.patch
@@ -0,0 +1,31 @@
+From 7e9944795e3f0046857379a5f878b365597ed373 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 18:18:18 +0100
+Subject: [PATCH] sd-bus: drop two inappropriate empty lines
+
+(cherry picked from commit 39feb2ce417e54cf9746e64b5dfd610cef6ac440)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/sd-bus.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 55b008cc9f..01060d105c 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -2634,7 +2634,6 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) {
+                                 SD_BUS_ERROR_UNKNOWN_METHOD,
+                                  "Unknown method '%s' on interface '%s'.", m->member, m->interface);
+         }
+-
+         if (r < 0)
+                 return r;
+ 
+@@ -2758,7 +2757,6 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd
+                         return r;
+ 
+                 *ret = TAKE_PTR(m);
+-
+                 return 1;
+         }
+ 
diff --git a/SOURCES/0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch b/SOURCES/0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch
new file mode 100644
index 0000000..d91eb20
--- /dev/null
+++ b/SOURCES/0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch
@@ -0,0 +1,33 @@
+From 247d4f826ab189c4dfc4706aaa94782342655218 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 21:06:30 +0100
+Subject: [PATCH] sd-bus: initialize mutex after we allocated the wqueue
+
+That way the mutex doesn't have to be destroyed when we exit early due
+to OOM.
+
+(cherry picked from commit 2fe9a10d7695c4c3a748969a0d1662c624e50e5e)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/sd-bus.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 01060d105c..e49d58137d 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -248,12 +248,12 @@ _public_ int sd_bus_new(sd_bus **ret) {
+         b->original_pid = getpid_cached();
+         b->n_groups = (size_t) -1;
+ 
+-        assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
+-
+         /* We guarantee that wqueue always has space for at least one entry */
+         if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1))
+                 return -ENOMEM;
+ 
++        assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
++
+         *ret = TAKE_PTR(b);
+         return 0;
+ }
diff --git a/SOURCES/0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch b/SOURCES/0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch
new file mode 100644
index 0000000..4e2883a
--- /dev/null
+++ b/SOURCES/0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch
@@ -0,0 +1,74 @@
+From 6180d5ee908c9c742f816c6922c229aefd533117 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 21:07:42 +0100
+Subject: [PATCH] sd-bus: always go through sd_bus_unref() to free messages
+
+Don't try to be smart, don't bypass the ref counting logic if there's no
+real reason to.
+
+This matters if we want to tweak the ref counting logic later.
+
+(cherry picked from commit b41812d1e308de03c879cfca490105216d528c4b)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/bus-message.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
+index e9cdf46c91..306b6d6816 100644
+--- a/src/libsystemd/sd-bus/bus-message.c
++++ b/src/libsystemd/sd-bus/bus-message.c
+@@ -138,8 +138,6 @@ static sd_bus_message* message_free(sd_bus_message *m) {
+         return mfree(m);
+ }
+ 
+-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, message_free);
+-
+ static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
+         void *op, *np;
+         size_t old_size, new_size, start;
+@@ -531,7 +529,7 @@ int bus_message_from_malloc(
+                 const char *label,
+                 sd_bus_message **ret) {
+ 
+-        _cleanup_(message_freep) sd_bus_message *m = NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+         size_t sz;
+         int r;
+ 
+@@ -651,7 +649,7 @@ _public_ int sd_bus_message_new_method_call(
+                 const char *interface,
+                 const char *member) {
+ 
+-        _cleanup_(message_freep) sd_bus_message *t = NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
+         int r;
+ 
+         assert_return(bus, -ENOTCONN);
+@@ -696,7 +694,7 @@ static int message_new_reply(
+                 uint8_t type,
+                 sd_bus_message **m) {
+ 
+-        _cleanup_(message_freep) sd_bus_message *t = NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
+         uint64_t cookie;
+         int r;
+ 
+@@ -747,7 +745,7 @@ _public_ int sd_bus_message_new_method_error(
+                 sd_bus_message **m,
+                 const sd_bus_error *e) {
+ 
+-        _cleanup_(message_freep) sd_bus_message *t = NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
+         int r;
+ 
+         assert_return(sd_bus_error_is_set(e), -EINVAL);
+@@ -850,7 +848,7 @@ int bus_message_new_synthetic_error(
+                 const sd_bus_error *e,
+                 sd_bus_message **m) {
+ 
+-        _cleanup_(message_freep) sd_bus_message *t = NULL;
++        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
+         int r;
+ 
+         assert(bus);
diff --git a/SOURCES/0313-bus-message-introduce-two-kinds-of-references-to-bus.patch b/SOURCES/0313-bus-message-introduce-two-kinds-of-references-to-bus.patch
new file mode 100644
index 0000000..7eb554d
--- /dev/null
+++ b/SOURCES/0313-bus-message-introduce-two-kinds-of-references-to-bus.patch
@@ -0,0 +1,182 @@
+From bc2d7df4fc21e9e54413169d5aad21616314d65e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 18:18:54 +0100
+Subject: [PATCH] bus-message: introduce two kinds of references to bus
+ messages
+
+Before this commit bus messages had a single reference count: when it
+reached zero the message would be freed. This simple approach meant a
+cyclic dependency was typically seen: a message that was enqueued in a
+bus connection object would reference the bus connection object but also
+itself be referenced by the bus connection object. So far out strategy
+to avoid cases like this was: make sure to process the bus connection
+regularly so that messages don#t stay queued, and at exit flush/close
+the connection so that the message queued would be emptied, and thus the
+cyclic dependencies resolved. Im many cases this isn't done properly
+however.
+
+With this change, let's address the issue more systematically: let's
+break the reference cycle. Specifically, there are now two types of
+references to a bus message:
+
+1. A regular one, which keeps both the message and the bus object it is
+   associated with pinned.
+
+2. A "queue" reference, which is weaker: it pins the message, but not
+   the bus object it is associated with.
+
+The idea is then that regular user handling uses regular references, but
+when a message is enqueued on its connection, then this takes a "queue"
+reference instead. This then means that a queued message doesn't imply
+the connection itself remains pinned, only regular references to the
+connection or a message associated with it do. Thus, if we end up in the
+situation where a user allocates a bus and a message and enqueues the
+latter in the former and drops all refs to both, then this will detect
+this case and free both.
+
+Note that this scheme isn't perfect, it only covers references between
+messages and the busses they are associated with. If OTOH a bus message
+is enqueued on a different bus than it is associated with cyclic deps
+cannot be recognized with this simple algorithm, and thus if you enqueue
+a message associated with a bus A on a bus B, and another message
+associated with bus B on a bus A, a cyclic ref will be in effect and not
+be discovered. However, given that this is an exotic case (though one
+that happens, consider systemd-bus-stdio-bridge), it should be OK not to
+cover with this, and people have to explicit flush all queues on exit in
+that case.
+
+Note that this commit only establishes the separate reference counters
+per message. A follow-up commit will start making use of this from the
+bus connection object.
+
+(cherry picked from commit 1b3f9dd759ca0ea215e7b89f8ce66d1b724497b9)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/bus-message.c | 60 ++++++++++++++++++++++++++---
+ src/libsystemd/sd-bus/bus-message.h | 14 ++++++-
+ 2 files changed, 68 insertions(+), 6 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
+index 306b6d6816..7fe8929f82 100644
+--- a/src/libsystemd/sd-bus/bus-message.c
++++ b/src/libsystemd/sd-bus/bus-message.c
+@@ -120,7 +120,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
+ 
+         message_reset_parts(m);
+ 
+-        sd_bus_unref(m->bus);
++        /* Note that we don't unref m->bus here. That's already done by sd_bus_message_unref() as each user
++         * reference to the bus message also is considered a reference to the bus connection itself. */
+ 
+         if (m->free_fds) {
+                 close_many(m->fds, m->n_fds);
+@@ -893,27 +894,76 @@ int bus_message_new_synthetic_error(
+ }
+ 
+ _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
+-
+         if (!m)
+                 return NULL;
+ 
+-        assert(m->n_ref > 0);
++        /* We are fine if this message so far was either explicitly reffed or not reffed but queued into at
++         * least one bus connection object. */
++        assert(m->n_ref > 0 || m->n_queued > 0);
++
+         m->n_ref++;
+ 
++        /* Each user reference to a bus message shall also be considered a ref on the bus */
++        sd_bus_ref(m->bus);
+         return m;
+ }
+ 
+ _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
+-
+         if (!m)
+                 return NULL;
+ 
+         assert(m->n_ref > 0);
++
++        sd_bus_unref(m->bus); /* Each regular ref is also a ref on the bus connection. Let's hence drop it
++                               * here. Note we have to do this before decrementing our own n_ref here, since
++                               * otherwise, if this message is currently queued sd_bus_unref() might call
++                               * bus_message_unref_queued() for this which might then destroy the message
++                               * while we are still processing it. */
+         m->n_ref--;
+ 
+-        if (m->n_ref > 0)
++        if (m->n_ref > 0 || m->n_queued > 0)
+                 return NULL;
+ 
++        /* Unset the bus field if neither the user has a reference nor this message is queued. We are careful
++         * to reset the field only after the last reference to the bus is dropped, after all we might keep
++         * multiple references to the bus, once for each reference kept on outselves. */
++        m->bus = NULL;
++
++        return message_free(m);
++}
++
++sd_bus_message* bus_message_ref_queued(sd_bus_message *m, sd_bus *bus) {
++        if (!m)
++                return NULL;
++
++        /* If this is a different bus than the message is associated with, then implicitly turn this into a
++         * regular reference. This means that you can create a memory leak by enqueuing a message generated
++         * on one bus onto another at the same time as enqueueing a message from the second one on the first,
++         * as we'll not detect the cyclic references there. */
++        if (bus != m->bus)
++                return sd_bus_message_ref(m);
++
++        assert(m->n_ref > 0 || m->n_queued > 0);
++        m->n_queued++;
++
++        return m;
++}
++
++sd_bus_message* bus_message_unref_queued(sd_bus_message *m, sd_bus *bus) {
++        if (!m)
++                return NULL;
++
++        if (bus != m->bus)
++                return sd_bus_message_unref(m);
++
++        assert(m->n_queued > 0);
++        m->n_queued--;
++
++        if (m->n_ref > 0 || m->n_queued > 0)
++                return NULL;
++
++        m->bus = NULL;
++
+         return message_free(m);
+ }
+ 
+diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
+index 97f6060e30..ded88005e2 100644
+--- a/src/libsystemd/sd-bus/bus-message.h
++++ b/src/libsystemd/sd-bus/bus-message.h
+@@ -51,7 +51,16 @@ struct bus_body_part {
+ };
+ 
+ struct sd_bus_message {
+-        unsigned n_ref;
++        /* Caveat: a message can be referenced in two different ways: the main (user-facing) way will also
++         * pin the bus connection object the message is associated with. The secondary way ("queued") is used
++         * when a message is in the read or write queues of the bus connection object, which will not pin the
++         * bus connection object. This is necessary so that we don't have to have a pair of cyclic references
++         * between a message that is queued and its connection: as soon as a message is only referenced by
++         * the connection (by means of being queued) and the connection itself has no other references it
++         * will be freed. */
++
++        unsigned n_ref;     /* Counter of references that pin the connection */
++        unsigned n_queued;  /* Counter of references that do not pin the connection */
+ 
+         sd_bus *bus;
+ 
+@@ -216,3 +225,6 @@ int bus_message_append_sender(sd_bus_message *m, const char *sender);
+ 
+ void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m);
+ void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m);
++
++sd_bus_message* bus_message_ref_queued(sd_bus_message *m, sd_bus *bus);
++sd_bus_message* bus_message_unref_queued(sd_bus_message *m, sd_bus *bus);
diff --git a/SOURCES/0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch b/SOURCES/0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch
new file mode 100644
index 0000000..fdafc3d
--- /dev/null
+++ b/SOURCES/0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch
@@ -0,0 +1,74 @@
+From 8efdae75ddf035c8c04983820f8d8cf767cc17b1 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 31 Jan 2020 11:34:45 +0100
+Subject: [PATCH] sd-bus: introduce API for re-enqueuing incoming messages
+
+When authorizing via PolicyKit we want to process incoming method calls
+twice: once to process and figure out that we need PK authentication,
+and a second time after we aquired PK authentication to actually execute
+the operation. With this new call sd_bus_enqueue_for_read() we have a
+way to put an incoming message back into the read queue for this
+purpose.
+
+This might have other uses too, for example debugging.
+Related: CVE-2020-1712
+---
+ src/libsystemd/libsystemd.sym  |  1 +
+ src/libsystemd/sd-bus/sd-bus.c | 24 ++++++++++++++++++++++++
+ src/systemd/sd-bus.h           |  1 +
+ 3 files changed, 26 insertions(+)
+
+diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
+index 1eec17db50..e9972593a6 100644
+--- a/src/libsystemd/libsystemd.sym
++++ b/src/libsystemd/libsystemd.sym
+@@ -569,4 +569,5 @@ global:
+         sd_event_source_get_inotify_mask;
+         sd_event_source_set_destroy_callback;
+         sd_event_source_get_destroy_callback;
++        sd_bus_enqueue_for_read;
+ } LIBSYSTEMD_238;
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index e49d58137d..68ad6cbe89 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -4120,3 +4120,27 @@ _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) {
+         *ret = bus->wqueue_size;
+         return 0;
+ }
++
++_public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) {
++        int r;
++
++        assert_return(bus, -EINVAL);
++        assert_return(bus = bus_resolve(bus), -ENOPKG);
++        assert_return(m, -EINVAL);
++        assert_return(m->sealed, -EINVAL);
++        assert_return(!bus_pid_changed(bus), -ECHILD);
++
++        if (!BUS_IS_OPEN(bus->state))
++                return -ENOTCONN;
++
++        /* Re-enqeue a message for reading. This is primarily useful for PolicyKit-style authentication,
++         * where we want accept a message, then determine we need to interactively authenticate the user, and
++         * when we have that process the message again. */
++
++        r = bus_rqueue_make_room(bus);
++        if (r < 0)
++                return r;
++
++        bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus);
++        return 0;
++}
+diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
+index 54c4b1ca83..9ba757b13d 100644
+--- a/src/systemd/sd-bus.h
++++ b/src/systemd/sd-bus.h
+@@ -193,6 +193,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r);
+ int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r);
+ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec);
+ int sd_bus_flush(sd_bus *bus);
++int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m);
+ 
+ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus);
+ sd_bus_message* sd_bus_get_current_message(sd_bus *bus);
diff --git a/SOURCES/0315-sd-event-add-sd_event_source_disable_unref-helper.patch b/SOURCES/0315-sd-event-add-sd_event_source_disable_unref-helper.patch
new file mode 100644
index 0000000..1748190
--- /dev/null
+++ b/SOURCES/0315-sd-event-add-sd_event_source_disable_unref-helper.patch
@@ -0,0 +1,130 @@
+From 73b87f8c73af714a32e7b56b217cd4e4f46a5ea7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Wed, 8 May 2019 14:39:57 +0200
+Subject: [PATCH] sd-event: add sd_event_source_disable_unref() helper
+
+(cherry picked from commit afd15bbb4b6414b9356799c63029e36642dae8e4)
+Related: CVE-2020-1712
+---
+ man/rules/meson.build              |  4 +++-
+ man/sd_event_source_unref.xml      | 30 +++++++++++++++++++-----------
+ src/libsystemd/libsystemd.sym      |  1 +
+ src/libsystemd/sd-event/sd-event.c |  6 ++++++
+ src/systemd/sd-event.h             |  1 +
+ 5 files changed, 30 insertions(+), 12 deletions(-)
+
+diff --git a/man/rules/meson.build b/man/rules/meson.build
+index 989d11c9b9..7ae94ea265 100644
+--- a/man/rules/meson.build
++++ b/man/rules/meson.build
+@@ -340,7 +340,9 @@ manpages = [
+  ['sd_event_source_set_userdata', '3', ['sd_event_source_get_userdata'], ''],
+  ['sd_event_source_unref',
+   '3',
+-  ['sd_event_source_ref', 'sd_event_source_unrefp'],
++  ['sd_event_source_disable_unref',
++   'sd_event_source_ref',
++   'sd_event_source_unrefp'],
+   ''],
+  ['sd_event_wait',
+   '3',
+diff --git a/man/sd_event_source_unref.xml b/man/sd_event_source_unref.xml
+index d1b83c57aa..af8fed33f2 100644
+--- a/man/sd_event_source_unref.xml
++++ b/man/sd_event_source_unref.xml
+@@ -22,6 +22,7 @@
+     <refname>sd_event_source_unref</refname>
+     <refname>sd_event_source_unrefp</refname>
+     <refname>sd_event_source_ref</refname>
++    <refname>sd_event_source_disable_unref</refname>
+ 
+     <refpurpose>Increase or decrease event source reference counters</refpurpose>
+   </refnamediv>
+@@ -45,6 +46,10 @@
+         <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
+       </funcprototype>
+ 
++      <funcprototype>
++        <funcdef>sd_event_source* <function>sd_event_source_disable_unref</function></funcdef>
++        <paramdef>sd_event_source *<parameter>source</parameter></paramdef>
++      </funcprototype>
+     </funcsynopsis>
+   </refsynopsisdiv>
+ 
+@@ -80,23 +85,26 @@
+     the passed event source object is
+     <constant>NULL</constant>.</para>
+ 
+-    <para>Note that event source objects stay alive and may be
+-    dispatched as long as they have a reference counter greater than
+-    zero. In order to drop a reference of an event source and make
+-    sure the associated event source handler function is not called
+-    anymore it is recommended to combine a call of
++    <para>Note that event source objects stay alive and may be dispatched as long as they have a reference
++    counter greater than zero. In order to drop a reference of an event source and make sure the associated
++    event source handler function is not called anymore it is recommended to combine a call of
+     <function>sd_event_source_unref()</function> with a prior call to
+-    <function>sd_event_source_set_enabled()</function> with
+-    <constant>SD_EVENT_OFF</constant>.</para>
++    <function>sd_event_source_set_enabled()</function> with <constant>SD_EVENT_OFF</constant> or call
++    <function>sd_event_source_disable_unref()</function>, see below.</para>
++
++    <para><function>sd_event_source_disable_unref()</function> combines a call to
++    <function>sd_event_source_set_enabled()</function> with <constant>SD_EVENT_OFF</constant> with
++    <function>sd_event_source_unref()</function>. This ensures that the source is disabled before the local
++    reference to it is lost. The <parameter>source</parameter> parameter is allowed to be
++    <constant>NULL</constant>.</para>
+   </refsect1>
+ 
+   <refsect1>
+     <title>Return Value</title>
+ 
+-    <para><function>sd_event_source_unref()</function> always returns
+-    <constant>NULL</constant>.
+-    <function>sd_event_source_ref()</function> always returns the
+-    event source object passed in.</para>
++    <para><function>sd_event_source_unref()</function> and
++    <function>sd_event_source_disable_unref()</function> always return <constant>NULL</constant>.
++    <function>sd_event_source_ref()</function> always returns the event source object passed in.</para>
+   </refsect1>
+ 
+   <xi:include href="libsystemd-pkgconfig.xml" />
+diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
+index e9972593a6..778e88a16c 100644
+--- a/src/libsystemd/libsystemd.sym
++++ b/src/libsystemd/libsystemd.sym
+@@ -570,4 +570,5 @@ global:
+         sd_event_source_set_destroy_callback;
+         sd_event_source_get_destroy_callback;
+         sd_bus_enqueue_for_read;
++        sd_event_source_disable_unref;
+ } LIBSYSTEMD_238;
+diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
+index d53b9a7026..0d3bf5cbb6 100644
+--- a/src/libsystemd/sd-event/sd-event.c
++++ b/src/libsystemd/sd-event/sd-event.c
+@@ -580,6 +580,12 @@ _public_ sd_event* sd_event_unref(sd_event *e) {
+         return NULL;
+ }
+ 
++_public_ sd_event_source* sd_event_source_disable_unref(sd_event_source *s) {
++        if (s)
++                (void) sd_event_source_set_enabled(s, SD_EVENT_OFF);
++        return sd_event_source_unref(s);
++}
++
+ static bool event_pid_changed(sd_event *e) {
+         assert(e);
+ 
+diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
+index 7fcae4ac49..9876be01c6 100644
+--- a/src/systemd/sd-event.h
++++ b/src/systemd/sd-event.h
+@@ -113,6 +113,7 @@ int sd_event_get_iteration(sd_event *e, uint64_t *ret);
+ 
+ sd_event_source* sd_event_source_ref(sd_event_source *s);
+ sd_event_source* sd_event_source_unref(sd_event_source *s);
++sd_event_source* sd_event_source_disable_unref(sd_event_source *s);
+ 
+ sd_event *sd_event_source_get_event(sd_event_source *s);
+ void* sd_event_source_get_userdata(sd_event_source *s);
diff --git a/SOURCES/0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch b/SOURCES/0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch
new file mode 100644
index 0000000..da3d850
--- /dev/null
+++ b/SOURCES/0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch
@@ -0,0 +1,156 @@
+From 2ec3c78b1d1ba907cd888aac3cdc3a86c03cda90 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Fri, 31 Jan 2020 15:17:25 +0100
+Subject: [PATCH] polkit: when authorizing via PK let's re-resolve
+ callback/userdata instead of caching it
+
+Previously, when doing an async PK query we'd store the original
+callback/userdata pair and call it again after the PK request is
+complete. This is problematic, since PK queries might be slow and in the
+meantime the userdata might be released and re-acquired. Let's avoid
+this by always traversing through the message handlers so that we always
+re-resolve the callback and userdata pair and thus can be sure it's
+up-to-date and properly valid.
+
+Resolves: CVE-2020-1712
+---
+ src/shared/bus-util.c | 74 +++++++++++++++++++++++++++++--------------
+ 1 file changed, 50 insertions(+), 24 deletions(-)
+
+diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
+index 2d908eb45c..5ed68429be 100644
+--- a/src/shared/bus-util.c
++++ b/src/shared/bus-util.c
+@@ -319,10 +319,10 @@ int bus_test_polkit(
+ 
+ typedef struct AsyncPolkitQuery {
+         sd_bus_message *request, *reply;
+-        sd_bus_message_handler_t callback;
+-        void *userdata;
+         sd_bus_slot *slot;
++
+         Hashmap *registry;
++        sd_event_source *defer_event_source;
+ } AsyncPolkitQuery;
+ 
+ static void async_polkit_query_free(AsyncPolkitQuery *q) {
+@@ -338,9 +338,22 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
+         sd_bus_message_unref(q->request);
+         sd_bus_message_unref(q->reply);
+ 
++        sd_event_source_disable_unref(q->defer_event_source);
+         free(q);
+ }
+ 
++static int async_polkit_defer(sd_event_source *s, void *userdata) {
++        AsyncPolkitQuery *q = userdata;
++
++        assert(s);
++
++        /* This is called as idle event source after we processed the async polkit reply, hopefully after the
++         * method call we re-enqueued has been properly processed. */
++
++        async_polkit_query_free(q);
++        return 0;
++}
++
+ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+         _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+         AsyncPolkitQuery *q = userdata;
+@@ -349,19 +362,45 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e
+         assert(reply);
+         assert(q);
+ 
++        assert(q->slot);
+         q->slot = sd_bus_slot_unref(q->slot);
++
++        assert(!q->reply);
+         q->reply = sd_bus_message_ref(reply);
+ 
++        /* Now, let's dispatch the original message a second time be re-enqueing. This will then traverse the
++         * whole message processing again, and thus re-validating and re-retrieving the "userdata" field
++         * again.
++         *
++         * We install an idle event loop event to clean-up the PolicyKit request data when we are idle again,
++         * i.e. after the second time the message is processed is complete. */
++
++        assert(!q->defer_event_source);
++        r = sd_event_add_defer(sd_bus_get_event(sd_bus_message_get_bus(reply)), &q->defer_event_source, async_polkit_defer, q);
++        if (r < 0)
++                goto fail;
++
++        r = sd_event_source_set_priority(q->defer_event_source, SD_EVENT_PRIORITY_IDLE);
++        if (r < 0)
++                goto fail;
++
++        r = sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_ONESHOT);
++        if (r < 0)
++                goto fail;
++
+         r = sd_bus_message_rewind(q->request, true);
+-        if (r < 0) {
+-                r = sd_bus_reply_method_errno(q->request, r, NULL);
+-                goto finish;
+-        }
++        if (r < 0)
++                goto fail;
+ 
+-        r = q->callback(q->request, q->userdata, &error_buffer);
+-        r = bus_maybe_reply_error(q->request, r, &error_buffer);
++        r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request);
++        if (r < 0)
++                goto fail;
+ 
+-finish:
++        return 1;
++
++fail:
++        log_debug_errno(r, "Processing asynchronous PolicyKit reply failed, ignoring: %m");
++        (void) sd_bus_reply_method_errno(q->request, r, NULL);
+         async_polkit_query_free(q);
+ 
+         return r;
+@@ -382,11 +421,9 @@ int bus_verify_polkit_async(
+ #if ENABLE_POLKIT
+         _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
+         AsyncPolkitQuery *q;
+-        const char *sender, **k, **v;
+-        sd_bus_message_handler_t callback;
+-        void *userdata;
+         int c;
+ #endif
++        const char *sender, **k, **v;
+         int r;
+ 
+         assert(call);
+@@ -444,20 +481,11 @@ int bus_verify_polkit_async(
+         else if (r > 0)
+                 return 1;
+ 
+-#if ENABLE_POLKIT
+-        if (sd_bus_get_current_message(call->bus) != call)
+-                return -EINVAL;
+-
+-        callback = sd_bus_get_current_handler(call->bus);
+-        if (!callback)
+-                return -EINVAL;
+-
+-        userdata = sd_bus_get_current_userdata(call->bus);
+-
+         sender = sd_bus_message_get_sender(call);
+         if (!sender)
+                 return -EBADMSG;
+ 
++#if ENABLE_POLKIT
+         c = sd_bus_message_get_allow_interactive_authorization(call);
+         if (c < 0)
+                 return c;
+@@ -509,8 +537,6 @@ int bus_verify_polkit_async(
+                 return -ENOMEM;
+ 
+         q->request = sd_bus_message_ref(call);
+-        q->callback = callback;
+-        q->userdata = userdata;
+ 
+         r = hashmap_put(*registry, call, q);
+         if (r < 0) {
diff --git a/SOURCES/0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch b/SOURCES/0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch
new file mode 100644
index 0000000..d7523ce
--- /dev/null
+++ b/SOURCES/0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch
@@ -0,0 +1,70 @@
+From b9be2c6b48227642ba85c5a741f121cc99655904 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
+Date: Mon, 6 Jan 2020 12:30:58 +0100
+Subject: [PATCH] sysctl: let's by default increase the numeric PID range from
+ 2^16 to 2^22
+
+This should PID collisions a tiny bit less likely, and thus improve
+security and robustness.
+
+2^22 isn't particularly a lot either, but it's the current kernel
+limitation.
+
+Bumping this limit was suggested by Linus himself:
+
+https://lwn.net/ml/linux-kernel/CAHk-=wiZ40LVjnXSi9iHLE_-ZBsWFGCgdmNiYZUXn1-V5YBg2g@mail.gmail.com/
+
+Let's experiment with this in systemd upstream first. Downstreams and
+users can after all still comment this easily.
+
+Besides compat concern the most often heard issue with such high PIDs is
+usability, since they are potentially hard to type. I am not entirely sure though
+whether 4194304 (as largest new PID) is that much worse to type or to
+copy than 65563.
+
+This should also simplify management of per system tasks limits as by
+this move the sysctl /proc/sys/kernel/threads-max becomes the primary
+knob to control how many processes to have in parallel.
+
+Resolves: #1744214
+---
+ sysctl.d/50-pid-max.conf | 17 +++++++++++++++++
+ sysctl.d/meson.build     |  1 +
+ 2 files changed, 18 insertions(+)
+ create mode 100644 sysctl.d/50-pid-max.conf
+
+diff --git a/sysctl.d/50-pid-max.conf b/sysctl.d/50-pid-max.conf
+new file mode 100644
+index 0000000000..3a8393d185
+--- /dev/null
++++ b/sysctl.d/50-pid-max.conf
+@@ -0,0 +1,17 @@
++#  This file is part of systemd.
++#
++#  systemd is free software; you can redistribute it and/or modify it
++#  under the terms of the GNU Lesser General Public License as published by
++#  the Free Software Foundation; either version 2.1 of the License, or
++#  (at your option) any later version.
++
++# See sysctl.d(5) and core(5) for documentation.
++
++# To override settings in this file, create a local file in /etc
++# (e.g. /etc/sysctl.d/90-override.conf), and put any assignments
++# there.
++
++# Bump the numeric PID range to its maximum of 2^22 (from the in-kernel default
++# of 2^16), to make PID collisions less likely.
++kernel.pid_max = 4194304
++
+diff --git a/sysctl.d/meson.build b/sysctl.d/meson.build
+index 64f6ce942e..a95957ad7d 100644
+--- a/sysctl.d/meson.build
++++ b/sysctl.d/meson.build
+@@ -2,6 +2,7 @@
+ 
+ install_data(
+         '50-default.conf',
++        '50-pid-max.conf',
+         install_dir : sysctldir)
+ 
+ in_files = []
diff --git a/SOURCES/0318-journal-do-not-trigger-assertion-when-journal_file_c.patch b/SOURCES/0318-journal-do-not-trigger-assertion-when-journal_file_c.patch
new file mode 100644
index 0000000..9ebc71d
--- /dev/null
+++ b/SOURCES/0318-journal-do-not-trigger-assertion-when-journal_file_c.patch
@@ -0,0 +1,49 @@
+From dc4c3a5aa35a5e88adcf210471d9460262c8c0d9 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Tue, 28 May 2019 12:40:17 +0900
+Subject: [PATCH] journal: do not trigger assertion when journal_file_close()
+ get NULL
+
+We generally expect destructors to not complain if a NULL argument is passed.
+
+Closes #12400.
+
+(cherry picked from commit c377a6f3ad3d9bed4ce7e873e8e9ec6b1650c57d)
+Resolves: #1788085
+---
+ src/journal/journal-file.c    | 3 ++-
+ src/journal/journald-server.c | 7 ++-----
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
+index efc3ee052b..8249b11b23 100644
+--- a/src/journal/journal-file.c
++++ b/src/journal/journal-file.c
+@@ -335,7 +335,8 @@ bool journal_file_is_offlining(JournalFile *f) {
+ }
+ 
+ JournalFile* journal_file_close(JournalFile *f) {
+-        assert(f);
++        if (!f)
++                return NULL;
+ 
+ #if HAVE_GCRYPT
+         /* Write the final tag */
+diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
+index 6aecb67d6c..6250eab831 100644
+--- a/src/journal/journald-server.c
++++ b/src/journal/journald-server.c
+@@ -1906,11 +1906,8 @@ void server_done(Server *s) {
+ 
+         client_context_flush_all(s);
+ 
+-        if (s->system_journal)
+-                (void) journal_file_close(s->system_journal);
+-
+-        if (s->runtime_journal)
+-                (void) journal_file_close(s->runtime_journal);
++        (void) journal_file_close(s->system_journal);
++        (void) journal_file_close(s->runtime_journal);
+ 
+         ordered_hashmap_free_with_destructor(s->user_journals, journal_file_close);
+ 
diff --git a/SOURCES/0319-journal-use-cleanup-attribute-at-one-more-place.patch b/SOURCES/0319-journal-use-cleanup-attribute-at-one-more-place.patch
new file mode 100644
index 0000000..9ca0d60
--- /dev/null
+++ b/SOURCES/0319-journal-use-cleanup-attribute-at-one-more-place.patch
@@ -0,0 +1,58 @@
+From ceacf935ac9f59bc08b5901f70f227958a2bcf52 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Tue, 28 May 2019 18:07:01 +0900
+Subject: [PATCH] journal: use cleanup attribute at one more place
+
+(cherry picked from commit 627df1dc42b68a74b0882b06366d1185b1a34332)
+
+Conflicts:
+	src/journal/journald-server.c
+
+Related: #1788085
+---
+ src/journal/journal-file.h    | 1 +
+ src/journal/journald-server.c | 9 ++++-----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
+index cd8a48a364..6a44fd39d2 100644
+--- a/src/journal/journal-file.h
++++ b/src/journal/journal-file.h
+@@ -144,6 +144,7 @@ int journal_file_open(
+ int journal_file_set_offline(JournalFile *f, bool wait);
+ bool journal_file_is_offlining(JournalFile *f);
+ JournalFile* journal_file_close(JournalFile *j);
++DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close);
+ 
+ int journal_file_open_reliably(
+                 const char *fname,
+diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
+index 6250eab831..7632e2d9d0 100644
+--- a/src/journal/journald-server.c
++++ b/src/journal/journald-server.c
+@@ -253,8 +253,9 @@ static int open_journal(
+                 bool seal,
+                 JournalMetrics *metrics,
+                 JournalFile **ret) {
++
++        _cleanup_(journal_file_closep) JournalFile *f = NULL;
+         int r;
+-        JournalFile *f;
+ 
+         assert(s);
+         assert(fname);
+@@ -271,12 +272,10 @@ static int open_journal(
+                 return r;
+ 
+         r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
+-        if (r < 0) {
+-                (void) journal_file_close(f);
++        if (r < 0)
+                 return r;
+-        }
+ 
+-        *ret = f;
++        *ret = TAKE_PTR(f);
+         return r;
+ }
+ 
diff --git a/SOURCES/0320-sd-bus-use-queue-message-references-for-managing-r-w.patch b/SOURCES/0320-sd-bus-use-queue-message-references-for-managing-r-w.patch
new file mode 100644
index 0000000..f8ff1d5
--- /dev/null
+++ b/SOURCES/0320-sd-bus-use-queue-message-references-for-managing-r-w.patch
@@ -0,0 +1,183 @@
+From 781a055c17400e953bb7929434fe7a2e6517d5e8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 17 Jan 2019 18:31:59 +0100
+Subject: [PATCH] sd-bus: use "queue" message references for managing r/w
+ message queues in connection objects
+
+Let's make use of the new concept the previous commit added.
+
+See: #4846
+(cherry picked from commit c1757a70eac0382c4837a3833d683919f6a48ed7)
+Related: CVE-2020-1712
+---
+ src/libsystemd/sd-bus/bus-socket.c |  6 ++-
+ src/libsystemd/sd-bus/sd-bus.c     | 60 ++++++++++++++----------------
+ 2 files changed, 32 insertions(+), 34 deletions(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
+index 17cfa8e1fd..4a72795d2b 100644
+--- a/src/libsystemd/sd-bus/bus-socket.c
++++ b/src/libsystemd/sd-bus/bus-socket.c
+@@ -1116,8 +1116,10 @@ static int bus_socket_make_message(sd_bus *bus, size_t size) {
+         bus->fds = NULL;
+         bus->n_fds = 0;
+ 
+-        if (t)
+-                bus->rqueue[bus->rqueue_size++] = t;
++        if (t) {
++                bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(t, bus);
++                sd_bus_message_unref(t);
++        }
+ 
+         return 1;
+ }
+diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
+index 68ad6cbe89..a3509f7e89 100644
+--- a/src/libsystemd/sd-bus/sd-bus.c
++++ b/src/libsystemd/sd-bus/sd-bus.c
+@@ -148,13 +148,13 @@ static void bus_reset_queues(sd_bus *b) {
+         assert(b);
+ 
+         while (b->rqueue_size > 0)
+-                sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
++                bus_message_unref_queued(b->rqueue[--b->rqueue_size], b);
+ 
+         b->rqueue = mfree(b->rqueue);
+         b->rqueue_allocated = 0;
+ 
+         while (b->wqueue_size > 0)
+-                sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
++                bus_message_unref_queued(b->wqueue[--b->wqueue_size], b);
+ 
+         b->wqueue = mfree(b->wqueue);
+         b->wqueue_allocated = 0;
+@@ -493,7 +493,7 @@ static int synthesize_connected_signal(sd_bus *bus) {
+ 
+         /* Insert at the very front */
+         memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size);
+-        bus->rqueue[0] = TAKE_PTR(m);
++        bus->rqueue[0] = bus_message_ref_queued(m, bus);
+         bus->rqueue_size++;
+ 
+         return 0;
+@@ -1760,7 +1760,7 @@ static int dispatch_wqueue(sd_bus *bus) {
+                          * anyway. */
+ 
+                         bus->wqueue_size--;
+-                        sd_bus_message_unref(bus->wqueue[0]);
++                        bus_message_unref_queued(bus->wqueue[0], bus);
+                         memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
+                         bus->windex = 0;
+ 
+@@ -1789,6 +1789,15 @@ int bus_rqueue_make_room(sd_bus *bus) {
+         return 0;
+ }
+ 
++static void rqueue_drop_one(sd_bus *bus, size_t i) {
++        assert(bus);
++        assert(i < bus->rqueue_size);
++
++        bus_message_unref_queued(bus->rqueue[i], bus);
++        memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
++        bus->rqueue_size--;
++}
++
+ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
+         int r, ret = 0;
+ 
+@@ -1803,10 +1812,8 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd
+         for (;;) {
+                 if (bus->rqueue_size > 0) {
+                         /* Dispatch a queued message */
+-
+-                        *m = bus->rqueue[0];
+-                        bus->rqueue_size--;
+-                        memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
++                        *m = sd_bus_message_ref(bus->rqueue[0]);
++                        rqueue_drop_one(bus, 0);
+                         return 1;
+                 }
+ 
+@@ -1884,7 +1891,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
+                          * of the wqueue array is always allocated so
+                          * that we always can remember how much was
+                          * written. */
+-                        bus->wqueue[0] = sd_bus_message_ref(m);
++                        bus->wqueue[0] = bus_message_ref_queued(m, bus);
+                         bus->wqueue_size = 1;
+                         bus->windex = idx;
+                 }
+@@ -1898,7 +1905,7 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
+                 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
+                         return -ENOMEM;
+ 
+-                bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
++                bus->wqueue[bus->wqueue_size++] = bus_message_ref_queued(m, bus);
+         }
+ 
+ finish:
+@@ -2124,37 +2131,30 @@ _public_ int sd_bus_call(
+                 usec_t left;
+ 
+                 while (i < bus->rqueue_size) {
+-                        sd_bus_message *incoming = NULL;
++                        _cleanup_(sd_bus_message_unrefp) sd_bus_message *incoming = NULL;
+ 
+-                        incoming = bus->rqueue[i];
++                        incoming = sd_bus_message_ref(bus->rqueue[i]);
+ 
+                         if (incoming->reply_cookie == cookie) {
+                                 /* Found a match! */
+ 
+-                                memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
+-                                bus->rqueue_size--;
++                                rqueue_drop_one(bus, i);
+                                 log_debug_bus_message(incoming);
+ 
+                                 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
+ 
+                                         if (incoming->n_fds <= 0 || bus->accept_fd) {
+                                                 if (reply)
+-                                                        *reply = incoming;
+-                                                else
+-                                                        sd_bus_message_unref(incoming);
++                                                        *reply = TAKE_PTR(incoming);
+ 
+                                                 return 1;
+                                         }
+ 
+-                                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
+-                                        sd_bus_message_unref(incoming);
+-                                        return r;
++                                        return sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
+ 
+-                                } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
+-                                        r = sd_bus_error_copy(error, &incoming->error);
+-                                        sd_bus_message_unref(incoming);
+-                                        return r;
+-                                } else {
++                                } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
++                                        return sd_bus_error_copy(error, &incoming->error);
++                                else {
+                                         r = -EIO;
+                                         goto fail;
+                                 }
+@@ -2164,15 +2164,11 @@ _public_ int sd_bus_call(
+                                    incoming->sender &&
+                                    streq(bus->unique_name, incoming->sender)) {
+ 
+-                                memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
+-                                bus->rqueue_size--;
++                                rqueue_drop_one(bus, i);
+ 
+-                                /* Our own message? Somebody is trying
+-                                 * to send its own client a message,
+-                                 * let's not dead-lock, let's fail
+-                                 * immediately. */
++                                /* Our own message? Somebody is trying to send its own client a message,
++                                 * let's not dead-lock, let's fail immediately. */
+ 
+-                                sd_bus_message_unref(incoming);
+                                 r = -ELOOP;
+                                 goto fail;
+                         }
diff --git a/SOURCES/0321-pid1-make-sure-to-restore-correct-default-values-for.patch b/SOURCES/0321-pid1-make-sure-to-restore-correct-default-values-for.patch
new file mode 100644
index 0000000..2ca5b14
--- /dev/null
+++ b/SOURCES/0321-pid1-make-sure-to-restore-correct-default-values-for.patch
@@ -0,0 +1,261 @@
+From 77a273e02c1c811485d13ddca0f844512aed2cff Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Wed, 12 Feb 2020 12:58:54 +0100
+Subject: [PATCH] pid1: make sure to restore correct default values for some
+ rlimits
+
+Commit fb39af4ce42d7ef9af63009f271f404038703704 forgot to restore the default
+rlimit values (RLIMIT_NOFILE and RLIMIT_MEMLOCK) while PID1 is reloading.
+
+This patch extracts the code in charge of initializing the default values for
+those rlimits in order to create dedicated functions, which take care of their
+initialization.
+
+These functions are then called in parse_configuration() so we make sure that
+the default values for these rlimits get restored every time PID1 is reloading
+its configuration.
+
+(cherry picked from commit a9fd4cd1206832a61aaf61fff583bb133e6cb965)
+Resolves: #1789930
+---
+ src/core/main.c | 135 +++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 106 insertions(+), 29 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index c83249a8dc..b8c1e567ad 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -136,7 +136,8 @@ static EmergencyAction arg_cad_burst_action;
+ static CPUSet arg_cpu_affinity;
+ static NUMAPolicy arg_numa_policy;
+ 
+-static int parse_configuration(void);
++static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
++                               const struct rlimit *saved_rlimit_memlock);
+ 
+ _noreturn_ static void freeze_or_reboot(void) {
+ 
+@@ -1149,25 +1150,6 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
+ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
+         int r, nr;
+ 
+-        assert(saved_rlimit);
+-
+-        /* Save the original RLIMIT_NOFILE so that we can reset it
+-         * later when transitioning from the initrd to the main
+-         * systemd or suchlike. */
+-        if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0)
+-                return log_warning_errno(errno, "Reading RLIMIT_NOFILE failed, ignoring: %m");
+-
+-        /* Make sure forked processes get the default kernel setting */
+-        if (!arg_default_rlimit[RLIMIT_NOFILE]) {
+-                struct rlimit *rl;
+-
+-                rl = newdup(struct rlimit, saved_rlimit, 1);
+-                if (!rl)
+-                        return log_oom();
+-
+-                arg_default_rlimit[RLIMIT_NOFILE] = rl;
+-        }
+-
+         /* Bump up the resource limit for ourselves substantially, all the way to the maximum the kernel allows */
+         nr = read_nr_open();
+         r = setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(nr));
+@@ -1180,16 +1162,12 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
+ static int bump_rlimit_memlock(struct rlimit *saved_rlimit) {
+         int r;
+ 
+-        assert(saved_rlimit);
+         assert(getuid() == 0);
+ 
+         /* BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK, even though we have CAP_IPC_LOCK which
+          * should normally disable such checks. We need them to implement IPAccessAllow= and IPAccessDeny=, hence let's
+          * bump the value high enough for the root user. */
+ 
+-        if (getrlimit(RLIMIT_MEMLOCK, saved_rlimit) < 0)
+-                return log_warning_errno(errno, "Reading RLIMIT_MEMLOCK failed, ignoring: %m");
+-
+         r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(1024ULL*1024ULL*16ULL));
+         if (r < 0)
+                 return log_warning_errno(r, "Setting RLIMIT_MEMLOCK failed, ignoring: %m");
+@@ -1651,6 +1629,8 @@ static void do_reexecute(
+ 
+ static int invoke_main_loop(
+                 Manager *m,
++                const struct rlimit *saved_rlimit_nofile,
++                const struct rlimit *saved_rlimit_memlock,
+                 bool *ret_reexecute,
+                 int *ret_retval,                   /* Return parameters relevant for shutting down */
+                 const char **ret_shutdown_verb,    /* … */
+@@ -1662,6 +1642,8 @@ static int invoke_main_loop(
+         int r;
+ 
+         assert(m);
++        assert(saved_rlimit_nofile);
++        assert(saved_rlimit_memlock);
+         assert(ret_reexecute);
+         assert(ret_retval);
+         assert(ret_shutdown_verb);
+@@ -1691,7 +1673,7 @@ static int invoke_main_loop(
+                         saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
+                         saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
+ 
+-                        (void) parse_configuration();
++                        (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
+ 
+                         set_manager_defaults(m);
+ 
+@@ -1983,6 +1965,80 @@ static int do_queue_default_job(
+         return 0;
+ }
+ 
++static void save_rlimits(struct rlimit *saved_rlimit_nofile,
++                         struct rlimit *saved_rlimit_memlock) {
++
++        assert(saved_rlimit_nofile);
++        assert(saved_rlimit_memlock);
++
++        if (getrlimit(RLIMIT_NOFILE, saved_rlimit_nofile) < 0)
++                log_warning_errno(errno, "Reading RLIMIT_NOFILE failed, ignoring: %m");
++
++        if (getrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock) < 0)
++                log_warning_errno(errno, "Reading RLIMIT_MEMLOCK failed, ignoring: %m");
++}
++
++static void fallback_rlimit_nofile(const struct rlimit *saved_rlimit_nofile) {
++        struct rlimit *rl;
++
++        if (arg_default_rlimit[RLIMIT_NOFILE])
++                return;
++
++        /* Make sure forked processes get limits based on the original kernel setting */
++
++        rl = newdup(struct rlimit, saved_rlimit_nofile, 1);
++        if (!rl) {
++                log_oom();
++                return;
++        }
++
++        /* Bump the hard limit for system services to a substantially higher value. The default
++         * hard limit current kernels set is pretty low (4K), mostly for historical
++         * reasons. According to kernel developers, the fd handling in recent kernels has been
++         * optimized substantially enough, so that we can bump the limit now, without paying too
++         * high a price in memory or performance. Note however that we only bump the hard limit,
++         * not the soft limit. That's because select() works the way it works, and chokes on fds
++         * >= 1024. If we'd bump the soft limit globally, it might accidentally happen to
++         * unexpecting programs that they get fds higher than what they can process using
++         * select(). By only bumping the hard limit but leaving the low limit as it is we avoid
++         * this pitfall:  programs that are written by folks aware of the select() problem in mind
++         * (and thus use poll()/epoll instead of select(), the way everybody should) can
++         * explicitly opt into high fds by bumping their soft limit beyond 1024, to the hard limit
++         * we pass. */
++        if (arg_system) {
++                int nr;
++
++                /* Get the underlying absolute limit the kernel enforces */
++                nr = read_nr_open();
++
++                rl->rlim_max = MIN((rlim_t) nr, MAX(rl->rlim_max, (rlim_t) HIGH_RLIMIT_NOFILE));
++        }
++
++        /* If for some reason we were invoked with a soft limit above 1024 (which should never
++         * happen!, but who knows what we get passed in from pam_limit when invoked as --user
++         * instance), then lower what we pass on to not confuse our children */
++        rl->rlim_cur = MIN(rl->rlim_cur, (rlim_t) FD_SETSIZE);
++
++        arg_default_rlimit[RLIMIT_NOFILE] = rl;
++}
++
++static void fallback_rlimit_memlock(const struct rlimit *saved_rlimit_memlock) {
++        struct rlimit *rl;
++
++        /* Pass the original value down to invoked processes */
++
++        if (arg_default_rlimit[RLIMIT_MEMLOCK])
++                return;
++
++        rl = newdup(struct rlimit, saved_rlimit_memlock, 1);
++        if (!rl) {
++                log_oom();
++                return;
++        }
++
++        arg_default_rlimit[RLIMIT_MEMLOCK] = rl;
++}
++
+ static void reset_arguments(void) {
+         /* Frees/resets arg_* variables, with a few exceptions commented below. */
+ 
+@@ -2040,9 +2096,13 @@ static void reset_arguments(void) {
+         numa_policy_reset(&arg_numa_policy);
+ }
+ 
+-static int parse_configuration(void) {
++static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
++                               const struct rlimit *saved_rlimit_memlock) {
+         int r;
+ 
++        assert(saved_rlimit_nofile);
++        assert(saved_rlimit_memlock);
++
+         arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+ 
+         /* Assign configuration defaults */
+@@ -2058,18 +2118,29 @@ static int parse_configuration(void) {
+                         log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
+         }
+ 
++        /* Initialize some default rlimits for services if they haven't been configured */
++        fallback_rlimit_nofile(saved_rlimit_nofile);
++        fallback_rlimit_memlock(saved_rlimit_memlock);
++
+         /* Note that this also parses bits from the kernel command line, including "debug". */
+         log_parse_environment();
+ 
+         return 0;
+ }
+ 
+-static int load_configuration(int argc, char **argv, const char **ret_error_message) {
++static int load_configuration(
++                int argc,
++                char **argv,
++                const struct rlimit *saved_rlimit_nofile,
++                const struct rlimit *saved_rlimit_memlock,
++                const char **ret_error_message) {
+         int r;
+ 
++        assert(saved_rlimit_nofile);
++        assert(saved_rlimit_memlock);
+         assert(ret_error_message);
+ 
+-        (void) parse_configuration();
++        (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
+ 
+         r = parse_argv(argc, argv);
+         if (r < 0) {
+@@ -2403,11 +2474,15 @@ int main(int argc, char *argv[]) {
+                 }
+         }
+ 
++        /* Save the original RLIMIT_NOFILE/RLIMIT_MEMLOCK so that we can reset it later when
++         * transitioning from the initrd to the main systemd or suchlike. */
++        save_rlimits(&saved_rlimit_nofile, &saved_rlimit_memlock);
++
+         /* Reset all signal handlers. */
+         (void) reset_all_signal_handlers();
+         (void) ignore_signals(SIGNALS_IGNORE, -1);
+ 
+-        r = load_configuration(argc, argv, &error_message);
++        r = load_configuration(argc, argv, &saved_rlimit_nofile, &saved_rlimit_memlock, &error_message);
+         if (r < 0)
+                 goto finish;
+ 
+@@ -2522,6 +2597,8 @@ int main(int argc, char *argv[]) {
+         }
+ 
+         (void) invoke_main_loop(m,
++                                &saved_rlimit_nofile,
++                                &saved_rlimit_memlock,
+                                 &reexecute,
+                                 &retval,
+                                 &shutdown_verb,
diff --git a/SOURCES/0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch b/SOURCES/0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch
new file mode 100644
index 0000000..72ec11c
--- /dev/null
+++ b/SOURCES/0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch
@@ -0,0 +1,37 @@
+From 0528a880ddf797a42b2de274e5c7bd2d9896c991 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Thu, 11 Oct 2018 18:31:11 +0200
+Subject: [PATCH] main: introduce a define HIGH_RLIMIT_MEMLOCK similar to
+ HIGH_RLIMIT_NOFILE
+
+(cherry picked from commit c8884aceefc85245b9bdfb626e2daf27521259bd)
+Related: #1789930
+---
+ src/basic/def.h | 3 +++
+ src/core/main.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/basic/def.h b/src/basic/def.h
+index 4d515c11b6..65ad659999 100644
+--- a/src/basic/def.h
++++ b/src/basic/def.h
+@@ -75,3 +75,6 @@
+                 _CONF_PATHS_SPLIT_USR(n))
+ 
+ #define LONG_LINE_MAX (1U*1024U*1024U)
++
++#define HIGH_RLIMIT_NOFILE (256*1024)
++#define HIGH_RLIMIT_MEMLOCK (1024ULL*1024ULL*64ULL)
+diff --git a/src/core/main.c b/src/core/main.c
+index b8c1e567ad..d6550ea161 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1168,7 +1168,7 @@ static int bump_rlimit_memlock(struct rlimit *saved_rlimit) {
+          * should normally disable such checks. We need them to implement IPAccessAllow= and IPAccessDeny=, hence let's
+          * bump the value high enough for the root user. */
+ 
+-        r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(1024ULL*1024ULL*16ULL));
++        r = setrlimit_closest(RLIMIT_MEMLOCK, &RLIMIT_MAKE_CONST(HIGH_RLIMIT_MEMLOCK));
+         if (r < 0)
+                 return log_warning_errno(r, "Setting RLIMIT_MEMLOCK failed, ignoring: %m");
+ 
diff --git a/SOURCES/0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch b/SOURCES/0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch
new file mode 100644
index 0000000..d63169b
--- /dev/null
+++ b/SOURCES/0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch
@@ -0,0 +1,178 @@
+From 5a62c0daff82e8343d24f98e1761d27bf8015782 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 20 Mar 2019 19:00:28 +0100
+Subject: [PATCH] seccomp: introduce seccomp_restrict_suid_sgid() for blocking
+ chmod() for suid/sgid files
+
+(cherry picked from commit 3c27973b13724ede05a06a5d346a569794cda433)
+Related: #1687512
+---
+ src/shared/seccomp-util.c | 132 ++++++++++++++++++++++++++++++++++++++
+ src/shared/seccomp-util.h |   1 +
+ 2 files changed, 133 insertions(+)
+
+diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
+index 92910acf0e..fd46b9f88d 100644
+--- a/src/shared/seccomp-util.c
++++ b/src/shared/seccomp-util.c
+@@ -1,12 +1,14 @@
+ /* SPDX-License-Identifier: LGPL-2.1+ */
+ 
+ #include <errno.h>
++#include <fcntl.h>
+ #include <linux/seccomp.h>
+ #include <seccomp.h>
+ #include <stddef.h>
+ #include <sys/mman.h>
+ #include <sys/prctl.h>
+ #include <sys/shm.h>
++#include <sys/stat.h>
+ 
+ #include "af-list.h"
+ #include "alloc-util.h"
+@@ -1747,3 +1749,133 @@ int seccomp_lock_personality(unsigned long personality) {
+ 
+         return 0;
+ }
++
++int seccomp_restrict_suid_sgid(void) {
++        uint32_t arch;
++        int r;
++
++        SECCOMP_FOREACH_LOCAL_ARCH(arch) {
++                _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
++
++                r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
++                if (r < 0)
++                        return r;
++
++                /* Checks the mode_t parameter of the following system calls:
++                 *
++                 *       → chmod() + fchmod() + fchmodat()
++                 *       → open() + creat() + openat()
++                 *       → mkdir() + mkdirat()
++                 *       → mknod() + mknodat()
++                 */
++
++                for (unsigned bit = 0; bit < 2; bit ++) {
++                        /* Block S_ISUID in the first iteration, S_ISGID in the second */
++                        mode_t m = bit == 0 ? S_ISUID : S_ISGID;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(chmod),
++                                        1,
++                                        SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(fchmod),
++                                        1,
++                                        SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(fchmodat),
++                                        1,
++                                        SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(mkdir),
++                                        1,
++                                        SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(mkdirat),
++                                        1,
++                                        SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(mknod),
++                                        1,
++                                        SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(mknodat),
++                                        1,
++                                        SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(open),
++                                        2,
++                                        SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT),
++                                        SCMP_A2(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(openat),
++                                        2,
++                                        SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT),
++                                        SCMP_A3(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++
++                        r = seccomp_rule_add_exact(
++                                        seccomp,
++                                        SCMP_ACT_ERRNO(EPERM),
++                                        SCMP_SYS(creat),
++                                        1,
++                                        SCMP_A1(SCMP_CMP_MASKED_EQ, m, m));
++                        if (r < 0)
++                                break;
++                }
++                if (r < 0) {
++                        log_debug_errno(r, "Failed to add suid/sgid rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
++                        continue;
++                }
++
++                r = seccomp_load(seccomp);
++                if (IN_SET(r, -EPERM, -EACCES))
++                        return r;
++                if (r < 0)
++                        log_debug_errno(r, "Failed to apply suid/sgid restrictions for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
++        }
++
++        return 0;
++}
+diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
+index d8a36c4e21..602f092255 100644
+--- a/src/shared/seccomp-util.h
++++ b/src/shared/seccomp-util.h
+@@ -85,6 +85,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist);
+ int seccomp_restrict_realtime(void);
+ int seccomp_memory_deny_write_execute(void);
+ int seccomp_lock_personality(unsigned long personality);
++int seccomp_restrict_suid_sgid(void);
+ 
+ extern const uint32_t seccomp_local_archs[];
+ 
diff --git a/SOURCES/0324-test-add-test-case-for-restrict_suid_sgid.patch b/SOURCES/0324-test-add-test-case-for-restrict_suid_sgid.patch
new file mode 100644
index 0000000..c04084f
--- /dev/null
+++ b/SOURCES/0324-test-add-test-case-for-restrict_suid_sgid.patch
@@ -0,0 +1,265 @@
+From b39697a80ad388e2063c54e56333882f4307c1a1 Mon Sep 17 00:00:00 2001
+From: Jan Synacek <jsynacek@redhat.com>
+Date: Tue, 12 Nov 2019 13:27:49 +0100
+Subject: [PATCH] test: add test case for restrict_suid_sgid()
+
+(cherry picked from commit 167fc10cb352b04d442c9010dab4f8dc24219749)
+Related: #1687512
+---
+ src/test/test-seccomp.c | 226 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 226 insertions(+)
+
+diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
+index d177515ac7..4021a06e0e 100644
+--- a/src/test/test-seccomp.c
++++ b/src/test/test-seccomp.c
+@@ -17,9 +17,11 @@
+ #include "nsflags.h"
+ #include "process-util.h"
+ #include "raw-clone.h"
++#include "rm-rf.h"
+ #include "seccomp-util.h"
+ #include "set.h"
+ #include "string-util.h"
++#include "umask-util.h"
+ #include "util.h"
+ #include "virt.h"
+ 
+@@ -666,6 +668,229 @@ static void test_filter_sets_ordered(void) {
+         }
+ }
+ 
++static int mkostemp_safe(char *pattern) {
++        _unused_ _cleanup_umask_ mode_t u = umask(0077);
++        int fd;
++
++        assert(pattern);
++
++        fd = mkostemp(pattern, O_CLOEXEC);
++        if (fd < 0)
++                return -errno;
++
++        return fd;
++}
++
++static int real_open(const char *path, int flags, mode_t mode) {
++        /* glibc internally calls openat() when open() is requested. Let's hence define our own wrapper for
++         * testing purposes that calls the real syscall, on architectures where SYS_open is defined. On
++         * other architectures, let's just fall back to the glibc call. */
++
++#ifdef SYS_open
++        return (int) syscall(SYS_open, path, flags, mode);
++#else
++        return open(path, flags, mode);
++#endif
++}
++
++static void test_restrict_suid_sgid(void) {
++        pid_t pid;
++
++        log_info("/* %s */", __func__);
++
++        if (!is_seccomp_available()) {
++                log_notice("Seccomp not available, skipping %s", __func__);
++                return;
++        }
++        if (geteuid() != 0) {
++                log_notice("Not root, skipping %s", __func__);
++                return;
++        }
++
++        pid = fork();
++        assert_se(pid >= 0);
++
++        if (pid == 0) {
++                char path[] = "/tmp/suidsgidXXXXXX", dir[] = "/tmp/suidsgiddirXXXXXX";
++                int fd = -1, k = -1;
++                const char *z;
++
++                fd = mkostemp_safe(path);
++                assert_se(fd >= 0);
++
++                assert_se(mkdtemp(dir));
++                z = strjoina(dir, "/test");
++
++                assert_se(chmod(path, 0755 | S_ISUID) >= 0);
++                assert_se(chmod(path, 0755 | S_ISGID) >= 0);
++                assert_se(chmod(path, 0755 | S_ISGID | S_ISUID) >= 0);
++                assert_se(chmod(path, 0755) >= 0);
++
++                assert_se(fchmod(fd, 0755 | S_ISUID) >= 0);
++                assert_se(fchmod(fd, 0755 | S_ISGID) >= 0);
++                assert_se(fchmod(fd, 0755 | S_ISGID | S_ISUID) >= 0);
++                assert_se(fchmod(fd, 0755) >= 0);
++
++                assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0);
++                assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0);
++                assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0);
++                assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0);
++
++                k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = creat(z, 0644 | S_ISUID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = creat(z, 0644 | S_ISGID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = creat(z, 0644 | S_ISUID | S_ISGID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = creat(z, 0644);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(mkdir(z, 0755 | S_ISUID) >= 0);
++                assert_se(rmdir(z) >= 0);
++                assert_se(mkdir(z, 0755 | S_ISGID) >= 0);
++                assert_se(rmdir(z) >= 0);
++                assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) >= 0);
++                assert_se(rmdir(z) >= 0);
++                assert_se(mkdir(z, 0755) >= 0);
++                assert_se(rmdir(z) >= 0);
++
++                assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) >= 0);
++                assert_se(rmdir(z) >= 0);
++                assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) >= 0);
++                assert_se(rmdir(z) >= 0);
++                assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) >= 0);
++                assert_se(rmdir(z) >= 0);
++                assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0);
++                assert_se(rmdir(z) >= 0);
++
++                assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++                assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++                assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++                assert_se(mknod(z, S_IFREG | 0755, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(seccomp_restrict_suid_sgid() >= 0);
++
++                assert_se(chmod(path, 0775 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(chmod(path, 0775 | S_ISGID) < 0  && errno == EPERM);
++                assert_se(chmod(path, 0775 | S_ISGID | S_ISUID) < 0  && errno == EPERM);
++                assert_se(chmod(path, 0775) >= 0);
++
++                assert_se(fchmod(fd, 0775 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(fchmod(fd, 0775 | S_ISGID) < 0  && errno == EPERM);
++                assert_se(fchmod(fd, 0775 | S_ISGID | S_ISUID) < 0  && errno == EPERM);
++                assert_se(fchmod(fd, 0775) >= 0);
++
++                assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM);
++                assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM);
++                assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM);
++                assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0);
++
++                assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM);
++                assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
++                k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(creat(z, 0644 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(creat(z, 0644 | S_ISGID) < 0 && errno == EPERM);
++                assert_se(creat(z, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
++                k = creat(z, 0644);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM);
++                assert_se(openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
++                k = openat(AT_FDCWD, z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644);
++                k = safe_close(k);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(mkdir(z, 0755 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(mkdir(z, 0755 | S_ISGID) < 0 && errno == EPERM);
++                assert_se(mkdir(z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
++                assert_se(mkdir(z, 0755) >= 0);
++                assert_se(rmdir(z) >= 0);
++
++                assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID) < 0 && errno == EPERM);
++                assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISGID) < 0 && errno == EPERM);
++                assert_se(mkdirat(AT_FDCWD, z, 0755 | S_ISUID | S_ISGID) < 0 && errno == EPERM);
++                assert_se(mkdirat(AT_FDCWD, z, 0755) >= 0);
++                assert_se(rmdir(z) >= 0);
++
++                assert_se(mknod(z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM);
++                assert_se(mknod(z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM);
++                assert_se(mknod(z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM);
++                assert_se(mknod(z, S_IFREG | 0755, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID, 0) < 0 && errno == EPERM);
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISGID, 0) < 0 && errno == EPERM);
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755 | S_ISUID | S_ISGID, 0) < 0 && errno == EPERM);
++                assert_se(mknodat(AT_FDCWD, z, S_IFREG | 0755, 0) >= 0);
++                assert_se(unlink(z) >= 0);
++
++                assert_se(unlink(path) >= 0);
++                assert_se(rm_rf(dir, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
++
++                _exit(EXIT_SUCCESS);
++        }
++
++        assert_se(wait_for_terminate_and_check("suidsgidseccomp", pid, WAIT_LOG) == EXIT_SUCCESS);
++}
++
+ int main(int argc, char *argv[]) {
+ 
+         log_set_max_level(LOG_DEBUG);
+@@ -684,6 +909,7 @@ int main(int argc, char *argv[]) {
+         test_load_syscall_filter_set_raw();
+         test_lock_personality();
+         test_filter_sets_ordered();
++        test_restrict_suid_sgid();
+ 
+         return 0;
+ }
diff --git a/SOURCES/0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch b/SOURCES/0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch
new file mode 100644
index 0000000..7d8d98a
--- /dev/null
+++ b/SOURCES/0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch
@@ -0,0 +1,157 @@
+From f79283a86531e3bbf0854b5f126b7b291fadfb43 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 20 Mar 2019 19:09:09 +0100
+Subject: [PATCH] core: expose SUID/SGID restriction as new unit setting
+ RestrictSUIDSGID=
+
+(cherry picked from commit f69567cbe26d09eac9d387c0be0fc32c65a83ada)
+Related: #1687512
+---
+ src/core/dbus-execute.c                     |  4 ++++
+ src/core/execute.c                          | 22 +++++++++++++++++++++
+ src/core/execute.h                          |  1 +
+ src/core/load-fragment-gperf.gperf.m4       |  2 ++
+ src/shared/bus-unit-util.c                  |  2 +-
+ test/fuzz/fuzz-unit-file/directives.service |  1 +
+ 6 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
+index 198f149210..e7c0b893d1 100644
+--- a/src/core/dbus-execute.c
++++ b/src/core/dbus-execute.c
+@@ -815,6 +815,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
+         SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
++        SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+         SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+@@ -1179,6 +1180,9 @@ int bus_exec_context_set_transient_property(
+         if (streq(name, "RestrictRealtime"))
+                 return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
+ 
++        if (streq(name, "RestrictSUIDSGID"))
++                return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error);
++
+         if (streq(name, "DynamicUser"))
+                 return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
+ 
+diff --git a/src/core/execute.c b/src/core/execute.c
+index 56aa89e1ec..f012023224 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -1366,6 +1366,7 @@ static bool context_has_no_new_privileges(const ExecContext *c) {
+         return context_has_address_families(c) ||
+                 c->memory_deny_write_execute ||
+                 c->restrict_realtime ||
++                c->restrict_suid_sgid ||
+                 exec_context_restrict_namespaces_set(c) ||
+                 c->protect_kernel_tunables ||
+                 c->protect_kernel_modules ||
+@@ -1470,6 +1471,19 @@ static int apply_restrict_realtime(const Unit* u, const ExecContext *c) {
+         return seccomp_restrict_realtime();
+ }
+ 
++static int apply_restrict_suid_sgid(const Unit* u, const ExecContext *c) {
++        assert(u);
++        assert(c);
++
++        if (!c->restrict_suid_sgid)
++                return 0;
++
++        if (skip_seccomp_unavailable(u, "RestrictSUIDSGID="))
++                return 0;
++
++        return seccomp_restrict_suid_sgid();
++}
++
+ static int apply_protect_sysctl(const Unit *u, const ExecContext *c) {
+         assert(u);
+         assert(c);
+@@ -3404,6 +3418,12 @@ static int exec_child(
+                         return log_unit_error_errno(unit, r, "Failed to apply realtime restrictions: %m");
+                 }
+ 
++                r = apply_restrict_suid_sgid(unit, context);
++                if (r < 0) {
++                        *exit_status = EXIT_SECCOMP;
++                        return log_unit_error_errno(unit, r, "Failed to apply SUID/SGID restrictions: %m");
++                }
++
+                 r = apply_restrict_namespaces(unit, context);
+                 if (r < 0) {
+                         *exit_status = EXIT_SECCOMP;
+@@ -4023,6 +4043,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
+                 "%sIgnoreSIGPIPE: %s\n"
+                 "%sMemoryDenyWriteExecute: %s\n"
+                 "%sRestrictRealtime: %s\n"
++                "%sRestrictSUIDSGID: %s\n"
+                 "%sKeyringMode: %s\n",
+                 prefix, c->umask,
+                 prefix, c->working_directory ? c->working_directory : "/",
+@@ -4041,6 +4062,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
+                 prefix, yes_no(c->ignore_sigpipe),
+                 prefix, yes_no(c->memory_deny_write_execute),
+                 prefix, yes_no(c->restrict_realtime),
++                prefix, yes_no(c->restrict_suid_sgid),
+                 prefix, exec_keyring_mode_to_string(c->keyring_mode));
+ 
+         if (c->root_image)
+diff --git a/src/core/execute.h b/src/core/execute.h
+index b2eb55f8f5..2266355962 100644
+--- a/src/core/execute.h
++++ b/src/core/execute.h
+@@ -245,6 +245,7 @@ struct ExecContext {
+          * that the autofs logic detects that it belongs to us and we
+          * don't enter a trigger loop. */
+         bool same_pgrp;
++        bool restrict_suid_sgid;
+ 
+         unsigned long personality;
+         bool lock_personality;
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index cdf4d14c4e..49e938d0ce 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -76,6 +76,7 @@ $1.SystemCallErrorNumber,        config_parse_syscall_errno,         0,
+ $1.MemoryDenyWriteExecute,       config_parse_bool,                  0,                             offsetof($1, exec_context.memory_deny_write_execute)
+ $1.RestrictNamespaces,           config_parse_restrict_namespaces,   0,                             offsetof($1, exec_context)
+ $1.RestrictRealtime,             config_parse_bool,                  0,                             offsetof($1, exec_context.restrict_realtime)
++$1.RestrictSUIDSGID,             config_parse_bool,                  0,                             offsetof($1, exec_context.restrict_suid_sgid)
+ $1.RestrictAddressFamilies,      config_parse_address_families,      0,                             offsetof($1, exec_context)
+ $1.LockPersonality,              config_parse_bool,                  0,                             offsetof($1, exec_context.lock_personality)',
+ `$1.SystemCallFilter,            config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
+@@ -84,6 +85,7 @@ $1.SystemCallErrorNumber,        config_parse_warn_compat,           DISABLED_CO
+ $1.MemoryDenyWriteExecute,       config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
+ $1.RestrictNamespaces,           config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
+ $1.RestrictRealtime,             config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
++$1.RestrictSUIDSGID,             config_parse_warn_compat,           DISABLED_CONFIGURATION         0
+ $1.RestrictAddressFamilies,      config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
+ $1.LockPersonality,              config_parse_warn_compat,           DISABLED_CONFIGURATION,        0')
+ $1.LimitCPU,                     config_parse_rlimit,                RLIMIT_CPU,                    offsetof($1, exec_context.rlimit)
+diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
+index 055edd6e22..3c42e97b7a 100644
+--- a/src/shared/bus-unit-util.c
++++ b/src/shared/bus-unit-util.c
+@@ -697,7 +697,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
+                        "PrivateMounts", "NoNewPrivileges", "SyslogLevelPrefix",
+                        "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC",
+                        "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups",
+-                       "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality"))
++                       "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality" "RestrictSUIDSGID"))
+ 
+                 return bus_append_parse_boolean(m, field, eq);
+ 
+diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
+index d8d1fc68b8..eab1820e20 100644
+--- a/test/fuzz/fuzz-unit-file/directives.service
++++ b/test/fuzz/fuzz-unit-file/directives.service
+@@ -849,6 +849,7 @@ ReserveVT=
+ RestrictAddressFamilies=
+ RestrictNamespaces=
+ RestrictRealtime=
++RestrictSUIDSGID=
+ RuntimeDirectory=
+ RuntimeDirectoryMode=
+ RuntimeDirectoryPreserve=
diff --git a/SOURCES/0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch b/SOURCES/0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch
new file mode 100644
index 0000000..ffdc4bf
--- /dev/null
+++ b/SOURCES/0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch
@@ -0,0 +1,52 @@
+From 3d338556760632b9c8b646a719d56e02e3ad2088 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 20 Mar 2019 19:20:35 +0100
+Subject: [PATCH] analyze: check for RestrictSUIDSGID= in "systemd-analyze
+ security"
+
+And let's give it a heigh weight, since it pretty much can be used for
+bad things only.
+
+(cherry picked from commit 9d880b70ba5c6ca83c82952f4c90e86e56c7b70c)
+Related: #1687512
+---
+ src/analyze/analyze-security.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c
+index eec040d5c3..969101c57b 100644
+--- a/src/analyze/analyze-security.c
++++ b/src/analyze/analyze-security.c
+@@ -69,6 +69,7 @@ struct security_info {
+ 
+         uint64_t restrict_namespaces;
+         bool restrict_realtime;
++        bool restrict_suid_sgid;
+ 
+         char *root_directory;
+         char *root_image;
+@@ -1130,6 +1131,16 @@ static const struct security_assessor security_assessor_table[] = {
+                 .assess = assess_bool,
+                 .offset = offsetof(struct security_info, restrict_realtime),
+         },
++        {
++                .id = "RestrictSUIDSGID=",
++                .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictSUIDSGID=",
++                .description_good = "SUID/SGID file creation by service is restricted",
++                .description_bad = "Service may create SUID/SGID files",
++                .weight = 1000,
++                .range = 1,
++                .assess = assess_bool,
++                .offset = offsetof(struct security_info, restrict_suid_sgid),
++        },
+         {
+                 .id = "RestrictNamespaces=~CLONE_NEWUSER",
+                 .url = "https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RestrictNamespaces=",
+@@ -1862,6 +1873,7 @@ static int acquire_security_info(sd_bus *bus, const char *name, struct security_
+                 { "RestrictAddressFamilies", "(bas)",   property_read_restrict_address_families, 0                                                         },
+                 { "RestrictNamespaces",      "t",       NULL,                                    offsetof(struct security_info, restrict_namespaces)       },
+                 { "RestrictRealtime",        "b",       NULL,                                    offsetof(struct security_info, restrict_realtime)         },
++                { "RestrictSUIDSGID",        "b",       NULL,                                    offsetof(struct security_info, restrict_suid_sgid)        },
+                 { "RootDirectory",           "s",       NULL,                                    offsetof(struct security_info, root_directory)            },
+                 { "RootImage",               "s",       NULL,                                    offsetof(struct security_info, root_image)                },
+                 { "SupplementaryGroups",     "as",      NULL,                                    offsetof(struct security_info, supplementary_groups)      },
diff --git a/SOURCES/0327-man-document-the-new-RestrictSUIDSGID-setting.patch b/SOURCES/0327-man-document-the-new-RestrictSUIDSGID-setting.patch
new file mode 100644
index 0000000..f362587
--- /dev/null
+++ b/SOURCES/0327-man-document-the-new-RestrictSUIDSGID-setting.patch
@@ -0,0 +1,83 @@
+From 797ebaa8240aefc39de3d1713468b221c83ed3f5 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 20 Mar 2019 19:45:32 +0100
+Subject: [PATCH] man: document the new RestrictSUIDSGID= setting
+
+(cherry picked from commit 7445db6eb70e8d5989f481d0c5a08ace7047ae5b)
+Related: #1687512
+---
+ doc/TRANSIENT-SETTINGS.md |  1 +
+ man/systemd.exec.xml      | 41 +++++++++++++++++++++++++++------------
+ 2 files changed, 30 insertions(+), 12 deletions(-)
+
+diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md
+index 0ea444b133..c2b5c0dcce 100644
+--- a/doc/TRANSIENT-SETTINGS.md
++++ b/doc/TRANSIENT-SETTINGS.md
+@@ -149,6 +149,7 @@ All execution-related settings are available for transient units.
+ ✓ MemoryDenyWriteExecute=
+ ✓ RestrictNamespaces=
+ ✓ RestrictRealtime=
++✓ RestrictSUIDSGID=
+ ✓ RestrictAddressFamilies=
+ ✓ LockPersonality=
+ ✓ LimitCPU=
+diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
+index 87fb8b34f4..45ed1864f8 100644
+--- a/man/systemd.exec.xml
++++ b/man/systemd.exec.xml
+@@ -348,18 +348,19 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
+       <varlistentry>
+         <term><varname>NoNewPrivileges=</varname></term>
+ 
+-        <listitem><para>Takes a boolean argument. If true, ensures that the service process and all its children can
+-        never gain new privileges through <function>execve()</function> (e.g. via setuid or setgid bits, or filesystem
+-        capabilities). This is the simplest and most effective way to ensure that a process and its children can never
+-        elevate privileges again. Defaults to false, but certain settings override this and ignore the value of this
+-        setting.  This is the case when <varname>SystemCallFilter=</varname>,
+-        <varname>SystemCallArchitectures=</varname>, <varname>RestrictAddressFamilies=</varname>,
+-        <varname>RestrictNamespaces=</varname>, <varname>PrivateDevices=</varname>,
+-        <varname>ProtectKernelTunables=</varname>, <varname>ProtectKernelModules=</varname>,
+-        <varname>MemoryDenyWriteExecute=</varname>, <varname>RestrictRealtime=</varname>, or
+-        <varname>LockPersonality=</varname> are specified. Note that even if this setting is overridden by them,
+-        <command>systemctl show</command> shows the original value of this setting. Also see
+-        <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
++        <listitem><para>Takes a boolean argument. If true, ensures that the service process and all its
++        children can never gain new privileges through <function>execve()</function> (e.g. via setuid or
++        setgid bits, or filesystem capabilities). This is the simplest and most effective way to ensure that
++        a process and its children can never elevate privileges again. Defaults to false, but certain
++        settings override this and ignore the value of this setting.  This is the case when
++        <varname>SystemCallFilter=</varname>, <varname>SystemCallArchitectures=</varname>,
++        <varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>,
++        <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
++        <varname>ProtectKernelModules=</varname>, <varname>MemoryDenyWriteExecute=</varname>,
++        <varname>RestrictRealtime=</varname>, <varname>RestrictSUIDSGID=</varname> or
++        <varname>LockPersonality=</varname> are specified. Note that even if this setting is overridden by
++        them, <command>systemctl show</command> shows the original value of this setting. Also see <ulink
++        url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
+         Flag</ulink>.  </para></listitem>
+       </varlistentry>
+ 
+@@ -1274,6 +1275,22 @@ RestrictNamespaces=~cgroup net</programlisting>
+         that actually require them. Defaults to off.</para></listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><varname>RestrictSUIDSGID=</varname></term>
++
++        <listitem><para>Takes a boolean argument. If set, any attempts to set the set-user-ID (SUID) or
++        set-group-ID (SGID) bits on files or directories will be denied (for details on these bits see
++        <citerefentry
++        project='man-pages'><refentrytitle>inode</refentrytitle><manvolnum>7</manvolnum></citerefentry>). If
++        running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
++        capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is
++        implied. As the SUID/SGID bits are mechanisms to elevate privileges, and allows users to acquire the
++        identity of other users, it is recommended to restrict creation of SUID/SGID files to the few
++        programs that actually require them. Note that this restricts marking of any type of file system
++        object with these bits, including both regular files and directories (where the SGID is a different
++        meaning than for files, see documentation). Defaults to off.</para></listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><varname>RemoveIPC=</varname></term>
+ 
diff --git a/SOURCES/0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch b/SOURCES/0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch
new file mode 100644
index 0000000..8a9917f
--- /dev/null
+++ b/SOURCES/0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch
@@ -0,0 +1,157 @@
+From b0573f1a6f8022aed4954d5ca19cc037d25cd5e7 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 20 Mar 2019 19:52:20 +0100
+Subject: [PATCH] units: turn on RestrictSUIDSGID= in most of our long-running
+ daemons
+
+(cherry picked from commit 62aa29247c3d74bcec0607c347f2be23cd90675d)
+Related: #1687512
+---
+ units/systemd-coredump@.service.in      | 1 +
+ units/systemd-hostnamed.service.in      | 1 +
+ units/systemd-journal-remote.service.in | 1 +
+ units/systemd-journald.service.in       | 1 +
+ units/systemd-localed.service.in        | 1 +
+ units/systemd-logind.service.in         | 1 +
+ units/systemd-networkd.service.in       | 1 +
+ units/systemd-resolved.service.in       | 1 +
+ units/systemd-timedated.service.in      | 1 +
+ units/systemd-timesyncd.service.in      | 1 +
+ units/systemd-udevd.service.in          | 3 ++-
+ 11 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in
+index 68a68a5055..d69ebd8b24 100644
+--- a/units/systemd-coredump@.service.in
++++ b/units/systemd-coredump@.service.in
+@@ -33,6 +33,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX
++RestrictSUIDSGID=yes
+ SystemCallFilter=@system-service
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
+index 4e5470dd29..97d4e142bc 100644
+--- a/units/systemd-hostnamed.service.in
++++ b/units/systemd-hostnamed.service.in
+@@ -29,6 +29,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX
++RestrictSUIDSGID=yes
+ SystemCallFilter=@system-service sethostname
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+diff --git a/units/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in
+index a94265f215..3c914f5a40 100644
+--- a/units/systemd-journal-remote.service.in
++++ b/units/systemd-journal-remote.service.in
+@@ -28,6 +28,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
++RestrictSUIDSGID=yes
+ SystemCallArchitectures=native
+ LockPersonality=yes
+ LogsDirectory=journal/remote
+diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
+index e109b25792..ab9ec35ff8 100644
+--- a/units/systemd-journald.service.in
++++ b/units/systemd-journald.service.in
+@@ -21,6 +21,7 @@ Sockets=systemd-journald.socket systemd-journald-dev-log.socket
+ ExecStart=@rootlibexecdir@/systemd-journald
+ Restart=always
+ RestartSec=0
++RestrictSUIDSGID=yes
+ StandardOutput=null
+ WatchdogSec=3min
+ FileDescriptorStoreMax=4224
+diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
+index ce043db154..b87d60e9eb 100644
+--- a/units/systemd-localed.service.in
++++ b/units/systemd-localed.service.in
+@@ -29,6 +29,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX
++RestrictSUIDSGID=yes
+ SystemCallFilter=@system-service
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
+index 6953fac55b..086338e03b 100644
+--- a/units/systemd-logind.service.in
++++ b/units/systemd-logind.service.in
+@@ -30,6 +30,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX AF_NETLINK
++RestrictSUIDSGID=yes
+ SystemCallFilter=@system-service
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
+index 371ab3a9cf..a0f34ac738 100644
+--- a/units/systemd-networkd.service.in
++++ b/units/systemd-networkd.service.in
+@@ -39,6 +39,7 @@ SystemCallFilter=@system-service
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+ LockPersonality=yes
++RestrictSUIDSGID=yes
+ RuntimeDirectory=systemd/netif
+ RuntimeDirectoryPreserve=yes
+ 
+diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in
+index aaed406ab2..6c2ad5ca86 100644
+--- a/units/systemd-resolved.service.in
++++ b/units/systemd-resolved.service.in
+@@ -41,6 +41,7 @@ SystemCallFilter=@system-service
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+ LockPersonality=yes
++RestrictSUIDSGID=yes
+ RuntimeDirectory=systemd/resolve
+ RuntimeDirectoryPreserve=yes
+ 
+diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
+index 662b39557a..1da2bc4bb0 100644
+--- a/units/systemd-timedated.service.in
++++ b/units/systemd-timedated.service.in
+@@ -27,6 +27,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX
++RestrictSUIDSGID=yes
+ SystemCallFilter=@system-service @clock
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
+diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
+index 4a490b6e16..c2b9551726 100644
+--- a/units/systemd-timesyncd.service.in
++++ b/units/systemd-timesyncd.service.in
+@@ -37,6 +37,7 @@ MemoryDenyWriteExecute=yes
+ RestrictRealtime=yes
+ RestrictNamespaces=yes
+ RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
++RestrictSUIDSGID=yes
+ RuntimeDirectory=systemd/timesync
+ SystemCallFilter=@system-service @clock
+ SystemCallErrorNumber=EPERM
+diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
+index fd9ead3bb8..970cf0f290 100644
+--- a/units/systemd-udevd.service.in
++++ b/units/systemd-udevd.service.in
+@@ -27,8 +27,9 @@ WatchdogSec=3min
+ TasksMax=infinity
+ PrivateMounts=yes
+ MemoryDenyWriteExecute=yes
+-RestrictRealtime=yes
+ RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
++RestrictRealtime=yes
++RestrictSUIDSGID=yes
+ SystemCallFilter=@system-service @module @raw-io
+ SystemCallErrorNumber=EPERM
+ SystemCallArchitectures=native
diff --git a/SOURCES/0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch b/SOURCES/0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch
new file mode 100644
index 0000000..df4279c
--- /dev/null
+++ b/SOURCES/0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch
@@ -0,0 +1,89 @@
+From 11f5677752f9b78239214b3064e5a2c3712d71b1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart@poettering.net>
+Date: Wed, 20 Mar 2019 20:19:38 +0100
+Subject: [PATCH] core: imply NNP and SUID/SGID restriction for DynamicUser=yes
+ service
+
+Let's be safe, rather than sorry. This way DynamicUser=yes services can
+neither take benefit of, nor create SUID/SGID binaries.
+
+Given that DynamicUser= is a recent addition only we should be able to
+get away with turning this on, even though this is strictly speaking a
+binary compatibility breakage.
+
+(cherry picked from commit bf65b7e0c9fc215897b676ab9a7c9d1c688143ba)
+Resolves: #1687512
+---
+ man/systemd.exec.xml | 16 ++++++++++------
+ src/core/unit.c      | 10 ++++++++--
+ 2 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
+index 45ed1864f8..bdaed68162 100644
+--- a/man/systemd.exec.xml
++++ b/man/systemd.exec.xml
+@@ -229,7 +229,9 @@
+         created by the executed processes is bound to the runtime of the service, and hence the lifetime of the dynamic
+         user/group. Since <filename>/tmp</filename> and <filename>/var/tmp</filename> are usually the only
+         world-writable directories on a system this ensures that a unit making use of dynamic user/group allocation
+-        cannot leave files around after unit termination. Moreover <varname>ProtectSystem=strict</varname> and
++        cannot leave files around after unit termination. Furthermore <varname>NoNewPrivileges=</varname> and
++        <varname>RestrictSUIDSGID=</varname> are implicitly enabled to ensure that processes invoked cannot take benefit
++        or create SUID/SGID files or directories. Moreover <varname>ProtectSystem=strict</varname> and
+         <varname>ProtectHome=read-only</varname> are implied, thus prohibiting the service to write to arbitrary file
+         system locations. In order to allow the service to write to certain directories, they have to be whitelisted
+         using <varname>ReadWritePaths=</varname>, but care must be taken so that UID/GID recycling doesn't create
+@@ -357,11 +359,12 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
+         <varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>,
+         <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
+         <varname>ProtectKernelModules=</varname>, <varname>MemoryDenyWriteExecute=</varname>,
+-        <varname>RestrictRealtime=</varname>, <varname>RestrictSUIDSGID=</varname> or
+-        <varname>LockPersonality=</varname> are specified. Note that even if this setting is overridden by
+-        them, <command>systemctl show</command> shows the original value of this setting. Also see <ulink
++        <varname>RestrictRealtime=</varname>, <varname>RestrictSUIDSGID=</varname>,
++        <varname>DynamicUser=</varname> or <varname>LockPersonality=</varname> are specified. Note that even
++        if this setting is overridden by them, <command>systemctl show</command> shows the original value of
++        this setting. Also see <ulink
+         url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
+-        Flag</ulink>.  </para></listitem>
++        Flag</ulink>.</para></listitem>
+       </varlistentry>
+ 
+       <varlistentry>
+@@ -1288,7 +1291,8 @@ RestrictNamespaces=~cgroup net</programlisting>
+         identity of other users, it is recommended to restrict creation of SUID/SGID files to the few
+         programs that actually require them. Note that this restricts marking of any type of file system
+         object with these bits, including both regular files and directories (where the SGID is a different
+-        meaning than for files, see documentation). Defaults to off.</para></listitem>
++        meaning than for files, see documentation). This option is implied if <varname>DynamicUser=</varname>
++        is enabled. Defaults to off.</para></listitem>
+       </varlistentry>
+ 
+       <varlistentry>
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 115739f4c6..e1f5e6f7bd 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -4161,14 +4161,20 @@ int unit_patch_contexts(Unit *u) {
+                                         return -ENOMEM;
+                         }
+ 
+-                        /* If the dynamic user option is on, let's make sure that the unit can't leave its UID/GID
+-                         * around in the file system or on IPC objects. Hence enforce a strict sandbox. */
++                        /* If the dynamic user option is on, let's make sure that the unit can't leave its
++                         * UID/GID around in the file system or on IPC objects. Hence enforce a strict
++                         * sandbox. */
+ 
+                         ec->private_tmp = true;
+                         ec->remove_ipc = true;
+                         ec->protect_system = PROTECT_SYSTEM_STRICT;
+                         if (ec->protect_home == PROTECT_HOME_NO)
+                                 ec->protect_home = PROTECT_HOME_READ_ONLY;
++
++                        /* Make sure this service can neither benefit from SUID/SGID binaries nor create
++                         * them. */
++                        ec->no_new_privileges = true;
++                        ec->restrict_suid_sgid = true;
+                 }
+         }
+ 
diff --git a/SOURCES/0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch b/SOURCES/0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch
new file mode 100644
index 0000000..d8d2f87
--- /dev/null
+++ b/SOURCES/0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch
@@ -0,0 +1,555 @@
+From b55c9b8e717d1967e6aa16c1e2646fc81d899ab7 Mon Sep 17 00:00:00 2001
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Mon, 29 Jul 2019 17:50:05 +0200
+Subject: [PATCH] cgroup: introduce support for cgroup v2 CPUSET controller
+
+Introduce support for configuring cpus and mems for processes using
+cgroup v2 CPUSET controller.  This allows users to limit which cpus
+and memory NUMA nodes can be used by processes to better utilize
+system resources.
+
+The cgroup v2 interfaces to control it are cpuset.cpus and cpuset.mems
+where the requested configuration is written.  However, it doesn't mean
+that the requested configuration will be actually used as parent cgroup
+may limit the cpus or mems as well.  In order to reflect the real
+configuration cgroup v2 provides read-only files cpuset.cpus.effective
+and cpuset.mems.effective which are exported to users as well.
+
+(cherry picked from commit 047f5d63d7a1ab75073f8485e2f9b550d25b0772)
+
+Related: #1724617
+---
+ doc/TRANSIENT-SETTINGS.md             |  2 +
+ man/systemd.resource-control.xml      | 30 +++++++++++++
+ src/basic/cgroup-util.c               |  1 +
+ src/basic/cgroup-util.h               |  2 +
+ src/core/cgroup.c                     | 63 +++++++++++++++++++++++++++
+ src/core/cgroup.h                     |  5 +++
+ src/core/dbus-cgroup.c                | 59 +++++++++++++++++++++++++
+ src/core/dbus-unit.c                  | 48 ++++++++++++++++++++
+ src/core/load-fragment-gperf.gperf.m4 |  2 +
+ src/core/load-fragment.c              | 38 ++++++++++++++++
+ src/core/load-fragment.h              |  2 +
+ src/shared/bus-unit-util.c            | 16 +++++++
+ src/systemctl/systemctl.c             |  2 +-
+ src/test/test-cgroup-mask.c           |  3 +-
+ 14 files changed, 271 insertions(+), 2 deletions(-)
+
+diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md
+index c2b5c0dcce..0b2ad66dcb 100644
+--- a/doc/TRANSIENT-SETTINGS.md
++++ b/doc/TRANSIENT-SETTINGS.md
+@@ -218,6 +218,8 @@ All cgroup/resource control settings are available for transient units
+ ✓ CPUShares=
+ ✓ StartupCPUShares=
+ ✓ CPUQuota=
++✓ AllowedCPUs=
++✓ AllowedMemoryNodes=
+ ✓ MemoryAccounting=
+ ✓ MemoryLow=
+ ✓ MemoryHigh=
+diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
+index 370c110592..4329742e94 100644
+--- a/man/systemd.resource-control.xml
++++ b/man/systemd.resource-control.xml
+@@ -201,6 +201,36 @@
+         </listitem>
+       </varlistentry>
+ 
++      <varlistentry>
++        <term><varname>AllowedCPUs=</varname></term>
++
++        <listitem>
++          <para>Restrict processes to be executed on specific CPUs. Takes a list of CPU indices or ranges separated by either
++          whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a dash.</para>
++
++          <para>Setting <varname>AllowedCPUs=</varname> doesn't guarantee that all of the CPUs will be used by the processes
++          as it may be limited by parent units. The effective configuration is reported as <varname>EffectiveCPUs=</varname>.</para>
++
++          <para>This setting is supported only with the unified control group hierarchy.</para>
++        </listitem>
++      </varlistentry>
++
++      <varlistentry>
++        <term><varname>AllowedMemoryNodes=</varname></term>
++
++        <listitem>
++          <para>Restrict processes to be executed on specific memory NUMA nodes. Takes a list of memory NUMA nodes indices
++          or ranges separated by either whitespace or commas. Memory NUMA nodes ranges are specified by the lower and upper
++          CPU indices separated by a dash.</para>
++
++          <para>Setting <varname>AllowedMemoryNodes=</varname> doesn't guarantee that all of the memory NUMA nodes will
++          be used by the processes as it may be limited by parent units. The effective configuration is reported as
++          <varname>EffectiveMemoryNodes=</varname>.</para>
++
++          <para>This setting is supported only with the unified control group hierarchy.</para>
++        </listitem>
++      </varlistentry>
++
+       <varlistentry>
+         <term><varname>MemoryAccounting=</varname></term>
+ 
+diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
+index 038ece4b06..6f47c3aacb 100644
+--- a/src/basic/cgroup-util.c
++++ b/src/basic/cgroup-util.c
+@@ -2763,6 +2763,7 @@ bool fd_is_cgroup_fs(int fd) {
+ static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
+         [CGROUP_CONTROLLER_CPU] = "cpu",
+         [CGROUP_CONTROLLER_CPUACCT] = "cpuacct",
++        [CGROUP_CONTROLLER_CPUSET] = "cpuset",
+         [CGROUP_CONTROLLER_IO] = "io",
+         [CGROUP_CONTROLLER_BLKIO] = "blkio",
+         [CGROUP_CONTROLLER_MEMORY] = "memory",
+diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h
+index 26e3ae0404..b414600dca 100644
+--- a/src/basic/cgroup-util.h
++++ b/src/basic/cgroup-util.h
+@@ -21,6 +21,7 @@
+ typedef enum CGroupController {
+         CGROUP_CONTROLLER_CPU,
+         CGROUP_CONTROLLER_CPUACCT,    /* v1 only */
++        CGROUP_CONTROLLER_CPUSET,     /* v2 only */
+         CGROUP_CONTROLLER_IO,         /* v2 only */
+         CGROUP_CONTROLLER_BLKIO,      /* v1 only */
+         CGROUP_CONTROLLER_MEMORY,
+@@ -36,6 +37,7 @@ typedef enum CGroupController {
+ typedef enum CGroupMask {
+         CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU),
+         CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT),
++        CGROUP_MASK_CPUSET = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUSET),
+         CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO),
+         CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO),
+         CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY),
+diff --git a/src/core/cgroup.c b/src/core/cgroup.c
+index 76eafdc082..664d269483 100644
+--- a/src/core/cgroup.c
++++ b/src/core/cgroup.c
+@@ -161,9 +161,14 @@ void cgroup_context_done(CGroupContext *c) {
+ 
+         c->ip_address_allow = ip_address_access_free_all(c->ip_address_allow);
+         c->ip_address_deny = ip_address_access_free_all(c->ip_address_deny);
++
++        cpu_set_reset(&c->cpuset_cpus);
++        cpu_set_reset(&c->cpuset_mems);
+ }
+ 
+ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
++        _cleanup_free_ char *cpuset_cpus = NULL;
++        _cleanup_free_ char *cpuset_mems = NULL;
+         CGroupIODeviceLimit *il;
+         CGroupIODeviceWeight *iw;
+         CGroupBlockIODeviceBandwidth *b;
+@@ -177,6 +182,9 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
+ 
+         prefix = strempty(prefix);
+ 
++        cpuset_cpus = cpu_set_to_range_string(&c->cpuset_cpus);
++        cpuset_mems = cpu_set_to_range_string(&c->cpuset_mems);
++
+         fprintf(f,
+                 "%sCPUAccounting=%s\n"
+                 "%sIOAccounting=%s\n"
+@@ -189,6 +197,8 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
+                 "%sCPUShares=%" PRIu64 "\n"
+                 "%sStartupCPUShares=%" PRIu64 "\n"
+                 "%sCPUQuotaPerSecSec=%s\n"
++                "%sAllowedCPUs=%s\n"
++                "%sAllowedMemoryNodes=%s\n"
+                 "%sIOWeight=%" PRIu64 "\n"
+                 "%sStartupIOWeight=%" PRIu64 "\n"
+                 "%sBlockIOWeight=%" PRIu64 "\n"
+@@ -212,6 +222,8 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
+                 prefix, c->cpu_shares,
+                 prefix, c->startup_cpu_shares,
+                 prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1),
++                prefix, cpuset_cpus,
++                prefix, cpuset_mems,
+                 prefix, c->io_weight,
+                 prefix, c->startup_io_weight,
+                 prefix, c->blockio_weight,
+@@ -541,6 +553,21 @@ static uint64_t cgroup_cpu_weight_to_shares(uint64_t weight) {
+                      CGROUP_CPU_SHARES_MIN, CGROUP_CPU_SHARES_MAX);
+ }
+ 
++static void cgroup_apply_unified_cpuset(Unit *u, CPUSet cpus, const char *name) {
++        _cleanup_free_ char *buf = NULL;
++        int r;
++
++        buf = cpu_set_to_range_string(&cpus);
++        if (!buf)
++            return;
++
++        r = cg_set_attribute("cpuset", u->cgroup_path, name, buf);
++        if (r < 0)
++                log_unit_full(u, IN_SET(r, -ENOENT, -EROFS, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
++                              "Failed to set %s: %m", name);
++
++}
++
+ static bool cgroup_context_has_io_config(CGroupContext *c) {
+         return c->io_accounting ||
+                 c->io_weight != CGROUP_WEIGHT_INVALID ||
+@@ -766,6 +793,11 @@ static void cgroup_context_apply(
+                 }
+         }
+ 
++        if ((apply_mask & CGROUP_MASK_CPUSET) && !is_root) {
++                cgroup_apply_unified_cpuset(u, c->cpuset_cpus, "cpuset.cpus");
++                cgroup_apply_unified_cpuset(u, c->cpuset_mems, "cpuset.mems");
++        }
++
+         if (apply_mask & CGROUP_MASK_IO) {
+                 bool has_io = cgroup_context_has_io_config(c);
+                 bool has_blockio = cgroup_context_has_blockio_config(c);
+@@ -1068,6 +1100,9 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) {
+             c->cpu_quota_per_sec_usec != USEC_INFINITY)
+                 mask |= CGROUP_MASK_CPUACCT | CGROUP_MASK_CPU;
+ 
++        if (c->cpuset_cpus.set || c->cpuset_mems.set)
++                mask |= CGROUP_MASK_CPUSET;
++
+         if (cgroup_context_has_io_config(c) || cgroup_context_has_blockio_config(c))
+                 mask |= CGROUP_MASK_IO | CGROUP_MASK_BLKIO;
+ 
+@@ -2697,4 +2732,32 @@ static const char* const cgroup_device_policy_table[_CGROUP_DEVICE_POLICY_MAX] =
+         [CGROUP_STRICT] = "strict",
+ };
+ 
++int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name) {
++        _cleanup_free_ char *v = NULL;
++        int r;
++
++        assert(u);
++        assert(cpus);
++
++        if (!u->cgroup_path)
++                return -ENODATA;
++
++        if ((u->cgroup_realized_mask & CGROUP_MASK_CPUSET) == 0)
++                return -ENODATA;
++
++        r = cg_all_unified();
++        if (r < 0)
++                return r;
++        if (r == 0)
++                return -ENODATA;
++        if (r > 0)
++                r = cg_get_attribute("cpuset", u->cgroup_path, name, &v);
++        if (r == -ENOENT)
++                return -ENODATA;
++        if (r < 0)
++                return r;
++
++        return parse_cpu_set_full(v, cpus, false, NULL, NULL, 0, NULL);
++}
++
+ DEFINE_STRING_TABLE_LOOKUP(cgroup_device_policy, CGroupDevicePolicy);
+diff --git a/src/core/cgroup.h b/src/core/cgroup.h
+index 2d2ff6fc3c..da10575394 100644
+--- a/src/core/cgroup.h
++++ b/src/core/cgroup.h
+@@ -4,6 +4,7 @@
+ #include <stdbool.h>
+ 
+ #include "cgroup-util.h"
++#include "cpu-set-util.h"
+ #include "ip-address-access.h"
+ #include "list.h"
+ #include "time-util.h"
+@@ -77,6 +78,9 @@ struct CGroupContext {
+         uint64_t startup_cpu_weight;
+         usec_t cpu_quota_per_sec_usec;
+ 
++        CPUSet cpuset_cpus;
++        CPUSet cpuset_mems;
++
+         uint64_t io_weight;
+         uint64_t startup_io_weight;
+         LIST_HEAD(CGroupIODeviceWeight, io_device_weights);
+@@ -205,3 +209,4 @@ const char* cgroup_device_policy_to_string(CGroupDevicePolicy i) _const_;
+ CGroupDevicePolicy cgroup_device_policy_from_string(const char *s) _pure_;
+ 
+ bool unit_cgroup_delegate(Unit *u);
++int unit_get_cpuset(Unit *u, CPUSet *cpus, const char *name);
+diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
+index 540bc77aed..30d4e83932 100644
+--- a/src/core/dbus-cgroup.c
++++ b/src/core/dbus-cgroup.c
+@@ -53,6 +53,27 @@ static int property_get_delegate_controllers(
+         return sd_bus_message_close_container(reply);
+ }
+ 
++static int property_get_cpuset(
++                sd_bus *bus,
++                const char *path,
++                const char *interface,
++                const char *property,
++                sd_bus_message *reply,
++                void *userdata,
++                sd_bus_error *error) {
++
++        CPUSet *cpus = userdata;
++        _cleanup_free_ uint8_t *array = NULL;
++        size_t allocated;
++
++        assert(bus);
++        assert(reply);
++        assert(cpus);
++
++        (void) cpu_set_to_dbus(cpus, &array, &allocated);
++        return sd_bus_message_append_array(reply, 'y', array, allocated);
++}
++
+ static int property_get_io_device_weight(
+                 sd_bus *bus,
+                 const char *path,
+@@ -283,6 +304,8 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
+         SD_BUS_PROPERTY("CPUShares", "t", NULL, offsetof(CGroupContext, cpu_shares), 0),
+         SD_BUS_PROPERTY("StartupCPUShares", "t", NULL, offsetof(CGroupContext, startup_cpu_shares), 0),
+         SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
++        SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_cpus), 0),
++        SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset, offsetof(CGroupContext, cpuset_mems), 0),
+         SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, io_accounting), 0),
+         SD_BUS_PROPERTY("IOWeight", "t", NULL, offsetof(CGroupContext, io_weight), 0),
+         SD_BUS_PROPERTY("StartupIOWeight", "t", NULL, offsetof(CGroupContext, startup_io_weight), 0),
+@@ -671,6 +694,42 @@ int bus_cgroup_set_property(
+ 
+                 return 1;
+ 
++        } else if (STR_IN_SET(name, "AllowedCPUs", "AllowedMemoryNodes")) {
++                const void *a;
++                size_t n;
++                _cleanup_(cpu_set_reset) CPUSet new_set = {};
++
++                r = sd_bus_message_read_array(message, 'y', &a, &n);
++                if (r < 0)
++                        return r;
++
++                r = cpu_set_from_dbus(a, n, &new_set);
++                if (r < 0)
++                        return r;
++
++                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
++                        _cleanup_free_ char *setstr = NULL;
++                        _cleanup_free_ char *data = NULL;
++                        CPUSet *set;
++
++                        setstr = cpu_set_to_range_string(&new_set);
++
++                        if (streq(name, "AllowedCPUs"))
++                                set = &c->cpuset_cpus;
++                        else
++                                set = &c->cpuset_mems;
++
++                        if (asprintf(&data, "%s=%s", name, setstr) < 0)
++                                return -ENOMEM;
++
++                        cpu_set_reset(set);
++                        cpu_set_add_all(set, &new_set);
++                        unit_invalidate_cgroup(u, CGROUP_MASK_CPUSET);
++                        unit_write_setting(u, flags, name, data);
++                }
++
++                return 1;
++
+         } else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) {
+                 const char *path;
+                 unsigned n = 0;
+diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
+index c5bca10979..aa15e47754 100644
+--- a/src/core/dbus-unit.c
++++ b/src/core/dbus-unit.c
+@@ -752,6 +752,52 @@ static int property_get_cpu_usage(
+         return sd_bus_message_append(reply, "t", ns);
+ }
+ 
++static int property_get_cpuset_cpus(
++                sd_bus *bus,
++                const char *path,
++                const char *interface,
++                const char *property,
++                sd_bus_message *reply,
++                void *userdata,
++                sd_bus_error *error) {
++
++        Unit *u = userdata;
++        _cleanup_(cpu_set_reset) CPUSet cpus = {};
++        _cleanup_free_ uint8_t *array = NULL;
++        size_t allocated;
++
++        assert(bus);
++        assert(reply);
++        assert(u);
++
++        (void) unit_get_cpuset(u, &cpus, "cpuset.cpus.effective");
++        (void) cpu_set_to_dbus(&cpus, &array, &allocated);
++        return sd_bus_message_append_array(reply, 'y', array, allocated);
++}
++
++static int property_get_cpuset_mems(
++                sd_bus *bus,
++                const char *path,
++                const char *interface,
++                const char *property,
++                sd_bus_message *reply,
++                void *userdata,
++                sd_bus_error *error) {
++
++        Unit *u = userdata;
++        _cleanup_(cpu_set_reset) CPUSet mems = {};
++        _cleanup_free_ uint8_t *array = NULL;
++        size_t allocated;
++
++        assert(bus);
++        assert(reply);
++        assert(u);
++
++        (void) unit_get_cpuset(u, &mems, "cpuset.mems.effective");
++        (void) cpu_set_to_dbus(&mems, &array, &allocated);
++        return sd_bus_message_append_array(reply, 'y', array, allocated);
++}
++
+ static int property_get_cgroup(
+                 sd_bus *bus,
+                 const char *path,
+@@ -1074,6 +1120,8 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
+         SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
+         SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
+         SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
++        SD_BUS_PROPERTY("EffectiveCPUs", "ay", property_get_cpuset_cpus, 0, 0),
++        SD_BUS_PROPERTY("EffectiveMemoryNodes", "ay", property_get_cpuset_mems, 0, 0),
+         SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
+         SD_BUS_PROPERTY("IPIngressBytes", "t", property_get_ip_counter, 0, 0),
+         SD_BUS_PROPERTY("IPIngressPackets", "t", property_get_ip_counter, 0, 0),
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index 49e938d0ce..ebb44df487 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -167,6 +167,8 @@ $1.StartupCPUWeight,             config_parse_cg_weight,             0,
+ $1.CPUShares,                    config_parse_cpu_shares,            0,                             offsetof($1, cgroup_context.cpu_shares)
+ $1.StartupCPUShares,             config_parse_cpu_shares,            0,                             offsetof($1, cgroup_context.startup_cpu_shares)
+ $1.CPUQuota,                     config_parse_cpu_quota,             0,                             offsetof($1, cgroup_context)
++$1.CPUSetCpus,                   config_parse_cpuset_cpus,           0,                             offsetof($1, cgroup_context)
++$1.CPUSetMems,                   config_parse_cpuset_mems,           0,                             offsetof($1, cgroup_context)
+ $1.MemoryAccounting,             config_parse_bool,                  0,                             offsetof($1, cgroup_context.memory_accounting)
+ $1.MemoryLow,                    config_parse_memory_limit,          0,                             offsetof($1, cgroup_context)
+ $1.MemoryHigh,                   config_parse_memory_limit,          0,                             offsetof($1, cgroup_context)
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index 35dd595098..6debf82401 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -3011,6 +3011,44 @@ int config_parse_cpu_quota(
+         return 0;
+ }
+ 
++int config_parse_cpuset_cpus(
++                const char *unit,
++                const char *filename,
++                unsigned line,
++                const char *section,
++                unsigned section_line,
++                const char *lvalue,
++                int ltype,
++                const char *rvalue,
++                void *data,
++                void *userdata) {
++
++        CGroupContext *c = data;
++
++        (void) parse_cpu_set_extend(rvalue, &c->cpuset_cpus, true, unit, filename, line, lvalue);
++
++        return 0;
++}
++
++int config_parse_cpuset_mems(
++                const char *unit,
++                const char *filename,
++                unsigned line,
++                const char *section,
++                unsigned section_line,
++                const char *lvalue,
++                int ltype,
++                const char *rvalue,
++                void *data,
++                void *userdata) {
++
++        CGroupContext *c = data;
++
++        (void) parse_cpu_set_extend(rvalue, &c->cpuset_mems, true, unit, filename, line, lvalue);
++
++        return 0;
++}
++
+ int config_parse_memory_limit(
+                 const char *unit,
+                 const char *filename,
+diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
+index f2ca1b8ee7..6612e1fb32 100644
+--- a/src/core/load-fragment.h
++++ b/src/core/load-fragment.h
+@@ -86,6 +86,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_set_status);
+ CONFIG_PARSER_PROTOTYPE(config_parse_namespace_path_strv);
+ CONFIG_PARSER_PROTOTYPE(config_parse_temporary_filesystems);
+ CONFIG_PARSER_PROTOTYPE(config_parse_cpu_quota);
++CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_cpus);
++CONFIG_PARSER_PROTOTYPE(config_parse_cpuset_mems);
+ CONFIG_PARSER_PROTOTYPE(config_parse_protect_home);
+ CONFIG_PARSER_PROTOTYPE(config_parse_protect_system);
+ CONFIG_PARSER_PROTOTYPE(config_parse_bus_name);
+diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
+index 3c42e97b7a..8f3b463c6b 100644
+--- a/src/shared/bus-unit-util.c
++++ b/src/shared/bus-unit-util.c
+@@ -396,6 +396,22 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
+ 
+                 return bus_append_cg_cpu_shares_parse(m, field, eq);
+ 
++        if (STR_IN_SET(field, "AllowedCPUs", "AllowedMemoryNodes")) {
++                _cleanup_(cpu_set_reset) CPUSet cpuset = {};
++                _cleanup_free_ uint8_t *array = NULL;
++                size_t allocated;
++
++                r = parse_cpu_set(eq, &cpuset);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
++
++                r = cpu_set_to_dbus(&cpuset, &array, &allocated);
++                if (r < 0)
++                        return log_error_errno(r, "Failed to serialize CPUSet: %m");
++
++                return bus_append_byte_array(m, field, array, allocated);
++        }
++
+         if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight"))
+ 
+                 return bus_append_cg_blkio_weight_parse(m, field, eq);
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 7274921e6d..a3074bc5e3 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -4892,7 +4892,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
+                         print_prop(name, "%s", h);
+ 
+                         return 1;
+-                } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
++                } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask", "AllowedCPUs", "AllowedMemoryNodes", "EffectiveCPUs", "EffectiveMemoryNodes")) {
+                         _cleanup_free_ char *affinity = NULL;
+                         _cleanup_(cpu_set_reset) CPUSet set = {};
+                         const void *a;
+diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c
+index d65959edf1..93c3f5d856 100644
+--- a/src/test/test-cgroup-mask.c
++++ b/src/test/test-cgroup-mask.c
+@@ -104,9 +104,10 @@ static void test_cg_mask_to_string_one(CGroupMask mask, const char *t) {
+ 
+ static void test_cg_mask_to_string(void) {
+         test_cg_mask_to_string_one(0, NULL);
+-        test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct io blkio memory devices pids");
++        test_cg_mask_to_string_one(_CGROUP_MASK_ALL, "cpu cpuacct cpuset io blkio memory devices pids");
+         test_cg_mask_to_string_one(CGROUP_MASK_CPU, "cpu");
+         test_cg_mask_to_string_one(CGROUP_MASK_CPUACCT, "cpuacct");
++        test_cg_mask_to_string_one(CGROUP_MASK_CPUSET, "cpuset");
+         test_cg_mask_to_string_one(CGROUP_MASK_IO, "io");
+         test_cg_mask_to_string_one(CGROUP_MASK_BLKIO, "blkio");
+         test_cg_mask_to_string_one(CGROUP_MASK_MEMORY, "memory");
diff --git a/SOURCES/0331-pid1-fix-DefaultTasksMax-initialization.patch b/SOURCES/0331-pid1-fix-DefaultTasksMax-initialization.patch
new file mode 100644
index 0000000..9c89a62
--- /dev/null
+++ b/SOURCES/0331-pid1-fix-DefaultTasksMax-initialization.patch
@@ -0,0 +1,41 @@
+From e809564cfa5af01a26075682d49f81a987c41dd8 Mon Sep 17 00:00:00 2001
+From: Franck Bui <fbui@suse.com>
+Date: Wed, 2 Oct 2019 11:58:16 +0200
+Subject: [PATCH 331/341] pid1: fix DefaultTasksMax initialization
+
+Otherwise DefaultTasksMax is always set to "inifinity".
+
+This was broken by fb39af4ce42.
+
+(cherry picked from commit c0000de87d2c7934cb1f4ba66a533a85277600ff)
+
+Resolves: #1809037
+---
+ src/core/main.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index d6550ea161..45d09b1e11 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -2088,7 +2088,7 @@ static void reset_arguments(void) {
+         arg_default_blockio_accounting = false;
+         arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
+         arg_default_tasks_accounting = true;
+-        arg_default_tasks_max = UINT64_MAX;
++        arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+         arg_machine_id = (sd_id128_t) {};
+         arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
+ 
+@@ -2103,8 +2103,6 @@ static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
+         assert(saved_rlimit_nofile);
+         assert(saved_rlimit_memlock);
+ 
+-        arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
+-
+         /* Assign configuration defaults */
+         reset_arguments();
+ 
+-- 
+2.21.1
+
diff --git a/SOURCES/0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch b/SOURCES/0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch
new file mode 100644
index 0000000..2596a8e
--- /dev/null
+++ b/SOURCES/0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch
@@ -0,0 +1,43 @@
+From 5fc2d94fbf8271bb340e834f832af5d890c267bf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
+Date: Tue, 3 Mar 2020 11:45:00 +0100
+Subject: [PATCH 332/341] cgroup: make sure that cpuset is supported on cgroup
+ v2 and disabled with v1
+
+Resolves: #1808940
+
+(rhel-only)
+---
+ src/basic/cgroup-util.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
+index 6f47c3aacb..92bc1f2543 100644
+--- a/src/basic/cgroup-util.c
++++ b/src/basic/cgroup-util.c
+@@ -2353,10 +2353,10 @@ int cg_mask_supported(CGroupMask *ret) {
+                 if (r < 0)
+                         return r;
+ 
+-                /* Currently, we support the cpu, memory, io and pids
++                /* Currently, we support the cpu, memory, io, pids and cpuset
+                  * controller in the unified hierarchy, mask
+                  * everything else off. */
+-                mask &= CGROUP_MASK_CPU | CGROUP_MASK_MEMORY | CGROUP_MASK_IO | CGROUP_MASK_PIDS;
++                mask &= CGROUP_MASK_CPU | CGROUP_MASK_MEMORY | CGROUP_MASK_IO | CGROUP_MASK_PIDS | CGROUP_MASK_CPUSET;
+ 
+         } else {
+                 CGroupController c;
+@@ -2367,6 +2367,9 @@ int cg_mask_supported(CGroupMask *ret) {
+                 for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
+                         const char *n;
+ 
++                        if (c == CGROUP_CONTROLLER_CPUSET)
++                                continue;
++
+                         n = cgroup_controller_to_string(c);
+                         if (controller_is_accessible(n) >= 0)
+                                 mask |= CGROUP_CONTROLLER_TO_MASK(c);
+-- 
+2.21.1
+
diff --git a/SOURCES/0333-test-introduce-TEST-36-NUMAPOLICY.patch b/SOURCES/0333-test-introduce-TEST-36-NUMAPOLICY.patch
new file mode 100644
index 0000000..2e1b42a
--- /dev/null
+++ b/SOURCES/0333-test-introduce-TEST-36-NUMAPOLICY.patch
@@ -0,0 +1,383 @@
+From 90dda340e4adeb1126639a849d4f31ae327fdc4b Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Tue, 25 Jun 2019 23:01:40 +0200
+Subject: [PATCH 333/341] test: introduce TEST-36-NUMAPOLICY
+
+(cherry picked from commit 8f65e26508969610ac934d1aadbade8223bfcaac)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/Makefile     |   1 +
+ test/TEST-36-NUMAPOLICY/test.sh      |  51 +++++
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 292 +++++++++++++++++++++++++++
+ 3 files changed, 344 insertions(+)
+ create mode 120000 test/TEST-36-NUMAPOLICY/Makefile
+ create mode 100755 test/TEST-36-NUMAPOLICY/test.sh
+ create mode 100755 test/TEST-36-NUMAPOLICY/testsuite.sh
+
+diff --git a/test/TEST-36-NUMAPOLICY/Makefile b/test/TEST-36-NUMAPOLICY/Makefile
+new file mode 120000
+index 0000000000..e9f93b1104
+--- /dev/null
++++ b/test/TEST-36-NUMAPOLICY/Makefile
+@@ -0,0 +1 @@
++../TEST-01-BASIC/Makefile
+\ No newline at end of file
+diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh
+new file mode 100755
+index 0000000000..a0d8623e8e
+--- /dev/null
++++ b/test/TEST-36-NUMAPOLICY/test.sh
+@@ -0,0 +1,51 @@
++#!/bin/bash
++set -e
++TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options"
++TEST_NO_NSPAWN=1
++QEMU_OPTIONS="-numa node,nodeid=0"
++
++. $TEST_BASE_DIR/test-functions
++
++test_setup() {
++    create_empty_image
++    mkdir -p $TESTDIR/root
++    mount ${LOOPDEV}p1 $TESTDIR/root
++
++    (
++        LOG_LEVEL=5
++        eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
++
++        setup_basic_environment
++        inst_binary mktemp
++
++        # mask some services that we do not want to run in these tests
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
++        ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
++
++        # setup the testsuite service
++        cat >$initdir/etc/systemd/system/testsuite.service <<EOF
++[Unit]
++Description=Testsuite service
++
++[Service]
++ExecStart=/bin/bash -x /testsuite.sh
++Type=oneshot
++StandardOutput=tty
++StandardError=tty
++NotifyAccess=all
++EOF
++        cp testsuite.sh $initdir/
++
++        setup_testsuite
++    ) || return 1
++    setup_nspawn_root
++
++    ddebug "umount $TESTDIR/root"
++    umount $TESTDIR/root
++}
++
++do_test "$@"
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+new file mode 100755
+index 0000000000..e15087b137
+--- /dev/null
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -0,0 +1,292 @@
++#!/bin/bash
++set -ex
++set -o pipefail
++
++at_exit() {
++    if [ $? -ne 0 ]; then
++        # We're exiting with a non-zero EC, let's dump test artifacts
++        # for easier debugging
++        [ -f "$straceLog" ] && cat "$straceLog"
++        [ -f "$journalLog" ] && cat "$journalLog"
++    fi
++}
++
++trap at_exit EXIT
++
++systemd-analyze log-level debug
++systemd-analyze log-target journal
++
++# Log files
++straceLog='strace.log'
++journalLog='journal.log'
++
++# Systemd config files
++testUnit='numa-test.service'
++testUnitFile="/etc/systemd/system/$testUnit"
++testUnitNUMAConf="$testUnitFile.d/numa.conf"
++
++# Sleep constants (we should probably figure out something better but nothing comes to mind)
++journalSleep=5
++sleepAfterStart=1
++
++startStrace() {
++    coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1
++}
++
++stopStrace() {
++    kill -s TERM $COPROC_PID
++}
++
++startJournalctl() {
++    coproc journalctl -u init.scope -f > $journalLog
++}
++
++stopJournalctl() {
++    # Wait a few seconds until the messages get properly queued...
++    sleep $journalSleep
++    # ...and then force journald to write them to the backing storage
++    # Also, using journalctl --sync should be better than using SIGRTMIN+1, as
++    # the --sync wait until the synchronization is complete
++    echo "Force journald to write all queued messages"
++    journalctl --sync
++    kill -s TERM $COPROC_PID
++}
++
++checkNUMA() {
++    # NUMA enabled system should have at least NUMA node0
++    test -e /sys/devices/system/node/node0
++}
++
++writePID1NUMAPolicy() {
++    echo [Manager] > $confDir/numa.conf
++    echo NUMAPolicy=$1 >> $confDir/numa.conf
++    echo NUMAMask=$2>> $confDir/numa.conf
++}
++
++writeTestUnit() {
++    echo [Service] > $testUnitFile
++    echo ExecStart=/bin/sleep 3600 >> $testUnitFile
++    mkdir -p $testUnitFile.d/
++}
++
++writeTestUnitNUMAPolicy() {
++    echo [Service] > $testUnitNUMAConf
++    echo NUMAPolicy=$1 >> $testUnitNUMAConf
++    echo NUMAMask=$2>> $testUnitNUMAConf
++    systemctl daemon-reload
++}
++
++pid1ReloadWithStrace() {
++    startStrace
++    systemctl daemon-reload
++    stopStrace
++}
++
++pid1ReloadWithJournal() {
++    startJournalctl
++    systemctl daemon-reload
++    stopJournalctl
++}
++
++pid1StartUnitWithStrace() {
++    startStrace '-f'
++    systemctl start $1
++    sleep $sleepAfterStart
++    stopStrace
++}
++
++pid1StartUnitWithJournal() {
++    startJournalctl
++    systemctl start $1
++    sleep $sleepAfterStart
++    stopJournalctl
++}
++
++pid1StopUnit() {
++    systemctl stop $1
++}
++
++systemctlCheckNUMAProperties() {
++    local LOGFILE="$(mktemp)"
++    systemctl show -p NUMAPolicy $1 > "$LOGFILE"
++    grep "NUMAPolicy=$2" "$LOGFILE"
++
++    > "$LOGFILE"
++
++    if [ -n $3 ]; then
++        systemctl show -p NUMAMask $1 > "$LOGFILE"
++        grep "NUMAMask=$3" "$LOGFILE"
++    fi
++}
++
++checkNUMA
++writeTestUnit
++
++# Create systemd config drop-in directory
++confDir="/etc/systemd/system.conf.d/"
++mkdir -p "$confDir"
++
++echo "PID1 NUMAPolicy support - Default policy w/o mask"
++writePID1NUMAPolicy "default"
++pid1ReloadWithStrace
++# Kernel requires that nodemask argument is set to NULL when setting default policy
++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++echo "PID1 NUMAPolicy support - Default policy w/ mask"
++writePID1NUMAPolicy "default" "0"
++pid1ReloadWithStrace
++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++echo "PID1 NUMAPolicy support - Bind policy w/o mask"
++writePID1NUMAPolicy "bind"
++pid1ReloadWithJournal
++grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
++
++echo "PID1 NUMAPolicy support - Bind policy w/ mask"
++writePID1NUMAPolicy "bind" "0"
++pid1ReloadWithStrace
++grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
++
++echo "PID1 NUMAPolicy support - Interleave policy w/o mask"
++writePID1NUMAPolicy "interleave"
++pid1ReloadWithJournal
++grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
++
++echo "PID1 NUMAPolicy support - Interleave policy w/ mask"
++writePID1NUMAPolicy "interleave" "0"
++pid1ReloadWithStrace
++grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
++
++echo "PID1 NUMAPolicy support - Preferred policy w/o mask"
++writePID1NUMAPolicy "preferred"
++pid1ReloadWithJournal
++# Preferred policy with empty node mask is actually allowed and should reset allocation policy to default
++! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
++
++echo "PID1 NUMAPolicy support - Preferred policy w/ mask"
++writePID1NUMAPolicy "preferred" "0"
++pid1ReloadWithStrace
++grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
++
++echo "PID1 NUMAPolicy support - Local policy w/o mask"
++writePID1NUMAPolicy "local"
++pid1ReloadWithStrace
++# Kernel requires that nodemask argument is set to NULL when setting default policy
++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++
++echo "PID1 NUMAPolicy support - Local policy w/ mask"
++writePID1NUMAPolicy "local" "0"
++pid1ReloadWithStrace
++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++
++echo "Unit file NUMAPolicy support - Default policy w/o mask"
++writeTestUnitNUMAPolicy "default"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "default"
++pid1StopUnit $testUnit
++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++echo "Unit file NUMAPolicy support - Default policy w/ mask"
++writeTestUnitNUMAPolicy "default" "0"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "default" "0"
++pid1StopUnit $testUnit
++# Maks must be ignored
++grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++echo "Unit file NUMAPolicy support - Bind policy w/o mask"
++writeTestUnitNUMAPolicy "bind"
++pid1StartUnitWithJournal $testUnit
++pid1StopUnit $testUnit
++grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
++
++echo "Unit file NUMAPolicy support - Bind policy w/ mask"
++writeTestUnitNUMAPolicy "bind" "0"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "bind" "0"
++pid1StopUnit $testUnit
++grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
++
++echo "Unit file NUMAPolicy support - Interleave policy w/o mask"
++writeTestUnitNUMAPolicy "interleave"
++pid1StartUnitWithStrace $testUnit
++pid1StopUnit $testUnit
++grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
++
++echo "Unit file NUMAPolicy support - Interleave policy w/ mask"
++writeTestUnitNUMAPolicy "interleave" "0"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "interleave" "0"
++pid1StopUnit $testUnit
++grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
++
++echo "Unit file NUMAPolicy support - Preferred policy w/o mask"
++writeTestUnitNUMAPolicy "preferred"
++pid1StartUnitWithJournal $testUnit
++systemctlCheckNUMAProperties $testUnit "preferred"
++pid1StopUnit $testUnit
++! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
++
++echo "Unit file NUMAPolicy support - Preferred policy w/ mask"
++writeTestUnitNUMAPolicy "preferred" "0"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "preferred" "0"
++pid1StopUnit $testUnit
++grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
++
++echo "Unit file NUMAPolicy support - Local policy w/o mask"
++writeTestUnitNUMAPolicy "local"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "local"
++pid1StopUnit $testUnit
++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++
++echo "Unit file NUMAPolicy support - Local policy w/ mask"
++writeTestUnitNUMAPolicy "local" "0"
++pid1StartUnitWithStrace $testUnit
++systemctlCheckNUMAProperties $testUnit "local" "0"
++pid1StopUnit $testUnit
++# Maks must be ignored
++grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++
++echo "systemd-run NUMAPolicy support"
++runUnit='numa-systemd-run-test.service'
++
++systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "default"
++pid1StopUnit $runUnit
++
++systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "default" ""
++pid1StopUnit $runUnit
++
++systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "bind" "0"
++pid1StopUnit $runUnit
++
++systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "interleave" "0"
++pid1StopUnit $runUnit
++
++systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "preferred" "0"
++pid1StopUnit $runUnit
++
++systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "local"
++pid1StopUnit $runUnit
++
++systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000
++systemctlCheckNUMAProperties $runUnit "local" ""
++pid1StopUnit $runUnit
++
++# Cleanup
++rm -rf $testDir
++rm -rf $confDir
++systemctl daemon-reload
++
++systemd-analyze log-level info
++
++echo OK > /testok
++
++exit 0
+-- 
+2.21.1
+
diff --git a/SOURCES/0334-test-replace-tail-f-with-journal-cursor-which-should.patch b/SOURCES/0334-test-replace-tail-f-with-journal-cursor-which-should.patch
new file mode 100644
index 0000000..8254d16
--- /dev/null
+++ b/SOURCES/0334-test-replace-tail-f-with-journal-cursor-which-should.patch
@@ -0,0 +1,55 @@
+From b93a2617d49d9636801130d974995cabe6335b71 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Mon, 1 Jul 2019 09:27:59 +0200
+Subject: [PATCH 334/341] test: replace `tail -f` with journal cursor which
+ should be...
+
+more reliable
+
+(cherry picked from commit d0b2178f3e79f302702bd7140766eee03643f734)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index e15087b137..306a96b517 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -29,6 +29,9 @@ testUnitNUMAConf="$testUnitFile.d/numa.conf"
+ journalSleep=5
+ sleepAfterStart=1
+ 
++# Journal cursor for easier navigation
++journalCursorFile="jounalCursorFile"
++
+ startStrace() {
+     coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1
+ }
+@@ -38,18 +41,16 @@ stopStrace() {
+ }
+ 
+ startJournalctl() {
+-    coproc journalctl -u init.scope -f > $journalLog
++    # Save journal's cursor for later navigation
++    journalctl --no-pager --cursor-file="$journalCursorFile" -n0 -ocat
+ }
+ 
+ stopJournalctl() {
+-    # Wait a few seconds until the messages get properly queued...
+-    sleep $journalSleep
+-    # ...and then force journald to write them to the backing storage
+-    # Also, using journalctl --sync should be better than using SIGRTMIN+1, as
++    # Using journalctl --sync should be better than using SIGRTMIN+1, as
+     # the --sync wait until the synchronization is complete
+     echo "Force journald to write all queued messages"
+     journalctl --sync
+-    kill -s TERM $COPROC_PID
++    journalctl -u init.scope --cursor-file="$journalCursorFile" > "$journalLog"
+ }
+ 
+ checkNUMA() {
+-- 
+2.21.1
+
diff --git a/SOURCES/0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch b/SOURCES/0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch
new file mode 100644
index 0000000..8d293d9
--- /dev/null
+++ b/SOURCES/0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch
@@ -0,0 +1,61 @@
+From d6d43b81df76d571d57f83ceb050c8b4ac4701b8 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Mon, 1 Jul 2019 13:08:26 +0200
+Subject: [PATCH 335/341] test: support MPOL_LOCAL matching in unpatched strace
+ versions
+
+The MPOL_LOCAL constant is not recognized in current strace versions.
+Let's match at least the numerical value of this constant until the
+strace patch is approved & merged.
+
+(cherry picked from commit ac14396d027023e1be910327989cb422cb2f6724)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index 306a96b517..a4134bdeca 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -173,12 +173,16 @@ echo "PID1 NUMAPolicy support - Local policy w/o mask"
+ writePID1NUMAPolicy "local"
+ pid1ReloadWithStrace
+ # Kernel requires that nodemask argument is set to NULL when setting default policy
+-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++# The unpatched versions of strace don't recognize the MPOL_LOCAL constant and
++# return a numerical constant instead (with a comment):
++#   set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0
++# Let's cover this scenario as well
++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+ 
+ echo "PID1 NUMAPolicy support - Local policy w/ mask"
+ writePID1NUMAPolicy "local" "0"
+ pid1ReloadWithStrace
+-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+ 
+ echo "Unit file NUMAPolicy support - Default policy w/o mask"
+ writeTestUnitNUMAPolicy "default"
+@@ -240,7 +244,7 @@ writeTestUnitNUMAPolicy "local"
+ pid1StartUnitWithStrace $testUnit
+ systemctlCheckNUMAProperties $testUnit "local"
+ pid1StopUnit $testUnit
+-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+ 
+ echo "Unit file NUMAPolicy support - Local policy w/ mask"
+ writeTestUnitNUMAPolicy "local" "0"
+@@ -248,7 +252,7 @@ pid1StartUnitWithStrace $testUnit
+ systemctlCheckNUMAProperties $testUnit "local" "0"
+ pid1StopUnit $testUnit
+ # Maks must be ignored
+-grep "set_mempolicy(MPOL_LOCAL, NULL" $straceLog
++grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+ 
+ echo "systemd-run NUMAPolicy support"
+ runUnit='numa-systemd-run-test.service'
+-- 
+2.21.1
+
diff --git a/SOURCES/0336-test-make-sure-the-strace-process-is-indeed-dead.patch b/SOURCES/0336-test-make-sure-the-strace-process-is-indeed-dead.patch
new file mode 100644
index 0000000..55d9b4f
--- /dev/null
+++ b/SOURCES/0336-test-make-sure-the-strace-process-is-indeed-dead.patch
@@ -0,0 +1,53 @@
+From 60813b55f9b5b44b14f38bbc1b8c0d2b30e3f6c7 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Mon, 1 Jul 2019 19:53:45 +0200
+Subject: [PATCH 336/341] test: make sure the strace process is indeed dead
+
+It may take a few moments for the strace process to properly terminate
+and write all logs to the backing storage
+
+(cherry picked from commit 56425e54a2140f47b4560b51c5db08aa2de199a6)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/test.sh      | 2 +-
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh
+index a0d8623e8e..f0a321e7a1 100755
+--- a/test/TEST-36-NUMAPOLICY/test.sh
++++ b/test/TEST-36-NUMAPOLICY/test.sh
+@@ -16,7 +16,7 @@ test_setup() {
+         eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+ 
+         setup_basic_environment
+-        inst_binary mktemp
++        dracut_install mktemp
+ 
+         # mask some services that we do not want to run in these tests
+         ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index a4134bdeca..daed8fcc1c 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -38,6 +38,8 @@ startStrace() {
+ 
+ stopStrace() {
+     kill -s TERM $COPROC_PID
++    # Make sure the strace process is indeed dead
++    while kill -0 $COPROC_PID 2>/dev/null; do sleep 0.1; done
+ }
+ 
+ startJournalctl() {
+@@ -80,6 +82,7 @@ writeTestUnitNUMAPolicy() {
+ pid1ReloadWithStrace() {
+     startStrace
+     systemctl daemon-reload
++    sleep $sleepAfterStart
+     stopStrace
+ }
+ 
+-- 
+2.21.1
+
diff --git a/SOURCES/0337-test-skip-the-test-on-systems-without-NUMA-support.patch b/SOURCES/0337-test-skip-the-test-on-systems-without-NUMA-support.patch
new file mode 100644
index 0000000..2680709
--- /dev/null
+++ b/SOURCES/0337-test-skip-the-test-on-systems-without-NUMA-support.patch
@@ -0,0 +1,39 @@
+From ad3e4a0f010c9497b01d89de54213af982f8afd2 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Tue, 2 Jul 2019 09:52:45 +0200
+Subject: [PATCH 337/341] test: skip the test on systems without NUMA support
+
+(cherry picked from commit b030847163e9bd63d3dd6eec6ac7f336411faba6)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index daed8fcc1c..4b715d305a 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -123,7 +123,18 @@ systemctlCheckNUMAProperties() {
+     fi
+ }
+ 
+-checkNUMA
++if ! checkNUMA; then
++    echo >&2 "NUMA is not supported on this machine, skipping the test"
++
++    # FIXME: add some sanity checks to verify systemd behaves correctly with
++    #        NUMA disabled together with NUMAPolicy= and NUMAMask=
++
++    systemd-analyze log-level info
++    echo OK > /testok
++
++    exit 0
++fi
++
+ writeTestUnit
+ 
+ # Create systemd config drop-in directory
+-- 
+2.21.1
+
diff --git a/SOURCES/0338-test-give-strace-some-time-to-initialize.patch b/SOURCES/0338-test-give-strace-some-time-to-initialize.patch
new file mode 100644
index 0000000..5d68666
--- /dev/null
+++ b/SOURCES/0338-test-give-strace-some-time-to-initialize.patch
@@ -0,0 +1,33 @@
+From 66f6f6304d87b2fe0c4f91373c7d1b836de1b054 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Tue, 23 Jul 2019 00:56:04 +0200
+Subject: [PATCH 338/341] test: give strace some time to initialize
+
+The `coproc` implementation seems to be a little bit different in older
+bash versions, so the `strace` is sometimes started AFTER `systemctl
+daemon-reload`, which causes unexpected fails. Let's help it a little by
+sleeping for a bit.
+
+(cherry picked from commit c7367d7cfdfdcec98f8659f0ed3f1d7b77123903)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index 4b715d305a..1c8cf7e6b6 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -34,6 +34,8 @@ journalCursorFile="jounalCursorFile"
+ 
+ startStrace() {
+     coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1
++    # Wait for strace to properly "initialize"
++    sleep $sleepAfterStart
+ }
+ 
+ stopStrace() {
+-- 
+2.21.1
+
diff --git a/SOURCES/0339-test-add-a-simple-sanity-check-for-systems-without-N.patch b/SOURCES/0339-test-add-a-simple-sanity-check-for-systems-without-N.patch
new file mode 100644
index 0000000..10d52aa
--- /dev/null
+++ b/SOURCES/0339-test-add-a-simple-sanity-check-for-systems-without-N.patch
@@ -0,0 +1,394 @@
+From 8239ecf0b4b8bbe5b3c17964d230d13cee4d900a Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Mon, 5 Aug 2019 14:38:45 +0200
+Subject: [PATCH 339/341] test: add a simple sanity check for systems without
+ NUMA support
+
+(cherry picked from commit 92f8e978923f962a57d744c5f358520ac06f7892)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 350 ++++++++++++++-------------
+ 1 file changed, 180 insertions(+), 170 deletions(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index 1c8cf7e6b6..a5ac788178 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -50,11 +50,12 @@ startJournalctl() {
+ }
+ 
+ stopJournalctl() {
++    local unit="${1:-init.scope}"
+     # Using journalctl --sync should be better than using SIGRTMIN+1, as
+     # the --sync wait until the synchronization is complete
+     echo "Force journald to write all queued messages"
+     journalctl --sync
+-    journalctl -u init.scope --cursor-file="$journalCursorFile" > "$journalLog"
++    journalctl -u $unit --cursor-file="$journalCursorFile" > "$journalLog"
+ }
+ 
+ checkNUMA() {
+@@ -125,181 +126,190 @@ systemctlCheckNUMAProperties() {
+     fi
+ }
+ 
+-if ! checkNUMA; then
+-    echo >&2 "NUMA is not supported on this machine, skipping the test"
+-
+-    # FIXME: add some sanity checks to verify systemd behaves correctly with
+-    #        NUMA disabled together with NUMAPolicy= and NUMAMask=
+-
+-    systemd-analyze log-level info
+-    echo OK > /testok
+-
+-    exit 0
+-fi
+-
+ writeTestUnit
+ 
+ # Create systemd config drop-in directory
+ confDir="/etc/systemd/system.conf.d/"
+ mkdir -p "$confDir"
+ 
+-echo "PID1 NUMAPolicy support - Default policy w/o mask"
+-writePID1NUMAPolicy "default"
+-pid1ReloadWithStrace
+-# Kernel requires that nodemask argument is set to NULL when setting default policy
+-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
+-
+-echo "PID1 NUMAPolicy support - Default policy w/ mask"
+-writePID1NUMAPolicy "default" "0"
+-pid1ReloadWithStrace
+-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
+-
+-echo "PID1 NUMAPolicy support - Bind policy w/o mask"
+-writePID1NUMAPolicy "bind"
+-pid1ReloadWithJournal
+-grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
+-
+-echo "PID1 NUMAPolicy support - Bind policy w/ mask"
+-writePID1NUMAPolicy "bind" "0"
+-pid1ReloadWithStrace
+-grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
+-
+-echo "PID1 NUMAPolicy support - Interleave policy w/o mask"
+-writePID1NUMAPolicy "interleave"
+-pid1ReloadWithJournal
+-grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
+-
+-echo "PID1 NUMAPolicy support - Interleave policy w/ mask"
+-writePID1NUMAPolicy "interleave" "0"
+-pid1ReloadWithStrace
+-grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
+-
+-echo "PID1 NUMAPolicy support - Preferred policy w/o mask"
+-writePID1NUMAPolicy "preferred"
+-pid1ReloadWithJournal
+-# Preferred policy with empty node mask is actually allowed and should reset allocation policy to default
+-! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
+-
+-echo "PID1 NUMAPolicy support - Preferred policy w/ mask"
+-writePID1NUMAPolicy "preferred" "0"
+-pid1ReloadWithStrace
+-grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
+-
+-echo "PID1 NUMAPolicy support - Local policy w/o mask"
+-writePID1NUMAPolicy "local"
+-pid1ReloadWithStrace
+-# Kernel requires that nodemask argument is set to NULL when setting default policy
+-# The unpatched versions of strace don't recognize the MPOL_LOCAL constant and
+-# return a numerical constant instead (with a comment):
+-#   set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0
+-# Let's cover this scenario as well
+-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+-
+-echo "PID1 NUMAPolicy support - Local policy w/ mask"
+-writePID1NUMAPolicy "local" "0"
+-pid1ReloadWithStrace
+-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Default policy w/o mask"
+-writeTestUnitNUMAPolicy "default"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "default"
+-pid1StopUnit $testUnit
+-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Default policy w/ mask"
+-writeTestUnitNUMAPolicy "default" "0"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "default" "0"
+-pid1StopUnit $testUnit
+-# Maks must be ignored
+-grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Bind policy w/o mask"
+-writeTestUnitNUMAPolicy "bind"
+-pid1StartUnitWithJournal $testUnit
+-pid1StopUnit $testUnit
+-grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
+-
+-echo "Unit file NUMAPolicy support - Bind policy w/ mask"
+-writeTestUnitNUMAPolicy "bind" "0"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "bind" "0"
+-pid1StopUnit $testUnit
+-grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Interleave policy w/o mask"
+-writeTestUnitNUMAPolicy "interleave"
+-pid1StartUnitWithStrace $testUnit
+-pid1StopUnit $testUnit
+-grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
+-
+-echo "Unit file NUMAPolicy support - Interleave policy w/ mask"
+-writeTestUnitNUMAPolicy "interleave" "0"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "interleave" "0"
+-pid1StopUnit $testUnit
+-grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Preferred policy w/o mask"
+-writeTestUnitNUMAPolicy "preferred"
+-pid1StartUnitWithJournal $testUnit
+-systemctlCheckNUMAProperties $testUnit "preferred"
+-pid1StopUnit $testUnit
+-! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
+-
+-echo "Unit file NUMAPolicy support - Preferred policy w/ mask"
+-writeTestUnitNUMAPolicy "preferred" "0"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "preferred" "0"
+-pid1StopUnit $testUnit
+-grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Local policy w/o mask"
+-writeTestUnitNUMAPolicy "local"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "local"
+-pid1StopUnit $testUnit
+-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+-
+-echo "Unit file NUMAPolicy support - Local policy w/ mask"
+-writeTestUnitNUMAPolicy "local" "0"
+-pid1StartUnitWithStrace $testUnit
+-systemctlCheckNUMAProperties $testUnit "local" "0"
+-pid1StopUnit $testUnit
+-# Maks must be ignored
+-grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
+-
+-echo "systemd-run NUMAPolicy support"
+-runUnit='numa-systemd-run-test.service'
+-
+-systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "default"
+-pid1StopUnit $runUnit
+-
+-systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "default" ""
+-pid1StopUnit $runUnit
+-
+-systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "bind" "0"
+-pid1StopUnit $runUnit
+-
+-systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "interleave" "0"
+-pid1StopUnit $runUnit
+-
+-systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "preferred" "0"
+-pid1StopUnit $runUnit
+-
+-systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "local"
+-pid1StopUnit $runUnit
+-
+-systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000
+-systemctlCheckNUMAProperties $runUnit "local" ""
+-pid1StopUnit $runUnit
++if ! checkNUMA; then
++    echo >&2 "NUMA is not supported on this machine, switching to a simple sanity check"
++
++    echo "PID1 NUMAPolicy=default && NUMAMask=0 check without NUMA support"
++    writePID1NUMAPolicy "default" "0"
++    startJournalctl
++    systemctl daemon-reload
++    stopJournalctl
++    grep "NUMA support not available, ignoring" "$journalLog"
++
++    echo "systemd-run NUMAPolicy=default && NUMAMask=0 check without NUMA support"
++    runUnit='numa-systemd-run-test.service'
++    startJournalctl
++    systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000
++    sleep $sleepAfterStart
++    pid1StopUnit $runUnit
++    stopJournalctl $runUnit
++    grep "NUMA support not available, ignoring" "$journalLog"
++
++else
++    echo "PID1 NUMAPolicy support - Default policy w/o mask"
++    writePID1NUMAPolicy "default"
++    pid1ReloadWithStrace
++    # Kernel requires that nodemask argument is set to NULL when setting default policy
++    grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++    echo "PID1 NUMAPolicy support - Default policy w/ mask"
++    writePID1NUMAPolicy "default" "0"
++    pid1ReloadWithStrace
++    grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++    echo "PID1 NUMAPolicy support - Bind policy w/o mask"
++    writePID1NUMAPolicy "bind"
++    pid1ReloadWithJournal
++    grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
++
++    echo "PID1 NUMAPolicy support - Bind policy w/ mask"
++    writePID1NUMAPolicy "bind" "0"
++    pid1ReloadWithStrace
++    grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
++
++    echo "PID1 NUMAPolicy support - Interleave policy w/o mask"
++    writePID1NUMAPolicy "interleave"
++    pid1ReloadWithJournal
++    grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
++
++    echo "PID1 NUMAPolicy support - Interleave policy w/ mask"
++    writePID1NUMAPolicy "interleave" "0"
++    pid1ReloadWithStrace
++    grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
++
++    echo "PID1 NUMAPolicy support - Preferred policy w/o mask"
++    writePID1NUMAPolicy "preferred"
++    pid1ReloadWithJournal
++    # Preferred policy with empty node mask is actually allowed and should reset allocation policy to default
++    ! grep "Failed to set NUMA memory policy: Invalid argument" $journalLog
++
++    echo "PID1 NUMAPolicy support - Preferred policy w/ mask"
++    writePID1NUMAPolicy "preferred" "0"
++    pid1ReloadWithStrace
++    grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
++
++    echo "PID1 NUMAPolicy support - Local policy w/o mask"
++    writePID1NUMAPolicy "local"
++    pid1ReloadWithStrace
++    # Kernel requires that nodemask argument is set to NULL when setting default policy
++    # The unpatched versions of strace don't recognize the MPOL_LOCAL constant and
++    # return a numerical constant instead (with a comment):
++    #   set_mempolicy(0x4 /* MPOL_??? */, NULL, 0) = 0
++    # Let's cover this scenario as well
++    grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
++
++    echo "PID1 NUMAPolicy support - Local policy w/ mask"
++    writePID1NUMAPolicy "local" "0"
++    pid1ReloadWithStrace
++    grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
++
++    echo "Unit file NUMAPolicy support - Default policy w/o mask"
++    writeTestUnitNUMAPolicy "default"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "default"
++    pid1StopUnit $testUnit
++    grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++    echo "Unit file NUMAPolicy support - Default policy w/ mask"
++    writeTestUnitNUMAPolicy "default" "0"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "default" "0"
++    pid1StopUnit $testUnit
++    # Maks must be ignored
++    grep "set_mempolicy(MPOL_DEFAULT, NULL" $straceLog
++
++    echo "Unit file NUMAPolicy support - Bind policy w/o mask"
++    writeTestUnitNUMAPolicy "bind"
++    pid1StartUnitWithJournal $testUnit
++    pid1StopUnit $testUnit
++    grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
++
++    echo "Unit file NUMAPolicy support - Bind policy w/ mask"
++    writeTestUnitNUMAPolicy "bind" "0"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "bind" "0"
++    pid1StopUnit $testUnit
++    grep -P "set_mempolicy\(MPOL_BIND, \[0x0*1\]" $straceLog
++
++    echo "Unit file NUMAPolicy support - Interleave policy w/o mask"
++    writeTestUnitNUMAPolicy "interleave"
++    pid1StartUnitWithStrace $testUnit
++    pid1StopUnit $testUnit
++    grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
++
++    echo "Unit file NUMAPolicy support - Interleave policy w/ mask"
++    writeTestUnitNUMAPolicy "interleave" "0"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "interleave" "0"
++    pid1StopUnit $testUnit
++    grep -P "set_mempolicy\(MPOL_INTERLEAVE, \[0x0*1\]" $straceLog
++
++    echo "Unit file NUMAPolicy support - Preferred policy w/o mask"
++    writeTestUnitNUMAPolicy "preferred"
++    pid1StartUnitWithJournal $testUnit
++    systemctlCheckNUMAProperties $testUnit "preferred"
++    pid1StopUnit $testUnit
++    ! grep "numa-test.service: Main process exited, code=exited, status=242/NUMA" $journalLog
++
++    echo "Unit file NUMAPolicy support - Preferred policy w/ mask"
++    writeTestUnitNUMAPolicy "preferred" "0"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "preferred" "0"
++    pid1StopUnit $testUnit
++    grep -P "set_mempolicy\(MPOL_PREFERRED, \[0x0*1\]" $straceLog
++
++    echo "Unit file NUMAPolicy support - Local policy w/o mask"
++    writeTestUnitNUMAPolicy "local"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "local"
++    pid1StopUnit $testUnit
++    grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
++
++    echo "Unit file NUMAPolicy support - Local policy w/ mask"
++    writeTestUnitNUMAPolicy "local" "0"
++    pid1StartUnitWithStrace $testUnit
++    systemctlCheckNUMAProperties $testUnit "local" "0"
++    pid1StopUnit $testUnit
++    # Maks must be ignored
++    grep -E "set_mempolicy\((MPOL_LOCAL|0x4 [^,]*), NULL" $straceLog
++
++    echo "systemd-run NUMAPolicy support"
++    runUnit='numa-systemd-run-test.service'
++
++    systemd-run -p NUMAPolicy=default --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "default"
++    pid1StopUnit $runUnit
++
++    systemd-run -p NUMAPolicy=default -p NUMAMask=0 --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "default" ""
++    pid1StopUnit $runUnit
++
++    systemd-run -p NUMAPolicy=bind -p NUMAMask=0 --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "bind" "0"
++    pid1StopUnit $runUnit
++
++    systemd-run -p NUMAPolicy=interleave -p NUMAMask=0 --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "interleave" "0"
++    pid1StopUnit $runUnit
++
++    systemd-run -p NUMAPolicy=preferred -p NUMAMask=0 --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "preferred" "0"
++    pid1StopUnit $runUnit
++
++    systemd-run -p NUMAPolicy=local --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "local"
++    pid1StopUnit $runUnit
++
++    systemd-run -p NUMAPolicy=local -p NUMAMask=0 --unit $runUnit sleep 1000
++    systemctlCheckNUMAProperties $runUnit "local" ""
++    pid1StopUnit $runUnit
++fi
+ 
+ # Cleanup
+ rm -rf $testDir
+-- 
+2.21.1
+
diff --git a/SOURCES/0340-test-drop-the-missed-exit-1-expression.patch b/SOURCES/0340-test-drop-the-missed-exit-1-expression.patch
new file mode 100644
index 0000000..d0df520
--- /dev/null
+++ b/SOURCES/0340-test-drop-the-missed-exit-1-expression.patch
@@ -0,0 +1,38 @@
+From 772f08f8255d7ab921c344ab4243249cbd1c37fc Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <frantisek@sumsal.cz>
+Date: Sat, 10 Aug 2019 16:05:07 +0200
+Subject: [PATCH 340/341] test: drop the missed || exit 1 expression
+
+...as we've already done in the rest of the testsuite, see
+cc469c3dfc398210f38f819d367e68646c71d8da
+
+(cherry picked from commit 67c434b03f8a24f5350f017dfb4b2464406046db)
+
+Related: #1808940
+---
+ test/TEST-36-NUMAPOLICY/test.sh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh
+index f0a321e7a1..3b3b120423 100755
+--- a/test/TEST-36-NUMAPOLICY/test.sh
++++ b/test/TEST-36-NUMAPOLICY/test.sh
+@@ -1,5 +1,6 @@
+ #!/bin/bash
+ set -e
++
+ TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options"
+ TEST_NO_NSPAWN=1
+ QEMU_OPTIONS="-numa node,nodeid=0"
+@@ -41,7 +42,7 @@ EOF
+         cp testsuite.sh $initdir/
+ 
+         setup_testsuite
+-    ) || return 1
++    )
+     setup_nspawn_root
+ 
+     ddebug "umount $TESTDIR/root"
+-- 
+2.21.1
+
diff --git a/SOURCES/0341-test-replace-cursor-file-with-a-plain-cursor.patch b/SOURCES/0341-test-replace-cursor-file-with-a-plain-cursor.patch
new file mode 100644
index 0000000..f3b1f25
--- /dev/null
+++ b/SOURCES/0341-test-replace-cursor-file-with-a-plain-cursor.patch
@@ -0,0 +1,62 @@
+From 0bef8805c81eecfe3960bf00b6022837e4979198 Mon Sep 17 00:00:00 2001
+From: Frantisek Sumsal <fsumsal@redhat.com>
+Date: Tue, 3 Mar 2020 15:54:29 +0100
+Subject: [PATCH 341/341] test: replace cursor file with a plain cursor
+
+systemd in RHEL 8 doesn't support the --cursor-file option, so let's
+fall back to a plain cursor string
+
+Related: #1808940
+rhel-only
+---
+ test/TEST-36-NUMAPOLICY/test.sh      | 2 +-
+ test/TEST-36-NUMAPOLICY/testsuite.sh | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh
+index 3b3b120423..7cc909765b 100755
+--- a/test/TEST-36-NUMAPOLICY/test.sh
++++ b/test/TEST-36-NUMAPOLICY/test.sh
+@@ -17,7 +17,7 @@ test_setup() {
+         eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
+ 
+         setup_basic_environment
+-        dracut_install mktemp
++        dracut_install mktemp awk
+ 
+         # mask some services that we do not want to run in these tests
+         ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
+diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/TEST-36-NUMAPOLICY/testsuite.sh
+index a5ac788178..bffac4ffe6 100755
+--- a/test/TEST-36-NUMAPOLICY/testsuite.sh
++++ b/test/TEST-36-NUMAPOLICY/testsuite.sh
+@@ -30,7 +30,7 @@ journalSleep=5
+ sleepAfterStart=1
+ 
+ # Journal cursor for easier navigation
+-journalCursorFile="jounalCursorFile"
++journalCursor=""
+ 
+ startStrace() {
+     coproc strace -qq -p 1 -o $straceLog -e set_mempolicy -s 1024 $1
+@@ -46,7 +46,7 @@ stopStrace() {
+ 
+ startJournalctl() {
+     # Save journal's cursor for later navigation
+-    journalctl --no-pager --cursor-file="$journalCursorFile" -n0 -ocat
++    journalCursor="$(journalctl --no-pager --show-cursor -n0 -ocat | awk '{print $3}')"
+ }
+ 
+ stopJournalctl() {
+@@ -55,7 +55,7 @@ stopJournalctl() {
+     # the --sync wait until the synchronization is complete
+     echo "Force journald to write all queued messages"
+     journalctl --sync
+-    journalctl -u $unit --cursor-file="$journalCursorFile" > "$journalLog"
++    journalctl -u $unit --after-cursor="$journalCursor" > "$journalLog"
+ }
+ 
+ checkNUMA() {
+-- 
+2.21.1
+
diff --git a/SOURCES/0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch b/SOURCES/0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch
new file mode 100644
index 0000000..4fee429
--- /dev/null
+++ b/SOURCES/0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch
@@ -0,0 +1,32 @@
+From ed282d8d84fa32aaef21994d92d1d3dbfa281094 Mon Sep 17 00:00:00 2001
+From: Ryan Gonzalez <kirbyfan64@users.noreply.github.com>
+Date: Fri, 22 Feb 2019 23:45:03 -0600
+Subject: [PATCH] cryptsetup: Treat key file errors as a failed password
+ attempt
+
+6f177c7dc092eb68762b4533d41b14244adb2a73 caused key file errors to immediately fail, which would make it hard to correct an issue due to e.g. a crypttab typo or a damaged key file.
+
+Closes #11723.
+
+(cherry picked from commit c20db3887569e0c0d9c0e2845c5286e7edf0133a)
+
+Related: #1763155
+---
+ src/cryptsetup/cryptsetup.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index 33c215eaa1..11162eb722 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -558,6 +558,10 @@ static int attach_luks_or_plain(struct crypt_device *cd,
+                         log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file);
+                         return -EAGAIN; /* Log actual error, but return EAGAIN */
+                 }
++                if (r == -EINVAL) {
++                        log_error_errno(r, "Failed to activate with key file '%s'. (Key file missing?)", key_file);
++                        return -EAGAIN; /* Log actual error, but return EAGAIN */
++                }
+                 if (r < 0)
+                         return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
+         } else {
diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec
index 9f79b7c..1c03e7a 100644
--- a/SPECS/systemd.spec
+++ b/SPECS/systemd.spec
@@ -13,7 +13,7 @@
 Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 Version:        239
-Release:        18%{?dist}.5
+Release:        29%{?dist}
 # For a breakdown of the licensing, see README
 License:        LGPLv2+ and MIT and GPLv2+
 Summary:        System and Service Manager
@@ -265,32 +265,133 @@ Patch0212: 0212-mount-simplify-proc-self-mountinfo-handler.patch
 Patch0213: 0213-mount-rescan-proc-self-mountinfo-before-processing-w.patch
 Patch0214: 0214-swap-scan-proc-swaps-before-processing-waitid-result.patch
 Patch0215: 0215-analyze-security-fix-potential-division-by-zero.patch
-Patch0216: 0216-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
-Patch0217: 0217-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
-Patch0218: 0218-sd-bus-adjust-indentation-of-comments.patch
-Patch0219: 0219-resolved-do-not-run-loop-twice.patch
-Patch0220: 0220-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
-Patch0221: 0221-resolved-query-polkit-only-after-parsing-the-data.patch
-Patch0222: 0222-ask-password-prevent-buffer-overrow-when-reading-fro.patch
-Patch0223: 0223-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
-Patch0224: 0224-syslog-fix-segfault-in-syslog_parse_priority.patch
-Patch0225: 0225-journald-fixed-assertion-failure-when-system-journal.patch
-Patch0226: 0226-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
-Patch0227: 0227-test-mask-several-unnecessary-services.patch
-Patch0228: 0228-test-bump-the-second-partition-s-size-to-50M.patch
-Patch0229: 0229-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch
-Patch0230: 0230-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch
-Patch0231: 0231-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch
-Patch0232: 0232-sd-bus-drop-two-inappropriate-empty-lines.patch
-Patch0233: 0233-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch
-Patch0234: 0234-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch
-Patch0235: 0235-bus-message-introduce-two-kinds-of-references-to-bus.patch
-Patch0236: 0236-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch
-Patch0237: 0237-sd-event-add-sd_event_source_disable_unref-helper.patch
-Patch0238: 0238-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch
-Patch0239: 0239-sd-bus-use-queue-message-references-for-managing-r-w.patch
-Patch0240: 0240-journal-do-not-trigger-assertion-when-journal_file_c.patch
-Patch0241: 0241-journal-use-cleanup-attribute-at-one-more-place.patch
+Patch0216: 0216-core-never-propagate-reload-failure-to-service-resul.patch
+Patch0217: 0217-man-document-systemd-analyze-security.patch
+Patch0218: 0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch
+Patch0219: 0219-travis-move-to-CentOS-8-docker-images.patch
+Patch0220: 0220-travis-drop-SCL-remains.patch
+Patch0221: 0221-syslog-fix-segfault-in-syslog_parse_priority.patch
+Patch0222: 0222-sd-bus-make-strict-asan-shut-up.patch
+Patch0223: 0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch
+Patch0224: 0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch
+Patch0225: 0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch
+Patch0226: 0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch
+Patch0227: 0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch
+Patch0228: 0228-udev-introduce-CONST-key-name.patch
+Patch0229: 0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch
+Patch0230: 0230-Consider-smb3-as-remote-filesystem.patch
+Patch0231: 0231-process-util-introduce-pid_is_my_child-helper.patch
+Patch0232: 0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch
+Patch0233: 0233-core-only-watch-processes-when-it-s-really-necessary.patch
+Patch0234: 0234-core-implement-per-unit-journal-rate-limiting.patch
+Patch0235: 0235-path-stop-watching-path-specs-once-we-triggered-the-.patch
+Patch0236: 0236-journald-fixed-assertion-failure-when-system-journal.patch
+Patch0237: 0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
+Patch0238: 0238-test-mask-several-unnecessary-services.patch
+Patch0239: 0239-test-bump-the-second-partition-s-size-to-50M.patch
+Patch0240: 0240-shared-sleep-config-exclude-zram-devices-from-hibern.patch
+Patch0241: 0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch
+Patch0242: 0242-sd-device-introduce-log_device_-macros.patch
+Patch0243: 0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch
+Patch0244: 0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
+Patch0245: 0245-sd-bus-adjust-indentation-of-comments.patch
+Patch0246: 0246-resolved-do-not-run-loop-twice.patch
+Patch0247: 0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
+Patch0248: 0248-resolved-query-polkit-only-after-parsing-the-data.patch
+Patch0249: 0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
+Patch0250: 0250-basic-user-util-allow-dots-in-user-names.patch
+Patch0251: 0251-sd-bus-bump-message-queue-size-again.patch
+Patch0252: 0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch
+Patch0253: 0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch
+Patch0254: 0254-basic-remove-an-assertion-from-cunescape_one.patch
+Patch0255: 0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch
+Patch0256: 0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch
+Patch0257: 0257-tests-add-a-reproducer-for-a-heap-buffer-overflow-fi.patch
+Patch0258: 0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch
+Patch0259: 0259-tests-add-a-fuzzer-for-process_audit_string.patch
+Patch0260: 0260-journald-check-whether-sscanf-has-changed-the-value-.patch
+Patch0261: 0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch
+Patch0262: 0262-tests-add-a-fuzzer-for-journald-streams.patch
+Patch0263: 0263-tests-add-a-fuzzer-for-server_process_native_file.patch
+Patch0264: 0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch
+Patch0265: 0265-journald-take-leading-spaces-into-account-in-syslog_.patch
+Patch0266: 0266-Add-a-warning-about-the-difference-in-permissions-be.patch
+Patch0267: 0267-execute-remove-one-redundant-comparison-check.patch
+Patch0268: 0268-core-change-ownership-mode-of-the-execution-director.patch
+Patch0269: 0269-core-dbus-execute-remove-unnecessary-initialization.patch
+Patch0270: 0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch
+Patch0271: 0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch
+Patch0272: 0272-Rework-cpu-affinity-parsing.patch
+Patch0273: 0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch
+Patch0274: 0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch
+Patch0275: 0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch
+Patch0276: 0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch
+Patch0277: 0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch
+Patch0278: 0278-pid1-when-reloading-configuration-forget-old-setting.patch
+Patch0279: 0279-test-execute-use-CPUSet-too.patch
+Patch0280: 0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch
+Patch0281: 0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch
+Patch0282: 0282-test-cpu-set-util-add-test-for-dbus-conversions.patch
+Patch0283: 0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch
+Patch0284: 0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch
+Patch0285: 0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch
+Patch0286: 0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch
+Patch0287: 0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch
+Patch0288: 0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch
+Patch0289: 0289-core-disable-CPUAccounting-by-default.patch
+Patch0290: 0290-set-kptr_restrict-1.patch
+Patch0291: 0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch
+Patch0292: 0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
+Patch0293: 0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch
+Patch0294: 0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch
+Patch0295: 0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch
+Patch0296: 0296-catalog-fix-name-of-variable.patch
+Patch0297: 0297-cryptsetup-add-keyfile-timeout-to-allow-a-keydev-tim.patch
+Patch0298: 0298-cryptsetup-add-documentation-for-keyfile-timeout.patch
+Patch0299: 0299-cryptsetup-use-unabbrieviated-variable-names.patch
+Patch0300: 0300-cryptsetup-don-t-assert-on-variable-which-is-optiona.patch
+Patch0301: 0301-cryptsetup-generator-guess-whether-the-keyfile-argum.patch
+Patch0302: 0302-crypt-util-Translate-libcryptsetup-log-level-instead.patch
+Patch0303: 0303-cryptsetup-add-some-commenting-about-EAGAIN-generati.patch
+Patch0304: 0304-cryptsetup-downgrade-a-log-message-we-ignore.patch
+Patch0305: 0305-cryptsetup-rework-how-we-log-about-activation-failur.patch
+Patch0306: 0306-rules-reintroduce-60-alias-kmsg.rules.patch
+Patch0307: 0307-sd-bus-make-rqueue-wqueue-sizes-of-type-size_t.patch
+Patch0308: 0308-sd-bus-reorder-bus-ref-and-bus-message-ref-handling.patch
+Patch0309: 0309-sd-bus-make-sure-dispatch_rqueue-initializes-return-.patch
+Patch0310: 0310-sd-bus-drop-two-inappropriate-empty-lines.patch
+Patch0311: 0311-sd-bus-initialize-mutex-after-we-allocated-the-wqueu.patch
+Patch0312: 0312-sd-bus-always-go-through-sd_bus_unref-to-free-messag.patch
+Patch0313: 0313-bus-message-introduce-two-kinds-of-references-to-bus.patch
+Patch0314: 0314-sd-bus-introduce-API-for-re-enqueuing-incoming-messa.patch
+Patch0315: 0315-sd-event-add-sd_event_source_disable_unref-helper.patch
+Patch0316: 0316-polkit-when-authorizing-via-PK-let-s-re-resolve-call.patch
+Patch0317: 0317-sysctl-let-s-by-default-increase-the-numeric-PID-ran.patch
+Patch0318: 0318-journal-do-not-trigger-assertion-when-journal_file_c.patch
+Patch0319: 0319-journal-use-cleanup-attribute-at-one-more-place.patch
+Patch0320: 0320-sd-bus-use-queue-message-references-for-managing-r-w.patch
+Patch0321: 0321-pid1-make-sure-to-restore-correct-default-values-for.patch
+Patch0322: 0322-main-introduce-a-define-HIGH_RLIMIT_MEMLOCK-similar-.patch
+Patch0323: 0323-seccomp-introduce-seccomp_restrict_suid_sgid-for-blo.patch
+Patch0324: 0324-test-add-test-case-for-restrict_suid_sgid.patch
+Patch0325: 0325-core-expose-SUID-SGID-restriction-as-new-unit-settin.patch
+Patch0326: 0326-analyze-check-for-RestrictSUIDSGID-in-systemd-analyz.patch
+Patch0327: 0327-man-document-the-new-RestrictSUIDSGID-setting.patch
+Patch0328: 0328-units-turn-on-RestrictSUIDSGID-in-most-of-our-long-r.patch
+Patch0329: 0329-core-imply-NNP-and-SUID-SGID-restriction-for-Dynamic.patch
+Patch0330: 0330-cgroup-introduce-support-for-cgroup-v2-CPUSET-contro.patch
+Patch0331: 0331-pid1-fix-DefaultTasksMax-initialization.patch
+Patch0332: 0332-cgroup-make-sure-that-cpuset-is-supported-on-cgroup-.patch
+Patch0333: 0333-test-introduce-TEST-36-NUMAPOLICY.patch
+Patch0334: 0334-test-replace-tail-f-with-journal-cursor-which-should.patch
+Patch0335: 0335-test-support-MPOL_LOCAL-matching-in-unpatched-strace.patch
+Patch0336: 0336-test-make-sure-the-strace-process-is-indeed-dead.patch
+Patch0337: 0337-test-skip-the-test-on-systems-without-NUMA-support.patch
+Patch0338: 0338-test-give-strace-some-time-to-initialize.patch
+Patch0339: 0339-test-add-a-simple-sanity-check-for-systems-without-N.patch
+Patch0340: 0340-test-drop-the-missed-exit-1-expression.patch
+Patch0341: 0341-test-replace-cursor-file-with-a-plain-cursor.patch
+Patch0342: 0342-cryptsetup-Treat-key-file-errors-as-a-failed-passwor.patch
 
 
 %ifarch %{ix86} x86_64 aarch64
@@ -358,6 +459,7 @@ Provides:       /bin/systemctl
 Provides:       /sbin/shutdown
 Provides:       syslog
 Provides:       systemd-units = %{version}-%{release}
+Provides:       systemd-rpm-macros = %{version}-%{release}
 Obsoletes:      system-setup-keyboard < 0.9
 Provides:       system-setup-keyboard = 0.9
 # systemd-sysv-convert was removed in f20: https://fedorahosted.org/fpc/ticket/308
@@ -552,6 +654,10 @@ CONFIGURE_OPTS=(
         -Ddefault-hierarchy=legacy
 )
 
+# Don't ship /var/log/README. The relationship between journal and syslog should be documented
+# in the official documentation.
+sed -ie "/subdir('doc\/var-log')/d" meson.build
+
 %meson "${CONFIGURE_OPTS[@]}"
 %meson_build
 
@@ -910,36 +1016,157 @@ fi
 %files tests -f .file-list-tests
 
 %changelog
-* Thu Feb 27 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-18.5
-- journal: do not trigger assertion when journal_file_close() get NULL (#1807350)
-- journal: use cleanup attribute at one more place (#1807350)
-
-* Thu Feb 13 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-18.4
+* Mon Mar 23 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-29
+- cryptsetup: Treat key file errors as a failed password attempt (#1763155)
+
+* Wed Mar 11 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-28
+- pid1: fix DefaultTasksMax initialization (#1809037)
+- cgroup: make sure that cpuset is supported on cgroup  v2 and disabled with v1 (#1808940)
+- test: introduce TEST-36-NUMAPOLICY (#1808940)
+- test: replace `tail -f` with journal cursor which  should be more reliable (#1808940)
+- test: support MPOL_LOCAL matching in unpatched strace  versions (#1808940)
+- test: make sure the strace process is indeed dead (#1808940)
+- test: skip the test on systems without NUMA support (#1808940)
+- test: give strace some time to initialize (#1808940)
+- test: add a simple sanity check for systems without  NUMA support (#1808940)
+- test: drop the missed || exit 1 expression (#1808940)
+- test: replace cursor file with a plain cursor (#1808940)
+
+* Fri Feb 21 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-27
+- cgroup: introduce support for cgroup v2 CPUSET controller (#1724617)
+
+* Wed Feb 19 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-26
+- seccomp: introduce seccomp_restrict_suid_sgid() for blocking chmod() for suid/sgid files (#1687512)
+- test: add test case for restrict_suid_sgid() (#1687512)
+- core: expose SUID/SGID restriction as new unit setting RestrictSUIDSGID= (#1687512)
+- analyze: check for RestrictSUIDSGID= in "systemd-analyze security" (#1687512)
+- man: document the new RestrictSUIDSGID= setting (#1687512)
+- units: turn on RestrictSUIDSGID= in most of our long-running daemons (#1687512)
+- core: imply NNP and SUID/SGID restriction for DynamicUser=yes service (#1687512)
+
+* Mon Feb 17 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-25
 - sd-bus: use "queue" message references for managing r/w message queues in connection objects (CVE-2020-1712)
-
-* Mon Feb 03 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-18.3
-- core, job: fix breakage of ordering dependencies by systemctl reload command (#1781712)
-- syslog: fix segfault in syslog_parse_priority() (#1781712)
-- journald: fixed assertion failure when system journal rotation fails (#9893) (#1781712)
-- test: use PBKDF2 instead of Argon2 in cryptsetup... (#1781712)
-- test: mask several unnecessary services (#1781712)
-- test: bump the second partition's size to 50M (#1781712)
-- sd-bus: make rqueue/wqueue sizes of type size_t (#20201712)
-- sd-bus: reorder bus ref and bus message ref handling (#20201712)
-- sd-bus: make sure dispatch_rqueue() initializes return parameter on all types of success (#20201712)
-- sd-bus: drop two inappropriate empty lines (#20201712)
-- sd-bus: initialize mutex after we allocated the wqueue (#20201712)
-- sd-bus: always go through sd_bus_unref() to free messages (#20201712)
-- bus-message: introduce two kinds of references to bus messages (#20201712)
-- sd-bus: introduce API for re-enqueuing incoming messages (#20201712)
-- sd-event: add sd_event_source_disable_unref() helper (#20201712)
-- polkit: when authorizing via PK let's re-resolve callback/userdata instead of caching it (#20201712)
-
-* Fri Nov 29 2019 systemd maintenance team <systemd-maint@redhat.com> - 239-18.2
-- ask-password: prevent buffer overrow when reading from keyring (#1777037)
-
-* Tue Nov 05 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-18.1
-- journal: rely on _cleanup_free_ to free a temporary string used in client_context_read_cgroup (#1767716)
+- pid1: make sure to restore correct default values for some rlimits (#1789930)
+- main: introduce a define HIGH_RLIMIT_MEMLOCK similar to HIGH_RLIMIT_NOFILE (#1789930)
+
+* Thu Feb 13 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-24
+- rules: reintroduce 60-alias-kmsg.rules (#1739353)
+- sd-bus: make rqueue/wqueue sizes of type size_t (CVE-2020-1712)
+- sd-bus: reorder bus ref and bus message ref handling (CVE-2020-1712)
+- sd-bus: make sure dispatch_rqueue() initializes return parameter on all types of success (CVE-2020-1712)
+- sd-bus: drop two inappropriate empty lines (CVE-2020-1712)
+- sd-bus: initialize mutex after we allocated the wqueue (CVE-2020-1712)
+- sd-bus: always go through sd_bus_unref() to free messages (CVE-2020-1712)
+- bus-message: introduce two kinds of references to bus messages (CVE-2020-1712)
+- sd-bus: introduce API for re-enqueuing incoming messages (CVE-2020-1712)
+- sd-event: add sd_event_source_disable_unref() helper (CVE-2020-1712)
+- polkit: when authorizing via PK let's re-resolve callback/userdata instead of caching it (CVE-2020-1712)
+- sysctl: let's by default increase the numeric PID range from 2^16 to 2^22 (#1744214)
+- journal: do not trigger assertion when journal_file_close() get NULL (#1788085)
+- journal: use cleanup attribute at one more place (#1788085)
+
+* Mon Jan 13 2020 systemd maintenance team <systemd-maint@redhat.com> - 239-23
+- catalog: fix name of variable (#1677768)
+- cryptsetup: add keyfile-timeout to allow a keydev timeout and allow to fallback to a password if it fails. (#1763155)
+- cryptsetup: add documentation for keyfile-timeout (#1763155)
+- cryptsetup: use unabbrieviated variable names (#1763155)
+- cryptsetup: don't assert on variable which is optional (#1763155)
+- cryptsetup-generator: guess whether the keyfile argument is two items or one (#1763155)
+- crypt-util: Translate libcryptsetup log level instead of using log_debug() (#1776408)
+- cryptsetup: add some commenting about EAGAIN generation (#1776408)
+- cryptsetup: downgrade a log message we ignore (#1776408)
+- cryptsetup: rework how we log about activation failures (#1776408)
+
+* Tue Dec 17 2019 systemd maintenance team <systemd-maint@redhat.com> - 239-22
+- spec: don't ship /var/log/README
+- spec: provide systemd-rpm-macros
+
+* Mon Dec 09 2019 systemd maintenance team <systemd-maint@redhat.com> - 239-21
+- test-cpu-set-util: fix comparison for allocation size (#1734787)
+- test-cpu-set-util: fix allocation size check on i386 (#1734787)
+
+* Mon Dec 09 2019 systemd maintenance team <systemd-maint@redhat.com> - 239-20
+- journal: rely on _cleanup_free_ to free a temporary string used in client_context_read_cgroup (#1764560)
+- basic/user-util: allow dots in user names (#1717603)
+- sd-bus: bump message queue size again (#1770189)
+- tests: put fuzz_journald_processing_function in a .c file (#1764560)
+- tests: add a fuzzer for dev_kmsg_record (#1764560)
+- basic: remove an assertion from cunescape_one (#1764560)
+- journal: fix an off-by-one error in dev_kmsg_record (#1764560)
+- tests: add a reproducer for a memory leak fixed in 30eddcd51b8a472e05d3b8d1 in August (#1764560)
+- tests: add a reproducer for a heap-buffer-overflow fixed in 937b1171378bc1000a (#1764560)
+- test: initialize syslog_fd in fuzz-journald-kmsg too (#1764560)
+- tests: add a fuzzer for process_audit_string (#1764560)
+- journald: check whether sscanf has changed the value corresponding to %n (#1764560)
+- tests: introduce dummy_server_init and use it in all journald fuzzers (#1764560)
+- tests: add a fuzzer for journald streams (#1764560)
+- tests: add a fuzzer for server_process_native_file (#1764560)
+- fuzz-journal-stream: avoid assertion failure on samples which don't fit in pipe (#1764560)
+- journald: take leading spaces into account in syslog_parse_identifier (#1764560)
+- Add a warning about the difference in permissions between existing directories and unit settings. (#1778384)
+- execute: remove one redundant comparison check (#1778384)
+- core: change ownership/mode of the execution directories also for static users (#1778384)
+- core/dbus-execute: remove unnecessary initialization (#1734787)
+- shared/cpu-set-util: move the part to print cpu-set into a separate function (#1734787)
+- shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM() (#1734787)
+- Rework cpu affinity parsing (#1734787)
+- Move cpus_in_affinity_mask() to cpu-set-util.[ch] (#1734787)
+- test-cpu-set-util: add simple test for cpus_in_affinity_mask() (#1734787)
+- test-cpu-set-util: add a smoke test for test_parse_cpu_set_extend() (#1734787)
+- pid1: parse CPUAffinity= in incremental fashion (#1734787)
+- pid1: don't reset setting from /proc/cmdline upon restart (#1734787)
+- pid1: when reloading configuration, forget old settings (#1734787)
+- test-execute: use CPUSet too (#1734787)
+- shared/cpu-set-util: drop now-unused cleanup function (#1734787)
+- shared/cpu-set-util: make transfer of cpu_set_t over bus endian safe (#1734787)
+- test-cpu-set-util: add test for dbus conversions (#1734787)
+- shared/cpu-set-util: introduce cpu_set_to_range() (#1734787)
+- systemctl: present CPUAffinity mask as a list of CPU index ranges (#1734787)
+- shared/cpu-set-util: only force range printing one time (#1734787)
+- execute: dump CPUAffinity as a range string instead of a list of CPUs (#1734787)
+- cpu-set-util: use %d-%d format in  cpu_set_to_range_string() only for actual ranges (#1734787)
+- core: introduce NUMAPolicy and NUMAMask options (#1734787)
+- core: disable CPUAccounting by default (#1734787)
+- set kptr_restrict=1 (#1689346)
+- cryptsetup: reduce the chance that we will be OOM killed (#1696602)
+- core, job: fix breakage of ordering dependencies by systemctl reload command (#1766417)
+- debug-generator: enable custom systemd.debug_shell tty (#1723722)
+
+* Thu Oct 24 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-19
+- core: never propagate reload failure to service result (#1735787)
+- man: document systemd-analyze security (#1750343)
+- man: reorder and add examples to systemd-analyze(1) (#1750343)
+- travis: move to CentOS 8 docker images (#1761519)
+- travis: drop SCL remains (#1761519)
+- syslog: fix segfault in syslog_parse_priority() (#1761519)
+- sd-bus: make strict asan shut up (#1761519)
+- travis: don't run slow tests under ASan/UBSan (#1761519)
+- kernel-install: do not require non-empty kernel cmdline (#1701454)
+- ask-password: prevent buffer overrow when reading from keyring (#1752050)
+- core: try to reopen /dev/kmsg again right after mounting /dev (#1749212)
+- buildsys: don't garbage collect sections while linking (#1748258)
+- udev: introduce CONST key name (#1762679)
+- Call getgroups() to know size of supplementary groups array to allocate (#1743230256 KB
+#1743235)
+- Consider smb3 as remote filesystem (#1757257)
+- process-util: introduce pid_is_my_child() helper (#1744972)
+- core: reduce the number of stalled PIDs from the watched processes list when possible (#1744972)
+- core: only watch processes when it's really necessary (#1744972)
+- core: implement per unit journal rate limiting (#1719577)
+- path: stop watching path specs once we triggered the target unit (#1763161)
+- journald: fixed assertion failure when system journal rotation fails (#9893) (#1763619)
+- test: use PBKDF2 instead of Argon2 in cryptsetup... (#1761519)
+- test: mask several unnecessary services (#1761519)
+- test: bump the second partition's size to 50M (#1761519)
+- shared/sleep-config: exclude zram devices from hibernation candidates (#1763617)
+- selinux: don't log SELINUX_INFO and SELINUX_WARNING messages to audit (#1763612)
+- sd-device: introduce log_device_*() macros (#1753369)
+- udev: Add id program and rule for FIDO security tokens (#1753369)
+- shared/but-util: drop trusted annotation from bus_open_system_watch_bind_with_description() (#1746857)
+- sd-bus: adjust indentation of comments (#1746857)
+- resolved: do not run loop twice (#1746857)
+- resolved: allow access to Set*Link and Revert methods through polkit (#1746857)
+- resolved: query polkit only after parsing the data (#1746857)
 
 * Fri Aug 30 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-18
 - shared/but-util: drop trusted annotation from bus_open_system_watch_bind_with_description() (#1746857)