diff --git a/.systemd.metadata b/.systemd.metadata
index 9237e09..aef1460 100644
--- a/.systemd.metadata
+++ b/.systemd.metadata
@@ -1 +1 @@
-886c84cfa6861e1b367659b594722737d43d0fde SOURCES/systemd-246.1.tar.gz
+9bad8622d0198406e6570ca7c54de0eac47e468e SOURCES/systemd-247.3.tar.gz
diff --git a/SOURCES/0001-Do-not-assert-in-test_add_acls_for_user.patch b/SOURCES/0001-Do-not-assert-in-test_add_acls_for_user.patch
deleted file mode 100644
index c13413c..0000000
--- a/SOURCES/0001-Do-not-assert-in-test_add_acls_for_user.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From b177b0ef92d226a9f303aecbff0cf2e7293667b3 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Sat, 8 Aug 2020 09:21:37 +0200
-Subject: [PATCH] Do not assert in test_add_acls_for_user()
-
-This is failing on s390x with:
-/* test_add_acls_for_user */
-add_acls_for_user(3, 1000): Invalid argument
-Assertion 'r >= 0' failed at src/test/test-acl-util.c:46, function test_add_acls_for_user(). Aborting.
----
- src/test/test-acl-util.c | 4 ----
- 1 file changed, 4 deletions(-)
-
-diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c
-index 9f0e594e67..a91d64ab0c 100644
---- a/src/test/test-acl-util.c
-+++ b/src/test/test-acl-util.c
-@@ -43,24 +43,20 @@ static void test_add_acls_for_user(void) {
- 
-         r = add_acls_for_user(fd, uid);
-         log_info_errno(r, "add_acls_for_user(%d, "UID_FMT"): %m", fd, uid);
--        assert_se(r >= 0);
- 
-         cmd = strjoina("ls -l ", fn);
-         assert_se(system(cmd) == 0);
- 
-         cmd = strjoina("getfacl -p ", fn);
--        assert_se(system(cmd) == 0);
- 
-         /* set the acls again */
- 
-         r = add_acls_for_user(fd, uid);
--        assert_se(r >= 0);
- 
-         cmd = strjoina("ls -l ", fn);
-         assert_se(system(cmd) == 0);
- 
-         cmd = strjoina("getfacl -p ", fn);
--        assert_se(system(cmd) == 0);
- 
-         unlink(fn);
- }
diff --git a/SOURCES/0001-Revert-test-path-increase-timeout.patch b/SOURCES/0001-Revert-test-path-increase-timeout.patch
deleted file mode 100644
index a9c226f..0000000
--- a/SOURCES/0001-Revert-test-path-increase-timeout.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From a73d30081a13eaeffce87f997726a179ec44d817 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Fri, 31 Jul 2020 10:50:37 +0200
-Subject: [PATCH 1/2] Revert "test-path: increase timeout"
-
-This partially reverts commit 500727c220354b81b68ed6667d9a6f0fafe3ba19.
-
-I was confused by the error message: the test says it timed out, but that's
-because it's waiting for a failed unit to come back to life. There is no actual
-timeout.
-
-So let's keep the minor refactoring that was done, but revert to the old short
-timeout.
----
- src/test/test-path.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/test/test-path.c b/src/test/test-path.c
-index 1075f31bc6..63b709c8da 100644
---- a/src/test/test-path.c
-+++ b/src/test/test-path.c
-@@ -82,7 +82,7 @@ static void check_states(Manager *m, Path *path, Service *service, PathState pat
-         assert_se(m);
-         assert_se(service);
- 
--        usec_t end = now(CLOCK_MONOTONIC) + 30 * USEC_PER_SEC;
-+        usec_t end = now(CLOCK_MONOTONIC) + 2 * USEC_PER_SEC;
- 
-         while (path->result != PATH_SUCCESS || service->result != SERVICE_SUCCESS ||
-                path->state != path_state || service->state != service_state) {
diff --git a/SOURCES/0001-bpf-pid1-Pin-reference-to-BPF-programs-for-post-cold.patch b/SOURCES/0001-bpf-pid1-Pin-reference-to-BPF-programs-for-post-cold.patch
deleted file mode 100644
index ed3536b..0000000
--- a/SOURCES/0001-bpf-pid1-Pin-reference-to-BPF-programs-for-post-cold.patch
+++ /dev/null
@@ -1,427 +0,0 @@
-From a1ff72565c2f12b644a081ebbe3492f93ceb3bd5 Mon Sep 17 00:00:00 2001
-From: Chris Down <chris@chrisdown.name>
-Date: Thu, 29 Oct 2020 12:03:52 +0000
-Subject: [PATCH 1/3] bpf: pid1: Pin reference to BPF programs for
- post-coldplug
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-During `daemon-reload` and `daemon-reexec`, we detach and reattach all
-BPF programs attached to cgroups. This, however, poses a real practical
-problem for DevicePolicy (and some other settings using BPF): it
-presents a period of time where the old device filtering BPF program has
-been unloaded, but the new one has not been loaded yet.
-
-Since the filtering is at open() time, it has become apparent that that
-there's a non-trivial period where applications inside that ostensibly
-filtered cgroup can grab any device -- and often do so -- and then
-retain access to that device even after the reload is over. Due to the
-file continuing to be available after the initial open(), this issue is
-particularly visible for DevicePolicy={strict,closed}, however it also
-applies to other BPF programs we install.
-
-In particular, for BPF ingress/egress filtering this may have more
-concerning implications: network traffic which is supposed to be
-filtered will -- for a very brief period of time -- not be filtered or
-subject to any restrictions imposed by BPF.
-
-These BPF programs are fundamentally attached to a cgroup lifetime, not
-our unit lifetime, so it's enough to pin these programs by taking a
-reference to affected BPF programs before reload/reexec. We can then
-serialise the program's kernel-facing FD and cgroup attachment FD for
-the new daemon, and have the daemon on the other side unpin the programs
-after it's finished with coldplug.
-
-That means that, for example, the BPF program lifecycle during
-daemon-reload or daemon-reexec changes from this:
-
-    manager_clear_jobs_and_units
-                 │
-          ╔══════╪═════════╤═══════╗
-          ║ prog │ no prog │ prog' ║
-          ╚══════╧═════════╪═══════╝
-                           │
-                    manager_coldplug
-
-to this:
-
-    manager_clear_jobs_and_units         manager_dispatch_cgroup_realize_queue
-                 │                                       │
-          ╔══════╪═══════════════╤═══════════════════════╪═══════╗
-          ║ prog │ prog (orphan) │ prog (orphan) + prog' │ prog' ║
-          ╚══════╧═══════════════╪═══════════════════════╧═══════╝
-                                 │
-                          manager_coldplug
-
-For daemon-reexec the semantics are mostly the same, but the point at
-which the program becomes orphan is tied to the process lifecycle
-instead.
-
-None of the BPF programs we install require exclusive access, so having
-multiple instances of them running at the same time is fine. Custom
-programs, of course, are unknown, but it's hard to imagine legitimate
-cases which should be affected, whereas the benefits of this "overlap"
-approach with reference pinning is immediately tangible.
-
-[keszybz: use _cleanup_ for unpin, use FOREACH_POINTER]
----
- src/core/bpf-firewall.c  |   9 +--
- src/core/main.c          |   9 +++
- src/core/manager.c       | 163 ++++++++++++++++++++++++++++++++++++++-
- src/core/manager.h       |   6 ++
- src/shared/bpf-program.c |  10 +++
- src/shared/bpf-program.h |   1 +
- 6 files changed, 191 insertions(+), 7 deletions(-)
-
-diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c
-index bceb049b58..e3089ff6f4 100644
---- a/src/core/bpf-firewall.c
-+++ b/src/core/bpf-firewall.c
-@@ -703,8 +703,7 @@ int bpf_firewall_install(Unit *u) {
-         if (r < 0)
-                 return log_unit_error_errno(u, r, "Failed to determine cgroup path: %m");
- 
--        flags = (supported == BPF_FIREWALL_SUPPORTED_WITH_MULTI &&
--                 (u->type == UNIT_SLICE || unit_cgroup_delegate(u))) ? BPF_F_ALLOW_MULTI : 0;
-+        flags = (supported == BPF_FIREWALL_SUPPORTED_WITH_MULTI) ? BPF_F_ALLOW_MULTI : 0;
- 
-         /* Unref the old BPF program (which will implicitly detach it) right before attaching the new program, to
-          * minimize the time window when we don't account for IP traffic. */
-@@ -712,8 +711,7 @@ int bpf_firewall_install(Unit *u) {
-         u->ip_bpf_ingress_installed = bpf_program_unref(u->ip_bpf_ingress_installed);
- 
-         if (u->ip_bpf_egress) {
--                r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path,
--                                              flags | (set_isempty(u->ip_bpf_custom_egress) ? 0 : BPF_F_ALLOW_MULTI));
-+                r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path, flags);
-                 if (r < 0)
-                         return log_unit_error_errno(u, r, "Attaching egress BPF program to cgroup %s failed: %m", path);
- 
-@@ -722,8 +720,7 @@ int bpf_firewall_install(Unit *u) {
-         }
- 
-         if (u->ip_bpf_ingress) {
--                r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path,
--                                              flags | (set_isempty(u->ip_bpf_custom_ingress) ? 0 : BPF_F_ALLOW_MULTI));
-+                r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path, flags);
-                 if (r < 0)
-                         return log_unit_error_errno(u, r, "Attaching ingress BPF program to cgroup %s failed: %m", path);
- 
-diff --git a/src/core/main.c b/src/core/main.c
-index 4a376976e9..9873f35f5e 100644
---- a/src/core/main.c
-+++ b/src/core/main.c
-@@ -1144,6 +1144,14 @@ static int prepare_reexecute(
-         if (!fds)
-                 return log_oom();
- 
-+        /* We need existing BPF programs to survive reload, otherwise there will be a period where no BPF
-+         * program is active during task execution within a cgroup. This would be bad since this may have
-+         * security or reliability implications: devices we should filter won't be filtered, network activity
-+         * we should filter won't be filtered, etc. We pin all the existing devices by bumping their
-+         * refcount, and then storing them to later have it decremented. */
-+        _cleanup_(manager_unpin_all_cgroup_bpf_programsp) Manager *m_unpin =
-+                manager_pin_all_cgroup_bpf_programs(m);
-+
-         r = manager_serialize(m, f, fds, switching_root);
-         if (r < 0)
-                 return r;
-@@ -1159,6 +1167,7 @@ static int prepare_reexecute(
-         if (r < 0)
-                 return log_error_errno(r, "Failed to disable O_CLOEXEC for serialization fds: %m");
- 
-+        TAKE_PTR(m_unpin);
-         *ret_f = TAKE_PTR(f);
-         *ret_fds = TAKE_PTR(fds);
- 
-diff --git a/src/core/manager.c b/src/core/manager.c
-index 41e0d73736..1ce0e05706 100644
---- a/src/core/manager.c
-+++ b/src/core/manager.c
-@@ -64,6 +64,7 @@
- #include "rlimit-util.h"
- #include "rm-rf.h"
- #include "serialize.h"
-+#include "set.h"
- #include "signal-util.h"
- #include "socket-util.h"
- #include "special.h"
-@@ -3210,6 +3211,79 @@ static void manager_serialize_gid_refs(Manager *m, FILE *f) {
-         manager_serialize_uid_refs_internal(m, f, &m->gid_refs, "destroy-ipc-gid");
- }
- 
-+static int serialize_limbo_bpf_program(FILE *f, FDSet *fds, BPFProgram *p) {
-+        int copy;
-+        _cleanup_free_ char *ap = NULL;
-+
-+        /* We don't actually need the instructions or other data, since this is only used on the other side
-+         * for BPF limbo, which just requires the program type, cgroup path, and kernel-facing BPF file
-+         * descriptor. We don't even need to know what unit or directive it's attached to, since we're just
-+         * going to expire it after coldplug. */
-+
-+        assert(f);
-+        assert(p);
-+
-+        /* If the program isn't attached to the kernel yet, there's no reason to serialise it for limbo. Just
-+         * let it be skeletonized and then coldplug can do the work on the other side if it's still
-+         * necessary. */
-+        if (p->kernel_fd < 0 || !p->attached_path)
-+                return -ENOTCONN;
-+
-+        copy = fdset_put_dup(fds, p->kernel_fd);
-+        if (copy < 0)
-+                return log_error_errno(copy, "Failed to add file descriptor to serialization set: %m");
-+
-+        /* Otherwise, on daemon-reload, we'd remain pinned. */
-+        safe_close(p->kernel_fd);
-+
-+        ap = cescape(p->attached_path);
-+        if (!ap)
-+                return log_oom();
-+
-+        return serialize_item_format(f, "bpf-limbo", "%i %i %i \"%s\"",
-+                                     copy, p->prog_type, p->attached_type, ap);
-+}
-+
-+static void deserialize_limbo_bpf_program(Manager *m, FDSet *fds, const char *value) {
-+        _cleanup_free_ char *raw_fd = NULL, *raw_pt = NULL, *raw_at = NULL, *cgpath = NULL;
-+        int fd, r, prog_type, attached_type;
-+
-+        assert(m);
-+        assert(value);
-+
-+        r = extract_first_word(&value, &raw_fd, NULL, 0);
-+        if (r <= 0 || safe_atoi(raw_fd, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
-+                return (void) log_error("Failed to parse bpf-limbo FD: %s", value);
-+
-+        r = extract_first_word(&value, &raw_pt, NULL, 0);
-+        if (r <= 0 || safe_atoi(raw_pt, &prog_type) < 0)
-+                return (void) log_error("Failed to parse bpf-limbo program type: %s", value);
-+
-+        r = extract_first_word(&value, &raw_at, NULL, 0);
-+        if (r <= 0 || safe_atoi(raw_at, &attached_type) < 0)
-+                return (void) log_error("Failed to parse bpf-limbo attached type: %s", value);
-+
-+        r = extract_first_word(&value, &cgpath, NULL, EXTRACT_CUNESCAPE | EXTRACT_UNQUOTE);
-+        if (r <= 0)
-+                return (void) log_error("Failed to parse attached path for BPF limbo FD %s", value);
-+
-+        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
-+        r = bpf_program_new(prog_type, &p);
-+        if (r < 0)
-+                return (void) log_error_errno(r, "Failed to create BPF limbo program: %m");
-+
-+        /* Just enough to free it when the time is right, this does not have enough information be used as a
-+         * real BPFProgram. */
-+        p->attached_type = attached_type;
-+        p->kernel_fd = fdset_remove(fds, fd);
-+        p->attached_path = TAKE_PTR(cgpath);
-+
-+        r = set_ensure_put(&m->bpf_limbo_progs, NULL, p);
-+        if (r < 0)
-+                return (void) log_error_errno(r, "Failed to register BPF limbo program for FD %s: %m", value);
-+        TAKE_PTR(p);
-+}
-+
- int manager_serialize(
-                 Manager *m,
-                 FILE *f,
-@@ -3221,6 +3295,7 @@ int manager_serialize(
-         Iterator i;
-         Unit *u;
-         int r;
-+        BPFProgram *p;
- 
-         assert(m);
-         assert(f);
-@@ -3265,6 +3340,9 @@ int manager_serialize(
-                 (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
-         }
- 
-+        SET_FOREACH(p, m->bpf_limbo_progs, i)
-+                (void) serialize_limbo_bpf_program(f, fds, p);
-+
-         if (!switching_root)
-                 (void) serialize_strv(f, "env", m->client_environment);
- 
-@@ -3543,7 +3621,10 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
-                         else
-                                 m->n_failed_jobs += n;
- 
--                } else if ((val = startswith(l, "taint-usr="))) {
-+                } else if ((val = startswith(l, "bpf-limbo=")))
-+                        deserialize_limbo_bpf_program(m, fds, val);
-+
-+                else if ((val = startswith(l, "taint-usr="))) {
-                         int b;
- 
-                         b = parse_boolean(val);
-@@ -3719,6 +3800,67 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
-         return manager_deserialize_units(m, f, fds);
- }
- 
-+Manager* manager_pin_all_cgroup_bpf_programs(Manager *m) {
-+        int r;
-+        Unit *u;
-+        Iterator ih, is;
-+
-+        assert(m);
-+
-+        HASHMAP_FOREACH(u, m->units, ih) {
-+                BPFProgram *p;
-+
-+                FOREACH_POINTER(p,
-+                                u->bpf_device_control_installed,
-+                                u->ip_bpf_ingress,
-+                                u->ip_bpf_ingress_installed,
-+                                u->ip_bpf_egress,
-+                                u->ip_bpf_egress_installed)
-+                        if (p) {
-+                                r = set_ensure_put(&m->bpf_limbo_progs, NULL, p);
-+                                if (r < 0) {
-+                                        log_unit_error_errno(u, r, "Cannot store BPF program for reload, ignoring: %m");
-+                                        continue;
-+                                }
-+
-+                                bpf_program_ref(p);
-+                        }
-+
-+                Set *s;
-+                FOREACH_POINTER(s,
-+                                u->ip_bpf_custom_ingress,
-+                                u->ip_bpf_custom_ingress_installed,
-+                                u->ip_bpf_custom_egress,
-+                                u->ip_bpf_custom_egress_installed)
-+                        SET_FOREACH(p, s, is) {
-+                                r = set_ensure_put(&m->bpf_limbo_progs, NULL, p);
-+                                if (r < 0) {
-+                                        log_unit_error_errno(u, r, "Cannot store BPF program for reload, ignoring: %m");
-+                                        continue;
-+                                }
-+
-+                                bpf_program_ref(p);
-+                        }
-+        }
-+
-+        log_debug("Pinned %d BPF programs", set_size(m->bpf_limbo_progs));
-+
-+        return m;
-+}
-+
-+static void manager_skeletonize_all_cgroup_bpf_programs(Manager *m) {
-+        BPFProgram *p;
-+        Iterator i;
-+
-+        SET_FOREACH(p, m->bpf_limbo_progs, i)
-+                bpf_program_skeletonize(p);
-+}
-+
-+void manager_unpin_all_cgroup_bpf_programs(Manager *m) {
-+        log_debug("Unpinning %d BPF programs", set_size(m->bpf_limbo_progs));
-+        set_clear_with_destructor(m->bpf_limbo_progs, bpf_program_unref);
-+}
-+
- int manager_reload(Manager *m) {
-         _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
-         _cleanup_fdset_free_ FDSet *fds = NULL;
-@@ -3738,6 +3880,13 @@ int manager_reload(Manager *m) {
-         /* We are officially in reload mode from here on. */
-         reloading = manager_reloading_start(m);
- 
-+        /* We need existing BPF programs to survive reload, otherwise there will be a period where no BPF
-+         * program is active during task execution within a cgroup. This would be bad since this may have
-+         * security or reliability implications: devices we should filter won't be filtered, network activity
-+         * we should filter won't be filtered, etc. We pin all the existing devices by bumping their
-+         * refcount, and then storing them to later have it decremented. */
-+        (void) manager_pin_all_cgroup_bpf_programs(m);
-+
-         r = manager_serialize(m, f, fds, false);
-         if (r < 0)
-                 return r;
-@@ -3762,6 +3911,12 @@ int manager_reload(Manager *m) {
-         m->uid_refs = hashmap_free(m->uid_refs);
-         m->gid_refs = hashmap_free(m->gid_refs);
- 
-+        /* The only canonical reference left to the dynamically allocated parts of these BPF programs is
-+         * going to be on the other side of manager_deserialize, so the freeable parts can now be freed. The
-+         * program itself will be detached as part of manager_vacuum. */
-+        manager_skeletonize_all_cgroup_bpf_programs(m);
-+        m->bpf_limbo_progs = set_free(m->bpf_limbo_progs);
-+
-         r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
-         if (r < 0)
-                 log_warning_errno(r, "Failed to initialize path lookup table, ignoring: %m");
-@@ -4700,6 +4855,12 @@ static void manager_vacuum(Manager *m) {
- 
-         /* Release any runtimes no longer referenced */
-         exec_runtime_vacuum(m);
-+
-+        /* Release any outmoded BPF programs that were deserialized from the previous manager, since new ones
-+         * should be in action now. We first need to make sure all entries in the cgroup realize queue are
-+         * complete, otherwise BPF firewalls/etc may not have been set up yet. */
-+        (void) manager_dispatch_cgroup_realize_queue(m);
-+        manager_unpin_all_cgroup_bpf_programs(m);
- }
- 
- int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
-diff --git a/src/core/manager.h b/src/core/manager.h
-index 81b0c13a95..6f8f8b04b4 100644
---- a/src/core/manager.h
-+++ b/src/core/manager.h
-@@ -433,6 +433,8 @@ struct Manager {
-         bool honor_device_enumeration;
- 
-         VarlinkServer *varlink_server;
-+
-+        Set *bpf_limbo_progs;
- };
- 
- static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
-@@ -474,6 +476,10 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode
- int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs,  Job **ret);
- int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e);
- 
-+Manager* manager_pin_all_cgroup_bpf_programs(Manager *m);
-+void manager_unpin_all_cgroup_bpf_programs(Manager *m);
-+DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unpin_all_cgroup_bpf_programs);
-+
- void manager_dump_units(Manager *s, FILE *f, const char *prefix);
- void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
- void manager_dump(Manager *s, FILE *f, const char *prefix);
-diff --git a/src/shared/bpf-program.c b/src/shared/bpf-program.c
-index e5c9df4004..cc479aa52e 100644
---- a/src/shared/bpf-program.c
-+++ b/src/shared/bpf-program.c
-@@ -210,6 +210,16 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
-         return 0;
- }
- 
-+void bpf_program_skeletonize(BPFProgram *p) {
-+        assert(p);
-+
-+        /* Called shortly after serialization. From this point on, we are frozen for serialization and entry
-+         * into BPF limbo, so we should proactively free our instructions and attached path. However, we
-+         * shouldn't detach the program or close the kernel FD -- we need those on the other side. */
-+        free(p->instructions);
-+        free(p->attached_path);
-+}
-+
- int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags) {
-         union bpf_attr attr = {
-                 .map_type = type,
-diff --git a/src/shared/bpf-program.h b/src/shared/bpf-program.h
-index a21589eb1f..6ea5d9a57c 100644
---- a/src/shared/bpf-program.h
-+++ b/src/shared/bpf-program.h
-@@ -28,6 +28,7 @@ struct BPFProgram {
- int bpf_program_new(uint32_t prog_type, BPFProgram **ret);
- BPFProgram *bpf_program_unref(BPFProgram *p);
- BPFProgram *bpf_program_ref(BPFProgram *p);
-+void bpf_program_skeletonize(BPFProgram *p);
- 
- int bpf_program_add_instructions(BPFProgram *p, const struct bpf_insn *insn, size_t count);
- int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size);
--- 
-2.24.1
-
diff --git a/SOURCES/0001-test-acl-util-output-more-debug-info.patch b/SOURCES/0001-test-acl-util-output-more-debug-info.patch
deleted file mode 100644
index 6db830f..0000000
--- a/SOURCES/0001-test-acl-util-output-more-debug-info.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 8cad57ed62a642515670ba79dddb30193456e803 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Fri, 7 Aug 2020 18:54:37 +0200
-Subject: [PATCH] test-acl-util: output more debug info
-
-For some reason this failed in koji build on s390x:
---- command ---
-16:12:46 PATH='/builddir/build/BUILD/systemd-stable-246.1/s390x-redhat-linux-gnu:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin' SYSTEMD_LANGUAGE_FALLBACK_MAP='/builddir/build/BUILD/systemd-stable-246.1/src/locale/language-fallback-map' SYSTEMD_KBD_MODEL_MAP='/builddir/build/BUILD/systemd-stable-246.1/src/locale/kbd-model-map' /builddir/build/BUILD/systemd-stable-246.1/s390x-redhat-linux-gnu/test-acl-util
---- stdout ---
--rw-r-----. 1 mockbuild mock 0 Aug  7 16:12 /tmp/test-empty.7RzmEc
-other::---
---- stderr ---
-Assertion 'r >= 0' failed at src/test/test-acl-util.c:42, function test_add_acls_for_user(). Aborting.
----
- src/test/test-acl-util.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c
-index df879747f5..9f0e594e67 100644
---- a/src/test/test-acl-util.c
-+++ b/src/test/test-acl-util.c
-@@ -7,6 +7,7 @@
- 
- #include "acl-util.h"
- #include "fd-util.h"
-+#include "format-util.h"
- #include "string-util.h"
- #include "tmpfile-util.h"
- #include "user-util.h"
-@@ -18,6 +19,8 @@ static void test_add_acls_for_user(void) {
-         uid_t uid;
-         int r;
- 
-+        log_info("/* %s */", __func__);
-+
-         fd = mkostemp_safe(fn);
-         assert_se(fd >= 0);
- 
-@@ -39,6 +42,7 @@ static void test_add_acls_for_user(void) {
-                 uid = getuid();
- 
-         r = add_acls_for_user(fd, uid);
-+        log_info_errno(r, "add_acls_for_user(%d, "UID_FMT"): %m", fd, uid);
-         assert_se(r >= 0);
- 
-         cmd = strjoina("ls -l ", fn);
diff --git a/SOURCES/0002-core-clean-up-inactive-failed-service-scope-s-cgroup.patch b/SOURCES/0002-core-clean-up-inactive-failed-service-scope-s-cgroup.patch
deleted file mode 100644
index d2a5150..0000000
--- a/SOURCES/0002-core-clean-up-inactive-failed-service-scope-s-cgroup.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From b554f941a8f275124508794b0b83f0554c7b84dc Mon Sep 17 00:00:00 2001
-From: Anita Zhang <the.anitazha@gmail.com>
-Date: Thu, 22 Oct 2020 22:44:22 -0700
-Subject: [PATCH 2/3] core: clean up inactive/failed {service|scope}'s cgroups
- when the last process exits
-
-If processes remain in the unit's cgroup after the final SIGKILL is
-sent and the unit has exceeded stop timeout, don't release the unit's
-cgroup information. Pid1 will have failed to `rmdir` the cgroup path due
-to processes remaining in the cgroup and releasing would leave the cgroup
-path on the file system with no tracking for pid1 to clean it up.
-
-Instead, keep the information around until the last process exits and pid1
-sends the cgroup empty notification. The service/scope can then prune
-the cgroup if the unit is inactive/failed.
----
- src/core/cgroup.c  | 26 +++++++++++++++++++++++++-
- src/core/cgroup.h  |  6 +++++-
- src/core/scope.c   |  5 +++++
- src/core/service.c |  7 +++++++
- 4 files changed, 42 insertions(+), 2 deletions(-)
-
-diff --git a/src/core/cgroup.c b/src/core/cgroup.c
-index 031b28a684..bce5f44e78 100644
---- a/src/core/cgroup.c
-+++ b/src/core/cgroup.c
-@@ -2414,6 +2414,29 @@ void unit_release_cgroup(Unit *u) {
-         }
- }
- 
-+bool unit_maybe_release_cgroup(Unit *u) {
-+        int r;
-+
-+        assert(u);
-+
-+        if (!u->cgroup_path)
-+                return true;
-+
-+        /* Don't release the cgroup if there are still processes under it. If we get notified later when all the
-+         * processes exit (e.g. the processes were in D-state and exited after the unit was marked as failed)
-+         * we need the cgroup paths to continue to be tracked by the manager so they can be looked up and cleaned
-+         * up later. */
-+        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
-+        if (r < 0)
-+                log_unit_debug_errno(u, r, "Error checking if the cgroup is recursively empty, ignoring: %m");
-+        else if (r == 1) {
-+                unit_release_cgroup(u);
-+                return true;
-+        }
-+
-+        return false;
-+}
-+
- void unit_prune_cgroup(Unit *u) {
-         int r;
-         bool is_root_slice;
-@@ -2441,7 +2464,8 @@ void unit_prune_cgroup(Unit *u) {
-         if (is_root_slice)
-                 return;
- 
--        unit_release_cgroup(u);
-+        if (!unit_maybe_release_cgroup(u)) /* Returns true if the cgroup was released */
-+                return;
- 
-         u->cgroup_realized = false;
-         u->cgroup_realized_mask = 0;
-diff --git a/src/core/cgroup.h b/src/core/cgroup.h
-index 52d028e740..be6856c20c 100644
---- a/src/core/cgroup.h
-+++ b/src/core/cgroup.h
-@@ -220,11 +220,15 @@ int unit_set_cgroup_path(Unit *u, const char *path);
- int unit_pick_cgroup_path(Unit *u);
- 
- int unit_realize_cgroup(Unit *u);
--void unit_release_cgroup(Unit *u);
- void unit_prune_cgroup(Unit *u);
- int unit_watch_cgroup(Unit *u);
- int unit_watch_cgroup_memory(Unit *u);
- 
-+void unit_release_cgroup(Unit *u);
-+/* Releases the cgroup only if it is recursively empty.
-+ * Returns true if the cgroup was released, false otherwise. */
-+bool unit_maybe_release_cgroup(Unit *u);
-+
- void unit_add_to_cgroup_empty_queue(Unit *u);
- int unit_check_oom(Unit *u);
- 
-diff --git a/src/core/scope.c b/src/core/scope.c
-index 42c51b0865..ffee783a4c 100644
---- a/src/core/scope.c
-+++ b/src/core/scope.c
-@@ -487,6 +487,11 @@ static void scope_notify_cgroup_empty_event(Unit *u) {
- 
-         if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
-                 scope_enter_dead(s, SCOPE_SUCCESS);
-+
-+        /* If the cgroup empty notification comes when the unit is not active, we must have failed to clean
-+         * up the cgroup earlier and should do it now. */
-+        if (IN_SET(s->state, SCOPE_DEAD, SCOPE_FAILED))
-+                unit_prune_cgroup(u);
- }
- 
- static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
-diff --git a/src/core/service.c b/src/core/service.c
-index 00e61945ba..db8f596ca6 100644
---- a/src/core/service.c
-+++ b/src/core/service.c
-@@ -3334,6 +3334,13 @@ static void service_notify_cgroup_empty_event(Unit *u) {
- 
-                 break;
- 
-+        /* If the cgroup empty notification comes when the unit is not active, we must have failed to clean
-+         * up the cgroup earlier and should do it now. */
-+        case SERVICE_DEAD:
-+        case SERVICE_FAILED:
-+                unit_prune_cgroup(u);
-+                break;
-+
-         default:
-                 ;
-         }
--- 
-2.24.1
-
diff --git a/SOURCES/0002-test-path-do-not-fail-the-test-if-we-fail-to-start-s.patch b/SOURCES/0002-test-path-do-not-fail-the-test-if-we-fail-to-start-s.patch
deleted file mode 100644
index c285891..0000000
--- a/SOURCES/0002-test-path-do-not-fail-the-test-if-we-fail-to-start-s.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From a2deeaeaa90d493ef8a2b20656745cd0531a1b30 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Fri, 31 Jul 2020 10:36:57 +0200
-Subject: [PATCH 2/2] test-path: do not fail the test if we fail to start some
- service
-
-The test was failing because it couldn't start the service:
-
-path-modified.service: state = failed; result = exit-code
-path-modified.path: state = waiting; result = success
-path-modified.service: state = failed; result = exit-code
-path-modified.path: state = waiting; result = success
-path-modified.service: state = failed; result = exit-code
-path-modified.path: state = waiting; result = success
-path-modified.service: state = failed; result = exit-code
-path-modified.path: state = waiting; result = success
-path-modified.service: state = failed; result = exit-code
-path-modified.path: state = waiting; result = success
-path-modified.service: state = failed; result = exit-code
-Failed to connect to system bus: No such file or directory
--.slice: Failed to enable/disable controllers on cgroup /system.slice/kojid.service, ignoring: Permission denied
-path-modified.service: Failed to create cgroup /system.slice/kojid.service/path-modified.service: Permission denied
-path-modified.service: Failed to attach to cgroup /system.slice/kojid.service/path-modified.service: No such file or directory
-path-modified.service: Failed at step CGROUP spawning /bin/true: No such file or directory
-path-modified.service: Main process exited, code=exited, status=219/CGROUP
-path-modified.service: Failed with result 'exit-code'.
-Test timeout when testing path-modified.path
-
-Let's just ignore the failure here. Services can occasionally fail to start,
-there's not much we can do in that case.
----
- src/test/test-path.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/src/test/test-path.c b/src/test/test-path.c
-index 63b709c8da..6c0db53f10 100644
---- a/src/test/test-path.c
-+++ b/src/test/test-path.c
-@@ -98,6 +98,14 @@ static void check_states(Manager *m, Path *path, Service *service, PathState pat
-                                 service_state_to_string(service->state),
-                                 service_result_to_string(service->result));
- 
-+                if (service->state == SERVICE_FAILED) {
-+                        log_warning("Failed to start service %s, ignoring: %s/%s",
-+                                    UNIT(service)->id,
-+                                    service_state_to_string(service->state),
-+                                    service_result_to_string(service->result));
-+                        break;
-+                }
-+
-                 if (now(CLOCK_MONOTONIC) >= end) {
-                         log_error("Test timeout when testing %s", UNIT(path)->id);
-                         exit(EXIT_FAILURE);
diff --git a/SOURCES/0003-timer-add-new-feature-FixedRandomDelay.patch b/SOURCES/0003-timer-add-new-feature-FixedRandomDelay.patch
deleted file mode 100644
index a1559c8..0000000
--- a/SOURCES/0003-timer-add-new-feature-FixedRandomDelay.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From de8f6fb530db706d14e9ece52b2acfd77c823133 Mon Sep 17 00:00:00 2001
-From: Kristijan Gjoshev <crypter@mail.com>
-Date: Sat, 1 Feb 2020 18:27:08 +0100
-Subject: [PATCH 3/3] timer: add new feature FixedRandomDelay=
-
-FixedRandomDelay=yes will use
-`siphash24(sd_id128_get_machine() || MANAGER_IS_SYSTEM(m) || getuid() || u->id)`,
-where || is concatenation, instead of a random number to choose a value between
-0 and RandomizedDelaySec= as the timer delay.
-This essentially sets up a fixed, but seemingly random, offset for each timer
-iteration rather than having a random offset recalculated each time it fires.
-
-Closes #10355
-
-Co-author: Anita Zhang <the.anitazha@gmail.com>
----
- docs/TRANSIENT-SETTINGS.md                    |  1 +
- man/org.freedesktop.systemd1.xml              |  6 ++++
- man/systemd.timer.xml                         | 12 +++++++
- src/core/dbus-timer.c                         |  4 +++
- src/core/timer.c                              | 34 ++++++++++++++++++-
- src/core/timer.h                              |  1 +
- src/shared/bus-unit-util.c                    |  3 +-
- test/fuzz/fuzz-unit-file/directives.service   |  1 +
- .../systemd-tmpfiles-clean.timer              |  1 +
- 9 files changed, 61 insertions(+), 2 deletions(-)
-
-diff --git a/docs/TRANSIENT-SETTINGS.md b/docs/TRANSIENT-SETTINGS.md
-index 19944d08b8..f4639b2e87 100644
---- a/docs/TRANSIENT-SETTINGS.md
-+++ b/docs/TRANSIENT-SETTINGS.md
-@@ -368,6 +368,7 @@ Most timer unit settings are available to transient units.
- ✓ RemainAfterElapse=
- ✓ AccuracySec=
- ✓ RandomizedDelaySec=
-+✓ FixedRandomDelay=
-   Unit=
- ```
- 
-diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
-index 6b16ae16da..ab4cbaa2fb 100644
---- a/man/org.freedesktop.systemd1.xml
-+++ b/man/org.freedesktop.systemd1.xml
-@@ -6866,6 +6866,8 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
-       readonly t RandomizedDelayUSec = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
-+      readonly b FixedRandomDelay = ...;
-+      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
-       readonly b Persistent = ...;
-       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
-       readonly b WakeSystem = ...;
-@@ -6891,6 +6893,8 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
- 
-     <!--property RandomizedDelayUSec is not documented!-->
- 
-+    <!--property FixedRandomDelay is not documented!-->
-+
-     <!--property Persistent is not documented!-->
- 
-     <!--property WakeSystem is not documented!-->
-@@ -6931,6 +6935,8 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="RandomizedDelayUSec"/>
- 
-+    <variablelist class="dbus-property" generated="True" extra-ref="FixedRandomDelay"/>
-+
-     <variablelist class="dbus-property" generated="True" extra-ref="Persistent"/>
- 
-     <variablelist class="dbus-property" generated="True" extra-ref="WakeSystem"/>
-diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
-index 5822402712..6f731e2311 100644
---- a/man/systemd.timer.xml
-+++ b/man/systemd.timer.xml
-@@ -268,6 +268,18 @@
-         <varname>AccuracySec=1us</varname>.</para></listitem>
-       </varlistentry>
- 
-+      <varlistentry>
-+        <term><varname>FixedRandomDelay=</varname></term>
-+
-+        <listitem><para>Takes a boolean argument. If true, some amount of time between 0 and
-+        <varname>RandomizedDelaySec=</varname> is chosen and added as the delay for each timer iteration. As this
-+        delay will not be recalculated on each run, this effectively creates a fixed offset for each iteration.
-+        The distribution between 0 and <varname>RandomizedDelaySec=</varname> is deterministic and based on
-+        a combination of the machine ID, whether the timer is run by the user/system manager, the service manager's
-+        user ID, and the timer's unit name. Has no effect if
-+        <varname>RandomizedDelaySec=</varname> is set to 0. Defaults to <option>false</option>.</para></listitem>
-+      </varlistentry>
-+
-       <varlistentry>
-         <term><varname>OnClockChange=</varname></term>
-         <term><varname>OnTimezoneChange=</varname></term>
-diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
-index da35fa8678..ee54ba8772 100644
---- a/src/core/dbus-timer.c
-+++ b/src/core/dbus-timer.c
-@@ -131,6 +131,7 @@ const sd_bus_vtable bus_timer_vtable[] = {
-         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-         SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
-         SD_BUS_PROPERTY("RandomizedDelayUSec", "t", bus_property_get_usec, offsetof(Timer, random_usec), SD_BUS_VTABLE_PROPERTY_CONST),
-+        SD_BUS_PROPERTY("FixedRandomDelay", "b", bus_property_get_bool, offsetof(Timer, fixed_random_delay), SD_BUS_VTABLE_PROPERTY_CONST),
-         SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
-         SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
-         SD_BUS_PROPERTY("RemainAfterElapse", "b", bus_property_get_bool, offsetof(Timer, remain_after_elapse), SD_BUS_VTABLE_PROPERTY_CONST),
-@@ -232,6 +233,9 @@ static int bus_timer_set_transient_property(
-         if (streq(name, "RandomizedDelayUSec"))
-                 return bus_set_transient_usec(u, name, &t->random_usec, message, flags, error);
- 
-+        if (streq(name, "FixedRandomDelay"))
-+                return bus_set_transient_bool(u, name, &t->fixed_random_delay, message, flags, error);
-+
-         if (streq(name, "WakeSystem"))
-                 return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error);
- 
-diff --git a/src/core/timer.c b/src/core/timer.c
-index 03a9c14f76..b2c5e26f63 100644
---- a/src/core/timer.c
-+++ b/src/core/timer.c
-@@ -169,6 +169,36 @@ static int timer_setup_persistent(Timer *t) {
-         return 0;
- }
- 
-+static uint64_t timer_get_fixed_delay_hash(Timer *t) {
-+        static const uint8_t hash_key[] = {
-+                0x51, 0x0a, 0xdb, 0x76, 0x29, 0x51, 0x42, 0xc2,
-+                0x80, 0x35, 0xea, 0xe6, 0x8e, 0x3a, 0x37, 0xbd
-+        };
-+
-+        struct siphash state;
-+        sd_id128_t machine_id;
-+        uid_t uid;
-+        int r;
-+
-+        assert(t);
-+
-+        uid = getuid();
-+        r = sd_id128_get_machine(&machine_id);
-+        if (r < 0) {
-+                log_unit_debug_errno(UNIT(t), r,
-+                                     "Failed to get machine ID for the fixed delay calculation, proceeding with 0: %m");
-+                machine_id = SD_ID128_NULL;
-+        }
-+
-+        siphash24_init(&state, hash_key);
-+        siphash24_compress(&machine_id, sizeof(sd_id128_t), &state);
-+        siphash24_compress_boolean(MANAGER_IS_SYSTEM(UNIT(t)->manager), &state);
-+        siphash24_compress(&uid, sizeof(uid_t), &state);
-+        siphash24_compress_string(UNIT(t)->id, &state);
-+
-+        return siphash24_finalize(&state);
-+}
-+
- static int timer_load(Unit *u) {
-         Timer *t = TIMER(u);
-         int r;
-@@ -215,6 +245,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
-                 "%sWakeSystem: %s\n"
-                 "%sAccuracy: %s\n"
-                 "%sRemainAfterElapse: %s\n"
-+                "%sFixedRandomDelay: %s\n"
-                 "%sOnClockChange: %s\n"
-                 "%sOnTimeZoneChange: %s\n",
-                 prefix, timer_state_to_string(t->state),
-@@ -224,6 +255,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
-                 prefix, yes_no(t->wake_system),
-                 prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1),
-                 prefix, yes_no(t->remain_after_elapse),
-+                prefix, yes_no(t->fixed_random_delay),
-                 prefix, yes_no(t->on_clock_change),
-                 prefix, yes_no(t->on_timezone_change));
- 
-@@ -332,7 +364,7 @@ static void add_random(Timer *t, usec_t *v) {
-         if (*v == USEC_INFINITY)
-                 return;
- 
--        add = random_u64() % t->random_usec;
-+        add = (t->fixed_random_delay ? timer_get_fixed_delay_hash(t) : random_u64()) % t->random_usec;
- 
-         if (*v + add < *v) /* overflow */
-                 *v = (usec_t) -2; /* Highest possible value, that is not USEC_INFINITY */
-diff --git a/src/core/timer.h b/src/core/timer.h
-index ab66a201ad..ce4046a210 100644
---- a/src/core/timer.h
-+++ b/src/core/timer.h
-@@ -59,6 +59,7 @@ struct Timer {
-         bool remain_after_elapse;
-         bool on_clock_change;
-         bool on_timezone_change;
-+        bool fixed_random_delay;
- 
-         char *stamp_path;
- };
-diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
-index f2652ed9a5..68de4a2ed1 100644
---- a/src/shared/bus-unit-util.c
-+++ b/src/shared/bus-unit-util.c
-@@ -1779,7 +1779,8 @@ static int bus_append_timer_property(sd_bus_message *m, const char *field, const
-                               "RemainAfterElapse",
-                               "Persistent",
-                               "OnTimezoneChange",
--                              "OnClockChange"))
-+                              "OnClockChange",
-+                              "FixedRandomDelay"))
-                 return bus_append_parse_boolean(m, field, eq);
- 
-         if (STR_IN_SET(field, "AccuracySec",
-diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
-index dbff9ab2cc..95304ea0c6 100644
---- a/test/fuzz/fuzz-unit-file/directives.service
-+++ b/test/fuzz/fuzz-unit-file/directives.service
-@@ -175,6 +175,7 @@ PipeSize=
- Priority=
- PropagatesReloadTo=
- RandomizedDelaySec=
-+FixedRandomDelay=
- RebootArgument=
- ReceiveBuffer=
- RefuseManualStart=
-diff --git a/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer b/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer
-index 7db361cd69..64b8808adc 100644
---- a/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer
-+++ b/test/fuzz/fuzz-unit-file/systemd-tmpfiles-clean.timer
-@@ -32,6 +32,7 @@ OnCalendar=Fri 2012-11-23 11:12:13
- Persistent=true
- AccuracySec=24h
- RandomizedDelaySec=234234234
-+FixedRandomDelay=true
- 
- Persistent=no
- Unit=foo.service
--- 
-2.24.1
-
diff --git a/SOURCES/16803_fix_asserts_conditions.patch b/SOURCES/16803_fix_asserts_conditions.patch
deleted file mode 100644
index 817ec45..0000000
--- a/SOURCES/16803_fix_asserts_conditions.patch
+++ /dev/null
@@ -1,553 +0,0 @@
-From 625a164069aff9efb61dcc5916c572f53c2a7ab0 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 20 Aug 2020 13:43:00 +0200
-Subject: [PATCH 1/3] analyze: rework condition testing
-
-Let's drop the private table and just use the generic concepts we have
-in place already that make the same information available.
-
-Fixes: #16781
----
- src/analyze/analyze-condition.c | 105 +++++++++-----------------------
- 1 file changed, 28 insertions(+), 77 deletions(-)
-
-diff --git a/src/analyze/analyze-condition.c b/src/analyze/analyze-condition.c
-index 52ad382637f..13f75e813a2 100644
---- a/src/analyze/analyze-condition.c
-+++ b/src/analyze/analyze-condition.c
-@@ -8,83 +8,27 @@
- #include "load-fragment.h"
- #include "service.h"
- 
--typedef struct condition_definition {
--        const char *name;
--        ConfigParserCallback parser;
--        ConditionType type;
--} condition_definition;
--
--static const condition_definition condition_definitions[] = {
--        { "ConditionPathExists",             config_parse_unit_condition_path,   CONDITION_PATH_EXISTS              },
--        { "ConditionPathExistsGlob",         config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB         },
--        { "ConditionPathIsDirectory",        config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY        },
--        { "ConditionPathIsSymbolicLink",     config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK    },
--        { "ConditionPathIsMountPoint",       config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT      },
--        { "ConditionPathIsReadWrite",        config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE       },
--        { "ConditionPathIsEncrypted",        config_parse_unit_condition_path,   CONDITION_PATH_IS_ENCRYPTED        },
--        { "ConditionDirectoryNotEmpty",      config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY      },
--        { "ConditionFileNotEmpty",           config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY           },
--        { "ConditionFileIsExecutable",       config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE       },
--        { "ConditionNeedsUpdate",            config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE             },
--        { "ConditionFirstBoot",              config_parse_unit_condition_string, CONDITION_FIRST_BOOT               },
--        { "ConditionKernelCommandLine",      config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE      },
--        { "ConditionKernelVersion",          config_parse_unit_condition_string, CONDITION_KERNEL_VERSION           },
--        { "ConditionArchitecture",           config_parse_unit_condition_string, CONDITION_ARCHITECTURE             },
--        { "ConditionVirtualization",         config_parse_unit_condition_string, CONDITION_VIRTUALIZATION           },
--        { "ConditionSecurity",               config_parse_unit_condition_string, CONDITION_SECURITY                 },
--        { "ConditionCapability",             config_parse_unit_condition_string, CONDITION_CAPABILITY               },
--        { "ConditionHost",                   config_parse_unit_condition_string, CONDITION_HOST                     },
--        { "ConditionACPower",                config_parse_unit_condition_string, CONDITION_AC_POWER                 },
--        { "ConditionUser",                   config_parse_unit_condition_string, CONDITION_USER                     },
--        { "ConditionGroup",                  config_parse_unit_condition_string, CONDITION_GROUP                    },
--        { "ConditionControlGroupController", config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER },
--
--        { "AssertPathExists",                config_parse_unit_condition_path,   CONDITION_PATH_EXISTS              },
--        { "AssertPathExistsGlob",            config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB         },
--        { "AssertPathIsDirectory",           config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY        },
--        { "AssertPathIsSymbolicLink",        config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK    },
--        { "AssertPathIsMountPoint",          config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT      },
--        { "AssertPathIsReadWrite",           config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE       },
--        { "AssertPathIsEncrypted",           config_parse_unit_condition_path,   CONDITION_PATH_IS_ENCRYPTED        },
--        { "AssertDirectoryNotEmpty",         config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY      },
--        { "AssertFileNotEmpty",              config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY           },
--        { "AssertFileIsExecutable",          config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE       },
--        { "AssertNeedsUpdate",               config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE             },
--        { "AssertFirstBoot",                 config_parse_unit_condition_string, CONDITION_FIRST_BOOT               },
--        { "AssertKernelCommandLine",         config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE      },
--        { "AssertKernelVersion",             config_parse_unit_condition_string, CONDITION_KERNEL_VERSION           },
--        { "AssertArchitecture",              config_parse_unit_condition_string, CONDITION_ARCHITECTURE             },
--        { "AssertVirtualization",            config_parse_unit_condition_string, CONDITION_VIRTUALIZATION           },
--        { "AssertSecurity",                  config_parse_unit_condition_string, CONDITION_SECURITY                 },
--        { "AssertCapability",                config_parse_unit_condition_string, CONDITION_CAPABILITY               },
--        { "AssertHost",                      config_parse_unit_condition_string, CONDITION_HOST                     },
--        { "AssertACPower",                   config_parse_unit_condition_string, CONDITION_AC_POWER                 },
--        { "AssertUser",                      config_parse_unit_condition_string, CONDITION_USER                     },
--        { "AssertGroup",                     config_parse_unit_condition_string, CONDITION_GROUP                    },
--        { "AssertControlGroupController",    config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER },
--
--        /* deprecated, but we should still parse them */
--        { "ConditionNull",                   config_parse_unit_condition_null,   0                                  },
--        { "AssertNull",                      config_parse_unit_condition_null,   0                                  },
--};
--
- static int parse_condition(Unit *u, const char *line) {
--        const char *p;
--        Condition **target;
--
--        if ((p = startswith(line, "Condition")))
--                target = &u->conditions;
--        else if ((p = startswith(line, "Assert")))
--                target = &u->asserts;
--        else
--                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line);
--
--        for (size_t i = 0; i < ELEMENTSOF(condition_definitions); i++) {
--                const condition_definition *c = &condition_definitions[i];
--
--                p = startswith(line, c->name);
--                if (!p)
--                        continue;
-+        assert(u);
-+        assert(line);
-+
-+        for (ConditionType t = 0; t < _CONDITION_TYPE_MAX; t++) {
-+                ConfigParserCallback callback;
-+                Condition **target;
-+                const char *p, *name;
-+
-+                name = condition_type_to_string(t);
-+                p = startswith(line, name);
-+                if (p)
-+                        target = &u->conditions;
-+                else {
-+                        name = assert_type_to_string(t);
-+                        p = startswith(line, name);
-+                        if (!p)
-+                                continue;
-+
-+                        target = &u->asserts;
-+                }
- 
-                 p += strspn(p, WHITESPACE);
- 
-@@ -94,7 +38,14 @@ static int parse_condition(Unit *u, const char *line) {
- 
-                 p += strspn(p, WHITESPACE);
- 
--                return c->parser(NULL, "(stdin)", 0, NULL, 0, c->name, c->type, p, target, u);
-+                if (t == CONDITION_NULL) /* deprecated, but we should still parse this for now */
-+                        callback = config_parse_unit_condition_null;
-+                else if (condition_takes_path(t))
-+                        callback = config_parse_unit_condition_path;
-+                else
-+                        callback = config_parse_unit_condition_string;
-+
-+                return callback(NULL, "(cmdline)", 0, NULL, 0, name, t, p, target, u);
-         }
- 
-         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line);
-
-From 4f55a5b0bf1e68e4595120d8ac4b518654355fc3 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 20 Aug 2020 13:44:12 +0200
-Subject: [PATCH 2/3] core: add missing conditions/asserts to unit file parsing
-
----
- src/core/load-fragment-gperf.gperf.m4 | 24 ++++++++++++++++--------
- 1 file changed, 16 insertions(+), 8 deletions(-)
-
-diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
-index b9e7769e4e3..1e6bd6483c2 100644
---- a/src/core/load-fragment-gperf.gperf.m4
-+++ b/src/core/load-fragment-gperf.gperf.m4
-@@ -272,22 +272,26 @@ Unit.ConditionPathIsDirectory,   config_parse_unit_condition_path,   CONDITION_P
- Unit.ConditionPathIsSymbolicLink,config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK,offsetof(Unit, conditions)
- Unit.ConditionPathIsMountPoint,  config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT, offsetof(Unit, conditions)
- Unit.ConditionPathIsReadWrite,   config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE,  offsetof(Unit, conditions)
-+Unit.ConditionPathIsEncrypted,   config_parse_unit_condition_path,   CONDITION_PATH_IS_ENCRYPTED,   offsetof(Unit, conditions)
- Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY, offsetof(Unit, conditions)
- Unit.ConditionFileNotEmpty,      config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY,      offsetof(Unit, conditions)
- Unit.ConditionFileIsExecutable,  config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE,  offsetof(Unit, conditions)
- Unit.ConditionNeedsUpdate,       config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE,        offsetof(Unit, conditions)
- Unit.ConditionFirstBoot,         config_parse_unit_condition_string, CONDITION_FIRST_BOOT,          offsetof(Unit, conditions)
--Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, conditions)
--Unit.ConditionKernelVersion,     config_parse_unit_condition_string, CONDITION_KERNEL_VERSION,      offsetof(Unit, conditions)
- Unit.ConditionArchitecture,      config_parse_unit_condition_string, CONDITION_ARCHITECTURE,        offsetof(Unit, conditions)
- Unit.ConditionVirtualization,    config_parse_unit_condition_string, CONDITION_VIRTUALIZATION,      offsetof(Unit, conditions)
-+Unit.ConditionHost,              config_parse_unit_condition_string, CONDITION_HOST,                offsetof(Unit, conditions)
-+Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, conditions)
-+Unit.ConditionKernelVersion,     config_parse_unit_condition_string, CONDITION_KERNEL_VERSION,      offsetof(Unit, conditions)
- Unit.ConditionSecurity,          config_parse_unit_condition_string, CONDITION_SECURITY,            offsetof(Unit, conditions)
- Unit.ConditionCapability,        config_parse_unit_condition_string, CONDITION_CAPABILITY,          offsetof(Unit, conditions)
--Unit.ConditionHost,              config_parse_unit_condition_string, CONDITION_HOST,                offsetof(Unit, conditions)
- Unit.ConditionACPower,           config_parse_unit_condition_string, CONDITION_AC_POWER,            offsetof(Unit, conditions)
-+Unit.ConditionMemory,            config_parse_unit_condition_string, CONDITION_MEMORY,              offsetof(Unit, conditions)
-+Unit.ConditionCPUs,              config_parse_unit_condition_string, CONDITION_CPUS,                offsetof(Unit, conditions)
-+Unit.ConditionEnvironment,       config_parse_unit_condition_string, CONDITION_ENVIRONMENT,         offsetof(Unit, conditions)
- Unit.ConditionUser,              config_parse_unit_condition_string, CONDITION_USER,                offsetof(Unit, conditions)
- Unit.ConditionGroup,             config_parse_unit_condition_string, CONDITION_GROUP,               offsetof(Unit, conditions)
--Unit.ConditionControlGroupController,  config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER,   offsetof(Unit, conditions)
-+Unit.ConditionControlGroupController, config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER, offsetof(Unit, conditions)
- Unit.ConditionNull,              config_parse_unit_condition_null,   0,                             offsetof(Unit, conditions)
- Unit.AssertPathExists,           config_parse_unit_condition_path,   CONDITION_PATH_EXISTS,         offsetof(Unit, asserts)
- Unit.AssertPathExistsGlob,       config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB,    offsetof(Unit, asserts)
-@@ -295,22 +299,26 @@ Unit.AssertPathIsDirectory,      config_parse_unit_condition_path,   CONDITION_P
- Unit.AssertPathIsSymbolicLink,   config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK,offsetof(Unit, asserts)
- Unit.AssertPathIsMountPoint,     config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT, offsetof(Unit, asserts)
- Unit.AssertPathIsReadWrite,      config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE,  offsetof(Unit, asserts)
-+Unit.AssertPathIsEncrypted,      config_parse_unit_condition_path,   CONDITION_PATH_IS_ENCRYPTED,   offsetof(Unit, asserts)
- Unit.AssertDirectoryNotEmpty,    config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY, offsetof(Unit, asserts)
- Unit.AssertFileNotEmpty,         config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY,      offsetof(Unit, asserts)
- Unit.AssertFileIsExecutable,     config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE,  offsetof(Unit, asserts)
- Unit.AssertNeedsUpdate,          config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE,        offsetof(Unit, asserts)
- Unit.AssertFirstBoot,            config_parse_unit_condition_string, CONDITION_FIRST_BOOT,          offsetof(Unit, asserts)
--Unit.AssertKernelCommandLine,    config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, asserts)
--Unit.AssertKernelVersion,        config_parse_unit_condition_string, CONDITION_KERNEL_VERSION,      offsetof(Unit, asserts)
- Unit.AssertArchitecture,         config_parse_unit_condition_string, CONDITION_ARCHITECTURE,        offsetof(Unit, asserts)
- Unit.AssertVirtualization,       config_parse_unit_condition_string, CONDITION_VIRTUALIZATION,      offsetof(Unit, asserts)
-+Unit.AssertHost,                 config_parse_unit_condition_string, CONDITION_HOST,                offsetof(Unit, asserts)
-+Unit.AssertKernelCommandLine,    config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, offsetof(Unit, asserts)
-+Unit.AssertKernelVersion,        config_parse_unit_condition_string, CONDITION_KERNEL_VERSION,      offsetof(Unit, asserts)
- Unit.AssertSecurity,             config_parse_unit_condition_string, CONDITION_SECURITY,            offsetof(Unit, asserts)
- Unit.AssertCapability,           config_parse_unit_condition_string, CONDITION_CAPABILITY,          offsetof(Unit, asserts)
--Unit.AssertHost,                 config_parse_unit_condition_string, CONDITION_HOST,                offsetof(Unit, asserts)
- Unit.AssertACPower,              config_parse_unit_condition_string, CONDITION_AC_POWER,            offsetof(Unit, asserts)
-+Unit.AssertMemory,               config_parse_unit_condition_string, CONDITION_MEMORY,              offsetof(Unit, asserts)
-+Unit.AssertCPUs,                 config_parse_unit_condition_string, CONDITION_CPUS,                offsetof(Unit, asserts)
-+Unit.AssertEnvironment,          config_parse_unit_condition_string, CONDITION_ENVIRONMENT,         offsetof(Unit, asserts)
- Unit.AssertUser,                 config_parse_unit_condition_string, CONDITION_USER,                offsetof(Unit, asserts)
- Unit.AssertGroup,                config_parse_unit_condition_string, CONDITION_GROUP,               offsetof(Unit, asserts)
--Unit.AssertControlGroupController,     config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER,   offsetof(Unit, asserts)
-+Unit.AssertControlGroupController, config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER, offsetof(Unit, asserts)
- Unit.AssertNull,                 config_parse_unit_condition_null,   0,                             offsetof(Unit, asserts)
- Unit.CollectMode,                config_parse_collect_mode,          0,                             offsetof(Unit, collect_mode)
- m4_dnl
-
-From 476cfe626dac41bb9879116c701333caa2ccec24 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 20 Aug 2020 14:01:25 +0200
-Subject: [PATCH 3/3] core: remove support for ConditionNull=
-
-The concept is flawed, and mostly useless. Let's finally remove it.
-
-It has been deprecated since 90a2ec10f2d43a8530aae856013518eb567c4039 (6
-years ago) and we started to warn since
-55dadc5c57ef1379dbc984938d124508a454be55 (1.5 years ago).
-
-Let's get rid of it altogether.
----
- man/systemd.unit.xml                          |  3 -
- src/analyze/analyze-condition.c               |  4 +-
- src/core/dbus-unit.c                          | 22 +++-----
- src/core/load-fragment-gperf.gperf.m4         |  2 -
- src/core/load-fragment.c                      | 55 -------------------
- src/core/load-fragment.h                      |  1 -
- src/shared/condition.c                        | 21 +------
- src/shared/condition.h                        |  2 -
- src/test/test-condition.c                     | 15 -----
- .../fuzz-unit-file/systemd-machined.service   |  3 -
- 10 files changed, 11 insertions(+), 117 deletions(-)
-
-diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
-index 7ef6080237e..50f35aaa3cc 100644
---- a/man/systemd.unit.xml
-+++ b/man/systemd.unit.xml
-@@ -1092,9 +1092,6 @@
-       <para>Except for <varname>ConditionPathIsSymbolicLink=</varname>, all path checks follow symlinks.</para>
- 
-       <variablelist class='unit-directives'>
--        <!-- We do not document ConditionNull= here, as it is not particularly useful and probably just
--             confusing. -->
--
-         <varlistentry>
-           <term><varname>ConditionArchitecture=</varname></term>
- 
-diff --git a/src/analyze/analyze-condition.c b/src/analyze/analyze-condition.c
-index 13f75e813a2..e1365e18056 100644
---- a/src/analyze/analyze-condition.c
-+++ b/src/analyze/analyze-condition.c
-@@ -38,9 +38,7 @@ static int parse_condition(Unit *u, const char *line) {
- 
-                 p += strspn(p, WHITESPACE);
- 
--                if (t == CONDITION_NULL) /* deprecated, but we should still parse this for now */
--                        callback = config_parse_unit_condition_null;
--                else if (condition_takes_path(t))
-+                if (condition_takes_path(t))
-                         callback = config_parse_unit_condition_path;
-                 else
-                         callback = config_parse_unit_condition_string;
-diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
-index 9e9d3b101e5..e799771c220 100644
---- a/src/core/dbus-unit.c
-+++ b/src/core/dbus-unit.c
-@@ -1974,14 +1974,11 @@ static int bus_set_transient_conditions(
-                 if (t < 0)
-                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid condition type: %s", type_name);
- 
--                if (t != CONDITION_NULL) {
--                        if (isempty(param))
--                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
-+                if (isempty(param))
-+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
- 
--                        if (condition_takes_path(t) && !path_is_absolute(param))
--                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
--                } else
--                        param = NULL;
-+                if (condition_takes_path(t) && !path_is_absolute(param))
-+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
- 
-                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
-                         Condition *c;
-@@ -1992,14 +1989,9 @@ static int bus_set_transient_conditions(
- 
-                         LIST_PREPEND(conditions, *list, c);
- 
--                        if (t != CONDITION_NULL)
--                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
--                                                    "%s=%s%s%s", type_name,
--                                                    trigger ? "|" : "", negate ? "!" : "", param);
--                        else
--                                unit_write_settingf(u, flags, name,
--                                                    "%s=%s%s", type_name,
--                                                    trigger ? "|" : "", yes_no(!negate));
-+                        unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
-+                                            "%s=%s%s%s", type_name,
-+                                            trigger ? "|" : "", negate ? "!" : "", param);
-                 }
- 
-                 empty = false;
-diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
-index 1e6bd6483c2..a191de62af3 100644
---- a/src/core/load-fragment-gperf.gperf.m4
-+++ b/src/core/load-fragment-gperf.gperf.m4
-@@ -292,7 +292,6 @@ Unit.ConditionEnvironment,       config_parse_unit_condition_string, CONDITION_E
- Unit.ConditionUser,              config_parse_unit_condition_string, CONDITION_USER,                offsetof(Unit, conditions)
- Unit.ConditionGroup,             config_parse_unit_condition_string, CONDITION_GROUP,               offsetof(Unit, conditions)
- Unit.ConditionControlGroupController, config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER, offsetof(Unit, conditions)
--Unit.ConditionNull,              config_parse_unit_condition_null,   0,                             offsetof(Unit, conditions)
- Unit.AssertPathExists,           config_parse_unit_condition_path,   CONDITION_PATH_EXISTS,         offsetof(Unit, asserts)
- Unit.AssertPathExistsGlob,       config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB,    offsetof(Unit, asserts)
- Unit.AssertPathIsDirectory,      config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY,   offsetof(Unit, asserts)
-@@ -319,7 +318,6 @@ Unit.AssertEnvironment,          config_parse_unit_condition_string, CONDITION_E
- Unit.AssertUser,                 config_parse_unit_condition_string, CONDITION_USER,                offsetof(Unit, asserts)
- Unit.AssertGroup,                config_parse_unit_condition_string, CONDITION_GROUP,               offsetof(Unit, asserts)
- Unit.AssertControlGroupController, config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER, offsetof(Unit, asserts)
--Unit.AssertNull,                 config_parse_unit_condition_null,   0,                             offsetof(Unit, asserts)
- Unit.CollectMode,                config_parse_collect_mode,          0,                             offsetof(Unit, collect_mode)
- m4_dnl
- Service.PIDFile,                 config_parse_pid_file,              0,                             offsetof(Service, pid_file)
-diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
-index 266382c84c7..cfd04f3b49f 100644
---- a/src/core/load-fragment.c
-+++ b/src/core/load-fragment.c
-@@ -2999,60 +2999,6 @@ int config_parse_unit_condition_string(
-         return 0;
- }
- 
--int config_parse_unit_condition_null(
--                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) {
--
--        Condition **list = data, *c;
--        bool trigger, negate;
--        int b;
--
--        assert(filename);
--        assert(lvalue);
--        assert(rvalue);
--        assert(data);
--
--        log_syntax(unit, LOG_WARNING, filename, line, 0, "%s= is deprecated, please do not use.", lvalue);
--
--        if (isempty(rvalue)) {
--                /* Empty assignment resets the list */
--                *list = condition_free_list(*list);
--                return 0;
--        }
--
--        trigger = rvalue[0] == '|';
--        if (trigger)
--                rvalue++;
--
--        negate = rvalue[0] == '!';
--        if (negate)
--                rvalue++;
--
--        b = parse_boolean(rvalue);
--        if (b < 0) {
--                log_syntax(unit, LOG_ERR, filename, line, b, "Failed to parse boolean value in condition, ignoring: %s", rvalue);
--                return 0;
--        }
--
--        if (!b)
--                negate = !negate;
--
--        c = condition_new(CONDITION_NULL, NULL, trigger, negate);
--        if (!c)
--                return log_oom();
--
--        LIST_PREPEND(conditions, *list, c);
--        return 0;
--}
--
- int config_parse_unit_requires_mounts_for(
-                 const char *unit,
-                 const char *filename,
-@@ -5266,7 +5212,6 @@ void unit_dump_config_items(FILE *f) {
-                 { config_parse_ip_tos,                "TOS" },
-                 { config_parse_unit_condition_path,   "CONDITION" },
-                 { config_parse_unit_condition_string, "CONDITION" },
--                { config_parse_unit_condition_null,   "CONDITION" },
-                 { config_parse_unit_slice,            "SLICE" },
-                 { config_parse_documentation,         "URL" },
-                 { config_parse_service_timeout,       "SECONDS" },
-diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
-index 2672db5ace2..cee5717d0fb 100644
---- a/src/core/load-fragment.h
-+++ b/src/core/load-fragment.h
-@@ -58,7 +58,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_unit_env_file);
- CONFIG_PARSER_PROTOTYPE(config_parse_ip_tos);
- CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_path);
- CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_string);
--CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_null);
- CONFIG_PARSER_PROTOTYPE(config_parse_kill_mode);
- CONFIG_PARSER_PROTOTYPE(config_parse_notify_access);
- CONFIG_PARSER_PROTOTYPE(config_parse_emergency_action);
-diff --git a/src/shared/condition.c b/src/shared/condition.c
-index bf3b5fa1622..1f6105622a5 100644
---- a/src/shared/condition.c
-+++ b/src/shared/condition.c
-@@ -52,7 +52,7 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger
- 
-         assert(type >= 0);
-         assert(type < _CONDITION_TYPE_MAX);
--        assert((!parameter) == (type == CONDITION_NULL));
-+        assert(parameter);
- 
-         c = new(Condition, 1);
-         if (!c)
-@@ -776,15 +776,6 @@ static int condition_test_file_is_executable(Condition *c, char **env) {
-                 (st.st_mode & 0111));
- }
- 
--static int condition_test_null(Condition *c, char **env) {
--        assert(c);
--        assert(c->type == CONDITION_NULL);
--
--        /* Note that during parsing we already evaluate the string and
--         * store it in c->negate */
--        return true;
--}
--
- int condition_test(Condition *c, char **env) {
- 
-         static int (*const condition_tests[_CONDITION_TYPE_MAX])(Condition *c, char **env) = {
-@@ -811,7 +802,6 @@ int condition_test(Condition *c, char **env) {
-                 [CONDITION_USER]                     = condition_test_user,
-                 [CONDITION_GROUP]                    = condition_test_group,
-                 [CONDITION_CONTROL_GROUP_CONTROLLER] = condition_test_control_group_controller,
--                [CONDITION_NULL]                     = condition_test_null,
-                 [CONDITION_CPUS]                     = condition_test_cpus,
-                 [CONDITION_MEMORY]                   = condition_test_memory,
-                 [CONDITION_ENVIRONMENT]              = condition_test_environment,
-@@ -859,23 +849,20 @@ bool condition_test_list(
-                 r = condition_test(c, env);
- 
-                 if (logger) {
--                        const char *p = c->type == CONDITION_NULL ? "true" : c->parameter;
--                        assert(p);
--
-                         if (r < 0)
-                                 logger(userdata, LOG_WARNING, r, PROJECT_FILE, __LINE__, __func__,
-                                        "Couldn't determine result for %s=%s%s%s, assuming failed: %m",
-                                        to_string(c->type),
-                                        c->trigger ? "|" : "",
-                                        c->negate ? "!" : "",
--                                       p);
-+                                       c->parameter);
-                         else
-                                 logger(userdata, LOG_DEBUG, 0, PROJECT_FILE, __LINE__, __func__,
-                                        "%s=%s%s%s %s.",
-                                        to_string(c->type),
-                                        c->trigger ? "|" : "",
-                                        c->negate ? "!" : "",
--                                       p,
-+                                       c->parameter,
-                                        condition_result_to_string(c->result));
-                 }
- 
-@@ -937,7 +924,6 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
-         [CONDITION_USER] = "ConditionUser",
-         [CONDITION_GROUP] = "ConditionGroup",
-         [CONDITION_CONTROL_GROUP_CONTROLLER] = "ConditionControlGroupController",
--        [CONDITION_NULL] = "ConditionNull",
-         [CONDITION_CPUS] = "ConditionCPUs",
-         [CONDITION_MEMORY] = "ConditionMemory",
-         [CONDITION_ENVIRONMENT] = "ConditionEnvironment",
-@@ -969,7 +955,6 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
-         [CONDITION_USER] = "AssertUser",
-         [CONDITION_GROUP] = "AssertGroup",
-         [CONDITION_CONTROL_GROUP_CONTROLLER] = "AssertControlGroupController",
--        [CONDITION_NULL] = "AssertNull",
-         [CONDITION_CPUS] = "AssertCPUs",
-         [CONDITION_MEMORY] = "AssertMemory",
-         [CONDITION_ENVIRONMENT] = "AssertEnvironment",
-diff --git a/src/shared/condition.h b/src/shared/condition.h
-index fea74d228d8..e5ad43f945b 100644
---- a/src/shared/condition.h
-+++ b/src/shared/condition.h
-@@ -34,8 +34,6 @@ typedef enum ConditionType {
-         CONDITION_FILE_NOT_EMPTY,
-         CONDITION_FILE_IS_EXECUTABLE,
- 
--        CONDITION_NULL,
--
-         CONDITION_USER,
-         CONDITION_GROUP,
- 
-diff --git a/src/test/test-condition.c b/src/test/test-condition.c
-index ddf2e669c03..d209c1304c8 100644
---- a/src/test/test-condition.c
-+++ b/src/test/test-condition.c
-@@ -438,20 +438,6 @@ static void test_condition_test_kernel_version(void) {
-         condition_free(condition);
- }
- 
--static void test_condition_test_null(void) {
--        Condition *condition;
--
--        condition = condition_new(CONDITION_NULL, NULL, false, false);
--        assert_se(condition);
--        assert_se(condition_test(condition, environ) > 0);
--        condition_free(condition);
--
--        condition = condition_new(CONDITION_NULL, NULL, false, true);
--        assert_se(condition);
--        assert_se(condition_test(condition, environ) == 0);
--        condition_free(condition);
--}
--
- static void test_condition_test_security(void) {
-         Condition *condition;
- 
-@@ -868,7 +854,6 @@ int main(int argc, char *argv[]) {
-         test_condition_test_architecture();
-         test_condition_test_kernel_command_line();
-         test_condition_test_kernel_version();
--        test_condition_test_null();
-         test_condition_test_security();
-         print_securities();
-         test_condition_test_virtualization();
-diff --git a/test/fuzz/fuzz-unit-file/systemd-machined.service b/test/fuzz/fuzz-unit-file/systemd-machined.service
-index 70b627c5f40..79ee9861d8e 100644
---- a/test/fuzz/fuzz-unit-file/systemd-machined.service
-+++ b/test/fuzz/fuzz-unit-file/systemd-machined.service
-@@ -15,9 +15,6 @@ Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
- Wants=machine.slice
- After=machine.slice
- RequiresMountsFor=/var/lib/machines
--ConditionNull=true
--ConditionNull=
--ConditionNull=|!false
- OnFailureIsolate=false
- FailureActionExitStatus=222
- FailureActionExitStatus=
diff --git a/SOURCES/16838_16857_improve_path_search.patch b/SOURCES/16838_16857_improve_path_search.patch
deleted file mode 100644
index 2120465..0000000
--- a/SOURCES/16838_16857_improve_path_search.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 3335de91437bc983c95cfab86489ceb3a0b0a6aa Mon Sep 17 00:00:00 2001
-From: Chris Down <chris@chrisdown.name>
-Date: Tue, 25 Aug 2020 21:59:11 +0100
-Subject: [PATCH 1/2] path: Skip directories when finalising $PATH search
-
-Imagine $PATH /a:/b. There is an echo command at /b/echo. Under this
-configuration, this works fine:
-
-    % systemd-run --user --scope echo .
-    Running scope as unit: run-rfe98e0574b424d63a641644af511ff30.scope
-    .
-
-However, if I do `mkdir /a/echo`, this happens:
-
-    % systemd-run --user --scope echo .
-    Running scope as unit: run-rcbe9369537ed47f282ee12ce9f692046.scope
-    Failed to execute: Permission denied
-
-We check whether the resulting file is executable for the performing
-user, but of course, most directories are anyway, since that's needed to
-list within it. As such, another is_dir() check is needed prior to
-considering the search result final.
-
-Another approach might be to check S_ISREG, but there may be more gnarly
-edge cases there than just eliminating this obviously pathological
-example, so let's just do this for now.
----
- src/basic/path-util.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/basic/path-util.c b/src/basic/path-util.c
-index c4e022b3a1..d3b4978239 100644
---- a/src/basic/path-util.c
-+++ b/src/basic/path-util.c
-@@ -637,6 +637,9 @@ int find_binary(const char *name, char **ret) {
-                 if (!j)
-                         return -ENOMEM;
- 
-+                if (is_dir(j, true))
-+                        continue;
-+
-                 if (access(j, X_OK) >= 0) {
-                         /* Found it! */
- 
--- 
-2.26.2
-
-
-From 2f94890f37c13dcd680a63876ed6d34f8e66d0a3 Mon Sep 17 00:00:00 2001
-From: Chris Down <chris@chrisdown.name>
-Date: Wed, 26 Aug 2020 18:49:27 +0100
-Subject: [PATCH 2/2] path: Improve $PATH search directory case
-
-Previously:
-
-1. last_error wouldn't be updated with errors from is_dir;
-2. We'd always issue a stat(), even for binaries without execute;
-3. We used stat() instead of access(), which is cheaper.
-
-This change avoids all of those, by only checking inside X_OK-positive
-case whether access() works on the path with an extra slash appended.
-Thanks to Lennart for the suggestion.
----
- src/basic/path-util.c | 25 ++++++++++++++++++-------
- 1 file changed, 18 insertions(+), 7 deletions(-)
-
-diff --git a/src/basic/path-util.c b/src/basic/path-util.c
-index d3b4978239..7b0863f749 100644
---- a/src/basic/path-util.c
-+++ b/src/basic/path-util.c
-@@ -637,16 +637,27 @@ int find_binary(const char *name, char **ret) {
-                 if (!j)
-                         return -ENOMEM;
- 
--                if (is_dir(j, true))
--                        continue;
--
-                 if (access(j, X_OK) >= 0) {
--                        /* Found it! */
-+                        _cleanup_free_ char *with_dash;
- 
--                        if (ret)
--                                *ret = path_simplify(TAKE_PTR(j), false);
-+                        with_dash = strjoin(j, "/");
-+                        if (!with_dash)
-+                                return -ENOMEM;
- 
--                        return 0;
-+                        /* If this passes, it must be a directory, and so should be skipped. */
-+                        if (access(with_dash, X_OK) >= 0)
-+                                continue;
-+
-+                        /**
-+                         * We can't just `continue` inverting this case, since we need to update last_error.
-+                         */
-+                        if (errno == ENOTDIR) {
-+                                /* Found it! */
-+                                if (ret)
-+                                        *ret = path_simplify(TAKE_PTR(j), false);
-+
-+                                return 0;
-+                        }
-                 }
- 
-                 /* PATH entries which we don't have access to are ignored, as per tradition. */
--- 
-2.26.2
-
diff --git a/SOURCES/16940_cleanup_socket_econn_handling.patch b/SOURCES/16940_cleanup_socket_econn_handling.patch
deleted file mode 100644
index 3de1ab0..0000000
--- a/SOURCES/16940_cleanup_socket_econn_handling.patch
+++ /dev/null
@@ -1,317 +0,0 @@
-From 056799e2e147d678e156c5a1fce15b04762f1313 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Tue, 1 Sep 2020 23:50:01 +0200
-Subject: [PATCH 1/3] core/socket: we may get ENOTCONN from
- socket_instantiate_service()
-
-This means that the connection was aborted before we even got to figure out
-what the service name will be. Let's treat this as a non-event and close the
-connection fd without any further messages.
-
-Code last changed in 934ef6a5.
-Reported-by: Thiago Macieira <thiago.macieira@intel.com>
-
-With the patch:
-systemd[1]: foobar.socket: Incoming traffic
-systemd[1]: foobar.socket: Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring.
-...
-
-Also, when we get ENOMEM, don't give the hint about missing unit.
----
- src/core/socket.c | 35 ++++++++++++++++++++++++-----------
- 1 file changed, 24 insertions(+), 11 deletions(-)
-
-diff --git a/src/core/socket.c b/src/core/socket.c
-index ebf5ce3b16..f880040331 100644
---- a/src/core/socket.c
-+++ b/src/core/socket.c
-@@ -18,6 +18,7 @@
- #include "dbus-socket.h"
- #include "dbus-unit.h"
- #include "def.h"
-+#include "errno-list.h"
- #include "exit-status.h"
- #include "fd-util.h"
- #include "format-util.h"
-@@ -1418,11 +1419,12 @@ int socket_load_service_unit(Socket *s, int cfd, Unit **ret) {
- 
-         if (cfd >= 0) {
-                 r = instance_from_socket(cfd, s->n_accepted, &instance);
--                if (r == -ENOTCONN)
--                        /* ENOTCONN is legitimate if TCP RST was received.
--                         * This connection is over, but the socket unit lives on. */
-+                if (ERRNO_IS_DISCONNECT(r))
-+                        /* ENOTCONN is legitimate if TCP RST was received. Other socket families might return
-+                         * different errors. This connection is over, but the socket unit lives on. */
-                         return log_unit_debug_errno(UNIT(s), r,
--                                                    "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring.");
-+                                                    "Got %s on incoming socket, assuming aborted connection attempt, ignoring.",
-+                                                    errno_to_name(r));
-                 if (r < 0)
-                         return r;
-         }
-@@ -2359,8 +2361,8 @@ static void socket_enter_running(Socket *s, int cfd) {
- 
-                 if (!pending) {
-                         if (!UNIT_ISSET(s->service)) {
--                                log_unit_error(UNIT(s), "Service to activate vanished, refusing activation.");
--                                r = -ENOENT;
-+                                r = log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOENT),
-+                                                         "Service to activate vanished, refusing activation.");
-                                 goto fail;
-                         }
- 
-@@ -2382,8 +2384,10 @@ static void socket_enter_running(Socket *s, int cfd) {
- 
-                 if (s->max_connections_per_source > 0) {
-                         r = socket_acquire_peer(s, cfd, &p);
--                        if (r < 0)
--                                goto refuse;
-+                        if (ERRNO_IS_DISCONNECT(r))
-+                                goto notconn;
-+                        if (r < 0) /* We didn't have enough resources to acquire peer information, let's fail. */
-+                                goto fail;
-                         if (r > 0 && p->n_ref > s->max_connections_per_source) {
-                                 _cleanup_free_ char *t = NULL;
- 
-@@ -2397,6 +2401,8 @@ static void socket_enter_running(Socket *s, int cfd) {
-                 }
- 
-                 r = socket_instantiate_service(s, cfd);
-+                if (ERRNO_IS_DISCONNECT(r))
-+                        goto notconn;
-                 if (r < 0)
-                         goto fail;
- 
-@@ -2406,6 +2412,8 @@ static void socket_enter_running(Socket *s, int cfd) {
-                 s->n_accepted++;
- 
-                 r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
-+                if (ERRNO_IS_DISCONNECT(r))
-+                        goto notconn;
-                 if (r < 0)
-                         goto fail;
- 
-@@ -2430,13 +2438,18 @@ static void socket_enter_running(Socket *s, int cfd) {
- 
- refuse:
-         s->n_refused++;
-+notconn:
-         safe_close(cfd);
-         return;
- 
- fail:
--        log_unit_warning(UNIT(s), "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
--                         cfd >= 0 ? "template" : "non-template",
--                         bus_error_message(&error, r));
-+        if (ERRNO_IS_RESOURCE(r))
-+                log_unit_warning(UNIT(s), "Failed to queue service startup job: %s",
-+                                 bus_error_message(&error, r));
-+        else
-+                log_unit_warning(UNIT(s), "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
-+                                 cfd >= 0 ? "template" : "non-template",
-+                                 bus_error_message(&error, r));
- 
-         socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
-         safe_close(cfd);
--- 
-2.26.2
-
-
-From 86f9af3eb8bea0bea86bb027cb341e6b13beecb5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Wed, 2 Sep 2020 18:04:10 +0200
-Subject: [PATCH 2/3] core/socket: fold socket_instantiate_service() into
- socket_enter_running()
-
-socket_instantiate_service() was doing unit_ref_set(), and the caller was
-immediately doing unit_ref_unset(). After we get rid of this, it doesn't seem
-worth it to have two functions.
----
- src/core/socket.c | 39 ++++++++++-----------------------------
- 1 file changed, 10 insertions(+), 29 deletions(-)
-
-diff --git a/src/core/socket.c b/src/core/socket.c
-index f880040331..5e128d9fef 100644
---- a/src/core/socket.c
-+++ b/src/core/socket.c
-@@ -206,27 +206,6 @@ static int socket_arm_timer(Socket *s, usec_t usec) {
-         return 0;
- }
- 
--static int socket_instantiate_service(Socket *s, int cfd) {
--        Unit *service;
--        int r;
--
--        assert(s);
--        assert(cfd >= 0);
--
--        /* This fills in s->service if it isn't filled in yet. For Accept=yes sockets we create the next
--         * connection service here. For Accept=no this is mostly a NOP since the service is figured out at
--         * load time anyway. */
--
--        r = socket_load_service_unit(s, cfd, &service);
--        if (r < 0)
--                return r;
--
--        unit_ref_set(&s->service, UNIT(s), service);
--
--        return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, service,
--                                         false, UNIT_DEPENDENCY_IMPLICIT);
--}
--
- static bool have_non_accept_socket(Socket *s) {
-         SocketPort *p;
- 
-@@ -2374,7 +2353,7 @@ static void socket_enter_running(Socket *s, int cfd) {
-                 socket_set_state(s, SOCKET_RUNNING);
-         } else {
-                 _cleanup_(socket_peer_unrefp) SocketPeer *p = NULL;
--                Service *service;
-+                Unit *service;
- 
-                 if (s->n_connections >= s->max_connections) {
-                         log_unit_warning(UNIT(s), "Too many incoming connections (%u), dropping connection.",
-@@ -2400,18 +2379,20 @@ static void socket_enter_running(Socket *s, int cfd) {
-                         }
-                 }
- 
--                r = socket_instantiate_service(s, cfd);
-+                r = socket_load_service_unit(s, cfd, &service);
-                 if (ERRNO_IS_DISCONNECT(r))
-                         goto notconn;
-                 if (r < 0)
-                         goto fail;
- 
--                service = SERVICE(UNIT_DEREF(s->service));
--                unit_ref_unset(&s->service);
-+                r = unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, service,
-+                                              false, UNIT_DEPENDENCY_IMPLICIT);
-+                if (r < 0)
-+                        goto fail;
- 
-                 s->n_accepted++;
- 
--                r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
-+                r = service_set_socket_fd(SERVICE(service), cfd, s, s->selinux_context_from_net);
-                 if (ERRNO_IS_DISCONNECT(r))
-                         goto notconn;
-                 if (r < 0)
-@@ -2420,13 +2401,13 @@ static void socket_enter_running(Socket *s, int cfd) {
-                 TAKE_FD(cfd); /* We passed ownership of the fd to the service now. Forget it here. */
-                 s->n_connections++;
- 
--                service->peer = TAKE_PTR(p); /* Pass ownership of the peer reference */
-+                SERVICE(service)->peer = TAKE_PTR(p); /* Pass ownership of the peer reference */
- 
--                r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, NULL, &error, NULL);
-+                r = manager_add_job(UNIT(s)->manager, JOB_START, service, JOB_REPLACE, NULL, &error, NULL);
-                 if (r < 0) {
-                         /* We failed to activate the new service, but it still exists. Let's make sure the
-                          * service closes and forgets the connection fd again, immediately. */
--                        service_close_socket_fd(service);
-+                        service_close_socket_fd(SERVICE(service));
-                         goto fail;
-                 }
- 
--- 
-2.26.2
-
-
-From b7e9403a4c6220478980555ef40905d030b307f5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Wed, 2 Sep 2020 18:17:14 +0200
-Subject: [PATCH 3/3] core/socket: use _cleanup_ to close the connection fd
-
-Removing the gotos would lead to a lot of duplicated code, so I left them
-as they were.
----
- src/core/socket.c | 22 ++++++++++------------
- 1 file changed, 10 insertions(+), 12 deletions(-)
-
-diff --git a/src/core/socket.c b/src/core/socket.c
-index 5e128d9fef..a77a297cf5 100644
---- a/src/core/socket.c
-+++ b/src/core/socket.c
-@@ -2296,13 +2296,14 @@ static void flush_ports(Socket *s) {
-         }
- }
- 
--static void socket_enter_running(Socket *s, int cfd) {
-+static void socket_enter_running(Socket *s, int cfd_in) {
-+        /* Note that this call takes possession of the connection fd passed. It either has to assign it
-+         * somewhere or close it. */
-+        _cleanup_close_ int cfd = cfd_in;
-+
-         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-         int r;
- 
--        /* Note that this call takes possession of the connection fd passed. It either has to assign it somewhere or
--         * close it. */
--
-         assert(s);
- 
-         /* We don't take connections anymore if we are supposed to shut down anyway */
-@@ -2312,9 +2313,8 @@ static void socket_enter_running(Socket *s, int cfd) {
- 
-                 if (cfd >= 0)
-                         goto refuse;
--                else
--                        flush_ports(s);
- 
-+                flush_ports(s);
-                 return;
-         }
- 
-@@ -2364,7 +2364,7 @@ static void socket_enter_running(Socket *s, int cfd) {
-                 if (s->max_connections_per_source > 0) {
-                         r = socket_acquire_peer(s, cfd, &p);
-                         if (ERRNO_IS_DISCONNECT(r))
--                                goto notconn;
-+                                return;
-                         if (r < 0) /* We didn't have enough resources to acquire peer information, let's fail. */
-                                 goto fail;
-                         if (r > 0 && p->n_ref > s->max_connections_per_source) {
-@@ -2381,7 +2381,7 @@ static void socket_enter_running(Socket *s, int cfd) {
- 
-                 r = socket_load_service_unit(s, cfd, &service);
-                 if (ERRNO_IS_DISCONNECT(r))
--                        goto notconn;
-+                        return;
-                 if (r < 0)
-                         goto fail;
- 
-@@ -2394,7 +2394,7 @@ static void socket_enter_running(Socket *s, int cfd) {
- 
-                 r = service_set_socket_fd(SERVICE(service), cfd, s, s->selinux_context_from_net);
-                 if (ERRNO_IS_DISCONNECT(r))
--                        goto notconn;
-+                        return;
-                 if (r < 0)
-                         goto fail;
- 
-@@ -2415,12 +2415,11 @@ static void socket_enter_running(Socket *s, int cfd) {
-                 unit_add_to_dbus_queue(UNIT(s));
-         }
- 
-+        TAKE_FD(cfd);
-         return;
- 
- refuse:
-         s->n_refused++;
--notconn:
--        safe_close(cfd);
-         return;
- 
- fail:
-@@ -2433,7 +2432,6 @@ fail:
-                                  bus_error_message(&error, r));
- 
-         socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
--        safe_close(cfd);
- }
- 
- static void socket_run_next(Socket *s) {
--- 
-2.26.2
-
diff --git a/SOURCES/17031_propagate_start_limit_hit.patch b/SOURCES/17031_propagate_start_limit_hit.patch
deleted file mode 100644
index 4490100..0000000
--- a/SOURCES/17031_propagate_start_limit_hit.patch
+++ /dev/null
@@ -1,233 +0,0 @@
-From 7a481a17ad01c7be526829a835f7da3d6b71577f Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Fri, 11 Sep 2020 19:49:33 +0200
-Subject: [PATCH 1/3] core: propagate triggered unit in more load states
-
-In 4c2ef3276735ad9f7fccf33f5bdcbe7d8751e7ec we enabled propagating
-triggered unit state to the triggering unit for service units in more
-load states, so that we don't accidentally stop tracking state
-correctly.
-
-Do the same for our other triggering unit states: automounts, paths, and
-timers.
-
-Also, make this an assertion rather than a simple test. After all it
-should never happen that we get called for half-loaded units or units of
-the wrong type. The load routines should already have made this
-impossible.
----
- src/core/automount.c   | 4 ++--
- src/core/path.c        | 7 +++----
- src/core/socket.c      | 9 ++-------
- src/core/timer.c       | 4 ++--
- src/core/transaction.c | 2 +-
- src/core/unit.h        | 4 ++++
- 6 files changed, 14 insertions(+), 16 deletions(-)
-
-diff --git a/src/core/automount.c b/src/core/automount.c
-index 1f05198766..73f0fb8c71 100644
---- a/src/core/automount.c
-+++ b/src/core/automount.c
-@@ -507,8 +507,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) {
-         assert(other);
- 
-         /* Filter out invocations with bogus state */
--        if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT)
--                return;
-+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
-+        assert(other->type == UNIT_MOUNT);
- 
-         /* Don't propagate state changes from the mount if we are already down */
-         if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))
-diff --git a/src/core/path.c b/src/core/path.c
-index 1c3c28e341..8ffec72ede 100644
---- a/src/core/path.c
-+++ b/src/core/path.c
-@@ -748,11 +748,10 @@ static void path_trigger_notify(Unit *u, Unit *other) {
-         assert(u);
-         assert(other);
- 
--        /* Invoked whenever the unit we trigger changes state or gains
--         * or loses a job */
-+        /* Invoked whenever the unit we trigger changes state or gains or loses a job */
- 
--        if (other->load_state != UNIT_LOADED)
--                return;
-+        /* Filter out invocations with bogus state */
-+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
- 
-         if (p->state == PATH_RUNNING &&
-             UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
-diff --git a/src/core/socket.c b/src/core/socket.c
-index 127195c9fe..ebf5ce3b16 100644
---- a/src/core/socket.c
-+++ b/src/core/socket.c
-@@ -3274,13 +3274,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
-         assert(other);
- 
-         /* Filter out invocations with bogus state */
--        if (!IN_SET(other->load_state,
--                    UNIT_LOADED,
--                    UNIT_NOT_FOUND,
--                    UNIT_BAD_SETTING,
--                    UNIT_ERROR,
--                    UNIT_MASKED) || other->type != UNIT_SERVICE)
--                return;
-+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
-+        assert(other->type == UNIT_SERVICE);
- 
-         /* Don't propagate state changes from the service if we are already down */
-         if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING))
-diff --git a/src/core/timer.c b/src/core/timer.c
-index 03a9c14f76..94388f0727 100644
---- a/src/core/timer.c
-+++ b/src/core/timer.c
-@@ -746,8 +746,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
-         assert(u);
-         assert(other);
- 
--        if (other->load_state != UNIT_LOADED)
--                return;
-+        /* Filter out invocations with bogus state */
-+        assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
- 
-         /* Reenable all timers that depend on unit state */
-         LIST_FOREACH(value, v, t->values)
-diff --git a/src/core/transaction.c b/src/core/transaction.c
-index 0fa419787e..befac19788 100644
---- a/src/core/transaction.c
-+++ b/src/core/transaction.c
-@@ -949,7 +949,7 @@ int transaction_add_job_and_dependencies(
- 
-         /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set
-          * temporarily. */
--        if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED))
-+        if (!UNIT_IS_LOAD_COMPLETE(unit->load_state))
-                 return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id);
- 
-         if (type != JOB_STOP) {
-diff --git a/src/core/unit.h b/src/core/unit.h
-index 4130cd50a9..ae2ce74243 100644
---- a/src/core/unit.h
-+++ b/src/core/unit.h
-@@ -49,6 +49,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) {
-         return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED);
- }
- 
-+static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) {
-+        return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED;
-+}
-+
- /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We
-  * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be
-  * created as a result of multiple "reasons", hence the bitmask. */
--- 
-2.26.2
-
-
-From 6b083e21c2bfdba79d43d5d56f02dc795dae9368 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Fri, 11 Sep 2020 19:57:09 +0200
-Subject: [PATCH 2/3] core: propagate unit start limit hit state to triggering
- path unit
-
-We already do this for socket and automount units, do it for path units
-too: if the triggered service keeps hitting the start limit, then fail
-the triggering unit too, so that we don#t busy loop forever.
-
-(Note that this leaves only timer units out in the cold for this kind of
-protection, but it shouldn't matter there, as they are naturally
-protected against busy loops: they are scheduled by time anyway).
-
-Fixes: #16669
----
- src/core/path.c | 15 +++++++++++++++
- src/core/path.h |  1 +
- 2 files changed, 16 insertions(+)
-
-diff --git a/src/core/path.c b/src/core/path.c
-index 8ffec72ede..4f4e7100cf 100644
---- a/src/core/path.c
-+++ b/src/core/path.c
-@@ -753,6 +753,20 @@ static void path_trigger_notify(Unit *u, Unit *other) {
-         /* Filter out invocations with bogus state */
-         assert(UNIT_IS_LOAD_COMPLETE(other->load_state));
- 
-+        /* Don't propagate state changes from the triggered unit if we are already down */
-+        if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING))
-+                return;
-+
-+        /* Propagate start limit hit state */
-+        if (other->start_limit_hit) {
-+                path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT);
-+                return;
-+        }
-+
-+        /* Don't propagate anything if there's still a job queued */
-+        if (other->job)
-+                return;
-+
-         if (p->state == PATH_RUNNING &&
-             UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
-                 log_unit_debug(UNIT(p), "Got notified about unit deactivation.");
-@@ -789,6 +803,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = {
-         [PATH_SUCCESS] = "success",
-         [PATH_FAILURE_RESOURCES] = "resources",
-         [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
-+        [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
- };
- 
- DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult);
-diff --git a/src/core/path.h b/src/core/path.h
-index 9e2836535a..4043650fe0 100644
---- a/src/core/path.h
-+++ b/src/core/path.h
-@@ -45,6 +45,7 @@ typedef enum PathResult {
-         PATH_SUCCESS,
-         PATH_FAILURE_RESOURCES,
-         PATH_FAILURE_START_LIMIT_HIT,
-+        PATH_FAILURE_UNIT_START_LIMIT_HIT,
-         _PATH_RESULT_MAX,
-         _PATH_RESULT_INVALID = -1
- } PathResult;
--- 
-2.26.2
-
-
-From 32c556c612ff38b09fe7d14d1840aceb2d76360d Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Mon, 14 Sep 2020 12:59:38 +0200
-Subject: [PATCH 3/3] unit-def: drop pointless 0 initialization of first enum
- value
-
-This is implied in C and we generally don't bother with this, so don't
-bother with this here either.
----
- src/basic/unit-def.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h
-index 53419ecd8a..1fab6c78ab 100644
---- a/src/basic/unit-def.h
-+++ b/src/basic/unit-def.h
-@@ -9,7 +9,7 @@
-  * when other criteria (cpu weight, nice level) are identical.
-  * In this case service units have the highest priority. */
- typedef enum UnitType {
--        UNIT_SERVICE = 0,
-+        UNIT_SERVICE,
-         UNIT_MOUNT,
-         UNIT_SWAP,
-         UNIT_SOCKET,
-@@ -25,7 +25,7 @@ typedef enum UnitType {
- } UnitType;
- 
- typedef enum UnitLoadState {
--        UNIT_STUB = 0,
-+        UNIT_STUB,
-         UNIT_LOADED,
-         UNIT_NOT_FOUND,    /* error condition #1: unit file not found */
-         UNIT_BAD_SETTING,  /* error condition #2: we couldn't parse some essential unit file setting */
--- 
-2.26.2
-
diff --git a/SOURCES/17082_nspawn_tty_tweaks.patch b/SOURCES/17082_nspawn_tty_tweaks.patch
deleted file mode 100644
index adee19a..0000000
--- a/SOURCES/17082_nspawn_tty_tweaks.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From 0ead15331dc9414e7d4b3f0b96ed1908ceaf8f8b Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Wed, 16 Sep 2020 22:11:48 +0200
-Subject: [PATCH 1/5] nspawn: check return of setsid()
-
-Let's verify that everything works the way we expect it to work, hence
-check setsid() return code.
----
- src/nspawn/nspawn-stub-pid1.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c
-index d86dd23185..f785a3b248 100644
---- a/src/nspawn/nspawn-stub-pid1.c
-+++ b/src/nspawn/nspawn-stub-pid1.c
-@@ -66,7 +66,10 @@ int stub_pid1(sd_id128_t uuid) {
-         if (pid == 0) {
-                 /* Return in the child */
-                 assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0);
--                setsid();
-+
-+                if (setsid() < 0)
-+                        return log_error_errno(errno, "Failed to become session leader in payload process: %m");
-+
-                 return 0;
-         }
- 
--- 
-2.26.2
-
-
-From b4fa908fbdcbcf01c96e983460689800b8bb76af Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Wed, 16 Sep 2020 22:12:29 +0200
-Subject: [PATCH 2/5] nspawn: print log notice when we are invoked from a tty
- but in "pipe" mode
-
-If people do this then things are weird, and they should probably use
---console=interactive (i.e. the default) instead.
-
-Prompted-by: #17070
----
- src/nspawn/nspawn.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
-index 3b9493f232..efc541f512 100644
---- a/src/nspawn/nspawn.c
-+++ b/src/nspawn/nspawn.c
-@@ -272,9 +272,15 @@ static int handle_arg_console(const char *arg) {
-                 arg_console_mode = CONSOLE_READ_ONLY;
-         else if (streq(arg, "passive"))
-                 arg_console_mode = CONSOLE_PASSIVE;
--        else if (streq(arg, "pipe"))
-+        else if (streq(arg, "pipe")) {
-+                if (isatty(STDIN_FILENO) > 0 && isatty(STDOUT_FILENO) > 0)
-+                        log_full(arg_quiet ? LOG_DEBUG : LOG_NOTICE,
-+                                 "Console mode 'pipe' selected, but standard input/output are connected to an interactive TTY. "
-+                                 "Most likely you want to use 'interactive' console mode for proper interactivity and shell job control. "
-+                                 "Proceeding anyway.");
-+
-                 arg_console_mode = CONSOLE_PIPE;
--        else
-+        } else
-                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown console mode: %s", optarg);
- 
-         arg_settings_mask |= SETTING_CONSOLE_MODE;
--- 
-2.26.2
-
-
-From 19db1706dadcec4f4c44f9abf8dc33a336f93326 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Wed, 16 Sep 2020 22:16:10 +0200
-Subject: [PATCH 3/5] nspawn: fix fd leak on failure path
-
----
- src/nspawn/nspawn.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
-index efc541f512..15dbdbe738 100644
---- a/src/nspawn/nspawn.c
-+++ b/src/nspawn/nspawn.c
-@@ -2178,7 +2178,7 @@ static int setup_pts(const char *dest) {
- }
- 
- static int setup_stdio_as_dev_console(void) {
--        int terminal;
-+        _cleanup_close_ int terminal = -1;
-         int r;
- 
-         terminal = open_terminal("/dev/console", O_RDWR);
-@@ -2193,6 +2193,7 @@ static int setup_stdio_as_dev_console(void) {
- 
-         /* invalidates 'terminal' on success and failure */
-         r = rearrange_stdio(terminal, terminal, terminal);
-+        TAKE_FD(terminal);
-         if (r < 0)
-                 return log_error_errno(r, "Failed to move console to stdin/stdout/stderr: %m");
- 
--- 
-2.26.2
-
-
-From d297a871ef720227af845fe8b0f1e0fe7560b433 Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Wed, 16 Sep 2020 22:34:43 +0200
-Subject: [PATCH 4/5] nspawn: don't become TTY controller just to undo it later
- again
-
-Instead of first becoming a controlling process of the payload pty
-as side effect of opening it (without O_NOCTTY), and then possibly
-dropping it again, let's do it cleanly an reverse the logic: let's open
-the pty without becoming its controller first. Only after everything
-went the way we wanted it to go become the controller explicitly.
-
-This has the benefit that the PID 1 stub process we run (as effect of
---as-pid2) doesn't have to lose the tty explicitly, but can just
-continue running with things. And we explicitly make the tty controlling
-right before invoking actual payload.
-
-In order to make sure everything works as expected validate that the
-stub PID 1 in the container really has no conrolling tty by issuing the
-TIOCNOTTY tty and expecting ENOTTY, and log about it.
-
-This shouldn't change behaviour much, it just makes thins a bit cleaner,
-in particular as we'll not trigger SIGHUP on ourselves (since we are
-controller and session leader) due to TIOCNOTTY which we then have to
-explicitly ignore.
----
- src/nspawn/nspawn-stub-pid1.c | 12 ++++++------
- src/nspawn/nspawn.c           | 16 +++++++++++++---
- 2 files changed, 19 insertions(+), 9 deletions(-)
-
-diff --git a/src/nspawn/nspawn-stub-pid1.c b/src/nspawn/nspawn-stub-pid1.c
-index f785a3b248..60d7439fb1 100644
---- a/src/nspawn/nspawn-stub-pid1.c
-+++ b/src/nspawn/nspawn-stub-pid1.c
-@@ -53,12 +53,6 @@ int stub_pid1(sd_id128_t uuid) {
-         assert_se(sigfillset(&fullmask) >= 0);
-         assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0);
- 
--        /* Surrender the terminal this stub may control so that child processes can have a controlling terminal
--         * without resorting to setsid hacks. */
--        r = ioctl(STDIN_FILENO, TIOCNOTTY);
--        if (r < 0 && errno != ENOTTY)
--                return log_error_errno(errno, "Failed to surrender controlling terminal: %m");
--
-         pid = fork();
-         if (pid < 0)
-                 return log_error_errno(errno, "Failed to fork child pid: %m");
-@@ -79,6 +73,12 @@ int stub_pid1(sd_id128_t uuid) {
-         (void) close_all_fds(NULL, 0);
-         log_open();
- 
-+        if (ioctl(STDIN_FILENO, TIOCNOTTY) < 0) {
-+                if (errno != ENOTTY)
-+                        log_warning_errno(errno, "Unexpected error from TIOCNOTTY ioctl in init stub process, ignoring: %m");
-+        } else
-+                log_warning("Expected TIOCNOTTY to fail, but it succeeded in init stub process, ignoring.");
-+
-         /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
-          * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
-          * find them set. */
-diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
-index 15dbdbe738..783147f122 100644
---- a/src/nspawn/nspawn.c
-+++ b/src/nspawn/nspawn.c
-@@ -11,10 +11,12 @@
- #endif
- #include <stdlib.h>
- #include <sys/file.h>
-+#include <sys/ioctl.h>
- #include <sys/personality.h>
- #include <sys/prctl.h>
- #include <sys/types.h>
- #include <sys/wait.h>
-+#include <termios.h>
- #include <unistd.h>
- 
- #include "sd-bus.h"
-@@ -2181,7 +2183,9 @@ static int setup_stdio_as_dev_console(void) {
-         _cleanup_close_ int terminal = -1;
-         int r;
- 
--        terminal = open_terminal("/dev/console", O_RDWR);
-+        /* We open the TTY in O_NOCTTY mode, so that we do not become controller yet. We'll do that later
-+         * explicitly, if we are configured to. */
-+        terminal = open_terminal("/dev/console", O_RDWR|O_NOCTTY);
-         if (terminal < 0)
-                 return log_error_errno(terminal, "Failed to open console: %m");
- 
-@@ -3213,8 +3217,7 @@ static int inner_child(
-          * wait until the parent is ready with the
-          * setup, too... */
-         if (!barrier_place_and_sync(barrier)) /* #5 */
--                return log_error_errno(SYNTHETIC_ERRNO(ESRCH),
--                                       "Parent died too early");
-+                return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Parent died too early");
- 
-         if (arg_chdir)
-                 if (chdir(arg_chdir) < 0)
-@@ -3226,6 +3229,13 @@ static int inner_child(
-                         return r;
-         }
- 
-+        if (arg_console_mode != CONSOLE_PIPE) {
-+                /* So far our pty wasn't controlled by any process. Finally, it's time to change that, if we
-+                 * are configured for that. Acquire it as controlling tty. */
-+                if (ioctl(STDIN_FILENO, TIOCSCTTY) < 0)
-+                        return log_error_errno(errno, "Failed to acquire controlling TTY: %m");
-+        }
-+
-         log_debug("Inner child completed, invoking payload.");
- 
-         /* Now, explicitly close the log, so that we then can close all remaining fds. Closing the log explicitly first
--- 
-2.26.2
-
-
-From 196b94c2db3f0b763480e98df98f288bcd044a6e Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 17 Sep 2020 16:26:14 +0200
-Subject: [PATCH 5/5] nspawn: add --console=autopipe mode
-
-By default we'll run a container in --console=interactive and
---console=read-only mode depending if we are invoked on a tty or not so
-that the container always gets a /dev/console allocated, i.e is always
-suitable to run a full init system /as those typically expect a
-/dev/console to exist).
-
-With the new --console=autopipe mode we do something similar, but
-slightly different: when not invoked on a tty we'll use --console=pipe.
-This means, if you invoke some tool in a container with this you'll get
-full inetractivity if you invoke it on a tty but things will also be
-very nicely pipeable. OTOH you cannot invoke a full init system like
-this, because you might or might not become a /dev/console this way...
-
-Prompted-by: #17070
-
-(I named this "autopipe" rather than "auto" or so, since the default
-mode probably should be named "auto" one day if we add a name for it,
-and this is so similar to "auto" except that it uses pipes in the
-non-tty case).
----
- man/systemd-nspawn.xml | 21 ++++++++++++---------
- src/nspawn/nspawn.c    | 12 +++++++++---
- 2 files changed, 21 insertions(+), 12 deletions(-)
-
-diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
-index 69558ac85c..b2c2a5006c 100644
---- a/man/systemd-nspawn.xml
-+++ b/man/systemd-nspawn.xml
-@@ -1370,15 +1370,18 @@
- 
-         <listitem><para>Configures how to set up standard input, output and error output for the container
-         payload, as well as the <filename>/dev/console</filename> device for the container. Takes one of
--        <option>interactive</option>, <option>read-only</option>, <option>passive</option>, or
--        <option>pipe</option>. If <option>interactive</option>, a pseudo-TTY is allocated and made available
--        as <filename>/dev/console</filename> in the container. It is then bi-directionally connected to the
--        standard input and output passed to <command>systemd-nspawn</command>. <option>read-only</option> is
--        similar but only the output of the container is propagated and no input from the caller is read. If
--        <option>passive</option>, a pseudo TTY is allocated, but it is not connected anywhere. Finally, in
--        <option>pipe</option> mode no pseudo TTY is allocated, but the standard input, output and error
--        output file descriptors passed to <command>systemd-nspawn</command> are passed on — as they are — to
--        the container payload, see the following paragraph. Defaults to <option>interactive</option> if
-+        <option>interactive</option>, <option>read-only</option>, <option>passive</option>,
-+        <option>pipe</option> or <option>autopipe</option>. If <option>interactive</option>, a pseudo-TTY is
-+        allocated and made available as <filename>/dev/console</filename> in the container. It is then
-+        bi-directionally connected to the standard input and output passed to
-+        <command>systemd-nspawn</command>. <option>read-only</option> is similar but only the output of the
-+        container is propagated and no input from the caller is read. If <option>passive</option>, a pseudo
-+        TTY is allocated, but it is not connected anywhere. In <option>pipe</option> mode no pseudo TTY is
-+        allocated, but the standard input, output and error output file descriptors passed to
-+        <command>systemd-nspawn</command> are passed on — as they are — to the container payload, see the
-+        following paragraph. Finally, <option>autopipe</option> mode operates like
-+        <option>interactive</option> when <command>systemd-nspawn</command> is invoked on a terminal, and
-+        like <option>pipe</option> otherwise. Defaults to <option>interactive</option> if
-         <command>systemd-nspawn</command> is invoked from a terminal, and <option>read-only</option>
-         otherwise.</para>
- 
-diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
-index 783147f122..8837371232 100644
---- a/src/nspawn/nspawn.c
-+++ b/src/nspawn/nspawn.c
-@@ -261,10 +261,11 @@ STATIC_DESTRUCTOR_REGISTER(arg_sysctl, strv_freep);
- 
- static int handle_arg_console(const char *arg) {
-         if (streq(arg, "help")) {
--                puts("interactive\n"
--                     "read-only\n"
-+                puts("autopipe\n"
-+                     "interactive\n"
-                      "passive\n"
--                     "pipe");
-+                     "pipe\n"
-+                     "read-only");
-                 return 0;
-         }
- 
-@@ -282,6 +283,11 @@ static int handle_arg_console(const char *arg) {
-                                  "Proceeding anyway.");
- 
-                 arg_console_mode = CONSOLE_PIPE;
-+        } else if (streq(arg, "autopipe")) {
-+                if (isatty(STDIN_FILENO) > 0 && isatty(STDOUT_FILENO) > 0)
-+                        arg_console_mode = CONSOLE_INTERACTIVE;
-+                else
-+                        arg_console_mode = CONSOLE_PIPE;
-         } else
-                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown console mode: %s", optarg);
- 
--- 
-2.26.2
-
diff --git a/SOURCES/17495.patch b/SOURCES/17495.patch
new file mode 100644
index 0000000..fc6302c
--- /dev/null
+++ b/SOURCES/17495.patch
@@ -0,0 +1,425 @@
+From 5adb2f01405d7cb7ba3cf9d4ee035f57952f79a6 Mon Sep 17 00:00:00 2001
+From: Chris Down <chris@chrisdown.name>
+Date: Thu, 29 Oct 2020 12:03:52 +0000
+Subject: [PATCH 3/3] bpf: pid1: Pin reference to BPF programs for
+ post-coldplug
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+During `daemon-reload` and `daemon-reexec`, we detach and reattach all
+BPF programs attached to cgroups. This, however, poses a real practical
+problem for DevicePolicy (and some other settings using BPF): it
+presents a period of time where the old device filtering BPF program has
+been unloaded, but the new one has not been loaded yet.
+
+Since the filtering is at open() time, it has become apparent that that
+there's a non-trivial period where applications inside that ostensibly
+filtered cgroup can grab any device -- and often do so -- and then
+retain access to that device even after the reload is over. Due to the
+file continuing to be available after the initial open(), this issue is
+particularly visible for DevicePolicy={strict,closed}, however it also
+applies to other BPF programs we install.
+
+In particular, for BPF ingress/egress filtering this may have more
+concerning implications: network traffic which is supposed to be
+filtered will -- for a very brief period of time -- not be filtered or
+subject to any restrictions imposed by BPF.
+
+These BPF programs are fundamentally attached to a cgroup lifetime, not
+our unit lifetime, so it's enough to pin these programs by taking a
+reference to affected BPF programs before reload/reexec. We can then
+serialise the program's kernel-facing FD and cgroup attachment FD for
+the new daemon, and have the daemon on the other side unpin the programs
+after it's finished with coldplug.
+
+That means that, for example, the BPF program lifecycle during
+daemon-reload or daemon-reexec changes from this:
+
+    manager_clear_jobs_and_units
+                 │
+          ╔══════╪═════════╤═══════╗
+          ║ prog │ no prog │ prog' ║
+          ╚══════╧═════════╪═══════╝
+                           │
+                    manager_coldplug
+
+to this:
+
+    manager_clear_jobs_and_units         manager_dispatch_cgroup_realize_queue
+                 │                                       │
+          ╔══════╪═══════════════╤═══════════════════════╪═══════╗
+          ║ prog │ prog (orphan) │ prog (orphan) + prog' │ prog' ║
+          ╚══════╧═══════════════╪═══════════════════════╧═══════╝
+                                 │
+                          manager_coldplug
+
+For daemon-reexec the semantics are mostly the same, but the point at
+which the program becomes orphan is tied to the process lifecycle
+instead.
+
+None of the BPF programs we install require exclusive access, so having
+multiple instances of them running at the same time is fine. Custom
+programs, of course, are unknown, but it's hard to imagine legitimate
+cases which should be affected, whereas the benefits of this "overlap"
+approach with reference pinning is immediately tangible.
+
+[keszybz: use _cleanup_ for unpin, use FOREACH_POINTER]
+---
+ src/core/bpf-firewall.c  |   9 +--
+ src/core/main.c          |   9 +++
+ src/core/manager.c       | 161 ++++++++++++++++++++++++++++++++++++++-
+ src/core/manager.h       |   6 ++
+ src/shared/bpf-program.c |  10 +++
+ src/shared/bpf-program.h |   1 +
+ 6 files changed, 189 insertions(+), 7 deletions(-)
+
+diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c
+index 99783aca22..c205ba1b19 100644
+--- a/src/core/bpf-firewall.c
++++ b/src/core/bpf-firewall.c
+@@ -702,8 +702,7 @@ int bpf_firewall_install(Unit *u) {
+         if (r < 0)
+                 return log_unit_error_errno(u, r, "Failed to determine cgroup path: %m");
+
+-        flags = (supported == BPF_FIREWALL_SUPPORTED_WITH_MULTI &&
+-                 (u->type == UNIT_SLICE || unit_cgroup_delegate(u))) ? BPF_F_ALLOW_MULTI : 0;
++        flags = (supported == BPF_FIREWALL_SUPPORTED_WITH_MULTI) ? BPF_F_ALLOW_MULTI : 0;
+
+         /* Unref the old BPF program (which will implicitly detach it) right before attaching the new program, to
+          * minimize the time window when we don't account for IP traffic. */
+@@ -711,8 +710,7 @@ int bpf_firewall_install(Unit *u) {
+         u->ip_bpf_ingress_installed = bpf_program_unref(u->ip_bpf_ingress_installed);
+
+         if (u->ip_bpf_egress) {
+-                r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path,
+-                                              flags | (set_isempty(u->ip_bpf_custom_egress) ? 0 : BPF_F_ALLOW_MULTI));
++                r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path, flags);
+                 if (r < 0)
+                         return log_unit_error_errno(u, r, "Attaching egress BPF program to cgroup %s failed: %m", path);
+
+@@ -721,8 +719,7 @@ int bpf_firewall_install(Unit *u) {
+         }
+
+         if (u->ip_bpf_ingress) {
+-                r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path,
+-                                              flags | (set_isempty(u->ip_bpf_custom_ingress) ? 0 : BPF_F_ALLOW_MULTI));
++                r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path, flags);
+                 if (r < 0)
+                         return log_unit_error_errno(u, r, "Attaching ingress BPF program to cgroup %s failed: %m", path);
+
+diff --git a/src/core/main.c b/src/core/main.c
+index a280b756ff..2ace4cb89c 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1144,6 +1144,14 @@ static int prepare_reexecute(
+         if (!fds)
+                 return log_oom();
+
++        /* We need existing BPF programs to survive reload, otherwise there will be a period where no BPF
++         * program is active during task execution within a cgroup. This would be bad since this may have
++         * security or reliability implications: devices we should filter won't be filtered, network activity
++         * we should filter won't be filtered, etc. We pin all the existing devices by bumping their
++         * refcount, and then storing them to later have it decremented. */
++        _cleanup_(manager_unpin_all_cgroup_bpf_programsp) Manager *m_unpin =
++                manager_pin_all_cgroup_bpf_programs(m);
++
+         r = manager_serialize(m, f, fds, switching_root);
+         if (r < 0)
+                 return r;
+@@ -1159,6 +1167,7 @@ static int prepare_reexecute(
+         if (r < 0)
+                 return log_error_errno(r, "Failed to disable O_CLOEXEC for serialization fds: %m");
+
++        TAKE_PTR(m_unpin);
+         *ret_f = TAKE_PTR(f);
+         *ret_fds = TAKE_PTR(fds);
+
+diff --git a/src/core/manager.c b/src/core/manager.c
+index a1d6f7cc10..b373d27844 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -65,6 +65,7 @@
+ #include "rm-rf.h"
+ #include "selinux-util.h"
+ #include "serialize.h"
++#include "set.h"
+ #include "signal-util.h"
+ #include "socket-util.h"
+ #include "special.h"
+@@ -3217,6 +3218,79 @@ static void manager_serialize_gid_refs(Manager *m, FILE *f) {
+         manager_serialize_uid_refs_internal(m, f, &m->gid_refs, "destroy-ipc-gid");
+ }
+
++static int serialize_limbo_bpf_program(FILE *f, FDSet *fds, BPFProgram *p) {
++        int copy;
++        _cleanup_free_ char *ap = NULL;
++
++        /* We don't actually need the instructions or other data, since this is only used on the other side
++         * for BPF limbo, which just requires the program type, cgroup path, and kernel-facing BPF file
++         * descriptor. We don't even need to know what unit or directive it's attached to, since we're just
++         * going to expire it after coldplug. */
++
++        assert(f);
++        assert(p);
++
++        /* If the program isn't attached to the kernel yet, there's no reason to serialise it for limbo. Just
++         * let it be skeletonized and then coldplug can do the work on the other side if it's still
++         * necessary. */
++        if (p->kernel_fd < 0 || !p->attached_path)
++                return -ENOTCONN;
++
++        copy = fdset_put_dup(fds, p->kernel_fd);
++        if (copy < 0)
++                return log_error_errno(copy, "Failed to add file descriptor to serialization set: %m");
++
++        /* Otherwise, on daemon-reload, we'd remain pinned. */
++        safe_close(p->kernel_fd);
++
++        ap = cescape(p->attached_path);
++        if (!ap)
++                return log_oom();
++
++        return serialize_item_format(f, "bpf-limbo", "%i %i %i \"%s\"",
++                                     copy, p->prog_type, p->attached_type, ap);
++}
++
++static void deserialize_limbo_bpf_program(Manager *m, FDSet *fds, const char *value) {
++        _cleanup_free_ char *raw_fd = NULL, *raw_pt = NULL, *raw_at = NULL, *cgpath = NULL;
++        int fd, r, prog_type, attached_type;
++
++        assert(m);
++        assert(value);
++
++        r = extract_first_word(&value, &raw_fd, NULL, 0);
++        if (r <= 0 || safe_atoi(raw_fd, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
++                return (void) log_error("Failed to parse bpf-limbo FD: %s", value);
++
++        r = extract_first_word(&value, &raw_pt, NULL, 0);
++        if (r <= 0 || safe_atoi(raw_pt, &prog_type) < 0)
++                return (void) log_error("Failed to parse bpf-limbo program type: %s", value);
++
++        r = extract_first_word(&value, &raw_at, NULL, 0);
++        if (r <= 0 || safe_atoi(raw_at, &attached_type) < 0)
++                return (void) log_error("Failed to parse bpf-limbo attached type: %s", value);
++
++        r = extract_first_word(&value, &cgpath, NULL, EXTRACT_CUNESCAPE | EXTRACT_UNQUOTE);
++        if (r <= 0)
++                return (void) log_error("Failed to parse attached path for BPF limbo FD %s", value);
++
++        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
++        r = bpf_program_new(prog_type, &p);
++        if (r < 0)
++                return (void) log_error_errno(r, "Failed to create BPF limbo program: %m");
++
++        /* Just enough to free it when the time is right, this does not have enough information be used as a
++         * real BPFProgram. */
++        p->attached_type = attached_type;
++        p->kernel_fd = fdset_remove(fds, fd);
++        p->attached_path = TAKE_PTR(cgpath);
++
++        r = set_ensure_put(&m->bpf_limbo_progs, NULL, p);
++        if (r < 0)
++                return (void) log_error_errno(r, "Failed to register BPF limbo program for FD %s: %m", value);
++        TAKE_PTR(p);
++}
++
+ int manager_serialize(
+                 Manager *m,
+                 FILE *f,
+@@ -3226,6 +3300,7 @@ int manager_serialize(
+         const char *t;
+         Unit *u;
+         int r;
++        BPFProgram *p;
+
+         assert(m);
+         assert(f);
+@@ -3270,6 +3345,9 @@ int manager_serialize(
+                 (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
+         }
+
++        SET_FOREACH(p, m->bpf_limbo_progs)
++                (void) serialize_limbo_bpf_program(f, fds, p);
++
+         if (!switching_root)
+                 (void) serialize_strv(f, "env", m->client_environment);
+
+@@ -3588,7 +3666,10 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+                         else
+                                 m->n_failed_jobs += n;
+
+-                } else if ((val = startswith(l, "taint-usr="))) {
++                } else if ((val = startswith(l, "bpf-limbo=")))
++                        deserialize_limbo_bpf_program(m, fds, val);
++
++                else if ((val = startswith(l, "taint-usr="))) {
+                         int b;
+
+                         b = parse_boolean(val);
+@@ -3764,6 +3845,65 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+         return manager_deserialize_units(m, f, fds);
+ }
+
++Manager* manager_pin_all_cgroup_bpf_programs(Manager *m) {
++        int r;
++        Unit *u;
++
++        assert(m);
++
++        HASHMAP_FOREACH(u, m->units) {
++                BPFProgram *p;
++
++                FOREACH_POINTER(p,
++                                u->bpf_device_control_installed,
++                                u->ip_bpf_ingress,
++                                u->ip_bpf_ingress_installed,
++                                u->ip_bpf_egress,
++                                u->ip_bpf_egress_installed)
++                        if (p) {
++                                r = set_ensure_put(&m->bpf_limbo_progs, NULL, p);
++                                if (r < 0) {
++                                        log_unit_error_errno(u, r, "Cannot store BPF program for reload, ignoring: %m");
++                                        continue;
++                                }
++
++                                bpf_program_ref(p);
++                        }
++
++                Set *s;
++                FOREACH_POINTER(s,
++                                u->ip_bpf_custom_ingress,
++                                u->ip_bpf_custom_ingress_installed,
++                                u->ip_bpf_custom_egress,
++                                u->ip_bpf_custom_egress_installed)
++                        SET_FOREACH(p, s) {
++                                r = set_ensure_put(&m->bpf_limbo_progs, NULL, p);
++                                if (r < 0) {
++                                        log_unit_error_errno(u, r, "Cannot store BPF program for reload, ignoring: %m");
++                                        continue;
++                                }
++
++                                bpf_program_ref(p);
++                        }
++        }
++
++        log_debug("Pinned %d BPF programs", set_size(m->bpf_limbo_progs));
++
++        return m;
++}
++
++static void manager_skeletonize_all_cgroup_bpf_programs(Manager *m) {
++        BPFProgram *p;
++
++        SET_FOREACH(p, m->bpf_limbo_progs)
++                bpf_program_skeletonize(p);
++}
++
++void manager_unpin_all_cgroup_bpf_programs(Manager *m) {
++        log_debug("Unpinning %d BPF programs", set_size(m->bpf_limbo_progs));
++        set_clear_with_destructor(m->bpf_limbo_progs, bpf_program_unref);
++}
++
+ int manager_reload(Manager *m) {
+         _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
+         _cleanup_fdset_free_ FDSet *fds = NULL;
+@@ -3783,6 +3923,13 @@ int manager_reload(Manager *m) {
+         /* We are officially in reload mode from here on. */
+         reloading = manager_reloading_start(m);
+
++        /* We need existing BPF programs to survive reload, otherwise there will be a period where no BPF
++         * program is active during task execution within a cgroup. This would be bad since this may have
++         * security or reliability implications: devices we should filter won't be filtered, network activity
++         * we should filter won't be filtered, etc. We pin all the existing devices by bumping their
++         * refcount, and then storing them to later have it decremented. */
++        (void) manager_pin_all_cgroup_bpf_programs(m);
++
+         r = manager_serialize(m, f, fds, false);
+         if (r < 0)
+                 return r;
+@@ -3807,6 +3954,12 @@ int manager_reload(Manager *m) {
+         m->uid_refs = hashmap_free(m->uid_refs);
+         m->gid_refs = hashmap_free(m->gid_refs);
+
++        /* The only canonical reference left to the dynamically allocated parts of these BPF programs is
++         * going to be on the other side of manager_deserialize, so the freeable parts can now be freed. The
++         * program itself will be detached as part of manager_vacuum. */
++        manager_skeletonize_all_cgroup_bpf_programs(m);
++        m->bpf_limbo_progs = set_free(m->bpf_limbo_progs);
++
+         r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
+         if (r < 0)
+                 log_warning_errno(r, "Failed to initialize path lookup table, ignoring: %m");
+@@ -4741,6 +4894,12 @@ static void manager_vacuum(Manager *m) {
+
+         /* Release any runtimes no longer referenced */
+         exec_runtime_vacuum(m);
++
++        /* Release any outmoded BPF programs that were deserialized from the previous manager, since new ones
++         * should be in action now. We first need to make sure all entries in the cgroup realize queue are
++         * complete, otherwise BPF firewalls/etc may not have been set up yet. */
++        (void) manager_dispatch_cgroup_realize_queue(m);
++        manager_unpin_all_cgroup_bpf_programs(m);
+ }
+
+ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
+diff --git a/src/core/manager.h b/src/core/manager.h
+index 19df889dd8..2c4a2b6063 100644
+--- a/src/core/manager.h
++++ b/src/core/manager.h
+@@ -438,6 +438,8 @@ struct Manager {
+         VarlinkServer *varlink_server;
+         /* Only systemd-oomd should be using this to subscribe to changes in ManagedOOM settings */
+         Varlink *managed_oom_varlink_request;
++
++        Set *bpf_limbo_progs;
+ };
+
+ static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
+@@ -479,6 +481,10 @@ int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode
+ int manager_add_job_by_name_and_warn(Manager *m, JobType type, const char *name, JobMode mode, Set *affected_jobs,  Job **ret);
+ int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error *e);
+
++Manager* manager_pin_all_cgroup_bpf_programs(Manager *m);
++void manager_unpin_all_cgroup_bpf_programs(Manager *m);
++DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unpin_all_cgroup_bpf_programs);
++
+ void manager_dump_units(Manager *s, FILE *f, const char *prefix);
+ void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
+ void manager_dump(Manager *s, FILE *f, const char *prefix);
+diff --git a/src/shared/bpf-program.c b/src/shared/bpf-program.c
+index 10239142af..549490da6c 100644
+--- a/src/shared/bpf-program.c
++++ b/src/shared/bpf-program.c
+@@ -209,6 +209,16 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
+         return 0;
+ }
+
++void bpf_program_skeletonize(BPFProgram *p) {
++        assert(p);
++
++        /* Called shortly after serialization. From this point on, we are frozen for serialization and entry
++         * into BPF limbo, so we should proactively free our instructions and attached path. However, we
++         * shouldn't detach the program or close the kernel FD -- we need those on the other side. */
++        free(p->instructions);
++        free(p->attached_path);
++}
++
+ int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags) {
+         union bpf_attr attr;
+         int fd;
+diff --git a/src/shared/bpf-program.h b/src/shared/bpf-program.h
+index eef77f9d8e..5957a6ce30 100644
+--- a/src/shared/bpf-program.h
++++ b/src/shared/bpf-program.h
+@@ -28,6 +28,7 @@ struct BPFProgram {
+ int bpf_program_new(uint32_t prog_type, BPFProgram **ret);
+ BPFProgram *bpf_program_unref(BPFProgram *p);
+ BPFProgram *bpf_program_ref(BPFProgram *p);
++void bpf_program_skeletonize(BPFProgram *p);
+
+ int bpf_program_add_instructions(BPFProgram *p, const struct bpf_insn *insn, size_t count);
+ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size);
+--
+2.29.2
+
diff --git a/SOURCES/17872.patch b/SOURCES/17872.patch
new file mode 100644
index 0000000..ffedc20
--- /dev/null
+++ b/SOURCES/17872.patch
@@ -0,0 +1,102 @@
+From 963a018bade094e38a71bf1b7e10d37b44225836 Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Sun, 6 Dec 2020 22:29:43 +0900
+Subject: [PATCH 2/3] core/namespace: use existing /proc when not enough
+ priviledge
+
+Fixes #17860.
+---
+ src/core/namespace.c | 61 ++++++++++++++++++++++++--------------------
+ 1 file changed, 34 insertions(+), 27 deletions(-)
+
+diff --git a/src/core/namespace.c b/src/core/namespace.c
+index cdf427a6ea..8560ad9a75 100644
+--- a/src/core/namespace.c
++++ b/src/core/namespace.c
+@@ -859,25 +859,15 @@ static int mount_sysfs(const MountEntry *m) {
+ }
+ 
+ static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
++        _cleanup_free_ char *opts = NULL;
+         const char *entry_path;
+-        int r;
++        int r, n;
+ 
+         assert(m);
+         assert(ns_info);
+ 
+-        entry_path = mount_entry_path(m);
+-
+-        /* Mount a new instance, so that we get the one that matches our user namespace, if we are running in
+-         * one. i.e we don't reuse existing mounts here under any condition, we want a new instance owned by
+-         * our user namespace and with our hidepid= settings applied. Hence, let's get rid of everything
+-         * mounted on /proc/ first. */
+-
+-        (void) mkdir_p_label(entry_path, 0755);
+-        (void) umount_recursive(entry_path, 0);
+-
+         if (ns_info->protect_proc != PROTECT_PROC_DEFAULT ||
+             ns_info->proc_subset != PROC_SUBSET_ALL) {
+-                _cleanup_free_ char *opts = NULL;
+ 
+                 /* Starting with kernel 5.8 procfs' hidepid= logic is truly per-instance (previously it
+                  * pretended to be per-instance but actually was per-namespace), hence let's make use of it
+@@ -891,23 +881,40 @@ static int mount_procfs(const MountEntry *m, const NamespaceInfo *ns_info) {
+                                ns_info->proc_subset == PROC_SUBSET_PID ? ",subset=pid" : "");
+                 if (!opts)
+                         return -ENOMEM;
+-
+-                r = mount_nofollow_verbose(LOG_DEBUG, "proc", entry_path, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, opts);
+-                if (r < 0) {
+-                        if (r != -EINVAL)
+-                                return r;
+-
+-                        /* If this failed with EINVAL then this likely means the textual hidepid= stuff is
+-                         * not supported by the kernel, and thus the per-instance hidepid= neither, which
+-                         * means we really don't want to use it, since it would affect our host's /proc
+-                         * mount. Hence let's gracefully fallback to a classic, unrestricted version. */
+-                } else
+-                        return 1;
+         }
+ 
+-        r = mount_nofollow_verbose(LOG_DEBUG, "proc", entry_path, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
+-        if (r < 0)
+-                return r;
++        entry_path = mount_entry_path(m);
++        (void) mkdir_p_label(entry_path, 0755);
++
++        /* Mount a new instance, so that we get the one that matches our user namespace, if we are running in
++         * one. i.e we don't reuse existing mounts here under any condition, we want a new instance owned by
++         * our user namespace and with our hidepid= settings applied. Hence, let's get rid of everything
++         * mounted on /proc/ first. */
++
++        n = umount_recursive(entry_path, 0);
++
++        r = mount_nofollow_verbose(LOG_DEBUG, "proc", entry_path, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, opts);
++        if (r == -EINVAL && opts)
++                /* If this failed with EINVAL then this likely means the textual hidepid= stuff is
++                 * not supported by the kernel, and thus the per-instance hidepid= neither, which
++                 * means we really don't want to use it, since it would affect our host's /proc
++                 * mount. Hence let's gracefully fallback to a classic, unrestricted version. */
++                r = mount_nofollow_verbose(LOG_DEBUG, "proc", entry_path, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
++        if (r == -EPERM) {
++                /* When we do not have enough priviledge to mount /proc, fallback to use existing /proc. */
++
++                if (n > 0)
++                        /* /proc or some of sub-mounts are umounted in the above. Refuse incomplete tree.
++                         * Propagate the original error code returned by mount() in the above. */
++                        return -EPERM;
++
++                r = path_is_mount_point(entry_path, NULL, 0);
++                if (r < 0)
++                        return log_debug_errno(r, "Unable to determine whether /proc is already mounted: %m");
++                if (r == 0)
++                        /* /proc is not mounted. Propagate the original error code. */
++                        return -EPERM;
++        }
+ 
+         return 1;
+ }
+-- 
+2.29.2
+
diff --git a/SOURCES/18211.patch b/SOURCES/18211.patch
new file mode 100644
index 0000000..15a2d9b
--- /dev/null
+++ b/SOURCES/18211.patch
@@ -0,0 +1,109 @@
+From 51f14e78a2ae0a971af1ce3cfcbbf8ca8250ca22 Mon Sep 17 00:00:00 2001
+From: Anita Zhang <the.anitazha@gmail.com>
+Date: Mon, 11 Jan 2021 20:04:20 -0800
+Subject: [PATCH 1/3] core: update setings on the unit and job as the result of
+ ExecCondition=
+
+Update ExecCondition= to set Unit->condition_result and return JOB_DONE
+in the Job results  if the check fails so as to match the current behavior
+of ConditionXYZ= w.r.t units/jobs dependency checks.
+
+Fixes: #18207
+---
+ src/core/job.c     |  3 +--
+ src/core/service.c | 17 ++++++++++-------
+ src/core/unit.c    |  2 --
+ src/core/unit.h    |  1 -
+ 4 files changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/src/core/job.c b/src/core/job.c
+index f3c1a02831..7d5c288ea4 100644
+--- a/src/core/job.c
++++ b/src/core/job.c
+@@ -882,8 +882,7 @@ static void job_log_done_status_message(Unit *u, uint32_t job_id, JobType t, Job
+                 return;
+ 
+         /* Show condition check message if the job did not actually do anything due to failed condition. */
+-        if ((t == JOB_START && result == JOB_DONE && !u->condition_result) ||
+-            (t == JOB_START && result == JOB_SKIPPED)) {
++        if (t == JOB_START && result == JOB_DONE && !u->condition_result) {
+                 log_struct(LOG_INFO,
+                            "MESSAGE=Condition check resulted in %s being skipped.", unit_status_string(u),
+                            "JOB_ID=%" PRIu32, job_id,
+diff --git a/src/core/service.c b/src/core/service.c
+index d7bdeb7cca..3b144153f4 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -1129,8 +1129,7 @@ static void service_set_state(Service *s, ServiceState state) {
+ 
+         unit_notify(UNIT(s), table[old_state], table[state],
+                     (s->reload_result == SERVICE_SUCCESS ? 0 : UNIT_NOTIFY_RELOAD_FAILURE) |
+-                    (s->will_auto_restart ? UNIT_NOTIFY_WILL_AUTO_RESTART : 0) |
+-                    (s->result == SERVICE_SKIP_CONDITION ? UNIT_NOTIFY_SKIP_CONDITION : 0));
++                    (s->will_auto_restart ? UNIT_NOTIFY_WILL_AUTO_RESTART : 0));
+ }
+ 
+ static usec_t service_coldplug_timeout(Service *s) {
+@@ -3546,10 +3545,6 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+         } else if (s->control_pid == pid) {
+                 s->control_pid = 0;
+ 
+-                /* ExecCondition= calls that exit with (0, 254] should invoke skip-like behavior instead of failing */
+-                if (f == SERVICE_FAILURE_EXIT_CODE && s->state == SERVICE_CONDITION && status < 255)
+-                        f = SERVICE_SKIP_CONDITION;
+-
+                 if (s->control_command) {
+                         exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
+ 
+@@ -3557,6 +3552,15 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+                                 f = SERVICE_SUCCESS;
+                 }
+ 
++                /* ExecCondition= calls that exit with (0, 254] should invoke skip-like behavior instead of failing */
++                if (s->state == SERVICE_CONDITION) {
++                        if (f == SERVICE_FAILURE_EXIT_CODE && status < 255) {
++                                UNIT(s)->condition_result = false;
++                                f = SERVICE_SKIP_CONDITION;
++                        } else if (f == SERVICE_SUCCESS)
++                                UNIT(s)->condition_result = true;
++                }
++
+                 unit_log_process_exit(
+                                 u,
+                                 "Control process",
+@@ -4601,7 +4605,6 @@ const UnitVTable service_vtable = {
+                 },
+                 .finished_start_job = {
+                         [JOB_FAILED]     = "Failed to start %s.",
+-                        [JOB_SKIPPED]    = "Skipped %s.",
+                 },
+                 .finished_stop_job = {
+                         [JOB_DONE]       = "Stopped %s.",
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 45a417a090..9614fb84aa 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2561,8 +2561,6 @@ static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags)
+                         if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
+                                 if (ns == UNIT_FAILED)
+                                         result = JOB_FAILED;
+-                                else if (FLAGS_SET(flags, UNIT_NOTIFY_SKIP_CONDITION))
+-                                        result = JOB_SKIPPED;
+                                 else
+                                         result = JOB_DONE;
+ 
+diff --git a/src/core/unit.h b/src/core/unit.h
+index 02b2b24206..f040e9dfe6 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -738,7 +738,6 @@ int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t cont
+ typedef enum UnitNotifyFlags {
+         UNIT_NOTIFY_RELOAD_FAILURE    = 1 << 0,
+         UNIT_NOTIFY_WILL_AUTO_RESTART = 1 << 1,
+-        UNIT_NOTIFY_SKIP_CONDITION    = 1 << 2,
+ } UnitNotifyFlags;
+ 
+ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags);
+-- 
+2.29.2
+
diff --git a/SOURCES/f58b96d3e8d1cb0dd3666bc74fa673918b586612.patch b/SOURCES/f58b96d3e8d1cb0dd3666bc74fa673918b586612.patch
new file mode 100644
index 0000000..84497ad
--- /dev/null
+++ b/SOURCES/f58b96d3e8d1cb0dd3666bc74fa673918b586612.patch
@@ -0,0 +1,129 @@
+From f58b96d3e8d1cb0dd3666bc74fa673918b586612 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
+Date: Mon, 14 Sep 2020 17:58:03 +0200
+Subject: [PATCH] test-mountpointutil-util: do not assert in test_mnt_id()
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1803070
+
+I *think* this a kernel bug: the mnt_id as listed in /proc/self/mountinfo is different
+than the one we get from /proc/self/fdinfo/. This only matters when both statx and
+name_to_handle_at are unavailable and we hit the fallback path that goes through fdinfo:
+
+(gdb) !uname -r
+5.6.19-200.fc31.ppc64le
+
+(gdb) !cat /proc/self/mountinfo
+697 664 253:0 /var/lib/mock/fedora-31-ppc64le/root / rw,relatime shared:298 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
+698 697 253:0 /var/cache/mock/fedora-31-ppc64le/yum_cache /var/cache/yum rw,relatime shared:299 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
+699 697 253:0 /var/cache/mock/fedora-31-ppc64le/dnf_cache /var/cache/dnf rw,relatime shared:300 master:1 - xfs /dev/mapper/fedora_rh--power--vm14-root rw,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota
+700 697 0:32 /mock-selinux-plugin.7me9bfpi /proc/filesystems rw,nosuid,nodev shared:301 master:18 - tmpfs tmpfs rw,seclabel <==========================================================
+701 697 0:41 / /sys ro,nosuid,nodev,noexec,relatime shared:302 - sysfs sysfs ro,seclabel
+702 701 0:21 / /sys/fs/selinux ro,nosuid,nodev,noexec,relatime shared:306 master:8 - selinuxfs selinuxfs rw
+703 697 0:42 / /dev rw,nosuid shared:303 - tmpfs tmpfs rw,seclabel,mode=755
+704 703 0:43 / /dev/shm rw,nosuid,nodev shared:304 - tmpfs tmpfs rw,seclabel
+705 703 0:45 / /dev/pts rw,nosuid,noexec,relatime shared:307 - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=666
+706 703 0:6 /btrfs-control /dev/btrfs-control rw,nosuid shared:308 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+707 703 0:6 /loop-control /dev/loop-control rw,nosuid shared:309 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+708 703 0:6 /loop0 /dev/loop0 rw,nosuid shared:310 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+709 703 0:6 /loop1 /dev/loop1 rw,nosuid shared:311 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+710 703 0:6 /loop10 /dev/loop10 rw,nosuid shared:312 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+711 703 0:6 /loop11 /dev/loop11 rw,nosuid shared:313 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+712 703 0:6 /loop2 /dev/loop2 rw,nosuid shared:314 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+713 703 0:6 /loop3 /dev/loop3 rw,nosuid shared:315 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+714 703 0:6 /loop4 /dev/loop4 rw,nosuid shared:316 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+715 703 0:6 /loop5 /dev/loop5 rw,nosuid shared:317 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+716 703 0:6 /loop6 /dev/loop6 rw,nosuid shared:318 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+717 703 0:6 /loop7 /dev/loop7 rw,nosuid shared:319 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+718 703 0:6 /loop8 /dev/loop8 rw,nosuid shared:320 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+719 703 0:6 /loop9 /dev/loop9 rw,nosuid shared:321 master:9 - devtmpfs devtmpfs rw,seclabel,size=4107840k,nr_inodes=64185,mode=755
+720 697 0:44 / /run rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+721 720 0:25 /systemd/nspawn/propagate/9cc8a155d0244558b273f773d2b92142 /run/systemd/nspawn/incoming ro master:12 - tmpfs tmpfs rw,seclabel,mode=755
+722 697 0:32 /mock-resolv.dvml91hp /etc/resolv.conf rw,nosuid,nodev shared:322 master:18 - tmpfs tmpfs rw,seclabel
+725 697 0:47 / /proc rw,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
+603 725 0:47 /sys /proc/sys ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
+604 725 0:44 /systemd/inaccessible/reg /proc/kallsyms ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+605 725 0:44 /systemd/inaccessible/reg /proc/kcore ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+606 725 0:44 /systemd/inaccessible/reg /proc/keys ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+607 725 0:44 /systemd/inaccessible/reg /proc/sysrq-trigger ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+608 725 0:44 /systemd/inaccessible/reg /proc/timer_list ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+609 725 0:47 /bus /proc/bus ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
+610 725 0:47 /fs /proc/fs ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
+611 725 0:47 /irq /proc/irq ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
+612 725 0:47 /scsi /proc/scsi ro,nosuid,nodev,noexec,relatime shared:323 - proc proc rw
+613 703 0:46 / /dev/mqueue rw,nosuid,nodev,noexec,relatime shared:324 - mqueue mqueue rw,seclabel
+614 701 0:26 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:325 - cgroup2 cgroup rw,seclabel,nsdelegate
+615 603 0:44 /.#proc-sys-kernel-random-boot-id4fbdce67af46d1c2//deleted /proc/sys/kernel/random/boot_id ro,nosuid,nodev,noexec shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+616 725 0:44 /.#proc-sys-kernel-random-boot-id4fbdce67af46d1c2//deleted /proc/sys/kernel/random/boot_id rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+617 725 0:44 /.#proc-kmsg5b7a8bcfe6717139//deleted /proc/kmsg rw,nosuid,nodev shared:305 - tmpfs tmpfs rw,seclabel,mode=755
+
+The test process does
+name_to_handle_at("/proc/filesystems") which returns -EOPNOTSUPP, and then
+openat(AT_FDCWD, "/proc/filesystems") which returns 4, and then
+read(open("/proc/self/fdinfo/4", ...)) which gives
+"pos:\t0\nflags:\t012100000\nmnt_id:\t725\n"
+
+and the "725" is clearly inconsistent with "700" in /proc/self/mountinfo.
+
+We could either drop the fallback path (and fail name_to_handle_at() is not
+avaliable) or ignore the error in the test. Not sure what is better. I think
+this issue only occurs sometimes and with older kernels, so probably continuing
+with the current flaky implementation is better than ripping out the fallback.
+
+Another strace:
+writev(2</dev/pts/0>, [{iov_base="mnt ids of /proc/sys is 603", iov_len=27}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/sys is 603
+) = 28
+name_to_handle_at(AT_FDCWD, "/", {handle_bytes=128 => 12, handle_type=129, f_handle=0x52748401000000008b93e20d}, [697], 0) = 0
+writev(2</dev/pts/0>, [{iov_base="mnt ids of / is 697", iov_len=19}, {iov_base="\n", iov_len=1}], 2mnt ids of / is 697
+) = 20
+name_to_handle_at(AT_FDCWD, "/proc/kcore", {handle_bytes=128 => 12, handle_type=1, f_handle=0x92ddcfcd2e802d0100000000}, [605], 0) = 0
+writev(2</dev/pts/0>, [{iov_base="mnt ids of /proc/kcore is 605", iov_len=29}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/kcore is 605
+) = 30
+name_to_handle_at(AT_FDCWD, "/dev", {handle_bytes=128 => 12, handle_type=1, f_handle=0x8ae269160c802d0100000000}, [703], 0) = 0
+writev(2</dev/pts/0>, [{iov_base="mnt ids of /dev is 703", iov_len=22}, {iov_base="\n", iov_len=1}], 2mnt ids of /dev is 703
+) = 23
+name_to_handle_at(AT_FDCWD, "/proc/filesystems", {handle_bytes=128}, 0x7fffe36ddb84, 0) = -1 EOPNOTSUPP (Operation not supported)
+openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = 4</proc/filesystems>
+openat(AT_FDCWD, "/proc/self/fdinfo/4", O_RDONLY|O_CLOEXEC) = 5</proc/20/fdinfo/4>
+fstat(5</proc/20/fdinfo/4>, {st_mode=S_IFREG|0400, st_size=0, ...}) = 0
+fstat(5</proc/20/fdinfo/4>, {st_mode=S_IFREG|0400, st_size=0, ...}) = 0
+read(5</proc/20/fdinfo/4>, "pos:\t0\nflags:\t012100000\nmnt_id:\t725\n", 2048) = 36
+read(5</proc/20/fdinfo/4>, "", 1024)    = 0
+close(5</proc/20/fdinfo/4>)             = 0
+close(4</proc/filesystems>)             = 0
+writev(2</dev/pts/0>, [{iov_base="mnt ids of /proc/filesystems are 700, 725", iov_len=41}, {iov_base="\n", iov_len=1}], 2mnt ids of /proc/filesystems are 700, 725
+) = 42
+writev(2</dev/pts/0>, [{iov_base="the other path for mnt id 725 is /proc", iov_len=38}, {iov_base="\n", iov_len=1}], 2the other path for mnt id 725 is /proc
+) = 39
+writev(2</dev/pts/0>, [{iov_base="Assertion 'path_equal(p, t)' failed at src/test/test-mountpoint-util.c:94, function test_mnt_id(). Aborting.", iov_len=108}, {iov_base="\n", iov_len=1}], 2Assertion 'path_equal(p, t)' failed at src/test/test-mountpoint-util.c:94, function test_mnt_id(). Aborting.
+) = 109
+rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
+rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
+getpid()                                = 20
+gettid()                                = 20
+tgkill(20, 20, SIGABRT)                 = 0
+rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
+--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=20, si_uid=0} ---
++++ killed by SIGABRT (core dumped) +++
+---
+ src/test/test-mountpoint-util.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/test/test-mountpoint-util.c b/src/test/test-mountpoint-util.c
+index 30b00ae4d8b..ffe5144b04a 100644
+--- a/src/test/test-mountpoint-util.c
++++ b/src/test/test-mountpoint-util.c
+@@ -89,8 +89,12 @@ static void test_mnt_id(void) {
+                 /* The ids don't match? If so, then there are two mounts on the same path, let's check if
+                  * that's really the case */
+                 char *t = hashmap_get(h, INT_TO_PTR(mnt_id2));
+-                log_debug("the other path for mnt id %i is %s\n", mnt_id2, t);
+-                assert_se(path_equal(p, t));
++                log_debug("Path for mnt id %i from /proc/self/mountinfo is %s\n", mnt_id2, t);
++
++                if (!path_equal(p, t))
++                        /* Apparent kernel bug in /proc/self/fdinfo */
++                        log_warning("Bad mount id given for %s: %d, should be %d",
++                                    p, mnt_id2, mnt_id);
+         }
+ }
+ 
diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec
index 578eccc..f6df179 100644
--- a/SPECS/systemd.spec
+++ b/SPECS/systemd.spec
@@ -1,15 +1,4 @@
-# Meson settings
-%global _vpath_srcdir .
-%global _vpath_builddir %{_target_platform}
-%global __global_cflags  %{optflags}
-%global __global_cxxflags  %{optflags}
-%global __global_fflags  %{optflags} -I%_fmoddir
-%global __global_fcflags %{optflags} -I%_fmoddir
-%global __global_ldflags -Wl,-z,relro %{_hardened_ldflags}
-
-%define _python_bytecompile_errors_terminate_build 0
-
-#global commit 7f56c26d1041e686efa72b339250a98fb6ee8f00
+#global commit 551dd873b0bdfb9e7e47431b2933c8b910228f0c
 %{?commit:%global shortcommit %(c=%{commit}; echo ${c:0:7})}
 
 %global stable 1
@@ -27,11 +16,12 @@
 # cryptsetup, e.g. when re-building cryptsetup on a json-c SONAME-bump.
 %bcond_with    bootstrap
 %bcond_without tests
+%bcond_without lto
 
 Name:           systemd
 Url:            https://www.freedesktop.org/wiki/Software/systemd
-Version:        246.1
-Release:        2%{?dist}
+Version:        247.3
+Release:        1%{?dist}
 # For a breakdown of the licensing, see README
 License:        LGPLv2+ and MIT and GPLv2+
 Summary:        System and Service Manager
@@ -73,22 +63,19 @@ i=1; for j in 00*patch; do printf "Patch%04d:      %s\n" $i $j; i=$((i+1));done|
 GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[67]* hwdb/parse_hwdb.py > hwdb.patch
 %endif
 
-Patch0002:      0001-Revert-test-path-increase-timeout.patch
-Patch0003:      0002-test-path-do-not-fail-the-test-if-we-fail-to-start-s.patch
-
-Patch0004:      0001-test-acl-util-output-more-debug-info.patch
-Patch0005:      0001-Do-not-assert-in-test_add_acls_for_user.patch
-
-Patch1002:      16838_16857_improve_path_search.patch
-Patch1003:      16940_cleanup_socket_econn_handling.patch
-Patch1004:      17031_propagate_start_limit_hit.patch
-Patch1005:      17082_nspawn_tty_tweaks.patch
-
-Patch1006:      0001-bpf-pid1-Pin-reference-to-BPF-programs-for-post-cold.patch
-Patch1007:      0002-core-clean-up-inactive-failed-service-scope-s-cgroup.patch
-Patch1008:      0003-timer-add-new-feature-FixedRandomDelay.patch
+# Backports of patches from upstream (0000–0499)
+# 18211: Fixes ExecCondition= dependency bug
+Patch0000:      https://github.com/systemd/systemd/pull/18211.patch
+# 17872: Fixes using PrivateUsers=yes with other sandboxing properties
+Patch0001:      https://github.com/systemd/systemd/pull/17872.patch
+%if 0%{?facebook}
+# 17495: Fixes BPF pinning post-coldplug
+Patch0002:      https://github.com/systemd/systemd/pull/17495.patch
+%endif
 
-Patch1009:      16803_fix_asserts_conditions.patch
+# Downstream-only patches (0500–9999)
+# https://github.com/systemd/systemd/pull/17050
+Patch0501:      https://github.com/systemd/systemd/pull/17050/commits/f58b96d3e8d1cb0dd3666bc74fa673918b586612.patch
 
 %ifarch %{ix86} x86_64 aarch64
 %global have_gnu_efi 1
@@ -140,8 +127,6 @@ BuildRequires:  tree
 BuildRequires:  hostname
 BuildRequires:  python3-devel
 BuildRequires:  python3-lxml
-BuildRequires:  python3
-%global __python3 /usr/bin/python3
 %if 0%{?have_gnu_efi}
 BuildRequires:  gnu-efi gnu-efi-devel
 %endif
@@ -151,6 +136,8 @@ BuildRequires:  gettext
 # We use RUNNING_ON_VALGRIND in tests, so the headers need to be available
 BuildRequires:  valgrind-devel
 BuildRequires:  pkgconfig(bash-completion)
+BuildRequires:  perl
+BuildRequires:  perl(IPC::SysV)
 
 Requires(post): coreutils
 Requires(post): sed
@@ -176,14 +163,31 @@ 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
 Obsoletes:      systemd-sysv < 206
+%if 0%{?facebook} == 0
 # self-obsoletes so that dnf will install new subpackages on upgrade (#1260394)
-Obsoletes:      %{name} < 229-5
+Obsoletes:      %{name} < 246.6-2
+Conflicts:      initscripts < 9.56.1
+%endif
 Provides:       systemd-sysv = 206
 %if 0%{?fedora}
 Conflicts:      fedora-release < 23-0.12
 %endif
 Obsoletes:      timedatex < 0.6-3
 Provides:       timedatex = 0.6-3
+Conflicts:      %{name}-standalone-tmpfiles < %{version}-%{release}^
+Obsoletes:      %{name}-standalone-tmpfiles < %{version}-%{release}^
+Conflicts:      %{name}-standalone-sysusers < %{version}-%{release}^
+Obsoletes:      %{name}-standalone-sysusers < %{version}-%{release}^
+
+# Recommends to replace normal Requires deps for stuff that is dlopen()ed
+Recommends:     libcryptsetup.so.12()(64bit)
+Recommends:     libcryptsetup.so.12(CRYPTSETUP_2.0)(64bit)
+Recommends:     libidn2.so.0()(64bit)
+Recommends:     libidn2.so.0(IDN2_0.0.0)(64bit)
+Recommends:     libpcre2-8.so.0()(64bit)
+Recommends:     libpwquality.so.1()(64bit)
+Recommends:     libpwquality.so.1(LIBPWQUALITY_1.0)(64bit)
+Recommends:     libqrencode.so.4()(64bit)
 
 %description
 systemd is a system and service manager that runs as PID 1 and starts
@@ -263,16 +267,14 @@ Requires(preun):  systemd
 Requires(postun): systemd
 Requires(post): grep
 Requires:       kmod >= 18-4
-%if 0%{?facebook}
-# obsolete parent package so that dnf will install new subpackage on upgrade (#1260394)
-Obsoletes:      %{name} < 229-5
-%else
+%if 0%{?facebook} == 0
 # https://bodhi.fedoraproject.org/updates/FEDORA-2020-dd43dd05b1
 Obsoletes:      systemd < 245.6-1
 %endif
 Provides:       udev = %{version}
 Provides:       udev%{_isa} = %{version}
 Obsoletes:      udev < 183
+
 # https://bugzilla.redhat.com/show_bug.cgi?id=1377733#c9
 Suggests:       systemd-bootchart
 # https://bugzilla.redhat.com/show_bug.cgi?id=1408878
@@ -282,6 +284,10 @@ Requires:       kbd
 Provides:       u2f-hidraw-policy = 1.0.2-40
 Obsoletes:      u2f-hidraw-policy < 1.0.2-40
 
+# Recommends to replace normal Requires deps for stuff that is dlopen()ed
+Recommends:     libcryptsetup.so.12()(64bit)
+Recommends:     libcryptsetup.so.12(CRYPTSETUP_2.0)(64bit)
+
 %description udev
 This package contains systemd-udev and the rules and hardware database
 needed to manage device nodes. This package is necessary on physical
@@ -341,16 +347,17 @@ They can be useful to test systemd internals.
 %{!?ntpvendor: echo 'NTP vendor zone is not set!'; exit 1}
 
 CONFIGURE_OPTS=(
+        -Dmode=release
         -Dsysvinit-path=/etc/rc.d/init.d
         -Drc-local=/etc/rc.d/rc.local
         -Dntp-servers='0.%{ntpvendor}.pool.ntp.org 1.%{ntpvendor}.pool.ntp.org 2.%{ntpvendor}.pool.ntp.org 3.%{ntpvendor}.pool.ntp.org'
+        -Ddns-servers=
         -Duser-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
         -Dservice-watchdog=
         -Ddev-kvm-mode=0666
         -Dkmod=true
         -Dxkbcommon=true
         -Dblkid=true
-        -Dfdisk=true
         -Dseccomp=true
         -Dima=true
         -Dselinux=true
@@ -364,6 +371,7 @@ CONFIGURE_OPTS=(
         -Dpam=true
         -Dacl=true
         -Dsmack=true
+        -Dopenssl=true
         -Dgcrypt=true
         -Daudit=true
         -Delfutils=true
@@ -373,8 +381,6 @@ CONFIGURE_OPTS=(
         -Dlibcryptsetup=false
 %endif
         -Delfutils=true
-        -Dpwquality=true
-        -Dqrencode=true
         -Dgnutls=true
         -Dmicrohttpd=true
         -Dlibidn2=true
@@ -392,20 +398,38 @@ CONFIGURE_OPTS=(
         -Dusers-gid=100
         -Dnobody-user=nobody
         -Dnobody-group=nobody
+        -Dcompat-mutable-uid-boundaries=true
         -Dsplit-usr=false
         -Dsplit-bin=true
+%if %{with lto}
         -Db_lto=true
+%else
+        -Db_lto=false
+%endif
         -Db_ndebug=false
         -Dman=true
         -Dversion-tag=v%{version}-%{release}
         -Ddocdir=%{_pkgdocdir}
-        -Ddefault-hierarchy=legacy
-)
-
-# FIXME: temporary hack to unbreak the build, as with audit link fails on
-# test-emergency-action (https://pagure.io/centos-sig-hyperscale/sig/issue/13)
-CONFIGURE_OPTS+=(
-        -Daudit=false
+        -Dfallback-hostname=fedora
+        -Ddefault-dnssec=no
+        # https://bugzilla.redhat.com/show_bug.cgi?id=1867830
+        -Ddefault-mdns=no
+        -Ddefault-llmnr=resolve
+        # CentOS is missing newer deps required to include these
+        # But also these aren't as relevant for the hyperscale use case
+        -Dp11kit=false
+        -Duserdb=false
+        -Dhomed=false
+        -Drepart=false
+        -Dfdisk=false
+        -Dpwquality=false
+        -Dqrencode=false
+        -Dlibfido2=false
+        # Old version of PAM might not support files in /usr/lib/pam.d/ so
+        # stick with the old /etc/pam.d
+        -Dpamconfdir=/etc/pam.d
+        # Standalone binaries are only relevant on non-systemd systems
+        -Dstandalone-binaries=false
 )
 
 %if 0%{?facebook}
@@ -415,13 +439,13 @@ CONFIGURE_OPTS+=(
         -Dsupport-url='https://www.facebook.com/groups/prodos.users/'
         -Ddefault-hierarchy=unified
         -Dcontainer-uid-base-min=10485760
-        -Dp11kit=false
-        -Duserdb=false
-        -Dhomed=false
-        -Drepart=false
 )
 %endif
 
+%if %{without lto}
+%global _lto_cflags %nil
+%endif
+
 export LANG=en_US.UTF-8
 export LC_ALL=en_US.UTF-8
 %meson "${CONFIGURE_OPTS[@]}"
@@ -528,7 +552,7 @@ install -m 0755 -D -t %{buildroot}%{_rpmconfigdir}/ %{SOURCE24}
 # Split files in build root into rpms. See split-files.py for the
 # rules towards the end, anything which is an exception needs a line
 # here.
-%{__python3} %{SOURCE2} %buildroot <<EOF
+python3 %{SOURCE2} %buildroot <<EOF
 %ghost %config(noreplace) /etc/crypttab
 %ghost /etc/udev/hwdb.bin
 /etc/inittab
@@ -632,6 +656,8 @@ chmod g+s /{run,var}/log/journal/{,${machine_id}} &>/dev/null || :
 # Apply ACL to the journal directory
 setfacl -Rnm g:wheel:rx,d:g:wheel:rx,g:adm:rx,d:g:adm:rx /var/log/journal/ &>/dev/null || :
 
+[ $1 -eq 1 ] || exit 0
+
 # We reset the enablement of all services upon initial installation
 # https://bugzilla.redhat.com/show_bug.cgi?id=1118740#c23
 # This will fix up enablement of any preset services that got installed
@@ -639,9 +665,26 @@ setfacl -Rnm g:wheel:rx,d:g:wheel:rx,g:adm:rx,d:g:adm:rx /var/log/journal/ &>/de
 # https://bugzilla.redhat.com/show_bug.cgi?id=1647172.
 # We also do this for user units, see
 # https://fedoraproject.org/wiki/Changes/Systemd_presets_for_user_units.
-if [ $1 -eq 1 ] ; then
-        systemctl preset-all &>/dev/null || :
-        systemctl --global preset-all &>/dev/null || :
+systemctl preset-all &>/dev/null || :
+systemctl --global preset-all &>/dev/null || :
+
+# Create /etc/resolv.conf symlink.
+# We would also create it using tmpfiles, but let's do this here
+# too before NetworkManager gets a chance. (systemd-tmpfiles invocation above
+# does not do this, because it's marked with ! and we don't specify --boot.)
+# https://bugzilla.redhat.com/show_bug.cgi?id=1873856
+#
+# If systemd is not running, don't overwrite the symlink because that
+# will immediately break DNS resolution, since systemd-resolved is
+# also not running (https://bugzilla.redhat.com/show_bug.cgi?id=1891847).
+#
+# Also don't creat the symlink to the stub when the stub is disabled (#1891847 again).
+if test -d /run/systemd/system/ &&
+   systemctl -q is-enabled systemd-resolved.service &>/dev/null &&
+   ! mountpoint /etc/resolv.conf &>/dev/null &&
+   ! systemd-analyze cat-config systemd/resolved.conf 2>/dev/null | \
+        grep -qE '^DNSStubListener\s*=\s*([nN][oO]?|[fF]|[fF][aA][lL][sS][eE]|0|[oO][fF][fF])$'; then
+  ln -fsv ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
 fi
 
 %preun
@@ -663,10 +706,14 @@ fi
 # This is for upgrades from previous versions before systemd-resolved became the default.
 systemctl --no-reload preset systemd-resolved.service &>/dev/null || :
 
-if systemctl is-enabled systemd-resolved.service &>/dev/null; then
+if systemctl -q is-enabled systemd-resolved.service &>/dev/null; then
+  systemctl -q is-enabled NetworkManager.service 2>/dev/null && \
+  ! test -L /etc/resolv.conf 2>/dev/null && \
+  ! mountpoint /etc/resolv.conf &>/dev/null && \
   grep -q 'Generated by NetworkManager' /etc/resolv.conf 2>/dev/null && \
   echo -e '/etc/resolv.conf was generated by NetworkManager.\nRemoving it to let systemd-resolved manage this file.' && \
-  mv -v /etc/resolv.conf /etc/resolv.conf.orig-with-nm || :
+  mv -v /etc/resolv.conf /etc/resolv.conf.orig-with-nm && \
+  ln -sv ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf 2>/dev/null || :
 
   systemctl start systemd-resolved.service &>/dev/null || :
 fi
@@ -685,7 +732,7 @@ function mod_nss() {
         # Add nss-resolve to hosts
         grep -E -q '^hosts:.* resolve' "$1" ||
         sed -i.bak -r -e '
-                s/^(hosts):(.*) files( mdns4_minimal .NOTFOUND=return.)? dns myhostname/\1:\2 resolve [!UNAVAIL=return] myhostname files\3 dns/
+                s/^(hosts):(.*) files( mdns4_minimal .NOTFOUND=return.)? dns myhostname/\1:\2 files\3 resolve [!UNAVAIL=return] myhostname dns/
                 ' "$1" &>/dev/null || :
     fi
 }
@@ -739,8 +786,12 @@ if [ -f %{_localstatedir}/lib/systemd/clock ] ; then
 fi
 
 udevadm hwdb --update &>/dev/null
+
 %systemd_post %udev_services
-/usr/lib/systemd/systemd-random-seed save 2>&1
+
+# Try to save the random seed, but don't complain if /dev/urandom is unavailable
+/usr/lib/systemd/systemd-random-seed save 2>&1 | \
+    grep -v 'Failed to open /dev/urandom' || :
 
 # Replace obsolete keymaps
 # https://bugzilla.redhat.com/show_bug.cgi?id=1151958
@@ -760,14 +811,11 @@ getent group systemd-journal-remote &>/dev/null || groupadd -r systemd-journal-r
 getent passwd systemd-journal-remote &>/dev/null || useradd -r -l -g systemd-journal-remote -d %{_localstatedir}/log/journal/remote -s /sbin/nologin -c "Journal Remote" systemd-journal-remote &>/dev/null || :
 
 %post journal-remote
-%systemd_post systemd-journal-gatewayd.socket systemd-journal-gatewayd.service
-%systemd_post systemd-journal-remote.socket systemd-journal-remote.service
-%systemd_post systemd-journal-upload.service
+%systemd_post systemd-journal-gatewayd.socket systemd-journal-gatewayd.service systemd-journal-remote.socket systemd-journal-remote.service systemd-journal-upload.service
+%firewalld_reload
 
 %preun journal-remote
-%systemd_preun systemd-journal-gatewayd.socket systemd-journal-gatewayd.service
-%systemd_preun systemd-journal-remote.socket systemd-journal-remote.service
-%systemd_preun systemd-journal-upload.service
+%systemd_preun systemd-journal-gatewayd.socket systemd-journal-gatewayd.service systemd-journal-remote.socket systemd-journal-remote.service systemd-journal-upload.service
 if [ $1 -eq 1 ] ; then
     if [ -f %{_localstatedir}/lib/systemd/journal-upload/state -a ! -L %{_localstatedir}/lib/systemd/journal-upload ] ; then
         mkdir -p %{_localstatedir}/lib/private/systemd/journal-upload
@@ -777,9 +825,7 @@ if [ $1 -eq 1 ] ; then
 fi
 
 %postun journal-remote
-%systemd_postun_with_restart systemd-journal-gatewayd.service
-%systemd_postun_with_restart systemd-journal-remote.service
-%systemd_postun_with_restart systemd-journal-upload.service
+%systemd_postun_with_restart systemd-journal-gatewayd.service systemd-journal-remote.service systemd-journal-upload.service
 
 %global _docdir_fmt %{name}
 
@@ -822,6 +868,12 @@ fi
 %files tests -f .file-list-tests
 
 %changelog
+* Wed Feb 17 2021 Anita Zhang <anitazha@fb.com> - 247.3-1
+- New release for 247
+- Backport PR #18211 (Fixes ExecCondition= dependency bug)
+- Backport PR #17872 (Fixes PrivateUsers=yes with other sandboxing properties)
+- FB only backport PR #17495 (Fixes BPF pinning post-coldplug)
+
 * Sun Feb  7 2021 Davide Cavalca <dcavalca@fb.com> - 246.1-2
 - Initial Hyperscale SIG package
 - Update release to use %%dist macro
@@ -830,8 +882,42 @@ fi
 - Drop no longer needed FB FusionIO patch
 - Temporarily disable audit support while debugging a link issue
 
-* Mon Jan 25 2021 Anita Zhang <anitazha@fb.com> - 246.1-1.fb6
-- Backport PR #16803 to fix ConditionEnvironment=
+* Tue Feb  2 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247.3-1
+- Minor stable release
+- Fixes #1895937, #1813219, #1903106.
+
+* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org>
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Wed Jan 13 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247.2-2
+- Fix bfq patch again (#1813219)
+
+* Wed Dec 23 2020 Jonathan Underwood <jonathan.underwood@gmail.com> - 247.2-2
+- Add patch to enable crypttab to support disabling of luks read and
+  write workqueues (corresponding to
+  https://github.com/systemd/systemd/pull/18062/).
+
+* Wed Dec 16 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247.2-1
+- Minor stable release
+- Fixes #1908071.
+
+* Tue Dec  8 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247.1-3
+- Rebuild with fallback hostname change reverted.
+
+* Fri Dec  4 2020 Bastien Nocera <bnocera@redhat.com> - 247.1-2
+- Unset fallback-hostname as plenty of applications expected localhost
+  to mean "default hostname" without ever standardising it (#1892235)
+
+* Tue Dec  1 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247.1-1
+- Latest stable release
+- Fixes #1902819.
+- Files to configure networking with systemd-networkd in a VM or container are
+  moved to systemd-networkd subpackage. (They were previously in the -container
+  subpackage, which is for container/VM management.)
+
+* Thu Nov 26 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247-1
+- Update to the latest version
+- #1900878 should be fixed
 
 * Thu Nov 19 2020 Chris Down <cdown@fb.com> - 246.1-1.fb5
 - Updated version of PR #17495 to fix program leak
@@ -841,12 +927,68 @@ fi
 - Backport PR #17422 to clean up cgroups more reliably after exit
 - Backport PR #17497 to add FixedRandomDelay= support
 
+* Tue Oct 20 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 247~rc2
+- New upstream pre-release. See
+  https://github.com/systemd/systemd/blob/v247-rc1/NEWS.
+  Many smaller and bigger improvements and features are introduced.
+  (#1885101, #1890632, #1879216)
+
+  A backwards-incompatible change affects PCI network devices which
+  are connected through a bridge which is itself associated with a
+  slot. When more than one device was associated with the same slot,
+  one of the devices would pseudo-randomly get named after the slot.
+  That name is now not generated at all. This changed behaviour is
+  causes the net naming scheme to be changed to "v247". To restore
+  previous behaviour, specify net.naming-scheme=v245.
+
+  systemd-oomd is built, but should not be considered "production
+  ready" at this point. Testing and bug reports are welcome.
+
+* Wed Sep 30 2020 Dusty Mabe <dusty@dustymabe.com> - 246.6-3
+- Try to make files in subpackages (especially the networkd subpackage)
+  more appropriate.
+
+* Thu Sep 24 2020 Filipe Brandenburger <filbranden@gmail.com> - 246.6-2
+- Build a package with standalone binaries for non-systemd systems.
+  For now, only systemd-sysusers is included.
+
+* Thu Sep 24 2020 Christian Glombek <lorbus@fedoraproject.org> - 246.6-2
+- Split out networkd sub-package and add to main package as recommended dependency
+
+* Sun Sep 20 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 246.6-1
+- Update to latest stable release (various minor fixes: manager,
+  networking, bootct, kernel-install, systemd-dissect, systemd-homed,
+  fstab-generator, documentation) (#1876905)
+- Do not fail in test because of kernel bug (#1803070)
+
 * Fri Sep 18 2020 Anita Zhang <anitazha@fb.com> - 246.1-1.fb3
 - Backport PR #16838 and #16857 to improve $PATH handling
 - Backport PR #16940 to fix ECONN handling in sockets
 - Backport PR #17031 to fix rate limiting on units in restart loop
 - Backport PR #17082 to get nspawn TTY tweaks
 
+* Sun Sep 13 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 246.5-1
+- Update to latest stable release (a bunch of small network-related
+  fixes in systemd-networkd and socket handling, documentation updates,
+  a bunch of fixes for error handling).
+- Also remove existing file when creating /etc/resolv.conf symlink
+  upon installation (#1873856 again)
+
+* Wed Sep  2 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 246.4-1
+- Update to latest stable version: a rework of how the unit cache mtime works
+  (hopefully #1872068, #1871327, #1867930), plus various fixes to
+  systemd-resolved, systemd-dissect, systemd-analyze, systemd-ask-password-agent,
+  systemd-networkd, systemd-homed, systemd-machine-id-setup, presets for
+  instantiated units, documentation and shell completions.
+- Create /etc/resolv.conf symlink upon installation (#1873856)
+- Move nss-mdns before nss-resolve in /etc/nsswitch.conf and disable
+  mdns by default in systemd-resolved (#1867830)
+
+* Wed Aug 26 2020 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 246.3-1
+- Update to bugfix version (some networkd fixes, minor documentation
+  fixes, relax handling of various error conditions, other fixlets for
+  bugs without bugzilla numbers).
+
 * Tue Aug 18 2020 Anita Zhang <anitazha@fb.com> - 246.1-1.fb2
 - Gate "Obsoletes: systemd < 245.6-1" out due to dependency issues on Facebook
   systems