diff --git a/core/systemd/0001-core-do-not-spawn-jobs-or-touch-other-units-during-c.patch b/core/systemd/0001-core-do-not-spawn-jobs-or-touch-other-units-during-c.patch
deleted file mode 100644
index f1d7c0461..000000000
--- a/core/systemd/0001-core-do-not-spawn-jobs-or-touch-other-units-during-c.patch
+++ /dev/null
@@ -1,376 +0,0 @@
-From 6e392c9c45643d106673c6643ac8bf4e65da13c1 Mon Sep 17 00:00:00 2001
-From: Ivan Shapovalov <intelfx100@gmail.com>
-Date: Sat, 7 Mar 2015 08:44:52 -0500
-Subject: [PATCH] core: do not spawn jobs or touch other units during
- coldplugging
-
-Because the order of coldplugging is not defined, we can reference a
-not-yet-coldplugged unit and read its state while it has not yet been
-set to a meaningful value.
-
-This way, already active units may get started again.
-
-We fix this by deferring such actions until all units have been at
-least somehow coldplugged.
-
-Fixes https://bugs.freedesktop.org/show_bug.cgi?id=88401
----
- src/core/automount.c |  2 +-
- src/core/busname.c   |  2 +-
- src/core/device.c    |  2 +-
- src/core/manager.c   | 35 +++++++++++++++++++++++++++++++++--
- src/core/mount.c     |  2 +-
- src/core/path.c      | 14 ++++++++++----
- src/core/scope.c     |  2 +-
- src/core/service.c   |  2 +-
- src/core/slice.c     |  2 +-
- src/core/snapshot.c  |  2 +-
- src/core/socket.c    |  2 +-
- src/core/swap.c      |  2 +-
- src/core/target.c    |  2 +-
- src/core/timer.c     | 14 ++++++++++----
- src/core/unit.c      | 25 ++++++++++++++++---------
- src/core/unit.h      | 12 +++++++++---
- 16 files changed, 89 insertions(+), 33 deletions(-)
-
-diff --git a/src/core/automount.c b/src/core/automount.c
-index 4a509ef..0539fbb 100644
---- a/src/core/automount.c
-+++ b/src/core/automount.c
-@@ -233,7 +233,7 @@ static void automount_set_state(Automount *a, AutomountState state) {
-         unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
- }
- 
--static int automount_coldplug(Unit *u) {
-+static int automount_coldplug(Unit *u, Hashmap *deferred_work) {
-         Automount *a = AUTOMOUNT(u);
-         int r;
- 
-diff --git a/src/core/busname.c b/src/core/busname.c
-index 1d77292..43d7607 100644
---- a/src/core/busname.c
-+++ b/src/core/busname.c
-@@ -335,7 +335,7 @@ static void busname_set_state(BusName *n, BusNameState state) {
-         unit_notify(UNIT(n), state_translation_table[old_state], state_translation_table[state], true);
- }
- 
--static int busname_coldplug(Unit *u) {
-+static int busname_coldplug(Unit *u, Hashmap *deferred_work) {
-         BusName *n = BUSNAME(u);
-         int r;
- 
-diff --git a/src/core/device.c b/src/core/device.c
-index eb976b8..6b489a4 100644
---- a/src/core/device.c
-+++ b/src/core/device.c
-@@ -140,7 +140,7 @@ static void device_set_state(Device *d, DeviceState state) {
-         unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true);
- }
- 
--static int device_coldplug(Unit *u) {
-+static int device_coldplug(Unit *u, Hashmap *deferred_work) {
-         Device *d = DEVICE(u);
- 
-         assert(d);
-diff --git a/src/core/manager.c b/src/core/manager.c
-index 7a6d519..3e87aa9 100644
---- a/src/core/manager.c
-+++ b/src/core/manager.c
-@@ -975,7 +975,28 @@ static int manager_coldplug(Manager *m) {
-         Unit *u;
-         char *k;
- 
--        assert(m);
-+        /*
-+         * Some unit types tend to spawn jobs or check other units' state
-+         * during coldplug. This is wrong because it is undefined whether the
-+         * units in question have been already coldplugged (i. e. their state
-+         * restored). This way, we can easily re-start an already started unit
-+         * or otherwise make a wrong decision based on the unit's state.
-+         *
-+         * Solve this by providing a way for coldplug functions to defer
-+         * such actions until after all units have been coldplugged.
-+         *
-+         * We store Unit* -> int(*)(Unit*).
-+         *
-+         * https://bugs.freedesktop.org/show_bug.cgi?id=88401
-+         */
-+        _cleanup_hashmap_free_ Hashmap *deferred_work = NULL;
-+        int(*proc)(Unit*);
-+
-+        assert(m);
-+
-+        deferred_work = hashmap_new(&trivial_hash_ops);
-+        if (!deferred_work)
-+                return -ENOMEM;
- 
-         /* Then, let's set up their initial state. */
-         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
-@@ -985,7 +1006,17 @@ static int manager_coldplug(Manager *m) {
-                 if (u->id != k)
-                         continue;
- 
--                q = unit_coldplug(u);
-+                q = unit_coldplug(u, deferred_work);
-+                if (q < 0)
-+                        r = q;
-+        }
-+
-+        /* After coldplugging and setting up initial state of the units,
-+         * let's perform operations which spawn jobs or query units' state. */
-+        HASHMAP_FOREACH_KEY(proc, u, deferred_work, i) {
-+                int q;
-+
-+                q = proc(u);
-                 if (q < 0)
-                         r = q;
-         }
-diff --git a/src/core/mount.c b/src/core/mount.c
-index 5ee679d..1251c94 100644
---- a/src/core/mount.c
-+++ b/src/core/mount.c
-@@ -612,7 +612,7 @@ static void mount_set_state(Mount *m, MountState state) {
-         m->reload_result = MOUNT_SUCCESS;
- }
- 
--static int mount_coldplug(Unit *u) {
-+static int mount_coldplug(Unit *u, Hashmap *deferred_work) {
-         Mount *m = MOUNT(u);
-         MountState new_state = MOUNT_DEAD;
-         int r;
-diff --git a/src/core/path.c b/src/core/path.c
-index fbb695d..6be9ac8 100644
---- a/src/core/path.c
-+++ b/src/core/path.c
-@@ -438,7 +438,12 @@ static void path_set_state(Path *p, PathState state) {
- 
- static void path_enter_waiting(Path *p, bool initial, bool recheck);
- 
--static int path_coldplug(Unit *u) {
-+static int path_enter_waiting_coldplug(Unit *u) {
-+        path_enter_waiting(PATH(u), true, true);
-+        return 0;
-+}
-+
-+static int path_coldplug(Unit *u, Hashmap *deferred_work) {
-         Path *p = PATH(u);
- 
-         assert(p);
-@@ -447,9 +452,10 @@ static int path_coldplug(Unit *u) {
-         if (p->deserialized_state != p->state) {
- 
-                 if (p->deserialized_state == PATH_WAITING ||
--                    p->deserialized_state == PATH_RUNNING)
--                        path_enter_waiting(p, true, true);
--                else
-+                    p->deserialized_state == PATH_RUNNING) {
-+                        hashmap_put(deferred_work, u, &path_enter_waiting_coldplug);
-+                        path_set_state(p, PATH_WAITING);
-+                } else
-                         path_set_state(p, p->deserialized_state);
-         }
- 
-diff --git a/src/core/scope.c b/src/core/scope.c
-index 1c3c6bb..8b2bb29 100644
---- a/src/core/scope.c
-+++ b/src/core/scope.c
-@@ -171,7 +171,7 @@ static int scope_load(Unit *u) {
-         return scope_verify(s);
- }
- 
--static int scope_coldplug(Unit *u) {
-+static int scope_coldplug(Unit *u, Hashmap *deferred_work) {
-         Scope *s = SCOPE(u);
-         int r;
- 
-diff --git a/src/core/service.c b/src/core/service.c
-index a89ff3f..cc4ea19 100644
---- a/src/core/service.c
-+++ b/src/core/service.c
-@@ -878,7 +878,7 @@ static void service_set_state(Service *s, ServiceState state) {
-         s->reload_result = SERVICE_SUCCESS;
- }
- 
--static int service_coldplug(Unit *u) {
-+static int service_coldplug(Unit *u, Hashmap *deferred_work) {
-         Service *s = SERVICE(u);
-         int r;
- 
-diff --git a/src/core/slice.c b/src/core/slice.c
-index 0bebdbc..0285c49 100644
---- a/src/core/slice.c
-+++ b/src/core/slice.c
-@@ -150,7 +150,7 @@ static int slice_load(Unit *u) {
-         return slice_verify(s);
- }
- 
--static int slice_coldplug(Unit *u) {
-+static int slice_coldplug(Unit *u, Hashmap *deferred_work) {
-         Slice *t = SLICE(u);
- 
-         assert(t);
-diff --git a/src/core/snapshot.c b/src/core/snapshot.c
-index b70c3be..b1d8448 100644
---- a/src/core/snapshot.c
-+++ b/src/core/snapshot.c
-@@ -75,7 +75,7 @@ static int snapshot_load(Unit *u) {
-         return 0;
- }
- 
--static int snapshot_coldplug(Unit *u) {
-+static int snapshot_coldplug(Unit *u, Hashmap *deferred_work) {
-         Snapshot *s = SNAPSHOT(u);
- 
-         assert(s);
-diff --git a/src/core/socket.c b/src/core/socket.c
-index 9606ac2..f67370b 100644
---- a/src/core/socket.c
-+++ b/src/core/socket.c
-@@ -1322,7 +1322,7 @@ static void socket_set_state(Socket *s, SocketState state) {
-         unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
- }
- 
--static int socket_coldplug(Unit *u) {
-+static int socket_coldplug(Unit *u, Hashmap *deferred_work) {
-         Socket *s = SOCKET(u);
-         int r;
- 
-diff --git a/src/core/swap.c b/src/core/swap.c
-index 4dd6be8..bb1398f 100644
---- a/src/core/swap.c
-+++ b/src/core/swap.c
-@@ -506,7 +506,7 @@ static void swap_set_state(Swap *s, SwapState state) {
-                         job_add_to_run_queue(UNIT(other)->job);
- }
- 
--static int swap_coldplug(Unit *u) {
-+static int swap_coldplug(Unit *u, Hashmap *deferred_work) {
-         Swap *s = SWAP(u);
-         SwapState new_state = SWAP_DEAD;
-         int r;
-diff --git a/src/core/target.c b/src/core/target.c
-index 8817ef2..5f64402 100644
---- a/src/core/target.c
-+++ b/src/core/target.c
-@@ -103,7 +103,7 @@ static int target_load(Unit *u) {
-         return 0;
- }
- 
--static int target_coldplug(Unit *u) {
-+static int target_coldplug(Unit *u, Hashmap *deferred_work) {
-         Target *t = TARGET(u);
- 
-         assert(t);
-diff --git a/src/core/timer.c b/src/core/timer.c
-index 9405501..79a7540 100644
---- a/src/core/timer.c
-+++ b/src/core/timer.c
-@@ -267,7 +267,12 @@ static void timer_set_state(Timer *t, TimerState state) {
- 
- static void timer_enter_waiting(Timer *t, bool initial);
- 
--static int timer_coldplug(Unit *u) {
-+static int timer_enter_waiting_coldplug(Unit *u) {
-+        timer_enter_waiting(TIMER(u), false);
-+        return 0;
-+}
-+
-+static int timer_coldplug(Unit *u, Hashmap *deferred_work) {
-         Timer *t = TIMER(u);
- 
-         assert(t);
-@@ -275,9 +280,10 @@ static int timer_coldplug(Unit *u) {
- 
-         if (t->deserialized_state != t->state) {
- 
--                if (t->deserialized_state == TIMER_WAITING)
--                        timer_enter_waiting(t, false);
--                else
-+                if (t->deserialized_state == TIMER_WAITING) {
-+                        hashmap_put(deferred_work, u, &timer_enter_waiting_coldplug);
-+                        timer_set_state(t, TIMER_WAITING);
-+                } else
-                         timer_set_state(t, t->deserialized_state);
-         }
- 
-diff --git a/src/core/unit.c b/src/core/unit.c
-index b639d68..ec4fa82 100644
---- a/src/core/unit.c
-+++ b/src/core/unit.c
-@@ -2856,27 +2856,34 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
-         return 0;
- }
- 
--int unit_coldplug(Unit *u) {
-+static int unit_add_deserialized_job_coldplug(Unit *u) {
-+        int r;
-+
-+        r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
-+        if (r < 0)
-+                return r;
-+
-+        u->deserialized_job = _JOB_TYPE_INVALID;
-+
-+        return 0;
-+}
-+
-+int unit_coldplug(Unit *u, Hashmap *deferred_work) {
-         int r;
- 
-         assert(u);
- 
-         if (UNIT_VTABLE(u)->coldplug)
--                if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
-+                if ((r = UNIT_VTABLE(u)->coldplug(u, deferred_work)) < 0)
-                         return r;
- 
-         if (u->job) {
-                 r = job_coldplug(u->job);
-                 if (r < 0)
-                         return r;
--        } else if (u->deserialized_job >= 0) {
-+        } else if (u->deserialized_job >= 0)
-                 /* legacy */
--                r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
--                if (r < 0)
--                        return r;
--
--                u->deserialized_job = _JOB_TYPE_INVALID;
--        }
-+                hashmap_put(deferred_work, u, &unit_add_deserialized_job_coldplug);
- 
-         return 0;
- }
-diff --git a/src/core/unit.h b/src/core/unit.h
-index ac5647a..11242c2 100644
---- a/src/core/unit.h
-+++ b/src/core/unit.h
-@@ -301,8 +301,14 @@ struct UnitVTable {
-         int (*load)(Unit *u);
- 
-         /* If a lot of units got created via enumerate(), this is
--         * where to actually set the state and call unit_notify(). */
--        int (*coldplug)(Unit *u);
-+         * where to actually set the state and call unit_notify().
-+         *
-+         * This must not reference other units (maybe implicitly through spawning
-+         * jobs), because it is possible that they are not yet coldplugged.
-+         * Such actions must be deferred until the end of coldplug bу adding
-+         * a "Unit* -> int(*)(Unit*)" entry into the hashmap.
-+         */
-+        int (*coldplug)(Unit *u, Hashmap *deferred_work);
- 
-         void (*dump)(Unit *u, FILE *f, const char *prefix);
- 
-@@ -538,7 +544,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds);
- 
- int unit_add_node_link(Unit *u, const char *what, bool wants);
- 
--int unit_coldplug(Unit *u);
-+int unit_coldplug(Unit *u, Hashmap *deferred_work);
- 
- void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0);
- 
--- 
-2.3.2
-
diff --git a/core/systemd/0001-core-don-t-change-removed-devices-to-state-tentative.patch b/core/systemd/0001-core-don-t-change-removed-devices-to-state-tentative.patch
deleted file mode 100644
index b9022c456..000000000
--- a/core/systemd/0001-core-don-t-change-removed-devices-to-state-tentative.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 496068a8288084ab3ecf8b179a8403ecff1a6be8 Mon Sep 17 00:00:00 2001
-From: Martin Pitt <martin.pitt@ubuntu.com>
-Date: Fri, 13 Mar 2015 08:35:59 +0100
-Subject: [PATCH] core: don't change removed devices to state "tentative"
-
-Commit 628c89c introduced the "tentative" device state, which caused
-devices to go from "plugged" to "tentative" on a remove uevent. This
-breaks the cleanup of stale mounts (see commit 3b48ce4), as that only
-applies to "dead" devices.
-
-The "tentative" state only really makes sense on adding a device when
-we don't know where it was coming from (i. e. not from udev). But when
-we get a device removal from udev we definitively know that it's gone,
-so change the device state back to "dead" as before 628c89c.
----
- src/core/device.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/core/device.c b/src/core/device.c
-index 4bfd71f..b5d9d82 100644
---- a/src/core/device.c
-+++ b/src/core/device.c
-@@ -419,7 +419,7 @@ static void device_update_found_one(Device *d, bool add, DeviceFound found, bool
-         if (now) {
-                 if (d->found & DEVICE_FOUND_UDEV)
-                         device_set_state(d, DEVICE_PLUGGED);
--                else if (d->found != DEVICE_NOT_FOUND)
-+                else if (add && d->found != DEVICE_NOT_FOUND)
-                         device_set_state(d, DEVICE_TENTATIVE);
-                 else
-                         device_set_state(d, DEVICE_DEAD);
--- 
-2.3.5
-
diff --git a/core/systemd/0001-core-rework-device-state-logic.patch b/core/systemd/0001-core-rework-device-state-logic.patch
deleted file mode 100644
index 290a72320..000000000
--- a/core/systemd/0001-core-rework-device-state-logic.patch
+++ /dev/null
@@ -1,910 +0,0 @@
-From 628c89cc68ab96fce2de7ebba5933725d147aecc Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Fri, 27 Feb 2015 21:55:08 +0100
-Subject: [PATCH] core: rework device state logic
-
-This change introduces a new state "tentative" for device units. Device
-units are considered "plugged" when udev announced them, "dead" when
-they are not available in the kernel, and "tentative" when they are
-referenced in /proc/self/mountinfo or /proc/swaps but not (yet)
-announced via udev.
-
-This should fix a race when device nodes (like loop devices) are created
-and immediately mounted. Previously, systemd might end up seeing the
-mount unit before the device, and would thus pull down the mount because
-its BindTo dependency on the device would not be fulfilled.
----
- src/core/device.c | 368 +++++++++++++++++++++++++++++++++---------------------
- src/core/device.h |  14 ++-
- src/core/mount.c  |  46 ++++---
- src/core/swap.c   |  32 +++--
- src/core/swap.h   |   4 +-
- src/core/unit.c   |   1 -
- 6 files changed, 285 insertions(+), 180 deletions(-)
-
-diff --git a/src/core/device.c b/src/core/device.c
-index 2d983cc..e41ed41 100644
---- a/src/core/device.c
-+++ b/src/core/device.c
-@@ -34,7 +34,8 @@
- 
- static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
-         [DEVICE_DEAD] = UNIT_INACTIVE,
--        [DEVICE_PLUGGED] = UNIT_ACTIVE
-+        [DEVICE_TENTATIVE] = UNIT_ACTIVATING,
-+        [DEVICE_PLUGGED] = UNIT_ACTIVE,
- };
- 
- static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
-@@ -63,6 +64,41 @@ static void device_unset_sysfs(Device *d) {
-         d->sysfs = NULL;
- }
- 
-+static int device_set_sysfs(Device *d, const char *sysfs) {
-+        Device *first;
-+        char *copy;
-+        int r;
-+
-+        assert(d);
-+
-+        if (streq_ptr(d->sysfs, sysfs))
-+                return 0;
-+
-+        r = hashmap_ensure_allocated(&UNIT(d)->manager->devices_by_sysfs, &string_hash_ops);
-+        if (r < 0)
-+                return r;
-+
-+        copy = strdup(sysfs);
-+        if (!copy)
-+                return -ENOMEM;
-+
-+        device_unset_sysfs(d);
-+
-+        first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, sysfs);
-+        LIST_PREPEND(same_sysfs, first, d);
-+
-+        r = hashmap_replace(UNIT(d)->manager->devices_by_sysfs, copy, first);
-+        if (r < 0) {
-+                LIST_REMOVE(same_sysfs, first, d);
-+                free(copy);
-+                return r;
-+        }
-+
-+        d->sysfs = copy;
-+
-+        return 0;
-+}
-+
- static void device_init(Unit *u) {
-         Device *d = DEVICE(u);
- 
-@@ -110,8 +146,13 @@ static int device_coldplug(Unit *u) {
-         assert(d);
-         assert(d->state == DEVICE_DEAD);
- 
--        if (d->sysfs)
-+        if (d->found & DEVICE_FOUND_UDEV)
-+                /* If udev says the device is around, it's around */
-                 device_set_state(d, DEVICE_PLUGGED);
-+        else if (d->found != DEVICE_NOT_FOUND)
-+                /* If a device is found in /proc/self/mountinfo or
-+                 * /proc/swaps, it's "tentatively" around. */
-+                device_set_state(d, DEVICE_TENTATIVE);
- 
-         return 0;
- }
-@@ -140,49 +181,9 @@ _pure_ static const char *device_sub_state_to_string(Unit *u) {
-         return device_state_to_string(DEVICE(u)->state);
- }
- 
--static int device_add_escaped_name(Unit *u, const char *dn) {
--        _cleanup_free_ char *e = NULL;
--        int r;
--
--        assert(u);
--        assert(dn);
--        assert(dn[0] == '/');
--
--        e = unit_name_from_path(dn, ".device");
--        if (!e)
--                return -ENOMEM;
--
--        r = unit_add_name(u, e);
--        if (r < 0 && r != -EEXIST)
--                return r;
--
--        return 0;
--}
--
--static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
--        _cleanup_free_ char *e = NULL;
--        Unit *u;
--
--        assert(m);
--        assert(dn);
--        assert(dn[0] == '/');
--        assert(_u);
--
--        e = unit_name_from_path(dn, ".device");
--        if (!e)
--                return -ENOMEM;
--
--        u = manager_get_unit(m, e);
--        if (u) {
--                *_u = u;
--                return 1;
--        }
--
--        return 0;
--}
--
--static int device_make_description(Unit *u, struct udev_device *dev, const char *path) {
-+static int device_update_description(Unit *u, struct udev_device *dev, const char *path) {
-         const char *model;
-+        int r;
- 
-         assert(u);
-         assert(dev);
-@@ -207,13 +208,16 @@ static int device_make_description(Unit *u, struct udev_device *dev, const char
- 
-                         j = strjoin(model, " ", label, NULL);
-                         if (j)
--                                return unit_set_description(u, j);
--                }
-+                                r = unit_set_description(u, j);
-+                } else
-+                        r = unit_set_description(u, model);
-+        } else
-+                r = unit_set_description(u, path);
- 
--                return unit_set_description(u, model);
--        }
-+        if (r < 0)
-+                log_unit_error_errno(u->id, r, "Failed to set device description: %m");
- 
--        return unit_set_description(u, path);
-+        return r;
- }
- 
- static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
-@@ -240,20 +244,20 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) {
- 
-                 n = unit_name_mangle(e, MANGLE_NOGLOB);
-                 if (!n)
--                        return -ENOMEM;
-+                        return log_oom();
- 
-                 r = unit_add_dependency_by_name(u, UNIT_WANTS, n, NULL, true);
-                 if (r < 0)
--                        return r;
-+                        return log_unit_error_errno(u->id, r, "Failed to add wants dependency: %m");
-         }
-         if (!isempty(state))
--                log_unit_warning(u->id, "Property %s on %s has trailing garbage, ignoring.",
--                                 property, strna(udev_device_get_syspath(dev)));
-+                log_unit_warning(u->id, "Property %s on %s has trailing garbage, ignoring.", property, strna(udev_device_get_syspath(dev)));
- 
-         return 0;
- }
- 
--static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
-+static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
-+        _cleanup_free_ char *e = NULL;
-         const char *sysfs;
-         Unit *u = NULL;
-         bool delete;
-@@ -267,12 +271,18 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
-         if (!sysfs)
-                 return 0;
- 
--        r = device_find_escape_name(m, path, &u);
--        if (r < 0)
--                return r;
-+        e = unit_name_from_path(path, ".device");
-+        if (!e)
-+                return log_oom();
-+
-+        u = manager_get_unit(m, e);
- 
--        if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
-+        if (u &&
-+            DEVICE(u)->sysfs &&
-+            !path_equal(DEVICE(u)->sysfs, sysfs)) {
-+                log_unit_error(u->id, "Device %s appeared twice with different sysfs paths %s and %s", e, DEVICE(u)->sysfs, sysfs);
-                 return -EEXIST;
-+        }
- 
-         if (!u) {
-                 delete = true;
-@@ -281,7 +291,7 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
-                 if (!u)
-                         return log_oom();
- 
--                r = device_add_escaped_name(u, path);
-+                r = unit_add_name(u, e);
-                 if (r < 0)
-                         goto fail;
- 
-@@ -293,37 +303,16 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
-          * actually been seen yet ->sysfs will not be
-          * initialized. Hence initialize it if necessary. */
- 
--        if (!DEVICE(u)->sysfs) {
--                Device *first;
--
--                DEVICE(u)->sysfs = strdup(sysfs);
--                if (!DEVICE(u)->sysfs) {
--                        r = -ENOMEM;
--                        goto fail;
--                }
--
--                r = hashmap_ensure_allocated(&m->devices_by_sysfs, &string_hash_ops);
--                if (r < 0)
--                        goto fail;
--
--                first = hashmap_get(m->devices_by_sysfs, sysfs);
--                LIST_PREPEND(same_sysfs, first, DEVICE(u));
--
--                r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first);
--                if (r < 0)
--                        goto fail;
--        }
--
--        device_make_description(u, dev, path);
-+        r = device_set_sysfs(DEVICE(u), sysfs);
-+        if (r < 0)
-+                goto fail;
- 
--        if (main) {
--                /* The additional systemd udev properties we only
--                 * interpret for the main object */
-+        (void) device_update_description(u, dev, path);
- 
--                r = device_add_udev_wants(u, dev);
--                if (r < 0)
--                        goto fail;
--        }
-+        /* The additional systemd udev properties we only interpret
-+         * for the main object */
-+        if (main)
-+                (void) device_add_udev_wants(u, dev);
- 
-         /* Note that this won't dispatch the load queue, the caller
-          * has to do that if needed and appropriate */
-@@ -332,7 +321,7 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
-         return 0;
- 
- fail:
--        log_warning_errno(r, "Failed to load device unit: %m");
-+        log_unit_warning_errno(u->id, r, "Failed to set up device unit: %m");
- 
-         if (delete && u)
-                 unit_free(u);
-@@ -340,7 +329,7 @@ fail:
-         return r;
- }
- 
--static int device_process_new_device(Manager *m, struct udev_device *dev) {
-+static int device_process_new(Manager *m, struct udev_device *dev) {
-         const char *sysfs, *dn, *alias;
-         struct udev_list_entry *item = NULL, *first = NULL;
-         int r;
-@@ -352,14 +341,14 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
-                 return 0;
- 
-         /* Add the main unit named after the sysfs path */
--        r = device_update_unit(m, dev, sysfs, true);
-+        r = device_setup_unit(m, dev, sysfs, true);
-         if (r < 0)
-                 return r;
- 
-         /* Add an additional unit for the device node */
-         dn = udev_device_get_devnode(dev);
-         if (dn)
--                device_update_unit(m, dev, dn, false);
-+                (void) device_setup_unit(m, dev, dn, false);
- 
-         /* Add additional units for all symlinks */
-         first = udev_device_get_devlinks_list_entry(dev);
-@@ -386,7 +375,7 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
-                             st.st_rdev != udev_device_get_devnum(dev))
-                                 continue;
- 
--                device_update_unit(m, dev, p, false);
-+                (void) device_setup_unit(m, dev, p, false);
-         }
- 
-         /* Add additional units for all explicitly configured
-@@ -403,7 +392,7 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
-                         e[l] = 0;
- 
-                         if (path_is_absolute(e))
--                                device_update_unit(m, dev, e, false);
-+                                (void) device_setup_unit(m, dev, e, false);
-                         else
-                                 log_warning("SYSTEMD_ALIAS for %s is not an absolute path, ignoring: %s", sysfs, e);
-                 }
-@@ -414,39 +403,62 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
-         return 0;
- }
- 
--static void device_set_path_plugged(Manager *m, struct udev_device *dev) {
--        const char *sysfs;
-+static void device_update_found_one(Device *d, bool add, DeviceFound found, bool now) {
-+        DeviceFound n;
-+
-+        assert(d);
-+
-+        n = add ? (d->found | found) : (d->found & ~found);
-+        if (n == d->found)
-+                return;
-+
-+        d->found = n;
-+
-+        if (now) {
-+                if (d->found & DEVICE_FOUND_UDEV)
-+                        device_set_state(d, DEVICE_PLUGGED);
-+                else if (d->found != DEVICE_NOT_FOUND)
-+                        device_set_state(d, DEVICE_TENTATIVE);
-+                else
-+                        device_set_state(d, DEVICE_DEAD);
-+        }
-+}
-+
-+static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
-         Device *d, *l;
- 
-         assert(m);
--        assert(dev);
-+        assert(sysfs);
- 
--        sysfs = udev_device_get_syspath(dev);
--        if (!sysfs)
--                return;
-+        if (found == DEVICE_NOT_FOUND)
-+                return 0;
- 
-         l = hashmap_get(m->devices_by_sysfs, sysfs);
-         LIST_FOREACH(same_sysfs, d, l)
--                device_set_state(d, DEVICE_PLUGGED);
-+                device_update_found_one(d, add, found, now);
-+
-+        return 0;
- }
- 
--static int device_process_removed_device(Manager *m, struct udev_device *dev) {
--        const char *sysfs;
--        Device *d;
-+static int device_update_found_by_name(Manager *m, const char *path, bool add, DeviceFound found, bool now) {
-+        _cleanup_free_ char *e = NULL;
-+        Unit *u;
- 
-         assert(m);
--        assert(dev);
-+        assert(path);
- 
--        sysfs = udev_device_get_syspath(dev);
--        if (!sysfs)
--                return -ENOMEM;
-+        if (found == DEVICE_NOT_FOUND)
-+                return 0;
- 
--        /* Remove all units of this sysfs path */
--        while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) {
--                device_unset_sysfs(d);
--                device_set_state(d, DEVICE_DEAD);
--        }
-+        e = unit_name_from_path(path, ".device");
-+        if (!e)
-+                return log_oom();
- 
-+        u = manager_get_unit(m, e);
-+        if (!u)
-+                return 0;
-+
-+        device_update_found_one(DEVICE(u), add, found, now);
-         return 0;
- }
- 
-@@ -462,22 +474,6 @@ static bool device_is_ready(struct udev_device *dev) {
-         return parse_boolean(ready) != 0;
- }
- 
--static int device_process_new_path(Manager *m, const char *path) {
--        _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
--
--        assert(m);
--        assert(path);
--
--        dev = udev_device_new_from_syspath(m->udev, path);
--        if (!dev)
--                return log_oom();
--
--        if (!device_is_ready(dev))
--                return 0;
--
--        return device_process_new_device(m, dev);
--}
--
- static Unit *device_following(Unit *u) {
-         Device *d = DEVICE(u);
-         Device *other, *first = NULL;
-@@ -604,12 +600,31 @@ static int device_enumerate(Manager *m) {
-                 goto fail;
- 
-         first = udev_enumerate_get_list_entry(e);
--        udev_list_entry_foreach(item, first)
--                device_process_new_path(m, udev_list_entry_get_name(item));
-+        udev_list_entry_foreach(item, first) {
-+                _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
-+                const char *sysfs;
-+
-+                sysfs = udev_list_entry_get_name(item);
-+
-+                dev = udev_device_new_from_syspath(m->udev, sysfs);
-+                if (!dev) {
-+                        log_oom();
-+                        continue;
-+                }
-+
-+                if (!device_is_ready(dev))
-+                        continue;
-+
-+                (void) device_process_new(m, dev);
-+
-+                device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, false);
-+        }
- 
-         return 0;
- 
- fail:
-+        log_error_errno(r, "Failed to enumerate devices: %m");
-+
-         device_shutdown(m);
-         return r;
- }
-@@ -617,7 +632,7 @@ fail:
- static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
-         _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
-         Manager *m = userdata;
--        const char *action;
-+        const char *action, *sysfs;
-         int r;
- 
-         assert(m);
-@@ -639,33 +654,47 @@ static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
-         if (!dev)
-                 return 0;
- 
-+        sysfs = udev_device_get_syspath(dev);
-+        if (!sysfs) {
-+                log_error("Failed to get udev sys path.");
-+                return 0;
-+        }
-+
-         action = udev_device_get_action(dev);
-         if (!action) {
-                 log_error("Failed to get udev action string.");
-                 return 0;
-         }
- 
--        if (streq(action, "remove") || !device_is_ready(dev))  {
--                r = device_process_removed_device(m, dev);
--                if (r < 0)
--                        log_error_errno(r, "Failed to process device remove event: %m");
--
--                r = swap_process_removed_device(m, dev);
-+        if (streq(action, "remove"))  {
-+                r = swap_process_device_remove(m, dev);
-                 if (r < 0)
-                         log_error_errno(r, "Failed to process swap device remove event: %m");
- 
--        } else {
--                r = device_process_new_device(m, dev);
--                if (r < 0)
--                        log_error_errno(r, "Failed to process device new event: %m");
-+                /* If we get notified that a device was removed by
-+                 * udev, then it's completely gone, hence unset all
-+                 * found bits */
-+                device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV|DEVICE_FOUND_MOUNT|DEVICE_FOUND_SWAP, true);
- 
--                r = swap_process_new_device(m, dev);
-+        } else if (device_is_ready(dev)) {
-+
-+                (void) device_process_new(m, dev);
-+
-+                r = swap_process_device_new(m, dev);
-                 if (r < 0)
-                         log_error_errno(r, "Failed to process swap device new event: %m");
- 
-                 manager_dispatch_load_queue(m);
- 
--                device_set_path_plugged(m, dev);
-+                /* The device is found now, set the udev found bit */
-+                device_update_found_by_sysfs(m, sysfs, true, DEVICE_FOUND_UDEV, true);
-+
-+        } else {
-+                /* The device is nominally around, but not ready for
-+                 * us. Hence unset the udev bit, but leave the rest
-+                 * around. */
-+
-+                device_update_found_by_sysfs(m, sysfs, false, DEVICE_FOUND_UDEV, true);
-         }
- 
-         return 0;
-@@ -684,9 +713,58 @@ static bool device_supported(Manager *m) {
-         return read_only <= 0;
- }
- 
-+int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now) {
-+        _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
-+        struct stat st;
-+
-+        assert(m);
-+        assert(node);
-+
-+        /* This is called whenever we find a device referenced in
-+         * /proc/swaps or /proc/self/mounts. Such a device might be
-+         * mounted/enabled at a time where udev has not finished
-+         * probing it yet, and we thus haven't learned about it
-+         * yet. In this case we will set the device unit to
-+         * "tentative" state. */
-+
-+        if (add) {
-+                if (!path_startswith(node, "/dev"))
-+                        return 0;
-+
-+                if (stat(node, &st) < 0) {
-+                        if (errno == ENOENT)
-+                                return 0;
-+
-+                        return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
-+                }
-+
-+                if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
-+                        return 0;
-+
-+                dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
-+                if (!dev) {
-+                        if (errno == ENOENT)
-+                                return 0;
-+
-+                        return log_oom();
-+                }
-+
-+                /* If the device is known in the kernel and newly
-+                 * appeared, then we'll create a device unit for it,
-+                 * under the name referenced in /proc/swaps or
-+                 * /proc/self/mountinfo. */
-+
-+                (void) device_setup_unit(m, dev, node, false);
-+        }
-+
-+        /* Update the device unit's state, should it exist */
-+        return device_update_found_by_name(m, node, add, found, now);
-+}
-+
- static const char* const device_state_table[_DEVICE_STATE_MAX] = {
-         [DEVICE_DEAD] = "dead",
--        [DEVICE_PLUGGED] = "plugged"
-+        [DEVICE_TENTATIVE] = "tentative",
-+        [DEVICE_PLUGGED] = "plugged",
- };
- 
- DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState);
-diff --git a/src/core/device.h b/src/core/device.h
-index 9065085..9f46e08 100644
---- a/src/core/device.h
-+++ b/src/core/device.h
-@@ -28,20 +28,28 @@ typedef struct Device Device;
-  * simplifies the state engine greatly */
- typedef enum DeviceState {
-         DEVICE_DEAD,
--        DEVICE_PLUGGED,
-+        DEVICE_TENTATIVE, /* mounted or swapped, but not (yet) announced by udev */
-+        DEVICE_PLUGGED,   /* announced by udev */
-         _DEVICE_STATE_MAX,
-         _DEVICE_STATE_INVALID = -1
- } DeviceState;
- 
-+typedef enum DeviceFound {
-+        DEVICE_NOT_FOUND = 0,
-+        DEVICE_FOUND_UDEV = 1,
-+        DEVICE_FOUND_MOUNT = 2,
-+        DEVICE_FOUND_SWAP = 4,
-+} DeviceFound;
-+
- struct Device {
-         Unit meta;
- 
-         char *sysfs;
-+        DeviceFound found;
- 
-         /* In order to be able to distinguish dependencies on
-         different device nodes we might end up creating multiple
-         devices for the same sysfs path. We chain them up here. */
--
-         LIST_FIELDS(struct Device, same_sysfs);
- 
-         DeviceState state;
-@@ -51,3 +59,5 @@ extern const UnitVTable device_vtable;
- 
- const char* device_state_to_string(DeviceState i) _const_;
- DeviceState device_state_from_string(const char *s) _pure_;
-+
-+int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now);
-diff --git a/src/core/mount.c b/src/core/mount.c
-index 40037e7..8e4a376 100644
---- a/src/core/mount.c
-+++ b/src/core/mount.c
-@@ -1386,7 +1386,7 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
-         return 0;
- }
- 
--static int mount_add_one(
-+static int mount_setup_unit(
-                 Manager *m,
-                 const char *what,
-                 const char *where,
-@@ -1429,7 +1429,7 @@ static int mount_add_one(
- 
-                 u = unit_new(m, sizeof(Mount));
-                 if (!u)
--                        return -ENOMEM;
-+                        return log_oom();
- 
-                 r = unit_add_name(u, e);
-                 if (r < 0)
-@@ -1542,6 +1542,8 @@ static int mount_add_one(
-         return 0;
- 
- fail:
-+        log_warning_errno(r, "Failed to set up mount unit: %m");
-+
-         if (delete && u)
-                 unit_free(u);
- 
-@@ -1549,33 +1551,36 @@ fail:
- }
- 
- static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
--        _cleanup_(mnt_free_tablep) struct libmnt_table *tb = NULL;
--        _cleanup_(mnt_free_iterp) struct libmnt_iter *itr = NULL;
--        struct libmnt_fs *fs;
-+        _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
-+        _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
-         int r = 0;
- 
-         assert(m);
- 
--        tb = mnt_new_table();
--        itr = mnt_new_iter(MNT_ITER_FORWARD);
--        if (!tb || !itr)
-+        t = mnt_new_table();
-+        if (!t)
-                 return log_oom();
- 
--        r = mnt_table_parse_mtab(tb, NULL);
-+        i = mnt_new_iter(MNT_ITER_FORWARD);
-+        if (!i)
-+                return log_oom();
-+
-+        r = mnt_table_parse_mtab(t, NULL);
-         if (r < 0)
--                return r;
-+                return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
- 
-         r = 0;
-         for (;;) {
-                 const char *device, *path, *options, *fstype;
-                 _cleanup_free_ const char *d = NULL, *p = NULL;
-+                struct libmnt_fs *fs;
-                 int k;
- 
--                k = mnt_table_next_fs(tb, itr, &fs);
-+                k = mnt_table_next_fs(t, i, &fs);
-                 if (k == 1)
-                         break;
--                else if (k < 0)
--                        return log_error_errno(k, "Failed to get next entry from /etc/fstab: %m");
-+                if (k < 0)
-+                        return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
- 
-                 device = mnt_fs_get_source(fs);
-                 path = mnt_fs_get_target(fs);
-@@ -1583,11 +1588,16 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
-                 fstype = mnt_fs_get_fstype(fs);
- 
-                 d = cunescape(device);
-+                if (!d)
-+                        return log_oom();
-+
-                 p = cunescape(path);
--                if (!d || !p)
-+                if (!p)
-                         return log_oom();
- 
--                k = mount_add_one(m, d, p, options, fstype, set_flags);
-+                (void) device_found_node(m, d, true, DEVICE_FOUND_MOUNT, set_flags);
-+
-+                k = mount_setup_unit(m, d, p, options, fstype, set_flags);
-                 if (r == 0 && k < 0)
-                         r = k;
-         }
-@@ -1731,8 +1741,6 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
- 
-         r = mount_load_proc_self_mountinfo(m, true);
-         if (r < 0) {
--                log_error_errno(r, "Failed to reread /proc/self/mountinfo: %m");
--
-                 /* Reset flags, just in case, for later calls */
-                 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
-                         Mount *mount = MOUNT(u);
-@@ -1765,6 +1773,10 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
-                                 break;
-                         }
- 
-+                        if (mount->parameters_proc_self_mountinfo.what)
-+                                (void) device_found_node(m, mount->parameters_proc_self_mountinfo.what, false, DEVICE_FOUND_MOUNT, true);
-+
-+
-                 } else if (mount->just_mounted || mount->just_changed) {
- 
-                         /* New or changed mount entry */
-diff --git a/src/core/swap.c b/src/core/swap.c
-index f73a8e6..de3a5d8 100644
---- a/src/core/swap.c
-+++ b/src/core/swap.c
-@@ -331,7 +331,7 @@ static int swap_load(Unit *u) {
-         return swap_verify(s);
- }
- 
--static int swap_add_one(
-+static int swap_setup_unit(
-                 Manager *m,
-                 const char *what,
-                 const char *what_proc_swaps,
-@@ -356,8 +356,10 @@ static int swap_add_one(
- 
-         if (u &&
-             SWAP(u)->from_proc_swaps &&
--            !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps))
-+            !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps)) {
-+                log_error("Swap %s appeared twice with different device paths %s and %s", e, SWAP(u)->parameters_proc_swaps.what, what_proc_swaps);
-                 return -EEXIST;
-+        }
- 
-         if (!u) {
-                 delete = true;
-@@ -372,7 +374,7 @@ static int swap_add_one(
- 
-                 SWAP(u)->what = strdup(what);
-                 if (!SWAP(u)->what) {
--                        r = log_oom();
-+                        r = -ENOMEM;
-                         goto fail;
-                 }
- 
-@@ -400,7 +402,6 @@ static int swap_add_one(
-         p->priority = priority;
- 
-         unit_add_to_dbus_queue(u);
--
-         return 0;
- 
- fail:
-@@ -412,7 +413,7 @@ fail:
-         return r;
- }
- 
--static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) {
-+static int swap_process_new(Manager *m, const char *device, int prio, bool set_flags) {
-         _cleanup_udev_device_unref_ struct udev_device *d = NULL;
-         struct udev_list_entry *item = NULL, *first = NULL;
-         const char *dn;
-@@ -421,7 +422,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
- 
-         assert(m);
- 
--        r = swap_add_one(m, device, device, prio, set_flags);
-+        r = swap_setup_unit(m, device, device, prio, set_flags);
-         if (r < 0)
-                 return r;
- 
-@@ -437,7 +438,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
-         /* Add the main device node */
-         dn = udev_device_get_devnode(d);
-         if (dn && !streq(dn, device))
--                swap_add_one(m, dn, device, prio, set_flags);
-+                swap_setup_unit(m, dn, device, prio, set_flags);
- 
-         /* Add additional units for all symlinks */
-         first = udev_device_get_devlinks_list_entry(d);
-@@ -458,7 +459,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool
-                             st.st_rdev != udev_device_get_devnum(d))
-                                 continue;
- 
--                swap_add_one(m, p, device, prio, set_flags);
-+                swap_setup_unit(m, p, device, prio, set_flags);
-         }
- 
-         return r;
-@@ -1084,15 +1085,17 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) {
-                         if (k == EOF)
-                                 break;
- 
--                        log_warning("Failed to parse /proc/swaps:%u", i);
-+                        log_warning("Failed to parse /proc/swaps:%u.", i);
-                         continue;
-                 }
- 
-                 d = cunescape(dev);
-                 if (!d)
--                        return -ENOMEM;
-+                        return log_oom();
-+
-+                device_found_node(m, d, true, DEVICE_FOUND_SWAP, set_flags);
- 
--                k = swap_process_new_swap(m, d, prio, set_flags);
-+                k = swap_process_new(m, d, prio, set_flags);
-                 if (k < 0)
-                         r = k;
-         }
-@@ -1144,6 +1147,9 @@ static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v
-                                 break;
-                         }
- 
-+                        if (swap->what)
-+                                device_found_node(m, swap->what, false, DEVICE_FOUND_SWAP, true);
-+
-                 } else if (swap->just_activated) {
- 
-                         /* New swap entry */
-@@ -1291,7 +1297,7 @@ fail:
-         return r;
- }
- 
--int swap_process_new_device(Manager *m, struct udev_device *dev) {
-+int swap_process_device_new(Manager *m, struct udev_device *dev) {
-         struct udev_list_entry *item = NULL, *first = NULL;
-         _cleanup_free_ char *e = NULL;
-         const char *dn;
-@@ -1334,7 +1340,7 @@ int swap_process_new_device(Manager *m, struct udev_device *dev) {
-         return r;
- }
- 
--int swap_process_removed_device(Manager *m, struct udev_device *dev) {
-+int swap_process_device_remove(Manager *m, struct udev_device *dev) {
-         const char *dn;
-         int r = 0;
-         Swap *s;
-diff --git a/src/core/swap.h b/src/core/swap.h
-index c36c6f2..5de8c20 100644
---- a/src/core/swap.h
-+++ b/src/core/swap.h
-@@ -115,8 +115,8 @@ struct Swap {
- 
- extern const UnitVTable swap_vtable;
- 
--int swap_process_new_device(Manager *m, struct udev_device *dev);
--int swap_process_removed_device(Manager *m, struct udev_device *dev);
-+int swap_process_device_new(Manager *m, struct udev_device *dev);
-+int swap_process_device_remove(Manager *m, struct udev_device *dev);
- 
- const char* swap_state_to_string(SwapState i) _const_;
- SwapState swap_state_from_string(const char *s) _pure_;
-diff --git a/src/core/unit.c b/src/core/unit.c
-index 63ccd67..7cd7043 100644
---- a/src/core/unit.c
-+++ b/src/core/unit.c
-@@ -2834,7 +2834,6 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
-                 return -ENOMEM;
- 
-         r = manager_load_unit(u->manager, e, NULL, NULL, &device);
--
-         if (r < 0)
-                 return r;
- 
--- 
-2.3.5
-
diff --git a/core/systemd/0001-core-shared-in-deserializing-match-same-files-reache.patch b/core/systemd/0001-core-shared-in-deserializing-match-same-files-reache.patch
deleted file mode 100644
index d2785d322..000000000
--- a/core/systemd/0001-core-shared-in-deserializing-match-same-files-reache.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From c78e47a61fa8d9a21fece01c83e4c26ce0938d27 Mon Sep 17 00:00:00 2001
-From: Michal Schmidt <mschmidt@redhat.com>
-Date: Thu, 19 Feb 2015 23:12:38 +0100
-Subject: [PATCH] core, shared: in deserializing, match same files reached via
- different paths
-
-When dbus.socket is updated like this:
--ListenStream=/var/run/dbus/system_bus_socket
-+ListenStream=/run/dbus/system_bus_socket
-... and daemon-reload is performed, bad things happen.
-During deserialization systemd does not recognize that the two paths
-refer to the same named socket and replaces the socket file with a new
-one. As a result, applications hang when they try talking to dbus.
-
-Fix this by finding a match not only when the path names are equal, but
-also when they point to the same inode.
-In socket_address_equal() it is necessary to move the address size
-comparison into the abstract sockets branch. For path name sockets the
-comparison must not be done and for other families it is redundant
-(their sizes are constant and checked by socket_address_verify()).
-
-FIFOs and special files can also have multiple pathnames, so compare the
-inodes for them as well. Note that previously the pathname checks used
-streq_ptr(), but the paths cannot be NULL.
-
-Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1186018
----
- src/core/socket.c        |  6 +++---
- src/shared/path-util.c   |  4 ++++
- src/shared/path-util.h   |  1 +
- src/shared/socket-util.c | 10 ++++------
- 4 files changed, 12 insertions(+), 9 deletions(-)
-
-diff --git a/src/core/socket.c b/src/core/socket.c
-index 48c43a2..88aae48 100644
---- a/src/core/socket.c
-+++ b/src/core/socket.c
-@@ -2100,7 +2100,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
- 
-                         LIST_FOREACH(port, p, s->ports)
-                                 if (p->type == SOCKET_FIFO &&
--                                    streq_ptr(p->path, value+skip))
-+                                    path_equal_or_files_same(p->path, value+skip))
-                                         break;
- 
-                         if (p) {
-@@ -2119,7 +2119,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
- 
-                         LIST_FOREACH(port, p, s->ports)
-                                 if (p->type == SOCKET_SPECIAL &&
--                                    streq_ptr(p->path, value+skip))
-+                                    path_equal_or_files_same(p->path, value+skip))
-                                         break;
- 
-                         if (p) {
-@@ -2138,7 +2138,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
- 
-                         LIST_FOREACH(port, p, s->ports)
-                                 if (p->type == SOCKET_MQUEUE &&
--                                    streq_ptr(p->path, value+skip))
-+                                    streq(p->path, value+skip))
-                                         break;
- 
-                         if (p) {
-diff --git a/src/shared/path-util.c b/src/shared/path-util.c
-index b9db7f1..70bc1ca 100644
---- a/src/shared/path-util.c
-+++ b/src/shared/path-util.c
-@@ -436,6 +436,10 @@ bool path_equal(const char *a, const char *b) {
-         }
- }
- 
-+bool path_equal_or_files_same(const char *a, const char *b) {
-+        return path_equal(a, b) || files_same(a, b) > 0;
-+}
-+
- char* path_join(const char *root, const char *path, const char *rest) {
-         assert(path);
- 
-diff --git a/src/shared/path-util.h b/src/shared/path-util.h
-index bd0d324..bcf116e 100644
---- a/src/shared/path-util.h
-+++ b/src/shared/path-util.h
-@@ -45,6 +45,7 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r);
- char* path_kill_slashes(char *path);
- char* path_startswith(const char *path, const char *prefix) _pure_;
- bool path_equal(const char *a, const char *b) _pure_;
-+bool path_equal_or_files_same(const char *a, const char *b);
- char* path_join(const char *root, const char *path, const char *rest);
- 
- char** path_strv_make_absolute_cwd(char **l);
-diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
-index c6f6487..c278d6f 100644
---- a/src/shared/socket-util.c
-+++ b/src/shared/socket-util.c
-@@ -325,9 +325,6 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
-         if (a->type != b->type)
-                 return false;
- 
--        if (a->size != b->size)
--                return false;
--
-         if (socket_address_family(a) != socket_address_family(b))
-                 return false;
- 
-@@ -352,14 +349,16 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
-                 break;
- 
-         case AF_UNIX:
--
-                 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
-                         return false;
- 
-                 if (a->sockaddr.un.sun_path[0]) {
--                        if (!strneq(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)))
-+                        if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
-                                 return false;
-                 } else {
-+                        if (a->size != b->size)
-+                                return false;
-+
-                         if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
-                                 return false;
-                 }
-@@ -367,7 +366,6 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
-                 break;
- 
-         case AF_NETLINK:
--
-                 if (a->protocol != b->protocol)
-                         return false;
- 
--- 
-2.3.2
-
diff --git a/core/systemd/0001-nspawn-when-connected-to-pipes-for-stdin-stdout-pass.patch b/core/systemd/0001-nspawn-when-connected-to-pipes-for-stdin-stdout-pass.patch
deleted file mode 100644
index 3e3c9e4c4..000000000
--- a/core/systemd/0001-nspawn-when-connected-to-pipes-for-stdin-stdout-pass.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From 9c857b9d160c10b4454fc9f83442c1878343422f Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Wed, 18 Feb 2015 23:32:55 +0100
-Subject: [PATCH] nspawn: when connected to pipes for stdin/stdout, pass them
- as-is to PID 1
-
-Previously we always invoked the container PID 1 on /dev/console of the
-container. With this change we do so only if nspawn was invoked
-interactively (i.e. its stdin/stdout was connected to a TTY). In all other
-cases we directly pass through the fds unmodified.
-
-This has the benefit that nspawn can be added into shell pipelines.
-
-https://bugs.freedesktop.org/show_bug.cgi?id=87732
----
- src/machine/machinectl.c |  2 +-
- src/nspawn/nspawn.c      | 48 +++++++++++++++++--------------
- src/run/run.c            |  2 +-
- src/shared/ptyfwd.c      | 75 ++++++++++++++++++++++++++++--------------------
- src/shared/ptyfwd.h      |  2 +-
- 5 files changed, 74 insertions(+), 55 deletions(-)
-
-diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
-index 053c8fb..55cd854 100644
---- a/src/machine/machinectl.c
-+++ b/src/machine/machinectl.c
-@@ -1150,7 +1150,7 @@ static int login_machine(int argc, char *argv[], void *userdata) {
-         sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
-         sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
- 
--        r = pty_forward_new(event, master, true, &forward);
-+        r = pty_forward_new(event, master, true, false, &forward);
-         if (r < 0)
-                 return log_error_errno(r, "Failed to create PTY forwarder: %m");
- 
-diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
-index 232629d..c84ed11 100644
---- a/src/nspawn/nspawn.c
-+++ b/src/nspawn/nspawn.c
-@@ -3606,6 +3606,7 @@ int main(int argc, char *argv[]) {
-         int ret = EXIT_SUCCESS;
-         union in_addr_union exposed = {};
-         _cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
-+        bool interactive;
- 
-         log_parse_environment();
-         log_open();
-@@ -3779,6 +3780,8 @@ int main(int argc, char *argv[]) {
-                         goto finish;
-         }
- 
-+        interactive = isatty(STDIN_FILENO) > 0 && isatty(STDOUT_FILENO) > 0;
-+
-         master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
-         if (master < 0) {
-                 r = log_error_errno(errno, "Failed to acquire pseudo tty: %m");
-@@ -3791,15 +3794,15 @@ int main(int argc, char *argv[]) {
-                 goto finish;
-         }
- 
--        if (!arg_quiet)
--                log_info("Spawning container %s on %s.\nPress ^] three times within 1s to kill container.",
--                         arg_machine, arg_image ?: arg_directory);
--
-         if (unlockpt(master) < 0) {
-                 r = log_error_errno(errno, "Failed to unlock tty: %m");
-                 goto finish;
-         }
- 
-+        if (!arg_quiet)
-+                log_info("Spawning container %s on %s.\nPress ^] three times within 1s to kill container.",
-+                         arg_machine, arg_image ?: arg_directory);
-+
-         assert_se(sigemptyset(&mask) == 0);
-         sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1);
-         assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
-@@ -3885,9 +3888,6 @@ int main(int argc, char *argv[]) {
- 
-                         master = safe_close(master);
- 
--                        close_nointr(STDIN_FILENO);
--                        close_nointr(STDOUT_FILENO);
--                        close_nointr(STDERR_FILENO);
- 
-                         kmsg_socket_pair[0] = safe_close(kmsg_socket_pair[0]);
-                         rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]);
-@@ -3895,21 +3895,27 @@ int main(int argc, char *argv[]) {
-                         reset_all_signal_handlers();
-                         reset_signal_mask();
- 
--                        r = open_terminal(console, O_RDWR);
--                        if (r != STDIN_FILENO) {
--                                if (r >= 0) {
--                                        safe_close(r);
--                                        r = -EINVAL;
--                                }
-+                        if (interactive) {
-+                                close_nointr(STDIN_FILENO);
-+                                close_nointr(STDOUT_FILENO);
-+                                close_nointr(STDERR_FILENO);
- 
--                                log_error_errno(r, "Failed to open console: %m");
--                                _exit(EXIT_FAILURE);
--                        }
-+                                r = open_terminal(console, O_RDWR);
-+                                if (r != STDIN_FILENO) {
-+                                        if (r >= 0) {
-+                                                safe_close(r);
-+                                                r = -EINVAL;
-+                                        }
- 
--                        if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
--                            dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) {
--                                log_error_errno(errno, "Failed to duplicate console: %m");
--                                _exit(EXIT_FAILURE);
-+                                        log_error_errno(r, "Failed to open console: %m");
-+                                        _exit(EXIT_FAILURE);
-+                                }
-+
-+                                if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
-+                                    dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) {
-+                                        log_error_errno(errno, "Failed to duplicate console: %m");
-+                                        _exit(EXIT_FAILURE);
-+                                }
-                         }
- 
-                         if (setsid() < 0) {
-@@ -4252,7 +4258,7 @@ int main(int argc, char *argv[]) {
- 
-                                 rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]);
- 
--                                r = pty_forward_new(event, master, true, &forward);
-+                                r = pty_forward_new(event, master, true, !interactive, &forward);
-                                 if (r < 0) {
-                                         log_error_errno(r, "Failed to create PTY forwarder: %m");
-                                         goto finish;
-diff --git a/src/run/run.c b/src/run/run.c
-index 32191a6..3ded2c7 100644
---- a/src/run/run.c
-+++ b/src/run/run.c
-@@ -776,7 +776,7 @@ static int start_transient_service(
-                 if (!arg_quiet)
-                         log_info("Running as unit %s.\nPress ^] three times within 1s to disconnect TTY.", service);
- 
--                r = pty_forward_new(event, master, false, &forward);
-+                r = pty_forward_new(event, master, false, false, &forward);
-                 if (r < 0)
-                         return log_error_errno(r, "Failed to create PTY forwarder: %m");
- 
-diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
-index 31274a1..164c9b6 100644
---- a/src/shared/ptyfwd.c
-+++ b/src/shared/ptyfwd.c
-@@ -42,6 +42,8 @@ struct PTYForward {
-         struct termios saved_stdin_attr;
-         struct termios saved_stdout_attr;
- 
-+        bool read_only:1;
-+
-         bool saved_stdin:1;
-         bool saved_stdout:1;
- 
-@@ -298,7 +300,13 @@ static int on_sigwinch_event(sd_event_source *e, const struct signalfd_siginfo *
-         return 0;
- }
- 
--int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, PTYForward **ret) {
-+int pty_forward_new(
-+                sd_event *event,
-+                int master,
-+                bool ignore_vhangup,
-+                bool read_only,
-+                PTYForward **ret) {
-+
-         _cleanup_(pty_forward_freep) PTYForward *f = NULL;
-         struct winsize ws;
-         int r;
-@@ -307,6 +315,7 @@ int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, PTYForward
-         if (!f)
-                 return -ENOMEM;
- 
-+        f->read_only = read_only;
-         f->ignore_vhangup = ignore_vhangup;
- 
-         if (event)
-@@ -317,13 +326,15 @@ int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, PTYForward
-                         return r;
-         }
- 
--        r = fd_nonblock(STDIN_FILENO, true);
--        if (r < 0)
--                return r;
-+        if (!read_only) {
-+                r = fd_nonblock(STDIN_FILENO, true);
-+                if (r < 0)
-+                        return r;
- 
--        r = fd_nonblock(STDOUT_FILENO, true);
--        if (r < 0)
--                return r;
-+                r = fd_nonblock(STDOUT_FILENO, true);
-+                if (r < 0)
-+                        return r;
-+        }
- 
-         r = fd_nonblock(master, true);
-         if (r < 0)
-@@ -334,36 +345,34 @@ int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, PTYForward
-         if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
-                 (void)ioctl(master, TIOCSWINSZ, &ws);
- 
--        if (tcgetattr(STDIN_FILENO, &f->saved_stdin_attr) >= 0) {
--                struct termios raw_stdin_attr;
--
--                f->saved_stdin = true;
-+        if (!read_only) {
-+                if (tcgetattr(STDIN_FILENO, &f->saved_stdin_attr) >= 0) {
-+                        struct termios raw_stdin_attr;
- 
--                raw_stdin_attr = f->saved_stdin_attr;
--                cfmakeraw(&raw_stdin_attr);
--                raw_stdin_attr.c_oflag = f->saved_stdin_attr.c_oflag;
--                tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin_attr);
--        }
-+                        f->saved_stdin = true;
- 
--        if (tcgetattr(STDOUT_FILENO, &f->saved_stdout_attr) >= 0) {
--                struct termios raw_stdout_attr;
-+                        raw_stdin_attr = f->saved_stdin_attr;
-+                        cfmakeraw(&raw_stdin_attr);
-+                        raw_stdin_attr.c_oflag = f->saved_stdin_attr.c_oflag;
-+                        tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin_attr);
-+                }
- 
--                f->saved_stdout = true;
-+                if (tcgetattr(STDOUT_FILENO, &f->saved_stdout_attr) >= 0) {
-+                        struct termios raw_stdout_attr;
- 
--                raw_stdout_attr = f->saved_stdout_attr;
--                cfmakeraw(&raw_stdout_attr);
--                raw_stdout_attr.c_iflag = f->saved_stdout_attr.c_iflag;
--                raw_stdout_attr.c_lflag = f->saved_stdout_attr.c_lflag;
--                tcsetattr(STDOUT_FILENO, TCSANOW, &raw_stdout_attr);
--        }
-+                        f->saved_stdout = true;
- 
--        r = sd_event_add_io(f->event, &f->master_event_source, master, EPOLLIN|EPOLLOUT|EPOLLET, on_master_event, f);
--        if (r < 0)
--                return r;
-+                        raw_stdout_attr = f->saved_stdout_attr;
-+                        cfmakeraw(&raw_stdout_attr);
-+                        raw_stdout_attr.c_iflag = f->saved_stdout_attr.c_iflag;
-+                        raw_stdout_attr.c_lflag = f->saved_stdout_attr.c_lflag;
-+                        tcsetattr(STDOUT_FILENO, TCSANOW, &raw_stdout_attr);
-+                }
- 
--        r = sd_event_add_io(f->event, &f->stdin_event_source, STDIN_FILENO, EPOLLIN|EPOLLET, on_stdin_event, f);
--        if (r < 0 && r != -EPERM)
--                return r;
-+                r = sd_event_add_io(f->event, &f->stdin_event_source, STDIN_FILENO, EPOLLIN|EPOLLET, on_stdin_event, f);
-+                if (r < 0 && r != -EPERM)
-+                        return r;
-+        }
- 
-         r = sd_event_add_io(f->event, &f->stdout_event_source, STDOUT_FILENO, EPOLLOUT|EPOLLET, on_stdout_event, f);
-         if (r == -EPERM)
-@@ -372,6 +381,10 @@ int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, PTYForward
-         else if (r < 0)
-                 return r;
- 
-+        r = sd_event_add_io(f->event, &f->master_event_source, master, EPOLLIN|EPOLLOUT|EPOLLET, on_master_event, f);
-+        if (r < 0)
-+                return r;
-+
-         r = sd_event_add_signal(f->event, &f->sigwinch_event_source, SIGWINCH, on_sigwinch_event, f);
-         if (r < 0)
-                 return r;
-diff --git a/src/shared/ptyfwd.h b/src/shared/ptyfwd.h
-index d3e229b..6208a54 100644
---- a/src/shared/ptyfwd.h
-+++ b/src/shared/ptyfwd.h
-@@ -30,7 +30,7 @@
- 
- typedef struct PTYForward PTYForward;
- 
--int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, PTYForward **f);
-+int pty_forward_new(sd_event *event, int master, bool ignore_vhangup, bool read_only, PTYForward **f);
- PTYForward *pty_forward_free(PTYForward *f);
- 
- int pty_forward_get_last_char(PTYForward *f, char *ch);
--- 
-2.3.2
-
diff --git a/core/systemd/0001-tmpfiles-Fix-handling-of-duplicate-lines.patch b/core/systemd/0001-tmpfiles-Fix-handling-of-duplicate-lines.patch
deleted file mode 100644
index fdf73f755..000000000
--- a/core/systemd/0001-tmpfiles-Fix-handling-of-duplicate-lines.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 6487ada88d63e4998113f4c57fa10b7c865f8026 Mon Sep 17 00:00:00 2001
-From: Martin Pitt <martin.pitt@ubuntu.com>
-Date: Thu, 5 Mar 2015 14:58:56 +0100
-Subject: [PATCH] tmpfiles: Fix handling of duplicate lines
-
-Commit 3f93da987 accidentally dropped the "return 0" after detection of a
-duplicate line. Put it back, to get back the documented and intended "first
-match wins" behaviour.
-
-https://launchpad.net/bugs/1428540
----
- src/tmpfiles/tmpfiles.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
-index 917bb3c..652fe5f 100644
---- a/src/tmpfiles/tmpfiles.c
-+++ b/src/tmpfiles/tmpfiles.c
-@@ -1746,9 +1746,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
-                 unsigned n;
- 
-                 for (n = 0; n < existing->count; n++) {
--                        if (!item_compatible(existing->items + n, &i))
-+                        if (!item_compatible(existing->items + n, &i)) {
-                                 log_warning("[%s:%u] Duplicate line for path \"%s\", ignoring.",
-                                             fname, line, i.path);
-+                                return 0;
-+                        }
-                 }
-         } else {
-                 existing = new0(ItemArray, 1);
--- 
-2.3.2
-
diff --git a/core/systemd/0001-tmpfiles-avoid-creating-duplicate-acl-entries.patch b/core/systemd/0001-tmpfiles-avoid-creating-duplicate-acl-entries.patch
deleted file mode 100644
index b9af3e7ce..000000000
--- a/core/systemd/0001-tmpfiles-avoid-creating-duplicate-acl-entries.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 1c73f3bc29111a00738569c9d40a989b161a0624 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
-Date: Mon, 23 Feb 2015 23:19:54 -0500
-Subject: [PATCH] tmpfiles: avoid creating duplicate acl entries
-
-https://bugs.freedesktop.org/show_bug.cgi?id=89202
-https://bugs.debian.org/778656
-
-Status quo ante can be restored with:
-  getfacl -p /var/log/journal/`cat /etc/machine-id`|grep -v '^#'|sort -u|sudo setfacl --set-file=- /var/log/journal/`cat /etc/machine-id`
----
- src/shared/acl-util.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++--
- src/shared/acl-util.h |  4 +++
- 2 files changed, 81 insertions(+), 2 deletions(-)
-
-diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c
-index 34707e6..36dc824 100644
---- a/src/shared/acl-util.c
-+++ b/src/shared/acl-util.c
-@@ -281,6 +281,77 @@ int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask)
-         return 0;
- }
- 
-+static int acl_entry_equal(acl_entry_t a, acl_entry_t b) {
-+        acl_tag_t tag_a, tag_b;
-+
-+        if (acl_get_tag_type(a, &tag_a) < 0)
-+                return -errno;
-+
-+        if (acl_get_tag_type(b, &tag_b) < 0)
-+                return -errno;
-+
-+        if (tag_a != tag_b)
-+                return false;
-+
-+        switch (tag_a) {
-+        case ACL_USER_OBJ:
-+        case ACL_GROUP_OBJ:
-+        case ACL_MASK:
-+        case ACL_OTHER:
-+                /* can have only one of those */
-+                return true;
-+        case ACL_USER: {
-+                _cleanup_(acl_free_uid_tpp) uid_t *uid_a, *uid_b;
-+
-+                uid_a = acl_get_qualifier(a);
-+                if (!uid_a)
-+                        return -errno;
-+
-+                uid_b = acl_get_qualifier(b);
-+                if (!uid_b)
-+                        return -errno;
-+
-+                return *uid_a == *uid_b;
-+        }
-+        case ACL_GROUP: {
-+                _cleanup_(acl_free_gid_tpp) gid_t *gid_a, *gid_b;
-+
-+                gid_a = acl_get_qualifier(a);
-+                if (!gid_a)
-+                        return -errno;
-+
-+                gid_b = acl_get_qualifier(b);
-+                if (!gid_b)
-+                        return -errno;
-+
-+                return *gid_a == *gid_b;
-+        }
-+        default:
-+                assert_not_reached("Unknown acl tag type");
-+        }
-+}
-+
-+static int find_acl_entry(acl_t acl, acl_entry_t entry, acl_entry_t *out) {
-+        acl_entry_t i;
-+        int r;
-+
-+        for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
-+             r > 0;
-+             r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
-+
-+                r = acl_entry_equal(i, entry);
-+                if (r < 0)
-+                        return r;
-+                if (r > 0) {
-+                        *out = i;
-+                        return 1;
-+                }
-+        }
-+        if (r < 0)
-+                return -errno;
-+        return 0;
-+}
-+
- int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) {
-         _cleanup_(acl_freep) acl_t old;
-         acl_entry_t i;
-@@ -296,8 +367,12 @@ int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl) {
- 
-                 acl_entry_t j;
- 
--                if (acl_create_entry(&old, &j) < 0)
--                        return -errno;
-+                r = find_acl_entry(old, i, &j);
-+                if (r < 0)
-+                        return r;
-+                if (r == 0)
-+                        if (acl_create_entry(&old, &j) < 0)
-+                                return -errno;
- 
-                 if (acl_copy_entry(j, i) < 0)
-                         return -errno;
-diff --git a/src/shared/acl-util.h b/src/shared/acl-util.h
-index 90e88ff..fdb9006 100644
---- a/src/shared/acl-util.h
-+++ b/src/shared/acl-util.h
-@@ -41,5 +41,9 @@ int acls_for_file(const char *path, acl_type_t type, acl_t new, acl_t *acl);
- DEFINE_TRIVIAL_CLEANUP_FUNC(acl_t, acl_free);
- #define acl_free_charp acl_free
- DEFINE_TRIVIAL_CLEANUP_FUNC(char*, acl_free_charp);
-+#define acl_free_uid_tp acl_free
-+DEFINE_TRIVIAL_CLEANUP_FUNC(uid_t*, acl_free_uid_tp);
-+#define acl_free_gid_tp acl_free
-+DEFINE_TRIVIAL_CLEANUP_FUNC(gid_t*, acl_free_gid_tp);
- 
- #endif
--- 
-2.3.2
-
diff --git a/core/systemd/0001-unit-use-weaker-dependencies-between-mount-and-devic.patch b/core/systemd/0001-unit-use-weaker-dependencies-between-mount-and-devic.patch
deleted file mode 100644
index 1f6f88271..000000000
--- a/core/systemd/0001-unit-use-weaker-dependencies-between-mount-and-devic.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 5bd4b173605142c7be493aa4d958ebaef21f421d Mon Sep 17 00:00:00 2001
-From: Lennart Poettering <lennart@poettering.net>
-Date: Wed, 25 Feb 2015 22:05:14 +0100
-Subject: [PATCH] unit: use weaker dependencies between mount and device units
- in --user mode
-
-When running in user mode unmounting of mount units when a device
-vanishes is unlikely to work, and even if it would work is already done
-by PID 1 anyway. HEnce, when creating implicit dependencies between
-mount units and their backing devices, created a Wants= type dependency
-in --user mode, but leave a BindsTo= dependency in --system mode.
----
- src/core/unit.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/core/unit.c b/src/core/unit.c
-index ad5348b..875befa 100644
---- a/src/core/unit.c
-+++ b/src/core/unit.c
-@@ -2839,7 +2839,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
-         if (r < 0)
-                 return r;
- 
--        r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
-+        r = unit_add_two_dependencies(u, UNIT_AFTER, u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_BINDS_TO : UNIT_WANTS, device, true);
-         if (r < 0)
-                 return r;
- 
--- 
-2.3.5
-
diff --git a/core/systemd/0001-use-x-machine-unix-prefix-for-the-container-bus-on-dbus1.patch b/core/systemd/0001-use-x-machine-unix-prefix-for-the-container-bus-on-dbus1.patch
deleted file mode 100644
index 0c685f6e0..000000000
--- a/core/systemd/0001-use-x-machine-unix-prefix-for-the-container-bus-on-dbus1.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From f2273101c21bc59a390379e182e53cd4f07a7e71 Mon Sep 17 00:00:00 2001
-From: Benjamin Franzke <benjaminfranzke@googlemail.com>
-Date: Thu, 19 Feb 2015 20:47:28 +0100
-Subject: machined: use x-machine-unix prefix for the container bus on dbus1
-
-This fixes "machinectl login" on systems configured with --disable-kdbus.
-
-The error was:
-machinectl login foo
-Failed to get machine PTY: Input/output error
-
-diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
-index 15c9159..9e78a67 100644
---- a/src/machine/machine-dbus.c
-+++ b/src/machine/machine-dbus.c
-@@ -511,7 +511,7 @@ int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *us
- #ifdef ENABLE_KDBUS
-         asprintf(&container_bus->address, "x-machine-kernel:pid=" PID_FMT ";x-machine-unix:pid=" PID_FMT, m->leader, m->leader);
- #else
--        asprintf(&container_bus->address, "x-machine-kernel:pid=" PID_FMT, m->leader);
-+        asprintf(&container_bus->address, "x-machine-unix:pid=" PID_FMT, m->leader);
- #endif
-         if (!container_bus->address)
-                 return log_oom();
--- 
-cgit v0.10.2
-
-
diff --git a/core/systemd/5bac5235934fabe5a3e6a9d47f4812f81034c427.patch b/core/systemd/5bac5235934fabe5a3e6a9d47f4812f81034c427.patch
deleted file mode 100644
index 6b015e8f2..000000000
--- a/core/systemd/5bac5235934fabe5a3e6a9d47f4812f81034c427.patch
+++ /dev/null
@@ -1,282 +0,0 @@
-From 5bac5235934fabe5a3e6a9d47f4812f81034c427 Mon Sep 17 00:00:00 2001
-From: Tom Gundersen <teg@jklm.no>
-Date: Thu, 22 Jan 2015 00:53:16 +0100
-Subject: sd-dhcp-client: use RFC4361-complient ClientID by default
-
-In addition to the benefits listed in the RFC, this allows DHCP to work also in
-case several interfaces share the same MAC address on the same link (IPVLAN).
-
-Note that this will make the ClientID (so probably the assigned IP address)
-change on upgrades. If it is desired to avoid that we would have to remember and
-write back the ID (which the library supports, but networkd currently does not).
-
-diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
-index 65e888a..5f90617 100644
---- a/src/libsystemd-network/sd-dhcp-client.c
-+++ b/src/libsystemd-network/sd-dhcp-client.c
-@@ -36,9 +36,10 @@
- #include "dhcp-protocol.h"
- #include "dhcp-internal.h"
- #include "dhcp-lease-internal.h"
-+#include "dhcp-identifier.h"
- #include "sd-dhcp-client.h"
- 
--#define MAX_CLIENT_ID_LEN 64  /* Arbitrary limit */
-+#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN)  /* Arbitrary limit */
- #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
- 
- struct sd_dhcp_client {
-@@ -60,29 +61,31 @@ struct sd_dhcp_client {
-         uint8_t mac_addr[MAX_MAC_ADDR_LEN];
-         size_t mac_addr_len;
-         uint16_t arp_type;
--        union {
--                struct {
--                        uint8_t type; /* 0: Generic (non-LL) (RFC 2132) */
--                        uint8_t data[MAX_CLIENT_ID_LEN];
--                } _packed_ gen;
--                struct {
--                        uint8_t type; /* 1: Ethernet Link-Layer (RFC 2132) */
--                        uint8_t haddr[ETH_ALEN];
--                } _packed_ eth;
--                struct {
--                        uint8_t type; /* 2 - 254: ARP/Link-Layer (RFC 2132) */
--                        uint8_t haddr[0];
--                } _packed_ ll;
--                struct {
--                        uint8_t type; /* 255: Node-specific (RFC 4361) */
--                        uint8_t iaid[4];
--                        uint8_t duid[MAX_CLIENT_ID_LEN - 4];
--                } _packed_ ns;
--                struct {
--                        uint8_t type;
--                        uint8_t data[MAX_CLIENT_ID_LEN];
--                } _packed_ raw;
--        } client_id;
-+        struct {
-+                uint8_t type;
-+                union {
-+                        struct {
-+                                /* 0: Generic (non-LL) (RFC 2132) */
-+                                uint8_t data[MAX_CLIENT_ID_LEN];
-+                        } _packed_ gen;
-+                        struct {
-+                                /* 1: Ethernet Link-Layer (RFC 2132) */
-+                                uint8_t haddr[ETH_ALEN];
-+                        } _packed_ eth;
-+                        struct {
-+                                /* 2 - 254: ARP/Link-Layer (RFC 2132) */
-+                                uint8_t haddr[0];
-+                        } _packed_ ll;
-+                        struct {
-+                                /* 255: Node-specific (RFC 4361) */
-+                                uint32_t iaid;
-+                                struct duid duid;
-+                        } _packed_ ns;
-+                        struct {
-+                                uint8_t data[MAX_CLIENT_ID_LEN];
-+                        } _packed_ raw;
-+                };
-+        } _packed_ client_id;
-         size_t client_id_len;
-         char *hostname;
-         char *vendor_class_identifier;
-@@ -239,10 +242,9 @@ int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
-         *data = NULL;
-         *data_len = 0;
-         if (client->client_id_len) {
--                *type = client->client_id.raw.type;
-+                *type = client->client_id.type;
-                 *data = client->client_id.raw.data;
--                *data_len = client->client_id_len -
--                        sizeof (client->client_id.raw.type);
-+                *data_len = client->client_id_len - sizeof(client->client_id.type);
-         }
- 
-         return 0;
-@@ -270,8 +272,8 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
-                 break;
-         }
- 
--        if (client->client_id_len == data_len + sizeof (client->client_id.raw.type) &&
--            client->client_id.raw.type == type &&
-+        if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
-+            client->client_id.type == type &&
-             memcmp(&client->client_id.raw.data, data, data_len) == 0)
-                 return 0;
- 
-@@ -282,9 +284,9 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
-                 client_stop(client, DHCP_EVENT_STOP);
-         }
- 
--        client->client_id.raw.type = type;
-+        client->client_id.type = type;
-         memcpy(&client->client_id.raw.data, data, data_len);
--        client->client_id_len = data_len + sizeof (client->client_id.raw.type);
-+        client->client_id_len = data_len + sizeof (client->client_id.type);
- 
-         if (need_restart && client->state != DHCP_STATE_STOPPED)
-                 sd_dhcp_client_start(client);
-@@ -461,12 +463,21 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
-         if (client->arp_type == ARPHRD_ETHER)
-                 memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
- 
--        /* If no client identifier exists, construct one from an ethernet
--           address if present */
--        if (client->client_id_len == 0 && client->arp_type == ARPHRD_ETHER) {
--                client->client_id.eth.type = ARPHRD_ETHER;
--                memcpy(&client->client_id.eth.haddr, &client->mac_addr, ETH_ALEN);
--                client->client_id_len = sizeof (client->client_id.eth);
-+        /* If no client identifier exists, construct an RFC 4361-compliant one */
-+        if (client->client_id_len == 0) {
-+                size_t duid_len;
-+
-+                client->client_id.type = 255;
-+
-+                r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
-+                if (r < 0)
-+                        return r;
-+
-+                r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &duid_len);
-+                if (r < 0)
-+                        return r;
-+
-+                client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len;
-         }
- 
-         /* Some DHCP servers will refuse to issue an DHCP lease if the Client
-@@ -475,7 +486,7 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
-                 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
-                                        DHCP_OPTION_CLIENT_IDENTIFIER,
-                                        client->client_id_len,
--                                       &client->client_id.raw);
-+                                       &client->client_id);
-                 if (r < 0)
-                         return r;
-         }
-@@ -1031,7 +1042,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
- 
-         if (client->client_id_len) {
-                 r = dhcp_lease_set_client_id(lease,
--                                             (uint8_t *) &client->client_id.raw,
-+                                             (uint8_t *) &client->client_id,
-                                              client->client_id_len);
-                 if (r < 0)
-                         return r;
-@@ -1098,7 +1109,7 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
- 
-         if (client->client_id_len) {
-                 r = dhcp_lease_set_client_id(lease,
--                                             (uint8_t *) &client->client_id.raw,
-+                                             (uint8_t *) &client->client_id,
-                                              client->client_id_len);
-                 if (r < 0)
-                         return r;
-diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
-index 0515440..a3d69f3 100644
---- a/src/libsystemd-network/test-dhcp-client.c
-+++ b/src/libsystemd-network/test-dhcp-client.c
-@@ -32,17 +32,16 @@
- #include "sd-event.h"
- #include "event-util.h"
- 
-+#include "dhcp-identifier.h"
- #include "dhcp-protocol.h"
- #include "dhcp-internal.h"
- #include "sd-dhcp-client.h"
- 
--static struct ether_addr mac_addr = {
--        .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
--};
-+static uint8_t mac_addr[] = {'A', 'B', 'C', '1', '2', '3'};
- 
- typedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
- 
--static bool verbose = false;
-+static bool verbose = true;
- static int test_fd[2];
- static test_callback_recv_t callback_recv;
- static be32_t xid;
-@@ -136,10 +135,22 @@ static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
- {
-         switch(code) {
-         case DHCP_OPTION_CLIENT_IDENTIFIER:
--                assert_se(len == 7);
--                assert_se(option[0] == 0x01);
--                assert_se(memcmp(&option[1], &mac_addr, ETH_ALEN) == 0);
-+        {
-+                uint32_t iaid;
-+                struct duid duid;
-+                size_t duid_len;
-+
-+                assert_se(dhcp_identifier_set_duid_en(&duid, &duid_len) >= 0);
-+                assert_se(dhcp_identifier_set_iaid(42, mac_addr, ETH_ALEN, &iaid) >= 0);
-+
-+                assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
-+                assert_se(len == 19);
-+                assert_se(option[0] == 0xff);
-+
-+                assert_se(memcmp(&option[1], &iaid, sizeof(iaid)) == 0);
-+                assert_se(memcmp(&option[5], &duid, duid_len) == 0);
-                 break;
-+        }
- 
-         default:
-                 break;
-@@ -185,8 +196,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
-         assert_se(ip_check == 0xffff);
- 
-         assert_se(discover->dhcp.xid);
--        assert_se(memcmp(discover->dhcp.chaddr,
--                      &mac_addr.ether_addr_octet, 6) == 0);
-+        assert_se(memcmp(discover->dhcp.chaddr, &mac_addr, ETH_ALEN) == 0);
- 
-         size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
- 
-@@ -246,10 +256,7 @@ static void test_discover_message(sd_event *e)
-         assert_se(r >= 0);
- 
-         assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
--        assert_se(sd_dhcp_client_set_mac(client,
--                                         (const uint8_t *) &mac_addr,
--                                         sizeof (mac_addr),
--                                         ARPHRD_ETHER) >= 0);
-+        assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
- 
-         assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
- 
-@@ -404,8 +411,7 @@ static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
- 
-         memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
-         memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
--        memcpy(&test_addr_acq_ack[56], &mac_addr.ether_addr_octet,
--               ETHER_ADDR_LEN);
-+        memcpy(&test_addr_acq_ack[56], &mac_addr, ETHER_ADDR_LEN);
- 
-         callback_recv = NULL;
- 
-@@ -436,8 +442,7 @@ static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover) {
- 
-         memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
-         memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
--        memcpy(&test_addr_acq_offer[56], &mac_addr.ether_addr_octet,
--               ETHER_ADDR_LEN);
-+        memcpy(&test_addr_acq_offer[56], &mac_addr, ETHER_ADDR_LEN);
- 
-         callback_recv = test_addr_acq_recv_request;
- 
-@@ -467,10 +472,7 @@ static void test_addr_acq(sd_event *e) {
-         assert_se(r >= 0);
- 
-         assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
--        assert_se(sd_dhcp_client_set_mac(client,
--                                         (const uint8_t *) &mac_addr,
--                                         sizeof (mac_addr),
--                                         ARPHRD_ETHER) >= 0);
-+        assert_se(sd_dhcp_client_set_mac(client, mac_addr, ETH_ALEN, ARPHRD_ETHER) >= 0);
- 
-         assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
-                 >= 0);
--- 
-cgit v0.10.2
-
diff --git a/core/systemd/PKGBUILD b/core/systemd/PKGBUILD
index cab626d7c..ab5c6fafb 100644
--- a/core/systemd/PKGBUILD
+++ b/core/systemd/PKGBUILD
@@ -3,82 +3,64 @@
 
 # ALARM: Kevin Mihelich <kevin@archlinuxarm.org>
 #  - disable optimization, currently breaks many things
-#  - v5: revert 5bac523 until the issue with it can be figured out
+#  - removed makedepend on gnu-efi-libs, --enable-gnuefi configure option
 
 pkgbase=systemd
 pkgname=('systemd' 'libsystemd' 'systemd-sysvcompat')
-pkgver=219
-pkgrel=6
+pkgver=221
+pkgrel=1
 arch=('i686' 'x86_64')
 url="http://www.freedesktop.org/wiki/Software/systemd"
-makedepends=('acl' 'cryptsetup' 'docbook-xsl' 'gobject-introspection' 'gperf'
-             'gtk-doc' 'intltool' 'iptables' 'kmod' 'libcap' 'libidn' 'libgcrypt'
-             'libmicrohttpd' 'libxslt' 'util-linux' 'linux-api-headers' 'lz4' 'pam'
-             'python' 'python-lxml' 'quota-tools' 'shadow' 'xz')
+makedepends=('acl' 'cryptsetup' 'docbook-xsl' 'gperf' 'lz4' 'xz' 'pam'
+             'intltool' 'iptables' 'kmod' 'libcap' 'libidn' 'libgcrypt'
+             'libmicrohttpd' 'libxslt' 'util-linux' 'linux-api-headers'
+             'python' 'python-lxml' 'quota-tools' 'shadow' 'git')
 options=('strip' 'debug')
-source=("http://www.freedesktop.org/software/$pkgname/$pkgname-$pkgver.tar.xz"
+source=("git://github.com/systemd/systemd.git#tag=v$pkgver"
         'initcpio-hook-udev'
         'initcpio-install-systemd'
         'initcpio-install-udev'
-        '0001-tmpfiles-avoid-creating-duplicate-acl-entries.patch'
-        '0001-nspawn-when-connected-to-pipes-for-stdin-stdout-pass.patch'
-        '0001-core-shared-in-deserializing-match-same-files-reache.patch'
-        '0001-tmpfiles-Fix-handling-of-duplicate-lines.patch'
-        '0001-core-do-not-spawn-jobs-or-touch-other-units-during-c.patch'
-        '0001-use-x-machine-unix-prefix-for-the-container-bus-on-dbus1.patch'
-        '0001-unit-use-weaker-dependencies-between-mount-and-devic.patch'
-        '0001-core-rework-device-state-logic.patch'
-        '0001-core-don-t-change-removed-devices-to-state-tentative.patch'
-        '5bac5235934fabe5a3e6a9d47f4812f81034c427.patch')
-md5sums=('e0d6c9a4b4f69f66932d2230298c9a34'
+        'arch.conf'
+        'loader.conf'
+        'splash-arch.bmp')
+md5sums=('SKIP'
          '90ea67a7bb237502094914622a39e281'
-         '58af51bd4c0464f195b3433b4e17cf6c'
+         '8516a7bd65157d0115c113118c10c3f3'
          'bde43090d4ac0ef048e3eaee8202a407'
-         '7cdefc73bf61934c353e4450e280e551'
-         'cb8550749cd52b5902ed6fdf0eb465ec'
-         '9d46aebfc04cc849fd4295f449b239a2'
-         'c4c9c0f0a06314450563ed571962881e'
-         '6b9d611dffd92c94641360c3ef2659c1'
-         '3a0fc672b34ced18ca1364edf8644165'
-         'cd2719e8e93ad662c00bf9f195fdce66'
-         '12e01f00c91e54680098a799517698f2'
-         'd0aa4e5ec598063eab2e79fb95bceece'
-         'a168ea8a805ee16c1dd1cfe6f5893558')
+         '20ead378f5d6df4b2a3e670301510a7d'
+         'ddaef54f68f6c86c6c07835fc668f62a'
+         '1e2f9a8b0fa32022bf0a8f39123e5f4e')
 
 prepare() {
-  cd "$pkgname-$pkgver"
+  cd "$pkgname"
 
-  patch -Np1 <../0001-tmpfiles-avoid-creating-duplicate-acl-entries.patch
-  patch -Np1 <../0001-nspawn-when-connected-to-pipes-for-stdin-stdout-pass.patch
-  patch -Np1 <../0001-core-shared-in-deserializing-match-same-files-reache.patch
-  patch -Np1 <../0001-tmpfiles-Fix-handling-of-duplicate-lines.patch
-  patch -Np1 <../0001-core-do-not-spawn-jobs-or-touch-other-units-during-c.patch
-  patch -Np1 <../0001-use-x-machine-unix-prefix-for-the-container-bus-on-dbus1.patch
-  patch -Np1 <../0001-unit-use-weaker-dependencies-between-mount-and-devic.patch
-  patch -Np1 <../0001-core-rework-device-state-logic.patch
-  patch -Np1 <../0001-core-don-t-change-removed-devices-to-state-tentative.patch
-  [[ $CARCH == "arm" ]] && patch -Rp1 -i ../5bac5235934fabe5a3e6a9d47f4812f81034c427.patch || true
+  # pam_systemd: Properly check kdbus availability
+  # https://github.com/systemd/systemd/commit/c5d452bb228e
+  git cherry-pick -n c5d452bb228e
+
+  # udevd: suppress warning if we don't find cgroup
+  # https://github.com/systemd/systemd/commit/11b9fb15be96
+  git cherry-pick -n 11b9fb15be96
+
+  ./autogen.sh
 }
 
 build() {
-  cd "$pkgname-$pkgver"
+  cd "$pkgname"
+
+  local timeservers=({0..3}.arch.pool.ntp.org)
 
   CFLAGS=`echo $CFLAGS | sed -e 's/-O2/-O0/'` && CXXFLAGS="$CFLAGS"
   unset CPPFLAGS
 
-  local timeservers=({0..3}.arch.pool.ntp.org)
-
   ./configure \
       --libexecdir=/usr/lib \
       --localstatedir=/var \
       --sysconfdir=/etc \
-      --enable-introspection \
-      --enable-gtk-doc \
       --enable-lz4 \
       --enable-compat-libs \
       --disable-audit \
       --disable-ima \
-      --disable-kdbus \
       --with-sysvinit-path= \
       --with-sysvrcnd-path= \
       --with-ntp-servers="${timeservers[*]}"
@@ -88,7 +70,7 @@ build() {
 
 package_systemd() {
   pkgdesc="system and service manager"
-  license=('GPL2' 'LGPL2.1' 'MIT')
+  license=('GPL2' 'LGPL2.1')
   depends=('acl' 'bash' 'dbus' 'glib2' 'iptables' 'kbd' 'kmod' 'hwids' 'libcap'
            'libgcrypt' 'libsystemd' 'libidn' 'lz4' 'pam' 'libseccomp' 'util-linux'
            'xz')
@@ -123,7 +105,7 @@ package_systemd() {
           etc/udev/udev.conf)
   install="systemd.install"
 
-  make -C "$pkgname-$pkgver" DESTDIR="$pkgdir" install
+  make -C "$pkgname" DESTDIR="$pkgdir" install
 
   # don't write units to /etc by default. some of these will be re-enabled on
   # post_install.
@@ -133,7 +115,7 @@ package_systemd() {
   rm -r "$pkgdir/usr/lib/rpm"
 
   # add back tmpfiles.d/legacy.conf
-  install -m644 "systemd-$pkgver/tmpfiles.d/legacy.conf" "$pkgdir/usr/lib/tmpfiles.d"
+  install -m644 "$pkgname/tmpfiles.d/legacy.conf" "$pkgdir/usr/lib/tmpfiles.d"
 
   # Replace dialout/tape/cdrom group in rules with uucp/storage/optical group
   sed -i 's#GROUP="dialout"#GROUP="uucp"#g;
@@ -171,18 +153,19 @@ package_systemd() {
   rm -rf "$srcdir/_libsystemd"
   install -dm755 "$srcdir"/_libsystemd/usr/lib
   cd "$srcdir"/_libsystemd
-  mv "$pkgdir"/usr/lib/lib{systemd,{g,}udev}*.so* usr/lib
+  mv "$pkgdir"/usr/lib/lib{systemd,udev}*.so* usr/lib
 
-  # include MIT license, since it's technically custom
-  install -Dm644 "$srcdir/$pkgname-$pkgver/LICENSE.MIT" \
-      "$pkgdir/usr/share/licenses/systemd/LICENSE.MIT"
+  # add example bootctl configuration
+  install -Dm644 "$srcdir/arch.conf" "$pkgdir"/usr/share/systemd/bootctl/arch.conf
+  install -Dm644 "$srcdir/loader.conf" "$pkgdir"/usr/share/systemd/bootctl/loader.conf
+  install -Dm644 "$srcdir/splash-arch.bmp" "$pkgdir"/usr/share/systemd/bootctl/splash-arch.bmp
 }
 
 package_libsystemd() {
   pkgdesc="systemd client libraries"
   depends=('glib2' 'glibc' 'libgcrypt' 'lz4' 'xz')
   license=('GPL2')
-  provides=('libgudev-1.0.so' 'libsystemd.so' 'libsystemd-daemon.so' 'libsystemd-id128.so'
+  provides=('libsystemd.so' 'libsystemd-daemon.so' 'libsystemd-id128.so'
             'libsystemd-journal.so' 'libsystemd-login.so' 'libudev.so')
 
   mv "$srcdir/_libsystemd"/* "$pkgdir"
diff --git a/core/systemd/arch.conf b/core/systemd/arch.conf
new file mode 100644
index 000000000..250b7785e
--- /dev/null
+++ b/core/systemd/arch.conf
@@ -0,0 +1,7 @@
+## This is just an example config file.
+## Please edit the paths and kernel parameters according to your system.
+
+title   Arch Linux
+linux   /vmlinuz-linux
+initrd  /initramfs-linux.img
+options root=PARTUUID=XXXX rootfstype=XXXX add_efi_memmap
diff --git a/core/systemd/initcpio-install-systemd b/core/systemd/initcpio-install-systemd
index 25e628305..acd8a226d 100644
--- a/core/systemd/initcpio-install-systemd
+++ b/core/systemd/initcpio-install-systemd
@@ -34,6 +34,7 @@ add_udev_rule() {
                     strip_quotes 'value'
                     # just take the first word as the binary name
                     binary=${value%% *}
+                    [[ ${binary:0:1} == '$' ]] && continue
                     if [[ ${binary:0:1} != '/' ]]; then
                         binary=$(PATH=/usr/lib/udev:/lib/udev type -P "$binary")
                     fi
diff --git a/core/systemd/loader.conf b/core/systemd/loader.conf
new file mode 100644
index 000000000..1f7cd7ef4
--- /dev/null
+++ b/core/systemd/loader.conf
@@ -0,0 +1 @@
+default arch
diff --git a/core/systemd/splash-arch.bmp b/core/systemd/splash-arch.bmp
new file mode 100755
index 000000000..f083d4bbf
Binary files /dev/null and b/core/systemd/splash-arch.bmp differ