[systemd/f16] Fixes and low-risk enhancements (no journald) from upstream v38.

Michal Schmidt michich at fedoraproject.org
Wed Jan 11 11:41:30 UTC 2012


commit e43452dfe678264ac81c087d2a8735c973f99686
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Jan 11 12:22:35 2012 +0100

    Fixes and low-risk enhancements (no journald) from upstream v38.

 ...mplementing-of-requirement-deps-with-Afte.patch |   33 -
 ...operly-detect-what-the-last-capability-is.patch |  122 ++
 0002-manager-fix-a-crash-in-isolating.patch        |    7 +-
 ...dit-do-not-complain-if-kernel-lacks-audit.patch |   56 +
 ...l-completion-always-invoke-with-no-legend.patch |    7 +-
 ...ake-list-unit-files-output-more-economica.patch |   80 +
 0006-plymouth-fix-ply-proto-endianess-issues.patch |   31 +
 ...-seed-convert-poolsize-from-bits-to-bytes.patch |   37 +
 ...ix-file-descriptor-leak-in-test_capabilit.patch |   28 +
 ...-t-use-dbus-connection-after-PID-1-got-re.patch |   55 +
 ...ys-recreate-cgroup-before-we-try-to-apply.patch |   33 +
 ...-remote-mounts-after-both-network.target-.patch |    9 +-
 ...Install-section-from-remote-fs-pre.target.patch |    8 +-
 ...up-generator-avoid-ordering-cycle-on-swap.patch |   40 +
 ...etion-update-with-new-verbs-and-arguments.patch |  153 ++
 ...tion-add-completions-for-systemd-loginctl.patch |  107 ++
 ...tion-rename-file-since-it-is-no-longer-fo.patch |  571 ++++++++
 ...reak-timestamp-formatting-out-into-a-sepe.patch |   60 +
 ...systemadm-allow-sorting-of-jobs-and-units.patch |   76 +
 ...plit-the-type-status-combo-box-into-type-.patch |  112 ++
 ...madm-filter-on-swaps-paths-and-timers-too.patch |   66 +
 ...dd-a-wrappable-label-and-use-it-for-statu.patch |  133 ++
 ...dd-libgee-as-dependency-and-use-it-for-a-.patch |  101 ++
 0023-systemadm-display-dependencies-sorted.patch   |   38 +
 ...-systemadm-use-color-for-dependency-links.patch |   53 +
 0025-systemadm-use-bold-for-requires-etc.patch     |   27 +
 ...dm-make-the-dependency-listing-selectable.patch |   27 +
 ...temadm-catch-exceptions-generated-by-dbus.patch |  146 ++
 ...stemadm-coalesce-id-and-decription-fields.patch |   83 ++
 ...adjust-row-numbers-after-removing-aliases.patch |   75 +
 ...se-colors-for-id-too-remove-color-from-fr.patch |   77 +
 ...diately-remove-all-cgroups-which-run-empt.patch |   56 +
 0032-utmp-remove-unneded-parameters.patch          |  137 ++
 ...d-to-zero-a-struct-before-overwriting-it-.patch |   27 +
 ...lize-store-with-the-found-entry-not-with-.patch |   27 +
 ...AD_PROCESS-write-the-current-time-to-wtmp.patch |   72 +
 0036-man-fix-a-typo-in-signal-number.patch         |   26 +
 ...ts-drop-unnecessary-StandardOutput-syslog.patch |   79 +
 ...fedora-let-rc-local.service-log-to-syslog.patch |   28 +
 ...-t-warn-if-the-pidfile-still-exists-after.patch |   61 +
 0040-job-colored-status-messages-on-boot.patch     |  132 ++
 0041-man-fix-typo-in-sd_notify.patch               |   27 +
 0042-Fix-same-expression-on-both-sides-of.patch    |   32 +
 0043-execute-avoid-logging-to-closed-fds.patch     |   61 +
 ...make-setup_pam-return-errno-when-possible.patch |   49 +
 0045-execute-log-errors-from-sd-EXEC.patch         |  478 ++++++
 ...-use-the-correct-session-type-unspecified.patch |   28 +
 ...module-treat-cron-in-PAM_TTY-as-empty-tty.patch |   55 +
 ...nd-swap-units-log-to-the-configured-defau.patch |   56 +
 0049-socket-add-option-for-SO_PASSCRED.patch       |   94 ++
 ...downd-use-PassCred-yes-in-the-socket-unit.patch |   58 +
 ...g-use-PassCred-yes-for-the-dev-log-socket.patch |   52 +
 0052-man-document-the-PassCred-option.patch        |   36 +
 ...d-a-generator-to-pull-rc-local.service-in.patch |  250 ++++
 ...-need-to-check-if-the-script-is-executabl.patch |   41 +
 0055-rc-local-order-after-network.target.patch     |   42 +
 0056-util-fix-error-checking-after-fgets.patch     |   54 +
 0057-path-use-m-instead-of-strerror-errno.patch    |   36 +
 0058-path-refactor-PathSpec-usage.patch            |  507 +++++++
 ...th-add-PathModified-PathChanged-IN_MODIFY.patch |   90 ++
 ...dle-services-with-racy-daemonization-grac.patch |  330 +++++
 ...p-the-service-if-ExecStartPost-ends-with-.patch |   60 +
 0062-Allow-list-unit-files-to-run-with-root.patch  |   63 +
 ...nit-garbage-collect-units-with-load-error.patch |   30 +
 0064-systemctl-print-error-load-state-in-red.patch |   41 +
 ...sat-not-an-ampersand-let-s-call-it-at-sym.patch |   27 +
 ...-path-add-missing-pieces-for-PathModified.patch |   52 +
 ...false-positive-in-check-for-unneeded-unit.patch |   55 +
 ...for-unneeded-dependencies-even-when-unit-.patch |   48 +
 ...m-module-add-a-couple-of-debugging-prints.patch |   42 +
 0070-fsck-Fix-typo-in-comment.patch                |   26 +
 0071-systemctl-fix-typo-in-is-enabled.patch        |   27 +
 ...e-an-enum-instead-of-plain-char-for-item-.patch |   75 +
 0073-tmpfiles-rename-a-couple-of-functions.patch   |   55 +
 ...e-a-common-function-to-set-owner-group-mo.patch |  211 +++
 ...parate-a-generic-item-glob-processing-fun.patch |  102 ++
 0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch   |  195 +++
 0077-man-document-Z-in-tmpfiles.patch              |   49 +
 0078-man-mention-that-Z-ignores-uid-gid-mode.patch |   36 +
 ...rvice-use-syslog-console-for-sysv_console.patch |   28 +
 ...files-apply-chown-chmod-for-Z-entries-too.patch |  194 +++
 0081-tmpfiles-add-z-like-Z-but-not-recursive.patch |  150 ++
 ...isplaced-remark-in-description-of-Sockets.patch |   32 +
 0083-execute-fix-losing-of-start-timestamps.patch  |   29 +
 0084-label-fix-labeling-of-symbolic-links.patch    |   27 +
 0085-dbus-register-to-DBus-asynchronously.patch    |  563 ++++++++
 0086-dbus-no-sync-D-Bus-connection-flushing.patch  |   29 +
 0087-log-never-block-on-syslog-in-PID-1.patch      |   77 +
 0088-macro-fix-ALIGN_TO-macro-definition.patch     |   27 +
 0089-man-document-the-sd-login-interfaces.patch    |  960 +++++++++++++
 ...ix-include-lines-since-we-now-ship-a-shar.patch |   83 ++
 0091-man-build-new-man-pages.patch                 |   30 +
 ...ahead-is-not-actually-available-in-libsys.patch |   61 +
 ...-build-sys-add-rules-for-man-page-aliases.patch |   41 +
 0094-man-add-sd-login-7-page.patch                 |  226 +++
 0095-man-various-updates.patch                     |  162 +++
 ...sd-login-7-in-regards-to-mixing-D-Bus-and.patch |   44 +
 ...e-HTML-instead-of-XHTML-with-XSL-docbook-.patch |   32 +
 ...to-UTF-8-output-to-work-around-charset-is.patch |   88 ++
 ...e-loopback-device-from-udev-rule-based-sy.patch |   28 +
 ...ount-api-vfs-handle-another-OOM-condition.patch |   75 +
 ...me-the-PassCred-option-to-PassCredentials.patch |  129 ++
 ...-add-dependency-on-kmsg-socket-to-socket-.patch |   49 +
 ...ring-export-definition-of-sd-readahead-in.patch |   75 +
 ...t-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch |   55 +
 ...emount-namespace-root-dir-for-SLAVE-to-av.patch |   35 +
 ...e-can-t-open-dev-tty0-assume-there-is-no-.patch |  200 +++
 0107-logind-don-t-watch-vcsa-if-nobody-cares.patch |   46 +
 0108-man-fix-SEE-ALSO-in-hostname-5.patch          |   27 +
 ...-logind-send-out-Lock-signal-when-locking.patch |   30 +
 0110-logind-add-needed-include-for-sd_notify.patch |   26 +
 ...compilation-error-with-PathSpec-redefined.patch |   35 +
 ...rinting-status-updates-during-boot-take-t.patch |  219 +++
 0113-log-minor-optimization.patch                  |   48 +
 0114-util-never-ellipsize-welcome-message.patch    |  146 ++
 0115-headers-fix-git-URLs-for-source-files.patch   |  160 ++
 0116-README-correct-license-claims.patch           |   27 +
 ...til-fix-switching-to-console-unicode-mode.patch |   36 +
 ...-switch-the-console-to-text-mode-on-reset.patch |   30 +
 ...ce-add-dependencies-on-configured-sockets.patch |   54 +
 ...ly-update-references-to-units-which-are-m.patch | 1515 ++++++++++++++++++++
 0121-main-fix-spelling.patch                       |   87 ++
 ...ad-fragment-fix-parsing-of-Socket-setting.patch |   43 +
 0123-fix-compiler-warning.patch                    |   25 +
 ...clude-processes-with-argv-0-0-from-killin.patch |  176 +++
 ...down-add-link-to-root-storage-daemon-text.patch |   29 +
 ...ent-new-PropagateReloadTo-PropagateReload.patch |  161 +++
 systemd-37-bug744415.patch                         |   11 -
 systemd.spec                                       |  163 ++-
 129 files changed, 13213 insertions(+), 76 deletions(-)
---
diff --git a/0001-util-properly-detect-what-the-last-capability-is.patch b/0001-util-properly-detect-what-the-last-capability-is.patch
new file mode 100644
index 0000000..12108c1
--- /dev/null
+++ b/0001-util-properly-detect-what-the-last-capability-is.patch
@@ -0,0 +1,122 @@
+From 3ad4e947bb0312940d56059328dd518d01718f6f Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 11 Oct 2011 22:30:31 +0200
+Subject: [PATCH 001/126] util: properly detect what the last capability is
+ (cherry picked from commit
+ 64685e0cea62b4937f0804e47ce2cb7929f58223)
+
+---
+ src/execute.c |    7 ++-----
+ src/nspawn.c  |    8 +-------
+ src/util.c    |   33 +++++++++++++++++++++++++++++++++
+ src/util.h    |    2 ++
+ 4 files changed, 38 insertions(+), 12 deletions(-)
+
+diff --git a/src/execute.c b/src/execute.c
+index 53e7e77..866e8bf 100644
+--- a/src/execute.c
++++ b/src/execute.c
+@@ -895,12 +895,9 @@ static int do_capability_bounding_set_drop(uint64_t drop) {
+                 }
+         }
+ 
+-        for (i = 0; i <= MAX(63LU, (unsigned long) CAP_LAST_CAP); i++)
++        for (i = 0; i <= cap_last_cap(); i++)
+                 if (drop & ((uint64_t) 1ULL << (uint64_t) i)) {
+                         if (prctl(PR_CAPBSET_DROP, i) < 0) {
+-                                if (errno == EINVAL)
+-                                        break;
+-
+                                 r = -errno;
+                                 goto finish;
+                         }
+@@ -1720,7 +1717,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
+                 unsigned long l;
+                 fprintf(f, "%sCapabilityBoundingSet:", prefix);
+ 
+-                for (l = 0; l <= (unsigned long) CAP_LAST_CAP; l++)
++                for (l = 0; l <= cap_last_cap(); l++)
+                         if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
+                                 char *t;
+ 
+diff --git a/src/nspawn.c b/src/nspawn.c
+index 8441c05..653d7db 100644
+--- a/src/nspawn.c
++++ b/src/nspawn.c
+@@ -361,7 +361,7 @@ static int drop_capabilities(void) {
+ 
+         unsigned long l;
+ 
+-        for (l = 0; l <= MAX(63LU, (unsigned long) CAP_LAST_CAP); l++) {
++        for (l = 0; l <= cap_last_cap(); l++) {
+                 unsigned i;
+ 
+                 for (i = 0; i < ELEMENTSOF(retain); i++)
+@@ -372,12 +372,6 @@ static int drop_capabilities(void) {
+                         continue;
+ 
+                 if (prctl(PR_CAPBSET_DROP, l) < 0) {
+-
+-                        /* If this capability is not known, EINVAL
+-                         * will be returned, let's ignore this. */
+-                        if (errno == EINVAL)
+-                                break;
+-
+                         log_error("PR_CAPBSET_DROP failed: %m");
+                         return -errno;
+                 }
+diff --git a/src/util.c b/src/util.c
+index e46606d..e93e6f6 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -5703,3 +5703,36 @@ int strdup_or_null(const char *a, char **b) {
+         *b = c;
+         return 0;
+ }
++
++unsigned long cap_last_cap(void) {
++        static __thread unsigned long saved;
++        static __thread bool valid = false;
++        unsigned long p;
++
++        if (valid)
++                return saved;
++
++        p = (unsigned long) CAP_LAST_CAP;
++
++        if (prctl(PR_CAPBSET_READ, p) < 0) {
++
++                /* Hmm, look downwards, until we find one that
++                 * works */
++                for (p--; p > 0; p --)
++                        if (prctl(PR_CAPBSET_READ, p) >= 0)
++                                break;
++
++        } else {
++
++                /* Hmm, look upwards, until we find one that doesn't
++                 * work */
++                for (;; p++)
++                        if (prctl(PR_CAPBSET_READ, p+1) < 0)
++                                break;
++        }
++
++        saved = p;
++        valid = true;
++
++        return p;
++}
+diff --git a/src/util.h b/src/util.h
+index ccbe8a3..a71a297 100644
+--- a/src/util.h
++++ b/src/util.h
+@@ -506,4 +506,6 @@ extern char **saved_argv;
+ 
+ bool kexec_loaded(void);
+ 
++unsigned long cap_last_cap(void);
++
+ #endif
+-- 
+1.7.7.5
+
diff --git a/0002-manager-fix-a-crash-in-isolating.patch b/0002-manager-fix-a-crash-in-isolating.patch
index b9697c7..eb76574 100644
--- a/0002-manager-fix-a-crash-in-isolating.patch
+++ b/0002-manager-fix-a-crash-in-isolating.patch
@@ -1,7 +1,7 @@
-From 563ba9ea6e60774086555998b957edf923e24b46 Mon Sep 17 00:00:00 2001
+From b93ae6c00edfe8ef2f0fd70177dee1d111598fe0 Mon Sep 17 00:00:00 2001
 From: Michal Schmidt <mschmidt at redhat.com>
 Date: Mon, 17 Oct 2011 11:12:12 +0200
-Subject: [PATCH 2/5] manager: fix a crash in isolating
+Subject: [PATCH 002/126] manager: fix a crash in isolating
 
 HASHMAP_FOREACH is safe against the removal of the current entry, but
 not against the removal of other entries. job_finish_and_invalidate()
@@ -17,6 +17,7 @@ possibility that the iterator could be invalid.
 It is O(n^2) in the worst case, but that's better than a crash.
 
 https://bugzilla.redhat.com/show_bug.cgi?id=717325
+(cherry picked from commit 563ba9ea6e60774086555998b957edf923e24b46)
 ---
  src/job.c     |   19 ++++++++++++++-----
  src/manager.c |    7 ++++++-
@@ -113,5 +114,5 @@ index e626347..6d20258 100644
          }
  
 -- 
-1.7.4.4
+1.7.7.5
 
diff --git a/0003-audit-do-not-complain-if-kernel-lacks-audit.patch b/0003-audit-do-not-complain-if-kernel-lacks-audit.patch
new file mode 100644
index 0000000..74ae8c7
--- /dev/null
+++ b/0003-audit-do-not-complain-if-kernel-lacks-audit.patch
@@ -0,0 +1,56 @@
+From 1d0ba48a582be7b9a539cbb5cbf6bbdf5f7b08e1 Mon Sep 17 00:00:00 2001
+From: Jonathan Nieder <jrnieder at gmail.com>
+Date: Mon, 17 Oct 2011 21:01:40 +0200
+Subject: [PATCH 003/126] audit: do not complain if kernel lacks audit
+
+When running on a kernel without audit support, systemd currently
+writes a mysterious-sounding error to its log:
+
+	systemd[1]: Failed to connect to audit log: Protocol not supported
+
+Better to suppress the audit_open() failure message when (and only
+when) it is due to running on a kernel without audit support, since in
+this case the admin probably does not mind systemd not writing to the
+audit log.  This way, more serious errors like ENOMEM and EACCES will
+stand out more.
+(cherry picked from commit 5a8d081c58f7b83172ad5031a8fdac0c33072b2a)
+---
+ src/manager.c     |    5 ++++-
+ src/update-utmp.c |    5 ++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/src/manager.c b/src/manager.c
+index 6d20258..111167a 100644
+--- a/src/manager.c
++++ b/src/manager.c
+@@ -286,7 +286,10 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) {
+                 goto fail;
+ 
+ #ifdef HAVE_AUDIT
+-        if ((m->audit_fd = audit_open()) < 0)
++        if ((m->audit_fd = audit_open()) < 0 &&
++            /* If the kernel lacks netlink or audit support,
++             * don't worry about it. */
++            errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
+                 log_error("Failed to connect to audit log: %m");
+ #endif
+ 
+diff --git a/src/update-utmp.c b/src/update-utmp.c
+index f81e7f4..12e4d11 100644
+--- a/src/update-utmp.c
++++ b/src/update-utmp.c
+@@ -376,7 +376,10 @@ int main(int argc, char *argv[]) {
+         umask(0022);
+ 
+ #ifdef HAVE_AUDIT
+-        if ((c.audit_fd = audit_open()) < 0)
++        if ((c.audit_fd = audit_open()) < 0 &&
++            /* If the kernel lacks netlink or audit support,
++             * don't worry about it. */
++            errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
+                 log_error("Failed to connect to audit log: %m");
+ #endif
+ 
+-- 
+1.7.7.5
+
diff --git a/0005-systemctl-completion-always-invoke-with-no-legend.patch b/0004-systemctl-completion-always-invoke-with-no-legend.patch
similarity index 93%
rename from 0005-systemctl-completion-always-invoke-with-no-legend.patch
rename to 0004-systemctl-completion-always-invoke-with-no-legend.patch
index a085836..7b82fe4 100644
--- a/0005-systemctl-completion-always-invoke-with-no-legend.patch
+++ b/0004-systemctl-completion-always-invoke-with-no-legend.patch
@@ -1,7 +1,7 @@
-From 74eeab044e506a39786f484b160d9f64d48ad243 Mon Sep 17 00:00:00 2001
+From fb4f5f218e83eb1496f2fdfa67b27e458b2bd6a4 Mon Sep 17 00:00:00 2001
 From: Dave Reisner <d at falconindy.com>
 Date: Tue, 11 Oct 2011 20:56:53 -0400
-Subject: [PATCH 5/5] systemctl-completion: always invoke with --no-legend
+Subject: [PATCH 004/126] systemctl-completion: always invoke with --no-legend
 
 In the case of completion for the 'restart' verb, passing the invalid
 unit name (the colums header) causes completion to cease functioning
@@ -11,6 +11,7 @@ entirely, with the error:
 
 This adds a small wrapper function for systemctl which can have common
 options added to it.
+(cherry picked from commit 74eeab044e506a39786f484b160d9f64d48ad243)
 ---
  src/systemctl-bash-completion.sh |   20 ++++++++++++--------
  1 files changed, 12 insertions(+), 8 deletions(-)
@@ -72,5 +73,5 @@ index 6369a6c..6ebb792 100644
          fi
  
 -- 
-1.7.4.4
+1.7.7.5
 
diff --git a/0005-systemctl-make-list-unit-files-output-more-economica.patch b/0005-systemctl-make-list-unit-files-output-more-economica.patch
new file mode 100644
index 0000000..d8b83a3
--- /dev/null
+++ b/0005-systemctl-make-list-unit-files-output-more-economica.patch
@@ -0,0 +1,80 @@
+From 62403a219c01f907e69012e502a73cdb9aeeb251 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Mon, 24 Oct 2011 11:49:59 +0200
+Subject: [PATCH 005/126] systemctl: make list-unit-files output more
+ economical
+
+The first column is given the width of the widest entry,
+if possible, otherwise all entries are ellipsized to fit
+in ($COLUMNS - (width of second column)).
+
+[ Added a few fixes, calculate state_cols too, respect '--no-legend',
+  better handling of '--full' -- michich ]
+(cherry picked from commit 1c0a113fd3fe3344b2c947ca9948760057052716)
+---
+ src/systemctl.c |   35 +++++++++++++++++++++++++++--------
+ 1 files changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/src/systemctl.c b/src/systemctl.c
+index 0de2444..b0baf8d 100644
+--- a/src/systemctl.c
++++ b/src/systemctl.c
+@@ -551,11 +551,30 @@ static bool output_show_unit_file(const UnitFileList *u) {
+ }
+ 
+ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
+-        unsigned n_shown = 0;
++        unsigned max_id_len, id_cols, state_cols, n_shown = 0;
+         const UnitFileList *u;
+ 
+-        if (on_tty())
+-                printf("%-25s %-6s\n", "UNIT FILE", "STATE");
++        max_id_len = sizeof("UNIT FILE")-1;
++        state_cols = sizeof("STATE")-1;
++        for (u = units; u < units + c; u++) {
++                if (!output_show_unit_file(u))
++                        continue;
++
++                max_id_len = MAX(max_id_len, strlen(file_name_from_path(u->path)));
++                state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
++        }
++
++        if (!arg_full) {
++                unsigned basic_cols;
++                id_cols = MIN(max_id_len, 25);
++                basic_cols = 1 + id_cols + state_cols;
++                if (basic_cols < (unsigned) columns())
++                        id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
++        } else
++                id_cols = max_id_len;
++
++        if (!arg_no_legend)
++                printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
+ 
+         for (u = units; u < units + c; u++) {
+                 char *e;
+@@ -580,16 +599,16 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
+ 
+                 id = file_name_from_path(u->path);
+ 
+-                e = arg_full ? NULL : ellipsize(id, 25, 33);
++                e = arg_full ? NULL : ellipsize(id, id_cols, 33);
+ 
+-                printf("%-25s %s%-6s%s\n",
+-                       e ? e : id,
+-                       on, unit_file_state_to_string(u->state), off);
++                printf("%-*s %s%-*s%s\n",
++                       id_cols, e ? e : id,
++                       on, state_cols, unit_file_state_to_string(u->state), off);
+ 
+                 free(e);
+         }
+ 
+-        if (on_tty())
++        if (!arg_no_legend)
+                 printf("\n%u unit files listed.\n", n_shown);
+ }
+ 
+-- 
+1.7.7.5
+
diff --git a/0006-plymouth-fix-ply-proto-endianess-issues.patch b/0006-plymouth-fix-ply-proto-endianess-issues.patch
new file mode 100644
index 0000000..32348b0
--- /dev/null
+++ b/0006-plymouth-fix-ply-proto-endianess-issues.patch
@@ -0,0 +1,31 @@
+From 4cff61c8150be456da22cc737696fad925c1393f Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 1 Nov 2011 14:20:31 +0100
+Subject: [PATCH 006/126] plymouth: fix ply proto endianess issues
+
+Plymouth enforces LE even for the local Ply proto, hence we should do
+the conversion properly for BE arch compat.
+
+Tracked down by Harald Hoyer.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=744415
+(cherry picked from commit bb53abeb8c3407ea250be69bc43510b03c0df3da)
+---
+ src/tty-ask-password-agent.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c
+index 43d008f..13481b2 100644
+--- a/src/tty-ask-password-agent.c
++++ b/src/tty-ask-password-agent.c
+@@ -206,6 +206,7 @@ static int ask_password_plymouth(
+                                 continue;
+ 
+                         memcpy(&size, buffer+1, sizeof(size));
++                        size = le32toh(size);
+                         if (size+5 > sizeof(buffer)) {
+                                 r = -EIO;
+                                 goto finish;
+-- 
+1.7.7.5
+
diff --git a/0007-random-seed-convert-poolsize-from-bits-to-bytes.patch b/0007-random-seed-convert-poolsize-from-bits-to-bytes.patch
new file mode 100644
index 0000000..4212e93
--- /dev/null
+++ b/0007-random-seed-convert-poolsize-from-bits-to-bytes.patch
@@ -0,0 +1,37 @@
+From fb47a8a6bc8903d8b4b7b71707baa2c7585a0407 Mon Sep 17 00:00:00 2001
+From: Tom Gundersen <teg at jklm.no>
+Date: Sat, 22 Oct 2011 18:47:08 +0200
+Subject: [PATCH 007/126] random-seed: convert poolsize from bits to bytes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The problem was first noted in a bug report against Arch's initscripts.
+
+Reported-by: Taylan Ulrich Bayırlı <taylanbayirli at gmail.com>
+Reported-by: Gerardo Exequiel Pozzi <vmlinuz386 at yahoo.com.ar>
+(cherry picked from commit 7c2ec00930ce1f4aabfbb405d84b67eb9d065ef0)
+---
+ src/random-seed.c |    6 +++++-
+ 1 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/src/random-seed.c b/src/random-seed.c
+index ee5cae3..0c63794 100644
+--- a/src/random-seed.c
++++ b/src/random-seed.c
+@@ -51,7 +51,11 @@ int main(int argc, char *argv[]) {
+ 
+         /* Read pool size, if possible */
+         if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) {
+-                fscanf(f, "%zu", &buf_size);
++                if (fscanf(f, "%zu", &buf_size) > 0) {
++                        /* poolsize is in bits on 2.6, but we want bytes */
++                        buf_size /= 8;
++                }
++
+                 fclose(f);
+         }
+ 
+-- 
+1.7.7.5
+
diff --git a/0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch b/0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch
new file mode 100644
index 0000000..b158ab1
--- /dev/null
+++ b/0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch
@@ -0,0 +1,28 @@
+From 62f4ee1b584845c8a3d4caf41c572ec5e7d7af66 Mon Sep 17 00:00:00 2001
+From: Thomas Jarosch <thomas.jarosch at intra2net.com>
+Date: Wed, 26 Oct 2011 09:38:39 +0200
+Subject: [PATCH 008/126] condition: Fix file descriptor leak in
+ test_capability()
+
+Detected by cppcheck.
+(cherry picked from commit 7670e5a2aab543bc6b442ab0683411770e06fe26)
+---
+ src/condition.c |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/src/condition.c b/src/condition.c
+index f18c454..2b51a16 100644
+--- a/src/condition.c
++++ b/src/condition.c
+@@ -187,6 +187,8 @@ static bool test_capability(const char *parameter) {
+                 }
+         }
+ 
++        fclose(f);
++
+         return !!(capabilities & (1ULL << value));
+ }
+ 
+-- 
+1.7.7.5
+
diff --git a/0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch b/0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch
new file mode 100644
index 0000000..08da8c6
--- /dev/null
+++ b/0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch
@@ -0,0 +1,55 @@
+From 3e750716de6acad59112a34d3d79f50da680d023 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 1 Nov 2011 18:18:17 +0100
+Subject: [PATCH 009/126] initctl: don't use dbus connection after PID 1 got
+ respawned
+
+After reexec PID 1 our bus connection is invalidated. Hence don't try to
+reuse it, just terminate so that when we are spawned the next time we
+just get a new one.
+
+Spotted by Marti Raudsepp.
+(cherry picked from commit f632a6634dd4eff041425aa9b3fb48ccfa98c014)
+---
+ src/initctl.c |   11 ++++++++++-
+ 1 files changed, 10 insertions(+), 1 deletions(-)
+
+diff --git a/src/initctl.c b/src/initctl.c
+index eaa717a..097c85f 100644
+--- a/src/initctl.c
++++ b/src/initctl.c
+@@ -56,6 +56,8 @@ typedef struct Server {
+         unsigned n_fifos;
+ 
+         DBusConnection *bus;
++
++        bool quit;
+ } Server;
+ 
+ struct Fifo {
+@@ -174,6 +176,13 @@ static void request_process(Server *s, const struct init_request *req) {
+                         case 'U':
+                                 if (kill(1, SIGTERM) < 0)
+                                         log_error("kill() failed: %m");
++
++                                /* The bus connection will be
++                                 * terminated if PID 1 is reexecuted,
++                                 * hence let's just exit here, and
++                                 * rely on that we'll be restarted on
++                                 * the next request */
++                                s->quit = true;
+                                 break;
+ 
+                         case 'q':
+@@ -404,7 +413,7 @@ int main(int argc, char *argv[]) {
+                   "READY=1\n"
+                   "STATUS=Processing requests...");
+ 
+-        for (;;) {
++        while (!server.quit) {
+                 struct epoll_event event;
+                 int k;
+ 
+-- 
+1.7.7.5
+
diff --git a/0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch b/0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch
new file mode 100644
index 0000000..2aa6a45
--- /dev/null
+++ b/0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch
@@ -0,0 +1,33 @@
+From b160c4add112ec90a811726ee3ac536f98cfd6cf Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 1 Nov 2011 22:02:36 +0100
+Subject: [PATCH 010/126] cgroup: always recreate cgroup before we try to
+ apply attributes
+
+We might have trimmed the cgroup tree previously, hence don't trust our
+own "realized" flag, always recreate cgroup tree before applying our
+attributes to make sure this actually works out.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=749687
+(cherry picked from commit 6ddaf1ca4ab0e6a094f6d37fa1e0c604c6d867ba)
+---
+ src/cgroup.c |    3 ---
+ 1 files changed, 0 insertions(+), 3 deletions(-)
+
+diff --git a/src/cgroup.c b/src/cgroup.c
+index dcf2c2f..be837c3 100644
+--- a/src/cgroup.c
++++ b/src/cgroup.c
+@@ -38,9 +38,6 @@ int cgroup_bonding_realize(CGroupBonding *b) {
+         assert(b->path);
+         assert(b->controller);
+ 
+-        if (b->realized)
+-                return 0;
+-
+         r = cg_create(b->controller, b->path);
+         if (r < 0) {
+                 log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r));
+-- 
+1.7.7.5
+
diff --git a/0001-mount-order-remote-mounts-after-both-network.target-.patch b/0011-mount-order-remote-mounts-after-both-network.target-.patch
similarity index 86%
rename from 0001-mount-order-remote-mounts-after-both-network.target-.patch
rename to 0011-mount-order-remote-mounts-after-both-network.target-.patch
index c845c8d..69f7415 100644
--- a/0001-mount-order-remote-mounts-after-both-network.target-.patch
+++ b/0011-mount-order-remote-mounts-after-both-network.target-.patch
@@ -1,14 +1,15 @@
-From 7fc2a89a7387db1e5daa4892393c9e9536920c25 Mon Sep 17 00:00:00 2001
+From 10e099981a14b6f435552854d4c9d5eaaa65c4da Mon Sep 17 00:00:00 2001
 From: Lennart Poettering <lennart at poettering.net>
 Date: Tue, 1 Nov 2011 22:27:48 +0100
-Subject: [PATCH] mount: order remote mounts after both network.target and
- remote-fs-pre.target
+Subject: [PATCH 011/126] mount: order remote mounts after both network.target
+ and remote-fs-pre.target
 
 Since remote-fs-pre.target is optional we cannot count on it to order
 remote mounts after network.target, so let's add that order explicitly
 in addition to remote-fs-pre.target.
 
 https://bugzilla.redhat.com/show_bug.cgi?id=749940
+(cherry picked from commit 7fc2a89a7387db1e5daa4892393c9e9536920c25)
 ---
  src/mount.c |    7 ++++++-
  1 files changed, 6 insertions(+), 1 deletions(-)
@@ -46,5 +47,5 @@ index ef953f0..f9cfe91 100644
                  Unit *am;
  
 -- 
-1.7.7
+1.7.7.5
 
diff --git a/0001-units-drop-Install-section-from-remote-fs-pre.target.patch b/0012-units-drop-Install-section-from-remote-fs-pre.target.patch
similarity index 74%
rename from 0001-units-drop-Install-section-from-remote-fs-pre.target.patch
rename to 0012-units-drop-Install-section-from-remote-fs-pre.target.patch
index bbad2fd..047833e 100644
--- a/0001-units-drop-Install-section-from-remote-fs-pre.target.patch
+++ b/0012-units-drop-Install-section-from-remote-fs-pre.target.patch
@@ -1,11 +1,13 @@
-From fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd Mon Sep 17 00:00:00 2001
+From 80c991c323a08ee03131d51c34b45286ae72001f Mon Sep 17 00:00:00 2001
 From: Lennart Poettering <lennart at poettering.net>
 Date: Tue, 1 Nov 2011 22:29:48 +0100
-Subject: [PATCH] units: drop [Install] section from remote-fs-pre.target
+Subject: [PATCH 012/126] units: drop [Install] section from
+ remote-fs-pre.target
 
 remote-fs-pre.target is not a unit a user should ever explicitly enable.
 Instead services which need to hook before network mounts should pull it
 in.
+(cherry picked from commit fc8f0b5c9cb8277950a2fefdb7f754c47b172dfd)
 ---
  units/remote-fs-pre.target |    3 ---
  1 files changed, 0 insertions(+), 3 deletions(-)
@@ -22,5 +24,5 @@ index 5406aa2..8aceb08 100644
 -[Install]
 -WantedBy=multi-user.target
 -- 
-1.7.7
+1.7.7.5
 
diff --git a/0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch b/0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch
new file mode 100644
index 0000000..6933026
--- /dev/null
+++ b/0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch
@@ -0,0 +1,40 @@
+From 88230ce30fcd48f8f6fadcdf838e6f047a91acdf Mon Sep 17 00:00:00 2001
+From: Tom Gundersen <teg at jklm.no>
+Date: Mon, 17 Oct 2011 13:01:08 +0200
+Subject: [PATCH 013/126] cryptsetup-generator: avoid ordering cycle on swap
+
+Devices with random keys (swap), should not be ordered before local-fs.target,
+as this creates a cycle with systemd-load-random-seed.service (and also it
+does not make sense, a swap device is not a local-fs).
+(cherry picked from commit 87e75fddbb3701fd5f4e0d62dc1d661e8d94b071)
+---
+ src/cryptsetup-generator.c |    6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/cryptsetup-generator.c b/src/cryptsetup-generator.c
+index 6f3aa78..a48b7a4 100644
+--- a/src/cryptsetup-generator.c
++++ b/src/cryptsetup-generator.c
+@@ -112,8 +112,7 @@ static int create_disk(
+                 "DefaultDependencies=no\n"
+                 "BindTo=%s dev-mapper-%%i.device\n"
+                 "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n"
+-                "Before=umount.target\n"
+-                "Before=local-fs.target\n",
++                "Before=umount.target\n",
+                 d, d);
+ 
+         if (!nofail)
+@@ -125,6 +124,9 @@ static int create_disk(
+                          streq(password, "/dev/hw_random")))
+                 fprintf(f,
+                         "After=systemd-random-seed-load.service\n");
++        else
++                fprintf(f,
++                        "Before=local-fs.target\n");
+ 
+         fprintf(f,
+                 "\n[Service]\n"
+-- 
+1.7.7.5
+
diff --git a/0014-bash-completion-update-with-new-verbs-and-arguments.patch b/0014-bash-completion-update-with-new-verbs-and-arguments.patch
new file mode 100644
index 0000000..9d26b47
--- /dev/null
+++ b/0014-bash-completion-update-with-new-verbs-and-arguments.patch
@@ -0,0 +1,153 @@
+From f116811feefbde2af0138ab73a2bfab38639f315 Mon Sep 17 00:00:00 2001
+From: Ran Benita <ran234 at gmail.com>
+Date: Wed, 2 Nov 2011 10:48:49 +0200
+Subject: [PATCH 014/126] bash-completion: update with new verbs and arguments
+
+Adds arguments --root= --runtime --no-legend.
+Adds verbs link mask unmask reenable list-unit-files.
+Also uses list-unit-files to make nicer enable and disable completions.
+
+Rebased due to changes in systemctl.
+(cherry picked from commit 8aea83c718af18e6436e6bdce9437238de052dbb)
+---
+ src/systemctl-bash-completion.sh |   61 +++++++++++++++++++++++++++----------
+ 1 files changed, 44 insertions(+), 17 deletions(-)
+
+diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
+index 6ebb792..0aa87af 100644
+--- a/src/systemctl-bash-completion.sh
++++ b/src/systemctl-bash-completion.sh
+@@ -16,7 +16,7 @@
+ # along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ 
+ __systemctl() {
+-        systemctl --no-legend "$@"
++        systemctl --full --no-legend "$@"
+ }
+ 
+ __contains_word () {
+@@ -36,10 +36,13 @@ __filter_units_by_property () {
+         done
+ }
+ 
+-__get_all_units      () { __systemctl list-units --full --all | awk '                 {print $1}' ; }
+-__get_active_units   () { __systemctl list-units --full       | awk '                 {print $1}' ; }
+-__get_inactive_units () { __systemctl list-units --full --all | awk '$3 == "inactive" {print $1}' ; }
+-__get_failed_units   () { __systemctl list-units --full       | awk '$3 == "failed"   {print $1}' ; }
++__get_all_units      () { __systemctl list-units --all | awk '                 {print $1}' ; }
++__get_active_units   () { __systemctl list-units       | awk '                 {print $1}' ; }
++__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; }
++__get_failed_units   () { __systemctl list-units       | awk '$3 == "failed"   {print $1}' ; }
++__get_enabled_units  () { __systemctl list-unit-files  | awk '$2 == "enabled"  {print $1}' ; }
++__get_disabled_units () { __systemctl list-unit-files  | awk '$2 == "disabled" {print $1}' ; }
++__get_masked_units   () { __systemctl list-unit-files  | awk '$2 == "masked"   {print $1}' ; }
+ 
+ _systemctl () {
+         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+@@ -47,15 +50,15 @@ _systemctl () {
+ 
+         local -A OPTS=(
+                [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
+-                             --help -h --no-ask-password --no-block --no-pager --no-reload --no-wall
+-                             --order --require --quiet -q --privileged -P --system --user --version'
+-                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t'
++                             --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
++                             --order --require --quiet -q --privileged -P --system --user --version --runtime'
++                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
+         )
+ 
+         if __contains_word "$prev" ${OPTS[ARG]}; then
+                 case $prev in
+                         --signal|-s)
+-                                comps=$(compgen -A signal | grep '^SIG' | grep -Ev 'RTMIN|RTMAX|JUNK')
++                                comps=$(compgen -A signal)
+                         ;;
+                         --type|-t)
+                                 comps='automount device mount path service snapshot socket swap target timer'
+@@ -66,7 +69,14 @@ _systemctl () {
+                         --kill-mode)
+                                 comps='control-group process'
+                         ;;
+-                        --property|-p|--host|-H)
++                        --root)
++                                comps=$(compgen -A directory -- "$cur" )
++                                compopt -o filenames
++                        ;;
++                        --host|-H)
++                                comps=$(compgen -A hostname)
++                        ;;
++                        --property|-p)
+                                 comps=''
+                         ;;
+                 esac
+@@ -81,22 +91,26 @@ _systemctl () {
+         fi
+ 
+         local -A VERBS=(
+-                [ALL_UNITS]='enable disable is-active is-enabled status show'
++                [ALL_UNITS]='is-active is-enabled status show mask preset'
++            [ENABLED_UNITS]='disable reenable'
++           [DISABLED_UNITS]='enable'
+              [FAILED_UNITS]='reset-failed'
+           [STARTABLE_UNITS]='start'
+-          [STOPPABLE_UNITS]='stop kill try-restart condrestart'
++          [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
+          [ISOLATABLE_UNITS]='isolate'
+-         [RELOADABLE_UNITS]='reload reload-or-try-restart force-reload'
+-          [RESTARTABLE_UNITS]='restart reload-or-restart'
++         [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
++        [RESTARTABLE_UNITS]='restart reload-or-restart'
++             [MASKED_UNITS]='unmask'
+                      [JOBS]='cancel'
+                 [SNAPSHOTS]='delete'
+                      [ENVS]='set-environment unset-environment'
+-               [STANDALONE]='daemon-reexec daemon-reload default dot dump emergency exit halt kexec
+-                             list-jobs list-units poweroff reboot rescue show-environment'
++               [STANDALONE]='daemon-reexec daemon-reload default dot dump
++                             emergency exit halt kexec list-jobs list-units
++                             list-unit-files poweroff reboot rescue show-environment'
+                      [NAME]='snapshot load'
++                     [FILE]='link'
+         )
+ 
+-        local verb
+         for ((i=0; $i <= $COMP_CWORD; i++)); do
+                 if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+                  ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
+@@ -111,6 +125,12 @@ _systemctl () {
+         elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
+                 comps=$( __get_all_units )
+ 
++        elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
++                comps=$( __get_enabled_units )
++
++        elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
++                comps=$( __get_disabled_units )
++
+         elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
+                 comps=$( __filter_units_by_property CanStart yes \
+                       $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' ))
+@@ -134,6 +154,9 @@ _systemctl () {
+         elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
+                 comps=$( __get_failed_units )
+ 
++        elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
++                comps=$( __get_masked_units )
++
+         elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
+                 comps=''
+ 
+@@ -146,6 +169,10 @@ _systemctl () {
+         elif __contains_word "$verb" ${VERBS[ENVS]}; then
+                 comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' )
+                 compopt -o nospace
++
++        elif __contains_word "$verb" ${VERBS[FILE]}; then
++                comps=$( compgen -A file -- "$cur" )
++                compopt -o filenames
+         fi
+ 
+         COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+-- 
+1.7.7.5
+
diff --git a/0015-bash-completion-add-completions-for-systemd-loginctl.patch b/0015-bash-completion-add-completions-for-systemd-loginctl.patch
new file mode 100644
index 0000000..b8beb1a
--- /dev/null
+++ b/0015-bash-completion-add-completions-for-systemd-loginctl.patch
@@ -0,0 +1,107 @@
+From cb1d467a016e97e74222fc775fefe4ee3790f8fb Mon Sep 17 00:00:00 2001
+From: Ran Benita <ran234 at gmail.com>
+Date: Wed, 2 Nov 2011 10:48:50 +0200
+Subject: [PATCH 015/126] bash-completion: add completions for
+ systemd-loginctl
+
+This script is straightforward and should give proper completions for
+all of systemd-loginctl's verbs.
+(cherry picked from commit 3cdbf916d3629733fa9998d5802bf4c20d98c50e)
+---
+ src/systemctl-bash-completion.sh |   83 ++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 83 insertions(+), 0 deletions(-)
+
+diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
+index 0aa87af..176591f 100644
+--- a/src/systemctl-bash-completion.sh
++++ b/src/systemctl-bash-completion.sh
+@@ -179,3 +179,86 @@ _systemctl () {
+         return 0
+ }
+ complete -F _systemctl systemctl
++
++__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; }
++__get_all_users    () { systemd-loginctl list-users    | awk '{print $2}' ; }
++__get_all_seats    () { systemd-loginctl list-seats    | awk '{print $1}' ; }
++
++_systemd_loginctl () {
++        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
++        local verb comps
++
++        local -A OPTS=(
++               [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
++                      [ARG]='--host -H --kill-who --property -p --signal -s'
++        )
++
++        if __contains_word "$prev" ${OPTS[ARG]}; then
++                case $prev in
++                        --signal|-s)
++                                comps=$(compgen -A signal)
++                        ;;
++                        --kill-who)
++                                comps='all leader'
++                        ;;
++                        --host|-H)
++                                comps=$(compgen -A hostname)
++                        ;;
++                        --property|-p)
++                                comps=''
++                        ;;
++                esac
++                COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
++                return 0
++        fi
++
++
++        if [[ "$cur" = -* ]]; then
++                COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
++                return 0
++        fi
++
++        local -A VERBS=(
++                [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
++                [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
++                [SEATS]='seat-status show-seat terminate-seat'
++                [STANDALONE]='list-sessions list-users list-seats flush-devices'
++                [ATTACH]='attach'
++        )
++
++        for ((i=0; $i <= $COMP_CWORD; i++)); do
++                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
++                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
++                        verb=${COMP_WORDS[i]}
++                        break
++                fi
++        done
++
++        if   [[ -z $verb ]]; then
++                comps="${VERBS[*]}"
++
++        elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
++                comps=$( __get_all_sessions )
++
++        elif __contains_word "$verb" ${VERBS[USERS]}; then
++                comps=$( __get_all_users )
++
++        elif __contains_word "$verb" ${VERBS[SEATS]}; then
++                comps=$( __get_all_seats )
++
++        elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
++                comps=''
++
++        elif __contains_word "$verb" ${VERBS[ATTACH]}; then
++                if [[ $prev = $verb ]]; then
++                        comps=$( __get_all_seats )
++                else
++                        comps=$(compgen -A file -- "$cur" )
++                        compopt -o filenames
++                fi
++        fi
++
++        COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
++        return 0
++}
++complete -F _systemd_loginctl systemd-loginctl
+-- 
+1.7.7.5
+
diff --git a/0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch b/0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch
new file mode 100644
index 0000000..dd3024a
--- /dev/null
+++ b/0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch
@@ -0,0 +1,571 @@
+From b7ff1f56d52becdc0820d54a26b2fbec7fbd698c Mon Sep 17 00:00:00 2001
+From: Ran Benita <ran234 at gmail.com>
+Date: Wed, 2 Nov 2011 10:48:51 +0200
+Subject: [PATCH 016/126] bash-completion: rename file since it is no longer
+ for systemctl only (cherry picked from commit
+ f5a613c03c54cc82e92c38af0b3e1c130003a68b)
+
+---
+ Makefile.am                      |    2 +-
+ src/systemctl-bash-completion.sh |  264 --------------------------------------
+ src/systemd-bash-completion.sh   |  264 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 265 insertions(+), 265 deletions(-)
+ delete mode 100644 src/systemctl-bash-completion.sh
+ create mode 100644 src/systemd-bash-completion.sh
+
+diff --git a/Makefile.am b/Makefile.am
+index dabe32a..8f1ffdc 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -314,7 +314,7 @@ dbusinterface_DATA += \
+ endif
+ 
+ dist_bashcompletion_DATA = \
+-	src/systemctl-bash-completion.sh
++	src/systemd-bash-completion.sh
+ 
+ dist_tmpfiles_DATA = \
+ 	tmpfiles.d/systemd.conf \
+diff --git a/src/systemctl-bash-completion.sh b/src/systemctl-bash-completion.sh
+deleted file mode 100644
+index 176591f..0000000
+--- a/src/systemctl-bash-completion.sh
++++ /dev/null
+@@ -1,264 +0,0 @@
+-# This file is part of systemd.
+-#
+-# Copyright 2010 Ran Benita
+-#
+-# systemd is free software; you can redistribute it and/or modify it
+-# under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# systemd is distributed in the hope that it will be useful, but
+-# WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+-# General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-
+-__systemctl() {
+-        systemctl --full --no-legend "$@"
+-}
+-
+-__contains_word () {
+-        local word=$1; shift
+-        for w in $*; do [[ $w = $word ]] && return 0; done
+-        return 1
+-}
+-
+-__filter_units_by_property () {
+-        local property=$1 value=$2 ; shift ; shift
+-        local -a units=( $* )
+-        local -a props=( $(__systemctl show --property "$property" -- ${units[*]} | grep -v ^$) )
+-        for ((i=0; $i < ${#units[*]}; i++)); do
+-                if [[ "${props[i]}" = "$property=$value" ]]; then
+-                        echo "${units[i]}"
+-                fi
+-        done
+-}
+-
+-__get_all_units      () { __systemctl list-units --all | awk '                 {print $1}' ; }
+-__get_active_units   () { __systemctl list-units       | awk '                 {print $1}' ; }
+-__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; }
+-__get_failed_units   () { __systemctl list-units       | awk '$3 == "failed"   {print $1}' ; }
+-__get_enabled_units  () { __systemctl list-unit-files  | awk '$2 == "enabled"  {print $1}' ; }
+-__get_disabled_units () { __systemctl list-unit-files  | awk '$2 == "disabled" {print $1}' ; }
+-__get_masked_units   () { __systemctl list-unit-files  | awk '$2 == "masked"   {print $1}' ; }
+-
+-_systemctl () {
+-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+-        local verb comps
+-
+-        local -A OPTS=(
+-               [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
+-                             --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
+-                             --order --require --quiet -q --privileged -P --system --user --version --runtime'
+-                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
+-        )
+-
+-        if __contains_word "$prev" ${OPTS[ARG]}; then
+-                case $prev in
+-                        --signal|-s)
+-                                comps=$(compgen -A signal)
+-                        ;;
+-                        --type|-t)
+-                                comps='automount device mount path service snapshot socket swap target timer'
+-                        ;;
+-                        --kill-who)
+-                                comps='all control main'
+-                        ;;
+-                        --kill-mode)
+-                                comps='control-group process'
+-                        ;;
+-                        --root)
+-                                comps=$(compgen -A directory -- "$cur" )
+-                                compopt -o filenames
+-                        ;;
+-                        --host|-H)
+-                                comps=$(compgen -A hostname)
+-                        ;;
+-                        --property|-p)
+-                                comps=''
+-                        ;;
+-                esac
+-                COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+-                return 0
+-        fi
+-
+-
+-        if [[ "$cur" = -* ]]; then
+-                COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
+-                return 0
+-        fi
+-
+-        local -A VERBS=(
+-                [ALL_UNITS]='is-active is-enabled status show mask preset'
+-            [ENABLED_UNITS]='disable reenable'
+-           [DISABLED_UNITS]='enable'
+-             [FAILED_UNITS]='reset-failed'
+-          [STARTABLE_UNITS]='start'
+-          [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
+-         [ISOLATABLE_UNITS]='isolate'
+-         [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
+-        [RESTARTABLE_UNITS]='restart reload-or-restart'
+-             [MASKED_UNITS]='unmask'
+-                     [JOBS]='cancel'
+-                [SNAPSHOTS]='delete'
+-                     [ENVS]='set-environment unset-environment'
+-               [STANDALONE]='daemon-reexec daemon-reload default dot dump
+-                             emergency exit halt kexec list-jobs list-units
+-                             list-unit-files poweroff reboot rescue show-environment'
+-                     [NAME]='snapshot load'
+-                     [FILE]='link'
+-        )
+-
+-        for ((i=0; $i <= $COMP_CWORD; i++)); do
+-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+-                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
+-                        verb=${COMP_WORDS[i]}
+-                        break
+-                fi
+-        done
+-
+-        if   [[ -z $verb ]]; then
+-                comps="${VERBS[*]}"
+-
+-        elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
+-                comps=$( __get_all_units )
+-
+-        elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
+-                comps=$( __get_enabled_units )
+-
+-        elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
+-                comps=$( __get_disabled_units )
+-
+-        elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
+-                comps=$( __filter_units_by_property CanStart yes \
+-                      $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' ))
+-
+-        elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
+-                comps=$( __filter_units_by_property CanStart yes \
+-                      $( __get_all_units | grep -Ev '\.(device|snapshot|socket|timer)$' ))
+-
+-        elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
+-                comps=$( __filter_units_by_property CanStop yes \
+-                      $( __get_active_units ) )
+-
+-        elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
+-                comps=$( __filter_units_by_property CanReload yes \
+-                      $( __get_active_units ) )
+-
+-        elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
+-                comps=$( __filter_units_by_property AllowIsolate yes \
+-                      $( __get_all_units ) )
+-
+-        elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
+-                comps=$( __get_failed_units )
+-
+-        elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
+-                comps=$( __get_masked_units )
+-
+-        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
+-                comps=''
+-
+-        elif __contains_word "$verb" ${VERBS[JOBS]}; then
+-                comps=$( __systemctl list-jobs | awk '{print $1}' )
+-
+-        elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
+-                comps=$( __systemctl list-units --type snapshot --full --all | awk '{print $1}' )
+-
+-        elif __contains_word "$verb" ${VERBS[ENVS]}; then
+-                comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' )
+-                compopt -o nospace
+-
+-        elif __contains_word "$verb" ${VERBS[FILE]}; then
+-                comps=$( compgen -A file -- "$cur" )
+-                compopt -o filenames
+-        fi
+-
+-        COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+-        return 0
+-}
+-complete -F _systemctl systemctl
+-
+-__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; }
+-__get_all_users    () { systemd-loginctl list-users    | awk '{print $2}' ; }
+-__get_all_seats    () { systemd-loginctl list-seats    | awk '{print $1}' ; }
+-
+-_systemd_loginctl () {
+-        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
+-        local verb comps
+-
+-        local -A OPTS=(
+-               [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
+-                      [ARG]='--host -H --kill-who --property -p --signal -s'
+-        )
+-
+-        if __contains_word "$prev" ${OPTS[ARG]}; then
+-                case $prev in
+-                        --signal|-s)
+-                                comps=$(compgen -A signal)
+-                        ;;
+-                        --kill-who)
+-                                comps='all leader'
+-                        ;;
+-                        --host|-H)
+-                                comps=$(compgen -A hostname)
+-                        ;;
+-                        --property|-p)
+-                                comps=''
+-                        ;;
+-                esac
+-                COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+-                return 0
+-        fi
+-
+-
+-        if [[ "$cur" = -* ]]; then
+-                COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
+-                return 0
+-        fi
+-
+-        local -A VERBS=(
+-                [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
+-                [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
+-                [SEATS]='seat-status show-seat terminate-seat'
+-                [STANDALONE]='list-sessions list-users list-seats flush-devices'
+-                [ATTACH]='attach'
+-        )
+-
+-        for ((i=0; $i <= $COMP_CWORD; i++)); do
+-                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
+-                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
+-                        verb=${COMP_WORDS[i]}
+-                        break
+-                fi
+-        done
+-
+-        if   [[ -z $verb ]]; then
+-                comps="${VERBS[*]}"
+-
+-        elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
+-                comps=$( __get_all_sessions )
+-
+-        elif __contains_word "$verb" ${VERBS[USERS]}; then
+-                comps=$( __get_all_users )
+-
+-        elif __contains_word "$verb" ${VERBS[SEATS]}; then
+-                comps=$( __get_all_seats )
+-
+-        elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
+-                comps=''
+-
+-        elif __contains_word "$verb" ${VERBS[ATTACH]}; then
+-                if [[ $prev = $verb ]]; then
+-                        comps=$( __get_all_seats )
+-                else
+-                        comps=$(compgen -A file -- "$cur" )
+-                        compopt -o filenames
+-                fi
+-        fi
+-
+-        COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
+-        return 0
+-}
+-complete -F _systemd_loginctl systemd-loginctl
+diff --git a/src/systemd-bash-completion.sh b/src/systemd-bash-completion.sh
+new file mode 100644
+index 0000000..176591f
+--- /dev/null
++++ b/src/systemd-bash-completion.sh
+@@ -0,0 +1,264 @@
++# This file is part of systemd.
++#
++# Copyright 2010 Ran Benita
++#
++# systemd is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# systemd is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with systemd; If not, see <http://www.gnu.org/licenses/>.
++
++__systemctl() {
++        systemctl --full --no-legend "$@"
++}
++
++__contains_word () {
++        local word=$1; shift
++        for w in $*; do [[ $w = $word ]] && return 0; done
++        return 1
++}
++
++__filter_units_by_property () {
++        local property=$1 value=$2 ; shift ; shift
++        local -a units=( $* )
++        local -a props=( $(__systemctl show --property "$property" -- ${units[*]} | grep -v ^$) )
++        for ((i=0; $i < ${#units[*]}; i++)); do
++                if [[ "${props[i]}" = "$property=$value" ]]; then
++                        echo "${units[i]}"
++                fi
++        done
++}
++
++__get_all_units      () { __systemctl list-units --all | awk '                 {print $1}' ; }
++__get_active_units   () { __systemctl list-units       | awk '                 {print $1}' ; }
++__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; }
++__get_failed_units   () { __systemctl list-units       | awk '$3 == "failed"   {print $1}' ; }
++__get_enabled_units  () { __systemctl list-unit-files  | awk '$2 == "enabled"  {print $1}' ; }
++__get_disabled_units () { __systemctl list-unit-files  | awk '$2 == "disabled" {print $1}' ; }
++__get_masked_units   () { __systemctl list-unit-files  | awk '$2 == "masked"   {print $1}' ; }
++
++_systemctl () {
++        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
++        local verb comps
++
++        local -A OPTS=(
++               [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global
++                             --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall
++                             --order --require --quiet -q --privileged -P --system --user --version --runtime'
++                      [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root'
++        )
++
++        if __contains_word "$prev" ${OPTS[ARG]}; then
++                case $prev in
++                        --signal|-s)
++                                comps=$(compgen -A signal)
++                        ;;
++                        --type|-t)
++                                comps='automount device mount path service snapshot socket swap target timer'
++                        ;;
++                        --kill-who)
++                                comps='all control main'
++                        ;;
++                        --kill-mode)
++                                comps='control-group process'
++                        ;;
++                        --root)
++                                comps=$(compgen -A directory -- "$cur" )
++                                compopt -o filenames
++                        ;;
++                        --host|-H)
++                                comps=$(compgen -A hostname)
++                        ;;
++                        --property|-p)
++                                comps=''
++                        ;;
++                esac
++                COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
++                return 0
++        fi
++
++
++        if [[ "$cur" = -* ]]; then
++                COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
++                return 0
++        fi
++
++        local -A VERBS=(
++                [ALL_UNITS]='is-active is-enabled status show mask preset'
++            [ENABLED_UNITS]='disable reenable'
++           [DISABLED_UNITS]='enable'
++             [FAILED_UNITS]='reset-failed'
++          [STARTABLE_UNITS]='start'
++          [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart'
++         [ISOLATABLE_UNITS]='isolate'
++         [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
++        [RESTARTABLE_UNITS]='restart reload-or-restart'
++             [MASKED_UNITS]='unmask'
++                     [JOBS]='cancel'
++                [SNAPSHOTS]='delete'
++                     [ENVS]='set-environment unset-environment'
++               [STANDALONE]='daemon-reexec daemon-reload default dot dump
++                             emergency exit halt kexec list-jobs list-units
++                             list-unit-files poweroff reboot rescue show-environment'
++                     [NAME]='snapshot load'
++                     [FILE]='link'
++        )
++
++        for ((i=0; $i <= $COMP_CWORD; i++)); do
++                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
++                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
++                        verb=${COMP_WORDS[i]}
++                        break
++                fi
++        done
++
++        if   [[ -z $verb ]]; then
++                comps="${VERBS[*]}"
++
++        elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then
++                comps=$( __get_all_units )
++
++        elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then
++                comps=$( __get_enabled_units )
++
++        elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
++                comps=$( __get_disabled_units )
++
++        elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
++                comps=$( __filter_units_by_property CanStart yes \
++                      $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' ))
++
++        elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
++                comps=$( __filter_units_by_property CanStart yes \
++                      $( __get_all_units | grep -Ev '\.(device|snapshot|socket|timer)$' ))
++
++        elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
++                comps=$( __filter_units_by_property CanStop yes \
++                      $( __get_active_units ) )
++
++        elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then
++                comps=$( __filter_units_by_property CanReload yes \
++                      $( __get_active_units ) )
++
++        elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then
++                comps=$( __filter_units_by_property AllowIsolate yes \
++                      $( __get_all_units ) )
++
++        elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then
++                comps=$( __get_failed_units )
++
++        elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then
++                comps=$( __get_masked_units )
++
++        elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
++                comps=''
++
++        elif __contains_word "$verb" ${VERBS[JOBS]}; then
++                comps=$( __systemctl list-jobs | awk '{print $1}' )
++
++        elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then
++                comps=$( __systemctl list-units --type snapshot --full --all | awk '{print $1}' )
++
++        elif __contains_word "$verb" ${VERBS[ENVS]}; then
++                comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' )
++                compopt -o nospace
++
++        elif __contains_word "$verb" ${VERBS[FILE]}; then
++                comps=$( compgen -A file -- "$cur" )
++                compopt -o filenames
++        fi
++
++        COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
++        return 0
++}
++complete -F _systemctl systemctl
++
++__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; }
++__get_all_users    () { systemd-loginctl list-users    | awk '{print $2}' ; }
++__get_all_seats    () { systemd-loginctl list-seats    | awk '{print $1}' ; }
++
++_systemd_loginctl () {
++        local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
++        local verb comps
++
++        local -A OPTS=(
++               [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version'
++                      [ARG]='--host -H --kill-who --property -p --signal -s'
++        )
++
++        if __contains_word "$prev" ${OPTS[ARG]}; then
++                case $prev in
++                        --signal|-s)
++                                comps=$(compgen -A signal)
++                        ;;
++                        --kill-who)
++                                comps='all leader'
++                        ;;
++                        --host|-H)
++                                comps=$(compgen -A hostname)
++                        ;;
++                        --property|-p)
++                                comps=''
++                        ;;
++                esac
++                COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
++                return 0
++        fi
++
++
++        if [[ "$cur" = -* ]]; then
++                COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") )
++                return 0
++        fi
++
++        local -A VERBS=(
++                [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session'
++                [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user'
++                [SEATS]='seat-status show-seat terminate-seat'
++                [STANDALONE]='list-sessions list-users list-seats flush-devices'
++                [ATTACH]='attach'
++        )
++
++        for ((i=0; $i <= $COMP_CWORD; i++)); do
++                if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
++                 ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
++                        verb=${COMP_WORDS[i]}
++                        break
++                fi
++        done
++
++        if   [[ -z $verb ]]; then
++                comps="${VERBS[*]}"
++
++        elif __contains_word "$verb" ${VERBS[SESSIONS]}; then
++                comps=$( __get_all_sessions )
++
++        elif __contains_word "$verb" ${VERBS[USERS]}; then
++                comps=$( __get_all_users )
++
++        elif __contains_word "$verb" ${VERBS[SEATS]}; then
++                comps=$( __get_all_seats )
++
++        elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
++                comps=''
++
++        elif __contains_word "$verb" ${VERBS[ATTACH]}; then
++                if [[ $prev = $verb ]]; then
++                        comps=$( __get_all_seats )
++                else
++                        comps=$(compgen -A file -- "$cur" )
++                        compopt -o filenames
++                fi
++        fi
++
++        COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
++        return 0
++}
++complete -F _systemd_loginctl systemd-loginctl
+-- 
+1.7.7.5
+
diff --git a/0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch b/0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch
new file mode 100644
index 0000000..9bf17d6
--- /dev/null
+++ b/0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch
@@ -0,0 +1,60 @@
+From 59c42570c4191f833c06561ea5c6df134946e1f8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Wed, 23 Feb 2011 14:03:59 +0100
+Subject: [PATCH 017/126] systemadm: break timestamp formatting out into a
+ seperate function
+
+Since the timezone is always local, it doesn't make much sense to
+display it. The timestamp is now formatted without the timezone.
+I guess it can be further improved, which should be easier now
+that it is tucked-away in a separate function.
+(cherry picked from commit 8401f1533d6936add337a621c5e58e3bbe9f346a)
+---
+ src/systemadm.vala |   24 +++++++++++-------------
+ 1 files changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index d45ec64..988e9f1 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -23,6 +23,13 @@ using Pango;
+ 
+ static bool user = false;
+ 
++public string format_time(uint64 time_ns) {
++        if (time_ns <= 0)
++                return "";
++        Time timestamp = Time.local((time_t) (time_ns / 1000000));
++        return timestamp.format("%a, %d %b %Y %H:%M:%S");
++}
++
+ public class LeftLabel : Label {
+         public LeftLabel(string? text = null) {
+                 if (text != null)
+@@ -515,19 +522,10 @@ public class MainWindow : Window {
+                 else
+                         unit_fragment_path_label.set_text_or_na();
+ 
+-                uint64 t = unit.active_enter_timestamp;
+-                if (t > 0) {
+-                        Time timestamp = Time.local((time_t) (t / 1000000));
+-                        unit_active_enter_timestamp_label.set_text_or_na(timestamp.format("%a, %d %b %Y %H:%M:%S %z"));
+-                } else
+-                        unit_active_enter_timestamp_label.set_text_or_na();
+-
+-                t = unit.active_exit_timestamp;
+-                if (t > 0) {
+-                        Time timestamp = Time.local((time_t) (t / 1000000));
+-                        unit_active_exit_timestamp_label.set_text_or_na(timestamp.format("%a, %d %b %Y %H:%M:%S %z"));
+-                } else
+-                        unit_active_exit_timestamp_label.set_text_or_na();
++
++                unit_active_enter_timestamp_label.set_text_or_na(format_time(unit.active_enter_timestamp));
++
++                unit_active_exit_timestamp_label.set_text_or_na(format_time(unit.active_exit_timestamp));
+ 
+                 bool b = unit.can_start;
+                 start_button.set_sensitive(b);
+-- 
+1.7.7.5
+
diff --git a/0018-systemadm-allow-sorting-of-jobs-and-units.patch b/0018-systemadm-allow-sorting-of-jobs-and-units.patch
new file mode 100644
index 0000000..ad9fe69
--- /dev/null
+++ b/0018-systemadm-allow-sorting-of-jobs-and-units.patch
@@ -0,0 +1,76 @@
+From 5a7251ffb8ea53dd6c0e0b78e78af704bbb1cbb2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 24 Feb 2011 16:29:24 +0100
+Subject: [PATCH 018/126] systemadm: allow sorting of jobs and units (cherry
+ picked from commit
+ 661ece1029ea454ff76093a5f1b40e9209cac86d)
+
+---
+ src/systemadm.vala |   31 ++++++++++++++++++++-----------
+ 1 files changed, 20 insertions(+), 11 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 988e9f1..21177bf 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -30,6 +30,13 @@ public string format_time(uint64 time_ns) {
+         return timestamp.format("%a, %d %b %Y %H:%M:%S");
+ }
+ 
++public void new_column(TreeView view, int column_id, string title) {
++        TreeViewColumn col;
++        col = new TreeViewColumn.with_attributes(title, new CellRendererText(), "text", column_id);
++        col.set_sort_column_id(column_id);
++        view.insert_column(col, -1);
++}
++
+ public class LeftLabel : Label {
+         public LeftLabel(string? text = null) {
+                 if (text != null)
+@@ -171,22 +178,24 @@ public class MainWindow : Window {
+                 unit_model_filter = new TreeModelFilter(unit_model, null);
+                 unit_model_filter.set_visible_func(unit_filter);
+ 
+-                unit_view = new TreeView.with_model(unit_model_filter);
++                TreeModelSort unit_model_sort = new TreeModelSort.with_model(unit_model_filter);
++
++                unit_view = new TreeView.with_model(unit_model_sort);
+                 job_view = new TreeView.with_model(job_model);
+ 
+                 unit_view.cursor_changed.connect(unit_changed);
+                 job_view.cursor_changed.connect(job_changed);
+ 
+-                unit_view.insert_column_with_attributes(-1, "Load State", new CellRendererText(), "text", 2);
+-                unit_view.insert_column_with_attributes(-1, "Active State", new CellRendererText(), "text", 3);
+-                unit_view.insert_column_with_attributes(-1, "Unit State", new CellRendererText(), "text", 4);
+-                unit_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 0);
+-                unit_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 5);
++                new_column(unit_view, 2, "Load State");
++                new_column(unit_view, 3, "Active State");
++                new_column(unit_view, 4, "Unit State");
++                new_column(unit_view, 0, "Unit");
++                new_column(unit_view, 5, "Job");
+ 
+-                job_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 0);
+-                job_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 1);
+-                job_view.insert_column_with_attributes(-1, "Type", new CellRendererText(), "text", 2);
+-                job_view.insert_column_with_attributes(-1, "State", new CellRendererText(), "text", 3);
++                new_column(job_view, 0, "Job");
++                new_column(job_view, 1, "Unit");
++                new_column(job_view, 2, "Type");
++                new_column(job_view, 3, "State");
+ 
+                 ScrolledWindow scroll = new ScrolledWindow(null, null);
+                 scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
+@@ -897,7 +906,7 @@ public class MainWindow : Window {
+         }
+ 
+         public void unit_type_changed() {
+-                TreeModelFilter model = (TreeModelFilter) unit_view.get_model();
++                TreeModelFilter model = (TreeModelFilter) ((TreeModelSort) unit_view.get_model()).get_model();
+ 
+                 model.refilter();
+         }
+-- 
+1.7.7.5
+
diff --git a/0019-systemadm-split-the-type-status-combo-box-into-type-.patch b/0019-systemadm-split-the-type-status-combo-box-into-type-.patch
new file mode 100644
index 0000000..7920cc7
--- /dev/null
+++ b/0019-systemadm-split-the-type-status-combo-box-into-type-.patch
@@ -0,0 +1,112 @@
+From 24924bc68792f49d73cfaf0ff4dd2975d1c3c765 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Fri, 25 Feb 2011 18:20:16 +0100
+Subject: [PATCH 019/126] systemadm: split the type+status combo box into type
+ combo & status checkbox (cherry picked from commit
+ a3c159a23c7cae889f89ed69bbe82c272bf163ca)
+
+---
+ src/systemadm.vala |   62 +++++++++++++++++++++++++--------------------------
+ 1 files changed, 30 insertions(+), 32 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 21177bf..e78fd7c 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -113,6 +113,7 @@ public class MainWindow : Window {
+         private RightLabel job_type_label;
+ 
+         private ComboBox unit_type_combo_box;
++        private CheckButton inactive_checkbox;
+ 
+         public MainWindow() throws IOError {
+                 title = user ? "systemd User Service Manager" : "systemd System Manager";
+@@ -137,8 +138,7 @@ public class MainWindow : Window {
+                 type_hbox.pack_start(unit_type_combo_box, false, false, 0);
+                 unit_vbox.pack_start(type_hbox, false, false, 0);
+ 
+-                unit_type_combo_box.append_text("Show All Units");
+-                unit_type_combo_box.append_text("Show Only Live Units");
++                unit_type_combo_box.append_text("Show All");
+                 unit_type_combo_box.append_text("Services");
+                 unit_type_combo_box.append_text("Sockets");
+                 unit_type_combo_box.append_text("Devices");
+@@ -146,9 +146,13 @@ public class MainWindow : Window {
+                 unit_type_combo_box.append_text("Automounts");
+                 unit_type_combo_box.append_text("Targets");
+                 unit_type_combo_box.append_text("Snapshots");
+-                unit_type_combo_box.set_active(1);
++                unit_type_combo_box.set_active(0); // Show All
+                 unit_type_combo_box.changed.connect(unit_type_changed);
+ 
++                inactive_checkbox = new CheckButton.with_label("inactive too");
++                inactive_checkbox.toggled.connect(unit_type_changed);
++                type_hbox.pack_start(inactive_checkbox, false, false, 0);
++
+                 unit_load_entry = new Entry();
+                 unit_load_button = new Button.with_mnemonic("_Load");
+                 unit_load_button.set_sensitive(false);
+@@ -872,37 +876,31 @@ public class MainWindow : Window {
+                 if (id == null)
+                         return false;
+ 
+-                switch (unit_type_combo_box.get_active()) {
+-
+-                        case 0:
+-                                return true;
+-
+-                        case 1:
+-                                return active_state != "inactive" || job != "";
+-
+-                        case 2:
+-                                return id.has_suffix(".service");
+-
+-                        case 3:
+-                                return id.has_suffix(".socket");
+-
+-                        case 4:
+-                                return id.has_suffix(".device");
+-
+-                        case 5:
+-                                return id.has_suffix(".mount");
+-
+-                        case 6:
+-                                return id.has_suffix(".automount");
+-
+-                        case 7:
+-                                return id.has_suffix(".target");
++                if (!inactive_checkbox.get_active()
++                    && active_state == "inactive" && job == "")
++                        return false;
+ 
+-                        case 8:
+-                                return id.has_suffix(".snapshot");
++                switch (unit_type_combo_box.get_active()) {
++                case 0:
++                        return true;
++                case 1:
++                        return id.has_suffix(".service");
++                case 2:
++                        return id.has_suffix(".socket");
++                case 3:
++                        return id.has_suffix(".device");
++                case 4:
++                        return id.has_suffix(".mount");
++                case 5:
++                        return id.has_suffix(".automount");
++                case 6:
++                        return id.has_suffix(".target");
++                case 7:
++                        return id.has_suffix(".snapshot");
++                default:
++                        assert(false);
++                        return false;
+                 }
+-
+-                return false;
+         }
+ 
+         public void unit_type_changed() {
+-- 
+1.7.7.5
+
diff --git a/0020-systemadm-filter-on-swaps-paths-and-timers-too.patch b/0020-systemadm-filter-on-swaps-paths-and-timers-too.patch
new file mode 100644
index 0000000..a5ea1e3
--- /dev/null
+++ b/0020-systemadm-filter-on-swaps-paths-and-timers-too.patch
@@ -0,0 +1,66 @@
+From ad2d88f188922c5267f15e25446e7ece114b5ac0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Mon, 28 Feb 2011 10:35:23 +0100
+Subject: [PATCH 020/126] systemadm: filter on swaps, paths, and timers too.
+ (cherry picked from commit
+ e377ad0d11e1bd9954c6084956494ebbf41b4486)
+
+---
+ src/systemadm.vala |   21 +++++++++++++++------
+ 1 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index e78fd7c..6126eca 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -138,13 +138,16 @@ public class MainWindow : Window {
+                 type_hbox.pack_start(unit_type_combo_box, false, false, 0);
+                 unit_vbox.pack_start(type_hbox, false, false, 0);
+ 
+-                unit_type_combo_box.append_text("Show All");
++                unit_type_combo_box.append_text("All unit types");
++                unit_type_combo_box.append_text("Targets");
+                 unit_type_combo_box.append_text("Services");
+-                unit_type_combo_box.append_text("Sockets");
+                 unit_type_combo_box.append_text("Devices");
+                 unit_type_combo_box.append_text("Mounts");
+                 unit_type_combo_box.append_text("Automounts");
+-                unit_type_combo_box.append_text("Targets");
++                unit_type_combo_box.append_text("Swaps");
++                unit_type_combo_box.append_text("Sockets");
++                unit_type_combo_box.append_text("Paths");
++                unit_type_combo_box.append_text("Timers");
+                 unit_type_combo_box.append_text("Snapshots");
+                 unit_type_combo_box.set_active(0); // Show All
+                 unit_type_combo_box.changed.connect(unit_type_changed);
+@@ -884,9 +887,9 @@ public class MainWindow : Window {
+                 case 0:
+                         return true;
+                 case 1:
+-                        return id.has_suffix(".service");
++                        return id.has_suffix(".target");
+                 case 2:
+-                        return id.has_suffix(".socket");
++                        return id.has_suffix(".service");
+                 case 3:
+                         return id.has_suffix(".device");
+                 case 4:
+@@ -894,8 +897,14 @@ public class MainWindow : Window {
+                 case 5:
+                         return id.has_suffix(".automount");
+                 case 6:
+-                        return id.has_suffix(".target");
++                        return id.has_suffix(".swap");
+                 case 7:
++                        return id.has_suffix(".socket");
++                case 8:
++                        return id.has_suffix(".path");
++                case 9:
++                        return id.has_suffix(".timer");
++                case 10:
+                         return id.has_suffix(".snapshot");
+                 default:
+                         assert(false);
+-- 
+1.7.7.5
+
diff --git a/0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch b/0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch
new file mode 100644
index 0000000..500c847
--- /dev/null
+++ b/0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch
@@ -0,0 +1,133 @@
+From fb6ffd0ed76b175b4eeb1c73b9fd7a3cbcf6ecbb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Tue, 1 Mar 2011 11:18:13 +0100
+Subject: [PATCH 021/126] systemadm: add a wrappable label and use it for
+ status lines
+
+The new WrapLabel is there to work around a deficiency in GTK,
+namely the fact that it is hard to make labels which are both
+resizable and wrappable. The code is a port from libview.
+(cherry picked from commit 0dd27daff4ba4bdad99b12b85b630ab21c84fa9e)
+---
+ Makefile.am        |    3 +-
+ src/systemadm.vala |    7 ++---
+ src/wraplabel.vala |   73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 78 insertions(+), 5 deletions(-)
+ create mode 100644 src/wraplabel.vala
+
+diff --git a/Makefile.am b/Makefile.am
+index 8f1ffdc..54bccb5 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1426,7 +1426,8 @@ systemd_stdio_bridge_LDADD = \
+ 
+ systemadm_SOURCES = \
+ 	src/systemadm.vala \
+-	src/systemd-interfaces.vala
++	src/systemd-interfaces.vala \
++	src/wraplabel.vala
+ 
+ systemadm_CFLAGS = \
+ 	$(AM_CFLAGS) \
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 6126eca..68652d0 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -46,12 +46,11 @@ public class LeftLabel : Label {
+         }
+ }
+ 
+-public class RightLabel : Label {
++public class RightLabel : WrapLabel {
++
+         public RightLabel(string? text = null) {
+-                set_text_or_na(text);
+-                set_alignment(0, 0);
+-                set_ellipsize(EllipsizeMode.START);
+                 set_selectable(true);
++                set_text_or_na(text);
+         }
+ 
+         public void set_text_or_na(string? text = null) {
+diff --git a/src/wraplabel.vala b/src/wraplabel.vala
+new file mode 100644
+index 0000000..49858c3
+--- /dev/null
++++ b/src/wraplabel.vala
+@@ -0,0 +1,73 @@
++// Copyright (c) 2005 VMware, Inc.
++
++// This is a translation of http://git.gnome.org/browse/meld/tree/meld/ui/wraplabel.py,
++// which in turn is a translation of WrapLabel from libview.
++
++// Permission is hereby granted, free of charge, to any person obtaining a copy
++// of this software and associated documentation files (the "Software"), to deal
++// in the Software without restriction, including without limitation the rights
++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++// copies of the Software, and to permit persons to whom the Software is
++// furnished to do so, subject to the following conditions:
++//
++// The above copyright notice and this permission notice shall be included in
++// all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++// SOFTWARE.
++
++// Python translation from wrapLabel.{cc|h} by Gian Mario Tagliaretti
++// Vala translation from wraplabel.py by Zbigniew Jędrzejewski-Szmek
++
++public class WrapLabel : Gtk.Label {
++        private int _wrap_width;
++
++        public WrapLabel(string? text = null) {
++                this._wrap_width = 0;
++                var layout = get_layout();
++                layout.set_wrap(Pango.WrapMode.WORD_CHAR);
++                if (text != null)
++                        this.set_text(text);
++                this.set_alignment(0, 0);
++        }
++
++        public override void size_request(out Gtk.Requisition requisition) {
++                int width, height;
++                var layout = get_layout();
++                layout.get_pixel_size(out width, out height);
++                requisition.width = 0;
++                requisition.height = height;
++        }
++
++        public override void size_allocate(Gdk.Rectangle allocation) {
++                base.size_allocate (allocation);
++                this._set_wrap_width(allocation.width);
++        }
++
++        public new void set_text(string str) {
++                base.set_text(str);
++                this._set_wrap_width(this._wrap_width);
++        }
++
++        public new void set_markup(string str) {
++                base.set_markup(str);
++                this._set_wrap_width(this._wrap_width);
++        }
++
++        private void _set_wrap_width(int width) {
++                if (width == 0)
++                        return;
++
++                var layout = get_layout();
++                layout.set_width(width * Pango.SCALE);
++                if (_wrap_width != width) {
++                        this._wrap_width = width;
++                        this.queue_resize();
++                }
++        }
++}
+-- 
+1.7.7.5
+
diff --git a/0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch b/0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch
new file mode 100644
index 0000000..cd401b8
--- /dev/null
+++ b/0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch
@@ -0,0 +1,101 @@
+From 6c8061acd30f7cb604953dd75f00bb8f8cc7323b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 3 Mar 2011 20:54:01 +0100
+Subject: [PATCH 022/126] systemadm: add libgee as dependency and use it for a
+ unit map (cherry picked from commit
+ 11216eb0bd5aab6b14af004fd2f24d423e3d356d)
+
+---
+ Makefile.am        |    1 +
+ configure.ac       |    2 +-
+ src/systemadm.vala |   14 ++++++++++++++
+ 3 files changed, 16 insertions(+), 1 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 54bccb5..4416ab7 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1440,6 +1440,7 @@ systemadm_CFLAGS = \
+ systemadm_VALAFLAGS = \
+ 	--pkg=posix \
+ 	--pkg=gtk+-2.0 \
++	--pkg=gee-1.0 \
+ 	-g
+ 
+ systemadm_LDADD = \
+diff --git a/configure.ac b/configure.ac
+index 0ec6f69..56b7d7a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -327,7 +327,7 @@ AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"])
+ have_gtk=no
+ AC_ARG_ENABLE(gtk, AS_HELP_STRING([--disable-gtk], [disable GTK tools]))
+ if test "x$enable_gtk" != "xno"; then
+-        PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 ],
++        PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0],
+                 [AC_DEFINE(HAVE_GTK, 1, [Define if GTK is available]) have_gtk=yes], have_gtk=no)
+         AC_SUBST(GTK_CFLAGS)
+         AC_SUBST(GTK_LIBS)
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 68652d0..c893da0 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -79,6 +79,8 @@ public class MainWindow : Window {
+         private ListStore unit_model;
+         private ListStore job_model;
+ 
++        private Gee.HashMap<string, Unit> unit_map;
++
+         private Button start_button;
+         private Button stop_button;
+         private Button restart_button;
+@@ -180,6 +182,8 @@ public class MainWindow : Window {
+                 unit_model = new ListStore(7, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(Unit));
+                 job_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(Job), typeof(uint32));
+ 
++                unit_map = new Gee.HashMap<string, Unit>();
++
+                 TreeModelFilter unit_model_filter;
+                 unit_model_filter = new TreeModelFilter(unit_model, null);
+                 unit_model_filter.set_visible_func(unit_filter);
+@@ -355,6 +359,8 @@ public class MainWindow : Window {
+                                         "org.freedesktop.systemd1",
+                                         i.unit_path);
+ 
++                        unit_map[i.id] = u;
++
+                         unit_model.append(out iter);
+                         unit_model.set(iter,
+                                        0, i.id,
+@@ -415,6 +421,10 @@ public class MainWindow : Window {
+                 return u;
+         }
+ 
++        public Unit? get_unit(string id) {
++                return this.unit_map[id];
++        }
++
+         public void unit_changed() {
+                 Unit u = get_current_unit();
+ 
+@@ -712,6 +722,8 @@ public class MainWindow : Window {
+                                         "org.freedesktop.systemd1",
+                                         path);
+ 
++                        unit_map[id] = u;
++
+                         update_unit_iter(iter, id, u);
+                 } catch (IOError e) {
+                         show_error(e.message);
+@@ -773,6 +785,8 @@ public class MainWindow : Window {
+                         }
+ 
+                 } while (unit_model.iter_next(ref iter));
++
++                unit_map.unset(id);
+         }
+ 
+         public void on_job_removed(uint32 id, ObjectPath path, string res) {
+-- 
+1.7.7.5
+
diff --git a/0023-systemadm-display-dependencies-sorted.patch b/0023-systemadm-display-dependencies-sorted.patch
new file mode 100644
index 0000000..adb2df2
--- /dev/null
+++ b/0023-systemadm-display-dependencies-sorted.patch
@@ -0,0 +1,38 @@
+From 9a11d4dc5b77fc3b9b33f96888f1a46f5a013786 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 3 Mar 2011 01:30:08 +0100
+Subject: [PATCH 023/126] systemadm: display dependencies sorted (cherry
+ picked from commit
+ 8278f06953f5339646e5ff98900321f1525c0a21)
+
+---
+ src/systemadm.vala |    6 +++++-
+ 1 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index c893da0..088ba26 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -458,6 +458,10 @@ public class MainWindow : Window {
+         }
+ 
+         public string make_dependency_string(string? prefix, string word, string[] dependencies) {
++                Gee.Collection<unowned string> sorted = new Gee.TreeSet<string>();
++                foreach (string i in dependencies)
++                        sorted.add(i);
++
+                 bool first = true;
+                 string r;
+ 
+@@ -466,7 +470,7 @@ public class MainWindow : Window {
+                 else
+                         r = prefix;
+ 
+-                foreach (string i in dependencies) {
++                foreach (string i in sorted) {
+                         if (r != "")
+                                 r += first ? "\n" : ",";
+ 
+-- 
+1.7.7.5
+
diff --git a/0024-systemadm-use-color-for-dependency-links.patch b/0024-systemadm-use-color-for-dependency-links.patch
new file mode 100644
index 0000000..22d7410
--- /dev/null
+++ b/0024-systemadm-use-color-for-dependency-links.patch
@@ -0,0 +1,53 @@
+From c9e50116433d60c2f296f7f542e43e13a872cc75 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 3 Mar 2011 22:20:19 +0100
+Subject: [PATCH 024/126] systemadm: use color for dependency links (cherry
+ picked from commit
+ 23b51f17b1cf473bff3ae5332477e2028a5c5f53)
+
+---
+ src/systemadm.vala |   21 ++++++++++++++++++++-
+ 1 files changed, 20 insertions(+), 1 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 088ba26..eed46b5 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -457,6 +457,25 @@ public class MainWindow : Window {
+                 unit_cgroup_label.set_text_or_na();
+         }
+ 
++        public string format_unit_link(string i) {
++                Unit? u = get_unit(i);
++                if(u == null)
++                        return "<span color='grey'>" + i + "</span";
++
++                string color;
++                switch (u.sub_state) {
++                case "active": color = "blue"; break;
++                case "dead": color = "red"; break;
++                case "running": color = "green"; break;
++                default: color = "black"; break;
++                }
++                string span = "<span underline='none' color='" + color + "'>"
++                              + i + "(" +
++                              u.sub_state + ")" + "</span>";
++                return  " <a href='" + i + "'>" + span + "</a>";
++        }
++
++
+         public string make_dependency_string(string? prefix, string word, string[] dependencies) {
+                 Gee.Collection<unowned string> sorted = new Gee.TreeSet<string>();
+                 foreach (string i in dependencies)
+@@ -479,7 +498,7 @@ public class MainWindow : Window {
+                                 first = false;
+                         }
+ 
+-                        r += " <a href=\"" + i + "\">" + i + "</a>";
++                        r += format_unit_link(i);
+                 }
+ 
+                 return r;
+-- 
+1.7.7.5
+
diff --git a/0025-systemadm-use-bold-for-requires-etc.patch b/0025-systemadm-use-bold-for-requires-etc.patch
new file mode 100644
index 0000000..596ac0d
--- /dev/null
+++ b/0025-systemadm-use-bold-for-requires-etc.patch
@@ -0,0 +1,27 @@
+From 4640202a44277e573dda7125d87e43025436fc4a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Sat, 17 Sep 2011 14:57:19 +0100
+Subject: [PATCH 025/126] systemadm: use bold for "requires", etc. (cherry
+ picked from commit
+ 8b1451ade7794c21d29141dc363d0f626e2070ee)
+
+---
+ src/systemadm.vala |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index eed46b5..a3068f1 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -494,7 +494,7 @@ public class MainWindow : Window {
+                                 r += first ? "\n" : ",";
+ 
+                         if (first) {
+-                                r += word;
++                                r += "<b>" + word + ":</b>";
+                                 first = false;
+                         }
+ 
+-- 
+1.7.7.5
+
diff --git a/0026-systemadm-make-the-dependency-listing-selectable.patch b/0026-systemadm-make-the-dependency-listing-selectable.patch
new file mode 100644
index 0000000..a232841
--- /dev/null
+++ b/0026-systemadm-make-the-dependency-listing-selectable.patch
@@ -0,0 +1,27 @@
+From edafba60cbcaab71266f53f3359126c69106b21c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Sun, 18 Sep 2011 11:06:07 +0200
+Subject: [PATCH 026/126] systemadm: make the dependency listing  selectable
+
+There's no reason to forbid selecting the text.
+(cherry picked from commit 37d3b881f1cc7c18d23013ff29429ab67ab5b61d)
+---
+ src/systemadm.vala |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index a3068f1..e7fa354 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -238,7 +238,7 @@ public class MainWindow : Window {
+                 job_type_label = new RightLabel();
+ 
+                 unit_dependency_label.set_track_visited_links(false);
+-                unit_dependency_label.set_selectable(false);
++                unit_dependency_label.set_selectable(true);
+                 unit_dependency_label.activate_link.connect(on_activate_link);
+ 
+                 unit_fragment_path_label.set_track_visited_links(false);
+-- 
+1.7.7.5
+
diff --git a/0027-systemadm-catch-exceptions-generated-by-dbus.patch b/0027-systemadm-catch-exceptions-generated-by-dbus.patch
new file mode 100644
index 0000000..74b63e9
--- /dev/null
+++ b/0027-systemadm-catch-exceptions-generated-by-dbus.patch
@@ -0,0 +1,146 @@
+From 328238ca7c52a658089aa5c8ba0d63dfeaf3c2bd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 24 Feb 2011 16:30:55 +0100
+Subject: [PATCH 027/126] systemadm: catch exceptions generated by dbus
+
+Otherwise, access-denied dbus errors were not caught, and only
+caused a message to be printed out on the console. After this
+change a proper popup window pops up :).
+(cherry picked from commit 734b60d7961a28adab45ef141807a0f3e0ba11e5)
+---
+ src/systemadm.vala |   28 ++++++++++++++--------------
+ 1 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index e7fa354..d420800 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -642,7 +642,7 @@ public class MainWindow : Window {
+ 
+                 try {
+                         u.start("replace");
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -655,7 +655,7 @@ public class MainWindow : Window {
+ 
+                 try {
+                         u.stop("replace");
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -668,7 +668,7 @@ public class MainWindow : Window {
+ 
+                 try {
+                         u.reload("replace");
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -681,7 +681,7 @@ public class MainWindow : Window {
+ 
+                 try {
+                         u.restart("replace");
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -694,7 +694,7 @@ public class MainWindow : Window {
+ 
+                 try {
+                         j.cancel();
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -722,7 +722,7 @@ public class MainWindow : Window {
+                                        4, u.sub_state,
+                                        5, t != "" ? "→ %s".printf(t) : "",
+                                        6, u);
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -748,7 +748,7 @@ public class MainWindow : Window {
+                         unit_map[id] = u;
+ 
+                         update_unit_iter(iter, id, u);
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -784,7 +784,7 @@ public class MainWindow : Window {
+ 
+                         update_job_iter(iter, id, j);
+ 
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -866,7 +866,7 @@ public class MainWindow : Window {
+ 
+                         } while (unit_model.iter_next(ref iter));
+ 
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -902,7 +902,7 @@ public class MainWindow : Window {
+ 
+                         } while (job_model.iter_next(ref iter));
+ 
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -957,7 +957,7 @@ public class MainWindow : Window {
+         public void on_server_reload() {
+                 try {
+                         manager.reload();
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -969,7 +969,7 @@ public class MainWindow : Window {
+                         if (unit_type_combo_box.get_active() != 0)
+                                 unit_type_combo_box.set_active(8);
+ 
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -998,7 +998,7 @@ public class MainWindow : Window {
+                         m.destroy();
+ 
+                         show_unit(u);
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+         }
+@@ -1018,7 +1018,7 @@ public class MainWindow : Window {
+                                         path);
+ 
+                         show_unit(u);
+-                } catch (IOError e) {
++                } catch (Error e) {
+                         show_error(e.message);
+                 }
+ 
+-- 
+1.7.7.5
+
diff --git a/0028-systemadm-coalesce-id-and-decription-fields.patch b/0028-systemadm-coalesce-id-and-decription-fields.patch
new file mode 100644
index 0000000..6e2e5dc
--- /dev/null
+++ b/0028-systemadm-coalesce-id-and-decription-fields.patch
@@ -0,0 +1,83 @@
+From 5581802cca0ebea3b8a3193f94c80cfc4d0a3111 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Sun, 18 Sep 2011 17:00:12 +0200
+Subject: [PATCH 028/126] systemadm: coalesce id and decription fields
+
+This is just in interest of saving space (e.g. 5 lines for multi-user.target).
+(cherry picked from commit 8f38d5a4c6e627180809db739b2bdaa5ca0c645a)
+---
+ src/systemadm.vala |   24 +++++++++++-------------
+ 1 files changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index d420800..4cb5c55 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -96,7 +96,6 @@ public class MainWindow : Window {
+         private Manager manager;
+ 
+         private RightLabel unit_id_label;
+-        private RightLabel unit_aliases_label;
+         private RightLabel unit_dependency_label;
+         private RightLabel unit_description_label;
+         private RightLabel unit_load_state_label;
+@@ -220,7 +219,6 @@ public class MainWindow : Window {
+                 job_vbox.pack_start(scroll, true, true, 0);
+ 
+                 unit_id_label = new RightLabel();
+-                unit_aliases_label = new RightLabel();
+                 unit_dependency_label = new RightLabel();
+                 unit_description_label = new RightLabel();
+                 unit_load_state_label = new RightLabel();
+@@ -255,8 +253,6 @@ public class MainWindow : Window {
+ 
+                 unit_table.attach(new LeftLabel("Id:"),                     0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                 unit_table.attach(unit_id_label,                            1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Aliases:"),                0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_aliases_label,                       1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                 unit_table.attach(new LeftLabel("Description:"),            0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                 unit_table.attach(unit_description_label,                   1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                 unit_table.attach(new LeftLabel("Dependencies:"),           0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+@@ -443,7 +439,6 @@ public class MainWindow : Window {
+                 restart_button.set_sensitive(false);
+ 
+                 unit_id_label.set_text_or_na();
+-                unit_aliases_label.set_text_or_na();
+                 unit_description_label.set_text_or_na();
+                 unit_description_label.set_text_or_na();
+                 unit_load_state_label.set_text_or_na();
+@@ -507,20 +502,23 @@ public class MainWindow : Window {
+         public void show_unit(Unit unit) {
+                 current_unit_id = unit.id;
+ 
+-                unit_id_label.set_text_or_na(current_unit_id);
+-
+-                string a = "";
++                string id_display = current_unit_id;
++                bool has_alias = false;
+                 foreach (string i in unit.names) {
+                         if (i == current_unit_id)
+                                 continue;
+ 
+-                        if (a == "")
+-                                a = i;
+-                        else
+-                                a += "\n" + i;
++                        if (!has_alias) {
++                                id_display += " (aliases:";
++                                has_alias = true;
++                        }
++
++                        id_display += " " + i;
+                 }
++                if(has_alias)
++                        id_display += ")";
+ 
+-                unit_aliases_label.set_text_or_na(a);
++                unit_id_label.set_text_or_na(id_display);
+ 
+                 string[]
+                         requires = unit.requires,
+-- 
+1.7.7.5
+
diff --git a/0029-systemadm-adjust-row-numbers-after-removing-aliases.patch b/0029-systemadm-adjust-row-numbers-after-removing-aliases.patch
new file mode 100644
index 0000000..67619db
--- /dev/null
+++ b/0029-systemadm-adjust-row-numbers-after-removing-aliases.patch
@@ -0,0 +1,75 @@
+From e3eece11dcdef669d90fef5f42428a921cad33b1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Mon, 19 Sep 2011 08:14:02 +0200
+Subject: [PATCH 029/126] systemadm: adjust row numbers after removing
+ 'aliases' (cherry picked from commit
+ fe7e28146f30ec442c0dd7f71002a1b482d910a9)
+
+---
+ src/systemadm.vala |   50 +++++++++++++++++++++++++-------------------------
+ 1 files changed, 25 insertions(+), 25 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 4cb5c55..1118999 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -253,31 +253,31 @@ public class MainWindow : Window {
+ 
+                 unit_table.attach(new LeftLabel("Id:"),                     0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                 unit_table.attach(unit_id_label,                            1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Description:"),            0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_description_label,                   1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Dependencies:"),           0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_dependency_label,                    1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Fragment Path:"),          0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_fragment_path_label,                 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Control Group:"),          0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_cgroup_label,                        1, 6, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-
+-                unit_table.attach(new LeftLabel("Load State:"),             0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_load_state_label,                    1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Active State:"),           0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_active_state_label,                  1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Unit State:"),             0, 1, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_sub_state_label,                     1, 2, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-
+-                unit_table.attach(new LeftLabel("Active Enter Timestamp:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_active_enter_timestamp_label,        3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Active Exit Timestamp:"),  2, 3, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_active_exit_timestamp_label,         3, 4, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-
+-                unit_table.attach(new LeftLabel("Can Start/Stop:"),         4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_can_start_label,                     5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(new LeftLabel("Can Reload:"),             4, 5, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-                unit_table.attach(unit_can_reload_label,                    5, 6, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Description:"),            0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_description_label,                   1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Dependencies:"),           0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_dependency_label,                    1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Fragment Path:"),          0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_fragment_path_label,                 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Control Group:"),          0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_cgroup_label,                        1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++
++                unit_table.attach(new LeftLabel("Load State:"),             0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_load_state_label,                    1, 2, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Active State:"),           0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_active_state_label,                  1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Unit State:"),             0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_sub_state_label,                     1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++
++                unit_table.attach(new LeftLabel("Activated:"),              2, 3, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_active_enter_timestamp_label,        3, 4, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Deactivated:"),            2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_active_exit_timestamp_label,         3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++
++                unit_table.attach(new LeftLabel("Can Start/Stop:"),         4, 5, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_can_start_label,                     5, 6, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(new LeftLabel("Can Reload:"),             4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
++                unit_table.attach(unit_can_reload_label,                    5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+ 
+                 job_table.attach(new LeftLabel("Id:"),                      0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                 job_table.attach(job_id_label,                              1, 2, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+-- 
+1.7.7.5
+
diff --git a/0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch b/0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch
new file mode 100644
index 0000000..5dc7013
--- /dev/null
+++ b/0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch
@@ -0,0 +1,77 @@
+From d21907af22f1c14445521cb6ae5cabccbe186bcc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Mon, 19 Sep 2011 08:20:17 +0200
+Subject: [PATCH 030/126] systemadm: use colors for id too, remove color from
+ fragment link (cherry picked from commit
+ 79b1e6cb8080e5c88754484f5af591ce74714ff0)
+
+---
+ src/systemadm.vala |   17 +++++++++++------
+ 1 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/src/systemadm.vala b/src/systemadm.vala
+index 1118999..5971ac0 100644
+--- a/src/systemadm.vala
++++ b/src/systemadm.vala
+@@ -452,7 +452,7 @@ public class MainWindow : Window {
+                 unit_cgroup_label.set_text_or_na();
+         }
+ 
+-        public string format_unit_link(string i) {
++        public string format_unit_link(string i, bool link) {
+                 Unit? u = get_unit(i);
+                 if(u == null)
+                         return "<span color='grey'>" + i + "</span";
+@@ -467,7 +467,10 @@ public class MainWindow : Window {
+                 string span = "<span underline='none' color='" + color + "'>"
+                               + i + "(" +
+                               u.sub_state + ")" + "</span>";
+-                return  " <a href='" + i + "'>" + span + "</a>";
++                if(link)
++                        return  " <a href='" + i + "'>" + span + "</a>";
++                else
++                        return span;
+         }
+ 
+ 
+@@ -493,7 +496,7 @@ public class MainWindow : Window {
+                                 first = false;
+                         }
+ 
+-                        r += format_unit_link(i);
++                        r += format_unit_link(i, true);
+                 }
+ 
+                 return r;
+@@ -502,7 +505,7 @@ public class MainWindow : Window {
+         public void show_unit(Unit unit) {
+                 current_unit_id = unit.id;
+ 
+-                string id_display = current_unit_id;
++                string id_display = format_unit_link(current_unit_id, false);
+                 bool has_alias = false;
+                 foreach (string i in unit.names) {
+                         if (i == current_unit_id)
+@@ -518,7 +521,7 @@ public class MainWindow : Window {
+                 if(has_alias)
+                         id_display += ")";
+ 
+-                unit_id_label.set_text_or_na(id_display);
++                unit_id_label.set_markup_or_na(id_display);
+ 
+                 string[]
+                         requires = unit.requires,
+@@ -564,7 +567,9 @@ public class MainWindow : Window {
+ 
+                 string fp = unit.fragment_path;
+                 if (fp != "")
+-                        unit_fragment_path_label.set_markup_or_na("<a href=\"file://" + fp +"\">" + fp + "</a>" );
++                        unit_fragment_path_label.set_markup_or_na(
++                                "<a href=\"file://" + fp +"\">" +
++                                "<span underline='none' color='black'>" + fp + "</span></a>");
+                 else
+                         unit_fragment_path_label.set_text_or_na();
+ 
+-- 
+1.7.7.5
+
diff --git a/0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch b/0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch
new file mode 100644
index 0000000..907b81d
--- /dev/null
+++ b/0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch
@@ -0,0 +1,56 @@
+From 54a91c5eae72181cc7aadf618c152e18ac336b5e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 3 Nov 2011 19:42:53 +0100
+Subject: [PATCH 031/126] cgroup: immediately remove all cgroups which run
+ empty
+
+Some controllers have scaling problems when many empty cgroups exist.
+Hence, as soon as we get a notification that a cgroup is empty, delete
+it. This is also nice to keep the systemd-cgls output short.
+(cherry picked from commit 353fa6a21aab96b0b82ab40cc22b08b1fb0bf652)
+---
+ src/cgroup.c |   12 +++++++++---
+ 1 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/src/cgroup.c b/src/cgroup.c
+index be837c3..4bbb54f 100644
+--- a/src/cgroup.c
++++ b/src/cgroup.c
+@@ -363,7 +363,8 @@ int cgroup_notify_empty(Manager *m, const char *group) {
+         assert(m);
+         assert(group);
+ 
+-        if (!(l = hashmap_get(m->cgroup_bondings, group)))
++        l = hashmap_get(m->cgroup_bondings, group);
++        if (!l)
+                 return 0;
+ 
+         LIST_FOREACH(by_path, b, l) {
+@@ -372,7 +373,8 @@ int cgroup_notify_empty(Manager *m, const char *group) {
+                 if (!b->unit)
+                         continue;
+ 
+-                if ((t = cgroup_bonding_is_empty_list(b)) < 0) {
++                t = cgroup_bonding_is_empty_list(b);
++                if (t < 0) {
+ 
+                         /* If we don't know, we don't know */
+                         if (t != -EAGAIN)
+@@ -381,9 +383,13 @@ int cgroup_notify_empty(Manager *m, const char *group) {
+                         continue;
+                 }
+ 
+-                if (t > 0)
++                if (t > 0) {
++                        /* If it is empty, let's delete it */
++                        cgroup_bonding_trim_list(b->unit->meta.cgroup_bondings, true);
++
+                         if (UNIT_VTABLE(b->unit)->cgroup_notify_empty)
+                                 UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit);
++                }
+         }
+ 
+         return 0;
+-- 
+1.7.7.5
+
diff --git a/0032-utmp-remove-unneded-parameters.patch b/0032-utmp-remove-unneded-parameters.patch
new file mode 100644
index 0000000..1dd926f
--- /dev/null
+++ b/0032-utmp-remove-unneded-parameters.patch
@@ -0,0 +1,137 @@
+From 9052b8afdf507b674b2e3abfb803d96c19c0a307 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sun, 6 Nov 2011 23:06:38 +0100
+Subject: [PATCH 032/126] utmp: remove unneded parameters
+
+With these functions no caller ever passes anything else than 0
+for 't' (meaning the current time will be used).
+(cherry picked from commit 0ad26e09de813857382ec3a787fc6df5e52cf98b)
+---
+ src/execute.c     |    2 +-
+ src/systemctl.c   |    2 +-
+ src/update-utmp.c |    4 ++--
+ src/utmp-wtmp.c   |   12 ++++++------
+ src/utmp-wtmp.h   |    6 +++---
+ 5 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/src/execute.c b/src/execute.c
+index 866e8bf..250d53a 100644
+--- a/src/execute.c
++++ b/src/execute.c
+@@ -1170,7 +1170,7 @@ int exec_spawn(ExecCommand *command,
+                         }
+ 
+                 if (context->utmp_id)
+-                        utmp_put_init_process(0, context->utmp_id, getpid(), getsid(0), context->tty_path);
++                        utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
+ 
+                 if (context->user) {
+                         username = context->user;
+diff --git a/src/systemctl.c b/src/systemctl.c
+index b0baf8d..4426f70 100644
+--- a/src/systemctl.c
++++ b/src/systemctl.c
+@@ -5156,7 +5156,7 @@ static int halt_main(DBusConnection *bus) {
+         if (!arg_no_wtmp) {
+                 if (sd_booted() > 0)
+                         log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
+-                else if ((r = utmp_put_shutdown(0)) < 0)
++                else if ((r = utmp_put_shutdown()) < 0)
+                         log_warning("Failed to write utmp record: %s", strerror(-r));
+         }
+ 
+diff --git a/src/update-utmp.c b/src/update-utmp.c
+index 12e4d11..073f28e 100644
+--- a/src/update-utmp.c
++++ b/src/update-utmp.c
+@@ -284,7 +284,7 @@ static int on_shutdown(Context *c) {
+                 }
+ #endif
+ 
+-        if ((q = utmp_put_shutdown(0)) < 0) {
++        if ((q = utmp_put_shutdown()) < 0) {
+                 log_error("Failed to write utmp record: %s", strerror(-q));
+                 r = q;
+         }
+@@ -339,7 +339,7 @@ static int on_runlevel(Context *c) {
+         }
+ #endif
+ 
+-        if ((q = utmp_put_runlevel(0, runlevel, previous)) < 0) {
++        if ((q = utmp_put_runlevel(runlevel, previous)) < 0) {
+                 log_error("Failed to write utmp record: %s", strerror(-q));
+                 r = q;
+         }
+diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
+index b03a3e7..e7b2e3c 100644
+--- a/src/utmp-wtmp.c
++++ b/src/utmp-wtmp.c
+@@ -172,10 +172,10 @@ static int write_entry_both(const struct utmpx *store) {
+         return r;
+ }
+ 
+-int utmp_put_shutdown(usec_t t) {
++int utmp_put_shutdown(void) {
+         struct utmpx store;
+ 
+-        init_entry(&store, t);
++        init_entry(&store, 0);
+ 
+         store.ut_type = RUN_LVL;
+         strncpy(store.ut_user, "shutdown", sizeof(store.ut_user));
+@@ -206,12 +206,12 @@ static const char *sanitize_id(const char *id) {
+         return id + l - sizeof(((struct utmpx*) NULL)->ut_id);
+ }
+ 
+-int utmp_put_init_process(usec_t t, const char *id, pid_t pid, pid_t sid, const char *line) {
++int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line) {
+         struct utmpx store;
+ 
+         assert(id);
+ 
+-        init_timestamp(&store, t);
++        init_timestamp(&store, 0);
+ 
+         store.ut_type = INIT_PROCESS;
+         store.ut_pid = pid;
+@@ -257,7 +257,7 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
+ }
+ 
+ 
+-int utmp_put_runlevel(usec_t t, int runlevel, int previous) {
++int utmp_put_runlevel(int runlevel, int previous) {
+         struct utmpx store;
+         int r;
+ 
+@@ -277,7 +277,7 @@ int utmp_put_runlevel(usec_t t, int runlevel, int previous) {
+         if (previous == runlevel)
+                 return 0;
+ 
+-        init_entry(&store, t);
++        init_entry(&store, 0);
+ 
+         store.ut_type = RUN_LVL;
+         store.ut_pid = (runlevel & 0xFF) | ((previous & 0xFF) << 8);
+diff --git a/src/utmp-wtmp.h b/src/utmp-wtmp.h
+index 4054aff..a5998eb 100644
+--- a/src/utmp-wtmp.h
++++ b/src/utmp-wtmp.h
+@@ -26,12 +26,12 @@
+ 
+ int utmp_get_runlevel(int *runlevel, int *previous);
+ 
+-int utmp_put_shutdown(usec_t timestamp);
++int utmp_put_shutdown(void);
+ int utmp_put_reboot(usec_t timestamp);
+-int utmp_put_runlevel(usec_t timestamp, int runlevel, int previous);
++int utmp_put_runlevel(int runlevel, int previous);
+ 
+ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status);
+-int utmp_put_init_process(usec_t timestamp, const char *id, pid_t pid, pid_t sid, const char *line);
++int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line);
+ 
+ int utmp_wall(const char *message, bool (*match_tty)(const char *tty));
+ 
+-- 
+1.7.7.5
+
diff --git a/0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch b/0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch
new file mode 100644
index 0000000..ff18fcc
--- /dev/null
+++ b/0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch
@@ -0,0 +1,27 @@
+From ddd712b60245be98042ad5212597ef9ec9833ccf Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sun, 6 Nov 2011 23:07:54 +0100
+Subject: [PATCH 033/126] utmp: no need to zero a struct before overwriting it
+ with memcpy (cherry picked from commit
+ b8e47420b32b52619c6c49c98a663bee7929ccbe)
+
+---
+ src/utmp-wtmp.c |    2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
+index e7b2e3c..98c1a25 100644
+--- a/src/utmp-wtmp.c
++++ b/src/utmp-wtmp.c
+@@ -242,8 +242,6 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
+         if (found->ut_pid != pid)
+                 return 0;
+ 
+-        zero(store);
+-
+         memcpy(&store, &lookup, sizeof(store));
+         store.ut_type = DEAD_PROCESS;
+         store.ut_exit.e_termination = code;
+-- 
+1.7.7.5
+
diff --git a/0034-utmp-initialize-store-with-the-found-entry-not-with-.patch b/0034-utmp-initialize-store-with-the-found-entry-not-with-.patch
new file mode 100644
index 0000000..1bd62cf
--- /dev/null
+++ b/0034-utmp-initialize-store-with-the-found-entry-not-with-.patch
@@ -0,0 +1,27 @@
+From b2072011a7998e22f6d8a4f2a815ed3dbab819cc Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sun, 6 Nov 2011 23:31:46 +0100
+Subject: [PATCH 034/126] utmp: initialize store with the found entry, not
+ with the lookup key (cherry picked from commit
+ fa4ad7ceca6c96d9f0b7022819acf8954cba35ea)
+
+---
+ src/utmp-wtmp.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
+index 98c1a25..00e19a3 100644
+--- a/src/utmp-wtmp.c
++++ b/src/utmp-wtmp.c
+@@ -242,7 +242,7 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
+         if (found->ut_pid != pid)
+                 return 0;
+ 
+-        memcpy(&store, &lookup, sizeof(store));
++        memcpy(&store, found, sizeof(store));
+         store.ut_type = DEAD_PROCESS;
+         store.ut_exit.e_termination = code;
+         store.ut_exit.e_exit = status;
+-- 
+1.7.7.5
+
diff --git a/0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch b/0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch
new file mode 100644
index 0000000..806f9ae
--- /dev/null
+++ b/0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch
@@ -0,0 +1,72 @@
+From 404b71bb18c983f62897ed40d9a4b310ddcca86a Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sun, 6 Nov 2011 23:55:06 +0100
+Subject: [PATCH 035/126] utmp: for DEAD_PROCESS write the current time to
+ wtmp
+
+Zeroed .ut_tv values in wtmp confuse chkrootkit.
+
+Reported and debugged by Norman Smith. This is based on his patch,
+but modified to behave more like upstart did in F14 and cleaned up.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=743696
+(cherry picked from commit 4743137a4b7ce6214a06d02872bdfac080b6f131)
+---
+ src/utmp-wtmp.c |   18 +++++++++++++-----
+ 1 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c
+index 00e19a3..217ae1e 100644
+--- a/src/utmp-wtmp.c
++++ b/src/utmp-wtmp.c
+@@ -155,11 +155,11 @@ static int write_entry_wtmp(const struct utmpx *store) {
+         return -errno;
+ }
+ 
+-static int write_entry_both(const struct utmpx *store) {
++static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *store_wtmp) {
+         int r, s;
+ 
+-        r = write_entry_utmp(store);
+-        s = write_entry_wtmp(store);
++        r = write_entry_utmp(store_utmp);
++        s = write_entry_wtmp(store_wtmp);
+ 
+         if (r >= 0)
+                 r = s;
+@@ -172,6 +172,10 @@ static int write_entry_both(const struct utmpx *store) {
+         return r;
+ }
+ 
++static int write_entry_both(const struct utmpx *store) {
++        return write_utmp_wtmp(store, store);
++}
++
+ int utmp_put_shutdown(void) {
+         struct utmpx store;
+ 
+@@ -226,7 +230,7 @@ int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line
+ }
+ 
+ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
+-        struct utmpx lookup, store, *found;
++        struct utmpx lookup, store, store_wtmp, *found;
+ 
+         assert(id);
+ 
+@@ -251,7 +255,11 @@ int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
+         zero(store.ut_host);
+         zero(store.ut_tv);
+ 
+-        return write_entry_both(&store);
++        memcpy(&store_wtmp, &store, sizeof(store_wtmp));
++        /* wtmp wants the current time */
++        init_timestamp(&store_wtmp, 0);
++
++        return write_utmp_wtmp(&store, &store_wtmp);
+ }
+ 
+ 
+-- 
+1.7.7.5
+
diff --git a/0036-man-fix-a-typo-in-signal-number.patch b/0036-man-fix-a-typo-in-signal-number.patch
new file mode 100644
index 0000000..f4fd2fe
--- /dev/null
+++ b/0036-man-fix-a-typo-in-signal-number.patch
@@ -0,0 +1,26 @@
+From abd72ba81496bd84a970faa7daec3bacd6a81356 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Mon, 7 Nov 2011 01:08:21 +0100
+Subject: [PATCH 036/126] man: fix a typo in signal number (cherry picked from
+ commit 75c982a79f68a9209f0bcaf422d50414167bc5d1)
+
+---
+ man/systemd.xml |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/man/systemd.xml b/man/systemd.xml
+index a8a6967..c1766e2 100644
+--- a/man/systemd.xml
++++ b/man/systemd.xml
+@@ -813,7 +813,7 @@
+                                 <listitem><para>Sets the log level to
+                                 <literal>debug</literal>
+                                 (resp. <literal>info</literal> on
+-                                <literal>SIGRTMIN+32</literal>), as
++                                <literal>SIGRTMIN+23</literal>), as
+                                 controlled via
+                                 <varname>systemd.log_level=debug</varname>
+                                 (resp. <varname>systemd.log_level=info</varname>
+-- 
+1.7.7.5
+
diff --git a/0037-units-drop-unnecessary-StandardOutput-syslog.patch b/0037-units-drop-unnecessary-StandardOutput-syslog.patch
new file mode 100644
index 0000000..e77d19d
--- /dev/null
+++ b/0037-units-drop-unnecessary-StandardOutput-syslog.patch
@@ -0,0 +1,79 @@
+From 27b67ec67a39321dd52828002a50868071cb5bbf Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 9 Nov 2011 08:42:03 +0100
+Subject: [PATCH 037/126] units: drop unnecessary 'StandardOutput=syslog'
+
+DefaultStandardOutput is syslog anyway. There's no reason to assume that
+the administrator would want these units to be excluded when he configures
+a different DefaultStandardOutput.
+(cherry picked from commit c99e42c1db91eb1982b90a1aa631f4c4a765f95e)
+---
+ units/quotacheck.service.in              |    1 -
+ units/quotaon.service                    |    1 -
+ units/remount-rootfs.service             |    1 -
+ units/systemd-logind.service.in          |    1 -
+ units/systemd-remount-api-vfs.service.in |    1 -
+ units/systemd-vconsole-setup.service.in  |    1 -
+ 6 files changed, 0 insertions(+), 6 deletions(-)
+
+diff --git a/units/quotacheck.service.in b/units/quotacheck.service.in
+index 27dcb1e..c97b7a4 100644
+--- a/units/quotacheck.service.in
++++ b/units/quotacheck.service.in
+@@ -16,5 +16,4 @@ ConditionPathExists=/sbin/quotacheck
+ Type=oneshot
+ RemainAfterExit=yes
+ ExecStart=@rootlibexecdir@/systemd-quotacheck
+-StandardOutput=syslog
+ TimeoutSec=0
+diff --git a/units/quotaon.service b/units/quotaon.service
+index 2c7b36b..ef2fc8c 100644
+--- a/units/quotaon.service
++++ b/units/quotaon.service
+@@ -16,4 +16,3 @@ ConditionPathExists=/sbin/quotaon
+ Type=oneshot
+ RemainAfterExit=yes
+ ExecStart=/sbin/quotaon -aug
+-StandardOutput=syslog
+diff --git a/units/remount-rootfs.service b/units/remount-rootfs.service
+index 89a16c8..7b63752 100644
+--- a/units/remount-rootfs.service
++++ b/units/remount-rootfs.service
+@@ -17,4 +17,3 @@ Wants=local-fs-pre.target
+ Type=oneshot
+ RemainAfterExit=yes
+ ExecStart=/bin/mount / -o remount
+-StandardOutput=syslog
+diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
+index 4241b8b..c332039 100644
+--- a/units/systemd-logind.service.in
++++ b/units/systemd-logind.service.in
+@@ -15,7 +15,6 @@ ExecStart=@rootlibexecdir@/systemd-logind
+ Type=dbus
+ BusName=org.freedesktop.login1
+ CapabilityBoundingSet=CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER
+-StandardOutput=syslog
+ 
+ # Increase the default a bit in order to allow many simultaneous
+ # logins since we keep one fd open per session.
+diff --git a/units/systemd-remount-api-vfs.service.in b/units/systemd-remount-api-vfs.service.in
+index 6339ee6..f4df0ca 100644
+--- a/units/systemd-remount-api-vfs.service.in
++++ b/units/systemd-remount-api-vfs.service.in
+@@ -17,4 +17,3 @@ Wants=local-fs-pre.target
+ Type=oneshot
+ RemainAfterExit=yes
+ ExecStart=@rootlibexecdir@/systemd-remount-api-vfs
+-StandardOutput=syslog
+diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
+index 91d95d6..673fb6c 100644
+--- a/units/systemd-vconsole-setup.service.in
++++ b/units/systemd-vconsole-setup.service.in
+@@ -16,4 +16,3 @@ Before=sysinit.target shutdown.target
+ Type=oneshot
+ RemainAfterExit=yes
+ ExecStart=@rootlibexecdir@/systemd-vconsole-setup
+-StandardOutput=syslog
+-- 
+1.7.7.5
+
diff --git a/0038-units-fedora-let-rc-local.service-log-to-syslog.patch b/0038-units-fedora-let-rc-local.service-log-to-syslog.patch
new file mode 100644
index 0000000..00bc3ec
--- /dev/null
+++ b/0038-units-fedora-let-rc-local.service-log-to-syslog.patch
@@ -0,0 +1,28 @@
+From a8fda0ca8760ccad7630b9dd4b544577ce97d232 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 9 Nov 2011 08:58:36 +0100
+Subject: [PATCH 038/126] units/fedora: let rc-local.service log to syslog
+
+rc-local.service should not be excluded from the default stdout logging.
+
+Missing logs were noticed by Andrew McNabb in
+ https://bugzilla.redhat.com/show_bug.cgi?id=750032#c3
+(cherry picked from commit 9d7286112d8b54da0294ca0d6bbd7314d890b7e2)
+---
+ units/fedora/rc-local.service |    1 -
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+
+diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
+index f5f940f..106b12c 100644
+--- a/units/fedora/rc-local.service
++++ b/units/fedora/rc-local.service
+@@ -13,6 +13,5 @@ ConditionFileIsExecutable=/etc/rc.d/rc.local
+ Type=forking
+ ExecStart=/etc/rc.d/rc.local start
+ TimeoutSec=0
+-StandardOutput=tty
+ RemainAfterExit=yes
+ SysVStartPriority=99
+-- 
+1.7.7.5
+
diff --git a/0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch b/0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch
new file mode 100644
index 0000000..54fe142
--- /dev/null
+++ b/0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch
@@ -0,0 +1,61 @@
+From 3fdac700a322217421675774e25cfd5cb09c2dd2 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 10 Nov 2011 09:55:47 +0100
+Subject: [PATCH 039/126] service: don't warn if the pidfile still exists
+ after SIGCHLD
+
+A service that drops its privileges may not be able to remove it when it
+exits. The stale pidfile is not a problem as long as the service
+carefully recognizes it on its next start.
+
+systemd would produce a warning after the service exits:
+  PID ... read from file ... does not exist. Your service or init
+  script might be broken.
+
+Silence the warning in this case. Still warn if this error is detected
+when loading the pidfile after service start.
+
+Noticed by Miroslav Lichvar in
+ https://bugzilla.redhat.com/show_bug.cgi?id=752396
+(cherry picked from commit c5419d4239ceb4c3bd0263a0a810cf24a072b3c0)
+---
+ src/service.c |    9 +++++----
+ 1 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/src/service.c b/src/service.c
+index e64d289..d51445e 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -1282,7 +1282,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
+         free(p2);
+ }
+ 
+-static int service_load_pid_file(Service *s, bool warn_if_missing) {
++static int service_load_pid_file(Service *s, bool may_warn) {
+         char *k;
+         int r;
+         pid_t pid;
+@@ -1293,7 +1293,7 @@ static int service_load_pid_file(Service *s, bool warn_if_missing) {
+                 return -ENOENT;
+ 
+         if ((r = read_one_line_file(s->pid_file, &k)) < 0) {
+-                if (warn_if_missing)
++                if (may_warn)
+                         log_warning("Failed to read PID file %s after %s. The service might be broken.",
+                                     s->pid_file, service_state_to_string(s->state));
+                 return r;
+@@ -1306,8 +1306,9 @@ static int service_load_pid_file(Service *s, bool warn_if_missing) {
+                 return r;
+ 
+         if (kill(pid, 0) < 0 && errno != EPERM) {
+-                log_warning("PID %lu read from file %s does not exist. Your service or init script might be broken.",
+-                            (unsigned long) pid, s->pid_file);
++                if (may_warn)
++                        log_warning("PID %lu read from file %s does not exist. Your service or init script might be broken.",
++                                    (unsigned long) pid, s->pid_file);
+                 return -ESRCH;
+         }
+ 
+-- 
+1.7.7.5
+
diff --git a/0040-job-colored-status-messages-on-boot.patch b/0040-job-colored-status-messages-on-boot.patch
new file mode 100644
index 0000000..356bb3f
--- /dev/null
+++ b/0040-job-colored-status-messages-on-boot.patch
@@ -0,0 +1,132 @@
+From dd36a516b3945e64578ab4190499266ae44b1155 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 10 Nov 2011 12:53:39 +0100
+Subject: [PATCH 040/126] job: colored status messages on boot
+
+The lack or green/red status marks on boot has been described by some
+users as "critical", "dramatic", "dealbreaker", "showstopper". Seriously.
+(cherry picked from commit 5831e9b726ab6e76b28a94861a014d3bc2aa3015)
+---
+ src/job.c  |   13 +++++++------
+ src/unit.c |   24 ++++++++++++++++++++----
+ src/unit.h |    2 +-
+ 3 files changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/src/job.c b/src/job.c
+index 20971da..1520d81 100644
+--- a/src/job.c
++++ b/src/job.c
+@@ -484,19 +484,20 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+                 switch (result) {
+ 
+                 case JOB_DONE:
+-                        unit_status_printf(u, "Started %s.\n", unit_description(u));
++                        unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u));
+                         break;
+ 
+                 case JOB_FAILED:
+-                        unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "failed" ANSI_HIGHLIGHT_OFF ", see 'systemctl status %s' for details.\n", unit_description(u), u->meta.id);
++                        unit_status_printf(u, ANSI_HIGHLIGHT_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u));
++                        unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->meta.id);
+                         break;
+ 
+                 case JOB_DEPENDENCY:
+-                        unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "aborted" ANSI_HIGHLIGHT_OFF " because a dependency failed.\n", unit_description(u));
++                        unit_status_printf(u, ANSI_HIGHLIGHT_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u));
+                         break;
+ 
+                 case JOB_TIMEOUT:
+-                        unit_status_printf(u, "Starting %s " ANSI_HIGHLIGHT_ON "timed out" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u), u->meta.id);
++                        unit_status_printf(u, ANSI_HIGHLIGHT_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u));
+                         break;
+ 
+                 default:
+@@ -508,12 +509,12 @@ static void job_print_status_message(Unit *u, JobType t, JobResult result) {
+                 switch (result) {
+ 
+                 case JOB_TIMEOUT:
+-                        unit_status_printf(u, "Stopping %s " ANSI_HIGHLIGHT_ON "timed out" ANSI_HIGHLIGHT_OFF ".\n", unit_description(u), u->meta.id);
++                        unit_status_printf(u, ANSI_HIGHLIGHT_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u));
+                         break;
+ 
+                 case JOB_DONE:
+                 case JOB_FAILED:
+-                        unit_status_printf(u, "Stopped %s.\n", unit_description(u));
++                        unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u));
+                         break;
+ 
+                 default:
+diff --git a/src/unit.c b/src/unit.c
+index 903a8e4..ad4063b 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -924,7 +924,7 @@ int unit_start(Unit *u) {
+ 
+         unit_add_to_dbus_queue(u);
+ 
+-        unit_status_printf(u, "Starting %s...\n", unit_description(u));
++        unit_status_printf(u, NULL, "Starting %s...", unit_description(u));
+         return UNIT_VTABLE(u)->start(u);
+ }
+ 
+@@ -966,7 +966,7 @@ int unit_stop(Unit *u) {
+ 
+         unit_add_to_dbus_queue(u);
+ 
+-        unit_status_printf(u, "Stopping %s...\n", unit_description(u));
++        unit_status_printf(u, NULL, "Stopping %s...", unit_description(u));
+         return UNIT_VTABLE(u)->stop(u);
+ }
+ 
+@@ -2426,8 +2426,11 @@ int unit_coldplug(Unit *u) {
+         return 0;
+ }
+ 
+-void unit_status_printf(Unit *u, const char *format, ...) {
++void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
+         va_list ap;
++        char *s, *e;
++        int err;
++        const unsigned emax = status ? 80 - (sizeof("[  OK  ]")-1) : 80;
+ 
+         assert(u);
+         assert(format);
+@@ -2442,8 +2445,21 @@ void unit_status_printf(Unit *u, const char *format, ...) {
+                 return;
+ 
+         va_start(ap, format);
+-        status_vprintf(format, ap);
++        err = vasprintf(&s, format, ap);
+         va_end(ap);
++        if (err < 0)
++                return;
++
++        e = ellipsize(s, emax, 100);
++        free(s);
++        if (!e)
++                return;
++
++        if (status)
++                status_printf("%s%*s[%s]\n", e, emax - strlen(e), "", status);
++        else
++                status_printf("%s\n", e);
++        free(e);
+ }
+ 
+ bool unit_need_daemon_reload(Unit *u) {
+diff --git a/src/unit.h b/src/unit.h
+index 7da5723..b32c1a7 100644
+--- a/src/unit.h
++++ b/src/unit.h
+@@ -512,7 +512,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants);
+ 
+ int unit_coldplug(Unit *u);
+ 
+-void unit_status_printf(Unit *u, const char *format, ...);
++void unit_status_printf(Unit *u, const char *status, const char *format, ...);
+ 
+ bool unit_need_daemon_reload(Unit *u);
+ 
+-- 
+1.7.7.5
+
diff --git a/0041-man-fix-typo-in-sd_notify.patch b/0041-man-fix-typo-in-sd_notify.patch
new file mode 100644
index 0000000..ae48ece
--- /dev/null
+++ b/0041-man-fix-typo-in-sd_notify.patch
@@ -0,0 +1,27 @@
+From acd5d830990975310998d28800cad086357a80c0 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 11 Nov 2011 10:48:17 +0100
+Subject: [PATCH 041/126] man: fix typo in sd_notify
+
+Noticed by guzu.
+(cherry picked from commit 9f84624270432cdff35c4f499fbdb9e0f94fe705)
+---
+ man/sd_notify.xml |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/man/sd_notify.xml b/man/sd_notify.xml
+index dd0ba93..62347f8 100644
+--- a/man/sd_notify.xml
++++ b/man/sd_notify.xml
+@@ -166,7 +166,7 @@
+                 for details.</para>
+ 
+                 <para><function>sd_notifyf()</function> is similar to
+-                <function>sd_notifyf()</function> but takes a
++                <function>sd_notify()</function> but takes a
+                 <function>printf()</function>-like format string plus
+                 arguments.</para>
+         </refsect1>
+-- 
+1.7.7.5
+
diff --git a/0042-Fix-same-expression-on-both-sides-of.patch b/0042-Fix-same-expression-on-both-sides-of.patch
new file mode 100644
index 0000000..7ff7a88
--- /dev/null
+++ b/0042-Fix-same-expression-on-both-sides-of.patch
@@ -0,0 +1,32 @@
+From b3070998c22feaa3b85337c56fb437527aec962e Mon Sep 17 00:00:00 2001
+From: Thomas Jarosch <thomas.jarosch at intra2net.com>
+Date: Wed, 9 Nov 2011 20:48:31 +0100
+Subject: [PATCH 042/126] Fix same expression on both sides of '&&'
+
+The code should probably look like the statements above it.
+Please verify, I just detected it using cppcheck.
+
+Signed-off-by: Thomas Jarosch <thomas.jarosch at intra2net.com>
+(cherry picked from commit 085c98af4eb17858b4687068f12eccc51a032732)
+---
+ src/unit.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/unit.c b/src/unit.c
+index ad4063b..2a549e2 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -564,8 +564,8 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
+             c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
+             c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
+             c->std_error != EXEC_OUTPUT_KMSG &&
+-            c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
+-            c->std_error != EXEC_OUTPUT_KMSG &&
++            c->std_error != EXEC_OUTPUT_SYSLOG &&
++            c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
+             c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
+                 return 0;
+ 
+-- 
+1.7.7.5
+
diff --git a/0043-execute-avoid-logging-to-closed-fds.patch b/0043-execute-avoid-logging-to-closed-fds.patch
new file mode 100644
index 0000000..1898c0c
--- /dev/null
+++ b/0043-execute-avoid-logging-to-closed-fds.patch
@@ -0,0 +1,61 @@
+From 838ad64f4f4502f370dcbf5faaed94b618bdac08 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 16 Nov 2011 23:45:01 +0100
+Subject: [PATCH 043/126] execute: avoid logging to closed fds
+
+Several functions called from the "sd(EXEC)" process try to log messages
+when all the file descriptors are already closed, including the logging
+ones. The logging functions do not expect their fds to be closed and
+they hit an assertion failure. The failure wants to be logged too,
+so there is an infinite recursion, ended by a SIGSEGV.
+
+When we close all fds, we must let log.c know about it.
+(cherry picked from commit 4d8a7798e7f12c6400495cbc4d0ad57ed20ce90a)
+---
+ src/execute.c |    1 +
+ src/log.c     |    4 ++++
+ src/log.h     |    1 +
+ 3 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/src/execute.c b/src/execute.c
+index 250d53a..0651014 100644
+--- a/src/execute.c
++++ b/src/execute.c
+@@ -1016,6 +1016,7 @@ int exec_spawn(ExecCommand *command,
+                 /* Close sockets very early to make sure we don't
+                  * block init reexecution because it cannot bind its
+                  * sockets */
++                log_forget_fds();
+                 if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
+                                   socket_fd >= 0 ? 1 : n_fds) < 0) {
+                         r = EXIT_FDS;
+diff --git a/src/log.c b/src/log.c
+index b8ce122..5c5b734 100644
+--- a/src/log.c
++++ b/src/log.c
+@@ -237,6 +237,10 @@ void log_close(void) {
+         log_close_syslog();
+ }
+ 
++void log_forget_fds(void) {
++        console_fd = kmsg_fd = syslog_fd = -1;
++}
++
+ void log_set_max_level(int level) {
+         assert((level & LOG_PRIMASK) == level);
+ 
+diff --git a/src/log.h b/src/log.h
+index c402afb..9942e3e 100644
+--- a/src/log.h
++++ b/src/log.h
+@@ -57,6 +57,7 @@ int log_get_max_level(void);
+ 
+ int log_open(void);
+ void log_close(void);
++void log_forget_fds(void);
+ 
+ void log_close_syslog(void);
+ void log_close_kmsg(void);
+-- 
+1.7.7.5
+
diff --git a/0044-execute-make-setup_pam-return-errno-when-possible.patch b/0044-execute-make-setup_pam-return-errno-when-possible.patch
new file mode 100644
index 0000000..17f8b96
--- /dev/null
+++ b/0044-execute-make-setup_pam-return-errno-when-possible.patch
@@ -0,0 +1,49 @@
+From 859dc200c20c5dd7e49e443bd29ab6c31dfb0b69 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 17 Nov 2011 00:16:22 +0100
+Subject: [PATCH 044/126] execute: make setup_pam() return -errno when
+ possible
+
+The only caller currently checks if the result is non-zero,
+so nothing changes there.
+(cherry picked from commit 9ba353983adc026b75a503c1381f6e5c8062f3e0)
+---
+ src/execute.c |    8 +++++++-
+ 1 files changed, 7 insertions(+), 1 deletions(-)
+
+diff --git a/src/execute.c b/src/execute.c
+index 0651014..2039861 100644
+--- a/src/execute.c
++++ b/src/execute.c
+@@ -716,6 +716,7 @@ static int setup_pam(
+         pam_handle_t *handle = NULL;
+         sigset_t ss, old_ss;
+         int pam_code = PAM_SUCCESS;
++        int err;
+         char **e = NULL;
+         bool close_session = false;
+         pid_t pam_pid = 0, parent_pid;
+@@ -835,6 +836,11 @@ static int setup_pam(
+         return 0;
+ 
+ fail:
++        if (pam_code != PAM_SUCCESS)
++                err = -EPERM;  /* PAM errors do not map to errno */
++        else
++                err = -errno;
++
+         if (handle) {
+                 if (close_session)
+                         pam_code = pam_close_session(handle, PAM_DATA_SILENT);
+@@ -851,7 +857,7 @@ fail:
+                 kill(pam_pid, SIGCONT);
+         }
+ 
+-        return EXIT_PAM;
++        return err;
+ }
+ #endif
+ 
+-- 
+1.7.7.5
+
diff --git a/0045-execute-log-errors-from-sd-EXEC.patch b/0045-execute-log-errors-from-sd-EXEC.patch
new file mode 100644
index 0000000..dcfdc14
--- /dev/null
+++ b/0045-execute-log-errors-from-sd-EXEC.patch
@@ -0,0 +1,478 @@
+From 43516d8c437d0afd7f4a70592487291e45675101 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 17 Nov 2011 00:21:16 +0100
+Subject: [PATCH 045/126] execute: log errors from "sd(EXEC)"
+
+To give the administrator more hints about failures occuring in spawning
+of commands than just the exit code, log the strerror.
+All fds are closed, so reopen the log.
+
+Related-to: https://bugzilla.redhat.com/show_bug.cgi?id=752901
+(cherry picked from commit 4c2630ebf23b6348174f0bdf1110e90efe45259c)
+---
+ src/execute.c     |  138 +++++++++++++++++++++++++++++++++++++++--------------
+ src/exit-status.c |    3 +
+ src/exit-status.h |    3 +-
+ 3 files changed, 107 insertions(+), 37 deletions(-)
+
+diff --git a/src/execute.c b/src/execute.c
+index 2039861..481725d 100644
+--- a/src/execute.c
++++ b/src/execute.c
+@@ -989,7 +989,7 @@ int exec_spawn(ExecCommand *command,
+         }
+ 
+         if (pid == 0) {
+-                int i;
++                int i, err;
+                 sigset_t ss;
+                 const char *username = NULL, *home = NULL;
+                 uid_t uid = (uid_t) -1;
+@@ -1015,6 +1015,7 @@ int exec_spawn(ExecCommand *command,
+ 
+                 if (sigemptyset(&ss) < 0 ||
+                     sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
++                        err = -errno;
+                         r = EXIT_SIGNAL_MASK;
+                         goto fail_child;
+                 }
+@@ -1023,14 +1024,16 @@ int exec_spawn(ExecCommand *command,
+                  * block init reexecution because it cannot bind its
+                  * sockets */
+                 log_forget_fds();
+-                if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
+-                                  socket_fd >= 0 ? 1 : n_fds) < 0) {
++                err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
++                                           socket_fd >= 0 ? 1 : n_fds);
++                if (err < 0) {
+                         r = EXIT_FDS;
+                         goto fail_child;
+                 }
+ 
+                 if (!context->same_pgrp)
+                         if (setsid() < 0) {
++                                err = -errno;
+                                 r = EXIT_SETSID;
+                                 goto fail_child;
+                         }
+@@ -1038,12 +1041,14 @@ int exec_spawn(ExecCommand *command,
+                 if (context->tcpwrap_name) {
+                         if (socket_fd >= 0)
+                                 if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
++                                        err = -EACCES;
+                                         r = EXIT_TCPWRAP;
+                                         goto fail_child;
+                                 }
+ 
+                         for (i = 0; i < (int) n_fds; i++) {
+                                 if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
++                                        err = -EACCES;
+                                         r = EXIT_TCPWRAP;
+                                         goto fail_child;
+                                 }
+@@ -1059,11 +1064,14 @@ int exec_spawn(ExecCommand *command,
+ 
+                         /* Set up terminal for the question */
+                         if ((r = setup_confirm_stdio(context,
+-                                                     &saved_stdin, &saved_stdout)))
++                                                     &saved_stdin, &saved_stdout))) {
++                                err = -errno;
+                                 goto fail_child;
++                        }
+ 
+                         /* Now ask the question. */
+                         if (!(line = exec_command_line(argv))) {
++                                err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+@@ -1072,18 +1080,21 @@ int exec_spawn(ExecCommand *command,
+                         free(line);
+ 
+                         if (r < 0 || response == 'n') {
++                                err = -ECANCELED;
+                                 r = EXIT_CONFIRM;
+                                 goto fail_child;
+                         } else if (response == 's') {
+-                                r = 0;
++                                err = r = 0;
+                                 goto fail_child;
+                         }
+ 
+                         /* Release terminal for the question */
+                         if ((r = restore_confirm_stdio(context,
+                                                        &saved_stdin, &saved_stdout,
+-                                                       &keep_stdin, &keep_stdout)))
++                                                       &keep_stdin, &keep_stdout))) {
++                                err = -errno;
+                                 goto fail_child;
++                        }
+                 }
+ 
+                 /* If a socket is connected to STDIN/STDOUT/STDERR, we
+@@ -1091,28 +1102,35 @@ int exec_spawn(ExecCommand *command,
+                 if (socket_fd >= 0)
+                         fd_nonblock(socket_fd, false);
+ 
+-                if (!keep_stdin)
+-                        if (setup_input(context, socket_fd, apply_tty_stdin) < 0) {
++                if (!keep_stdin) {
++                        err = setup_input(context, socket_fd, apply_tty_stdin);
++                        if (err < 0) {
+                                 r = EXIT_STDIN;
+                                 goto fail_child;
+                         }
++                }
+ 
+-                if (!keep_stdout)
+-                        if (setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin) < 0) {
++                if (!keep_stdout) {
++                        err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
++                        if (err < 0) {
+                                 r = EXIT_STDOUT;
+                                 goto fail_child;
+                         }
++                }
+ 
+-                if (setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin) < 0) {
++                err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin);
++                if (err < 0) {
+                         r = EXIT_STDERR;
+                         goto fail_child;
+                 }
+ 
+-                if (cgroup_bondings)
+-                        if (cgroup_bonding_install_list(cgroup_bondings, 0) < 0) {
++                if (cgroup_bondings) {
++                        err = cgroup_bonding_install_list(cgroup_bondings, 0);
++                        if (err < 0) {
+                                 r = EXIT_CGROUP;
+                                 goto fail_child;
+                         }
++                }
+ 
+                 if (context->oom_score_adjust_set) {
+                         char t[16];
+@@ -1133,6 +1151,7 @@ int exec_spawn(ExecCommand *command,
+ 
+                                 if (write_one_line_file("/proc/self/oom_adj", t) < 0
+                                     && errno != EACCES) {
++                                        err = -errno;
+                                         r = EXIT_OOM_ADJUST;
+                                         goto fail_child;
+                                 }
+@@ -1141,6 +1160,7 @@ int exec_spawn(ExecCommand *command,
+ 
+                 if (context->nice_set)
+                         if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
++                                err = -errno;
+                                 r = EXIT_NICE;
+                                 goto fail_child;
+                         }
+@@ -1153,6 +1173,7 @@ int exec_spawn(ExecCommand *command,
+ 
+                         if (sched_setscheduler(0, context->cpu_sched_policy |
+                                                (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), &param) < 0) {
++                                err = -errno;
+                                 r = EXIT_SETSCHEDULER;
+                                 goto fail_child;
+                         }
+@@ -1160,18 +1181,21 @@ int exec_spawn(ExecCommand *command,
+ 
+                 if (context->cpuset)
+                         if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
++                                err = -errno;
+                                 r = EXIT_CPUAFFINITY;
+                                 goto fail_child;
+                         }
+ 
+                 if (context->ioprio_set)
+                         if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
++                                err = -errno;
+                                 r = EXIT_IOPRIO;
+                                 goto fail_child;
+                         }
+ 
+                 if (context->timer_slack_nsec_set)
+                         if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
++                                err = -errno;
+                                 r = EXIT_TIMERSLACK;
+                                 goto fail_child;
+                         }
+@@ -1181,36 +1205,45 @@ int exec_spawn(ExecCommand *command,
+ 
+                 if (context->user) {
+                         username = context->user;
+-                        if (get_user_creds(&username, &uid, &gid, &home) < 0) {
++                        err = get_user_creds(&username, &uid, &gid, &home);
++                        if (err < 0) {
+                                 r = EXIT_USER;
+                                 goto fail_child;
+                         }
+ 
+-                        if (is_terminal_input(context->std_input))
+-                                if (chown_terminal(STDIN_FILENO, uid) < 0) {
++                        if (is_terminal_input(context->std_input)) {
++                                err = chown_terminal(STDIN_FILENO, uid);
++                                if (err < 0) {
+                                         r = EXIT_STDIN;
+                                         goto fail_child;
+                                 }
++                        }
+ 
+-                        if (cgroup_bondings && context->control_group_modify)
+-                                if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 ||
+-                                    cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) {
++                        if (cgroup_bondings && context->control_group_modify) {
++                                err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid);
++                                if (err >= 0)
++                                        err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid);
++                                if (err < 0) {
+                                         r = EXIT_CGROUP;
+                                         goto fail_child;
+                                 }
++                        }
+                 }
+ 
+-                if (apply_permissions)
+-                        if (enforce_groups(context, username, gid) < 0) {
++                if (apply_permissions) {
++                        err = enforce_groups(context, username, gid);
++                        if (err < 0) {
+                                 r = EXIT_GROUP;
+                                 goto fail_child;
+                         }
++                }
+ 
+                 umask(context->umask);
+ 
+ #ifdef HAVE_PAM
+                 if (context->pam_name && username) {
+-                        if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) != 0) {
++                        err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds);
++                        if (err < 0) {
+                                 r = EXIT_PAM;
+                                 goto fail_child;
+                         }
+@@ -1218,6 +1251,7 @@ int exec_spawn(ExecCommand *command,
+ #endif
+                 if (context->private_network) {
+                         if (unshare(CLONE_NEWNET) < 0) {
++                                err = -errno;
+                                 r = EXIT_NETWORK;
+                                 goto fail_child;
+                         }
+@@ -1229,23 +1263,28 @@ int exec_spawn(ExecCommand *command,
+                     strv_length(context->read_only_dirs) > 0 ||
+                     strv_length(context->inaccessible_dirs) > 0 ||
+                     context->mount_flags != MS_SHARED ||
+-                    context->private_tmp)
+-                        if ((r = setup_namespace(
+-                                             context->read_write_dirs,
+-                                             context->read_only_dirs,
+-                                             context->inaccessible_dirs,
+-                                             context->private_tmp,
+-                                             context->mount_flags)) < 0)
++                    context->private_tmp) {
++                        err = setup_namespace(context->read_write_dirs,
++                                              context->read_only_dirs,
++                                              context->inaccessible_dirs,
++                                              context->private_tmp,
++                                              context->mount_flags);
++                        if (err < 0) {
++                                r = EXIT_NAMESPACE;
+                                 goto fail_child;
++                        }
++                }
+ 
+                 if (apply_chroot) {
+                         if (context->root_directory)
+                                 if (chroot(context->root_directory) < 0) {
++                                        err = -errno;
+                                         r = EXIT_CHROOT;
+                                         goto fail_child;
+                                 }
+ 
+                         if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
++                                err = -errno;
+                                 r = EXIT_CHDIR;
+                                 goto fail_child;
+                         }
+@@ -1256,11 +1295,13 @@ int exec_spawn(ExecCommand *command,
+                         if (asprintf(&d, "%s/%s",
+                                      context->root_directory ? context->root_directory : "",
+                                      context->working_directory ? context->working_directory : "") < 0) {
++                                err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+ 
+                         if (chdir(d) < 0) {
++                                err = -errno;
+                                 free(d);
+                                 r = EXIT_CHDIR;
+                                 goto fail_child;
+@@ -1271,9 +1312,12 @@ int exec_spawn(ExecCommand *command,
+ 
+                 /* We repeat the fd closing here, to make sure that
+                  * nothing is leaked from the PAM modules */
+-                if (close_all_fds(fds, n_fds) < 0 ||
+-                    shift_fds(fds, n_fds) < 0 ||
+-                    flags_fds(fds, n_fds, context->non_blocking) < 0) {
++                err = close_all_fds(fds, n_fds);
++                if (err >= 0)
++                        err = shift_fds(fds, n_fds);
++                if (err >= 0)
++                        err = flags_fds(fds, n_fds, context->non_blocking);
++                if (err < 0) {
+                         r = EXIT_FDS;
+                         goto fail_child;
+                 }
+@@ -1285,22 +1329,27 @@ int exec_spawn(ExecCommand *command,
+                                         continue;
+ 
+                                 if (setrlimit(i, context->rlimit[i]) < 0) {
++                                        err = -errno;
+                                         r = EXIT_LIMITS;
+                                         goto fail_child;
+                                 }
+                         }
+ 
+-                        if (context->capability_bounding_set_drop)
+-                                if (do_capability_bounding_set_drop(context->capability_bounding_set_drop) < 0) {
++                        if (context->capability_bounding_set_drop) {
++                                err = do_capability_bounding_set_drop(context->capability_bounding_set_drop);
++                                if (err < 0) {
+                                         r = EXIT_CAPABILITIES;
+                                         goto fail_child;
+                                 }
++                        }
+ 
+-                        if (context->user)
+-                                if (enforce_user(context, uid) < 0) {
++                        if (context->user) {
++                                err = enforce_user(context, uid);
++                                if (err < 0) {
+                                         r = EXIT_USER;
+                                         goto fail_child;
+                                 }
++                        }
+ 
+                         /* PR_GET_SECUREBITS is not privileged, while
+                          * PR_SET_SECUREBITS is. So to suppress
+@@ -1308,18 +1357,21 @@ int exec_spawn(ExecCommand *command,
+                          * PR_SET_SECUREBITS unless necessary. */
+                         if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
+                                 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
++                                        err = -errno;
+                                         r = EXIT_SECUREBITS;
+                                         goto fail_child;
+                                 }
+ 
+                         if (context->capabilities)
+                                 if (cap_set_proc(context->capabilities) < 0) {
++                                        err = -errno;
+                                         r = EXIT_CAPABILITIES;
+                                         goto fail_child;
+                                 }
+                 }
+ 
+                 if (!(our_env = new0(char*, 7))) {
++                        err = -ENOMEM;
+                         r = EXIT_MEMORY;
+                         goto fail_child;
+                 }
+@@ -1327,12 +1379,14 @@ int exec_spawn(ExecCommand *command,
+                 if (n_fds > 0)
+                         if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
+                             asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) {
++                                err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+ 
+                 if (home)
+                         if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) {
++                                err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+@@ -1340,6 +1394,7 @@ int exec_spawn(ExecCommand *command,
+                 if (username)
+                         if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
+                             asprintf(our_env + n_env++, "USER=%s", username) < 0) {
++                                err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+@@ -1348,6 +1403,7 @@ int exec_spawn(ExecCommand *command,
+                     context->std_output == EXEC_OUTPUT_TTY ||
+                     context->std_error == EXEC_OUTPUT_TTY)
+                         if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) {
++                                err = -ENOMEM;
+                                 r = EXIT_MEMORY;
+                                 goto fail_child;
+                         }
+@@ -1362,11 +1418,13 @@ int exec_spawn(ExecCommand *command,
+                                       files_env,
+                                       pam_env,
+                                       NULL))) {
++                        err = -ENOMEM;
+                         r = EXIT_MEMORY;
+                         goto fail_child;
+                 }
+ 
+                 if (!(final_argv = replace_env_argv(argv, final_env))) {
++                        err = -ENOMEM;
+                         r = EXIT_MEMORY;
+                         goto fail_child;
+                 }
+@@ -1374,9 +1432,17 @@ int exec_spawn(ExecCommand *command,
+                 final_env = strv_env_clean(final_env);
+ 
+                 execve(command->path, final_argv, final_env);
++                err = -errno;
+                 r = EXIT_EXEC;
+ 
+         fail_child:
++                if (r != 0) {
++                        log_open();
++                        log_warning("Failed at step %s spawning %s: %s",
++                                    exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
++                                    command->path, strerror(-err));
++                }
++
+                 strv_free(our_env);
+                 strv_free(final_env);
+                 strv_free(pam_env);
+diff --git a/src/exit-status.c b/src/exit-status.c
+index 8ed1a0e..ab8907d 100644
+--- a/src/exit-status.c
++++ b/src/exit-status.c
+@@ -119,6 +119,9 @@ const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) {
+ 
+                 case EXIT_NETWORK:
+                         return "NETWORK";
++
++                case EXIT_NAMESPACE:
++                        return "NAMESPACE";
+                 }
+         }
+ 
+diff --git a/src/exit-status.h b/src/exit-status.h
+index 3e977b1..44ef879 100644
+--- a/src/exit-status.h
++++ b/src/exit-status.h
+@@ -65,7 +65,8 @@ typedef enum ExitStatus {
+         EXIT_STDERR,
+         EXIT_TCPWRAP,
+         EXIT_PAM,
+-        EXIT_NETWORK
++        EXIT_NETWORK,
++        EXIT_NAMESPACE
+ 
+ } ExitStatus;
+ 
+-- 
+1.7.7.5
+
diff --git a/0046-pam-module-use-the-correct-session-type-unspecified.patch b/0046-pam-module-use-the-correct-session-type-unspecified.patch
new file mode 100644
index 0000000..e394873
--- /dev/null
+++ b/0046-pam-module-use-the-correct-session-type-unspecified.patch
@@ -0,0 +1,28 @@
+From d9e63f3d535758350a83b9b39050e98e01d8d638 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 19 Nov 2011 01:14:11 +0100
+Subject: [PATCH 046/126] pam-module: use the correct session type
+ "unspecified"
+
+logind does not understand "other".
+(cherry picked from commit 1dc995370987660ff045ff4d7cf512da0390cf96)
+---
+ src/pam-module.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/pam-module.c b/src/pam-module.c
+index dd05f93..e650886 100644
+--- a/src/pam-module.c
++++ b/src/pam-module.c
+@@ -472,7 +472,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
+                 get_seat_from_display(display, &seat, &vtnr);
+ 
+         type = !isempty(display) ? "x11" :
+-                   !isempty(tty) ? "tty" : "other";
++                   !isempty(tty) ? "tty" : "unspecified";
+ 
+         remote = !isempty(remote_host) && !streq(remote_host, "localhost") && !streq(remote_host, "localhost.localdomain");
+ 
+-- 
+1.7.7.5
+
diff --git a/0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch b/0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch
new file mode 100644
index 0000000..9e99b0e
--- /dev/null
+++ b/0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch
@@ -0,0 +1,55 @@
+From ecac03685b4679d53c0ec86db257e061bec2d2c9 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 19 Nov 2011 01:17:46 +0100
+Subject: [PATCH 047/126] pam-module: treat "cron" in PAM_TTY as empty tty
+
+cron sets PAM_TTY to "cron" and it has been doing it for a long time.
+It cannot be changed because user configurations may depend on it.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=727315
+(cherry picked from commit 1a4459d63323cdfdb8751077e555ddbbf80564b1)
+---
+ src/logind-session.c |    4 ++--
+ src/pam-module.c     |    4 ++++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/logind-session.c b/src/logind-session.c
+index b0a09e3..63ee758 100644
+--- a/src/logind-session.c
++++ b/src/logind-session.c
+@@ -536,7 +536,7 @@ int session_start(Session *s) {
+         if (r < 0)
+                 return r;
+ 
+-        log_full(s->display || s->tty ? LOG_INFO : LOG_DEBUG,
++        log_full(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
+                  "New session %s of user %s.", s->id, s->user->name);
+ 
+         /* Create cgroup */
+@@ -659,7 +659,7 @@ int session_stop(Session *s) {
+         assert(s);
+ 
+         if (s->started)
+-                log_full(s->display || s->tty ? LOG_INFO : LOG_DEBUG,
++                log_full(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
+                          "Removed session %s.", s->id);
+ 
+         /* Kill cgroup */
+diff --git a/src/pam-module.c b/src/pam-module.c
+index e650886..46b7bec 100644
+--- a/src/pam-module.c
++++ b/src/pam-module.c
+@@ -463,6 +463,10 @@ _public_ PAM_EXTERN int pam_sm_open_session(
+                 if (isempty(display))
+                         display = tty;
+                 tty = "";
++        } else if (streq(tty, "cron")) {
++                /* cron has been setting PAM_TTY to "cron" for a very long time
++                 * and it cannot stop doing that for compatibility reasons. */
++                tty = "";
+         }
+ 
+         if (!isempty(cvtnr))
+-- 
+1.7.7.5
+
diff --git a/0048-let-mount-and-swap-units-log-to-the-configured-defau.patch b/0048-let-mount-and-swap-units-log-to-the-configured-defau.patch
new file mode 100644
index 0000000..968e536
--- /dev/null
+++ b/0048-let-mount-and-swap-units-log-to-the-configured-defau.patch
@@ -0,0 +1,56 @@
+From 003cb5ce02b9660a790ab330796e92b5d79806b6 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 19 Nov 2011 02:47:09 +0100
+Subject: [PATCH 048/126] let mount and swap units log to the configured
+ defaults
+
+Related-to: https://bugzilla.redhat.com/show_bug.cgi?id=750032
+(cherry picked from commit f6cebb3bd5a00d79c8131637c0f6796a75e6af99)
+---
+ src/mount.c |    6 ++++--
+ src/swap.c  |    5 +++--
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/mount.c b/src/mount.c
+index f9cfe91..47422cc 100644
+--- a/src/mount.c
++++ b/src/mount.c
+@@ -68,8 +68,10 @@ static void mount_init(Unit *u) {
+ 
+         /* The stdio/kmsg bridge socket is on /, in order to avoid a
+          * dep loop, don't use kmsg logging for -.mount */
+-        if (!unit_has_name(u, "-.mount"))
+-                m->exec_context.std_output = EXEC_OUTPUT_KMSG;
++        if (!unit_has_name(u, "-.mount")) {
++                m->exec_context.std_output = u->meta.manager->default_std_output;
++                m->exec_context.std_error = u->meta.manager->default_std_error;
++        }
+ 
+         /* We need to make sure that /bin/mount is always called in
+          * the same process group as us, so that the autofs kernel
+diff --git a/src/swap.c b/src/swap.c
+index 54a8640..4fa30a3 100644
+--- a/src/swap.c
++++ b/src/swap.c
+@@ -74,7 +74,7 @@ static void swap_unset_proc_swaps(Swap *s) {
+         s->parameters_proc_swaps.what = NULL;
+ }
+ 
+- static void swap_init(Unit *u) {
++static void swap_init(Unit *u) {
+         Swap *s = SWAP(u);
+ 
+         assert(s);
+@@ -83,7 +83,8 @@ static void swap_unset_proc_swaps(Swap *s) {
+         s->timeout_usec = DEFAULT_TIMEOUT_USEC;
+ 
+         exec_context_init(&s->exec_context);
+-        s->exec_context.std_output = EXEC_OUTPUT_KMSG;
++        s->exec_context.std_output = u->meta.manager->default_std_output;
++        s->exec_context.std_error = u->meta.manager->default_std_error;
+ 
+         s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
+ 
+-- 
+1.7.7.5
+
diff --git a/0049-socket-add-option-for-SO_PASSCRED.patch b/0049-socket-add-option-for-SO_PASSCRED.patch
new file mode 100644
index 0000000..45b0769
--- /dev/null
+++ b/0049-socket-add-option-for-SO_PASSCRED.patch
@@ -0,0 +1,94 @@
+From 1a542f80955b0d425412f5c3dd604483747db133 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 29 Nov 2011 22:15:41 +0100
+Subject: [PATCH 049/126] socket: add option for SO_PASSCRED
+
+Add an option to enable SO_PASSCRED for unix sockets.
+(cherry picked from commit d68af58657ce0e99594dff199fbb9b319cf6af96)
+---
+ src/dbus-socket.c                |    2 ++
+ src/load-fragment-gperf.gperf.m4 |    1 +
+ src/socket.c                     |    8 ++++++++
+ src/socket.h                     |    1 +
+ 4 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/src/dbus-socket.c b/src/dbus-socket.c
+index 2a1a17d..37ab7eb 100644
+--- a/src/dbus-socket.c
++++ b/src/dbus-socket.c
+@@ -51,6 +51,7 @@
+         "  <property name=\"FreeBind\" type=\"b\" access=\"read\"/>\n"  \
+         "  <property name=\"Transparent\" type=\"b\" access=\"read\"/>\n" \
+         "  <property name=\"Broadcast\" type=\"b\" access=\"read\"/>\n" \
++        "  <property name=\"PassCred\" type=\"b\" access=\"read\"/>\n" \
+         "  <property name=\"Mark\" type=\"i\" access=\"read\"/>\n"      \
+         "  <property name=\"MaxConnections\" type=\"u\" access=\"read\"/>\n" \
+         "  <property name=\"NAccepted\" type=\"u\" access=\"read\"/>\n" \
+@@ -113,6 +114,7 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes
+                 { "org.freedesktop.systemd1.Socket", "FreeBind",       bus_property_append_bool,         "b", &u->socket.free_bind       },
+                 { "org.freedesktop.systemd1.Socket", "Transparent",    bus_property_append_bool,         "b", &u->socket.transparent     },
+                 { "org.freedesktop.systemd1.Socket", "Broadcast",      bus_property_append_bool,         "b", &u->socket.broadcast       },
++                { "org.freedesktop.systemd1.Socket", "PassCred",       bus_property_append_bool,         "b", &u->socket.pass_cred       },
+                 { "org.freedesktop.systemd1.Socket", "Mark",           bus_property_append_int,          "i", &u->socket.mark            },
+                 { "org.freedesktop.systemd1.Socket", "MaxConnections", bus_property_append_unsigned,     "u", &u->socket.max_connections },
+                 { "org.freedesktop.systemd1.Socket", "NConnections",   bus_property_append_unsigned,     "u", &u->socket.n_connections   },
+diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
+index 41797d2..84ae28c 100644
+--- a/src/load-fragment-gperf.gperf.m4
++++ b/src/load-fragment-gperf.gperf.m4
+@@ -177,6 +177,7 @@ Socket.PipeSize,                 config_parse_size,                  0,
+ Socket.FreeBind,                 config_parse_bool,                  0,                             offsetof(Socket, free_bind)
+ Socket.Transparent,              config_parse_bool,                  0,                             offsetof(Socket, transparent)
+ Socket.Broadcast,                config_parse_bool,                  0,                             offsetof(Socket, broadcast)
++Socket.PassCred,                 config_parse_bool,                  0,                             offsetof(Socket, pass_cred)
+ Socket.TCPCongestion,            config_parse_string,                0,                             offsetof(Socket, tcp_congestion)
+ Socket.MessageQueueMaxMessages,  config_parse_long,                  0,                             offsetof(Socket, mq_maxmsg)
+ Socket.MessageQueueMessageSize,  config_parse_long,                  0,                             offsetof(Socket, mq_msgsize)
+diff --git a/src/socket.c b/src/socket.c
+index 7ddf326..0864cce 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -406,6 +406,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
+                 "%sFreeBind: %s\n"
+                 "%sTransparent: %s\n"
+                 "%sBroadcast: %s\n"
++                "%sPassCred: %s\n"
+                 "%sTCPCongestion: %s\n",
+                 prefix, socket_state_to_string(s->state),
+                 prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
+@@ -416,6 +417,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
+                 prefix, yes_no(s->free_bind),
+                 prefix, yes_no(s->transparent),
+                 prefix, yes_no(s->broadcast),
++                prefix, yes_no(s->pass_cred),
+                 prefix, strna(s->tcp_congestion));
+ 
+         if (s->control_pid > 0)
+@@ -657,6 +659,12 @@ static void socket_apply_socket_options(Socket *s, int fd) {
+                         log_warning("SO_BROADCAST failed: %m");
+         }
+ 
++        if (s->pass_cred) {
++                int one = 1;
++                if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
++                        log_warning("SO_PASSCRED failed: %m");
++        }
++
+         if (s->priority >= 0)
+                 if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
+                         log_warning("SO_PRIORITY failed: %m");
+diff --git a/src/socket.h b/src/socket.h
+index fd13ac4..fbd29da 100644
+--- a/src/socket.h
++++ b/src/socket.h
+@@ -118,6 +118,7 @@ struct Socket {
+         bool free_bind;
+         bool transparent;
+         bool broadcast;
++        bool pass_cred;
+         int priority;
+         int mark;
+         size_t receive_buffer;
+-- 
+1.7.7.5
+
diff --git a/0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch b/0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch
new file mode 100644
index 0000000..b232173
--- /dev/null
+++ b/0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch
@@ -0,0 +1,58 @@
+From 6811dc0646d92f0c668cbf3ce5a6426e273c4abf Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 29 Nov 2011 23:14:36 +0100
+Subject: [PATCH 050/126] shutdownd: use PassCred=yes in the socket unit
+
+Since Linux 3.2 in order to receive SCM_CREDENTIALS it is not sufficient
+to set SO_PASSCRED just before recvmsg(). The option has to be already
+set when the sender sends the message.
+
+With socket activation it is too late to set the option in the service.
+It must be set on the socket right from the start.
+
+See the kernel commit:
+16e57262 af_unix: dont send SCM_CREDENTIALS by default
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=757628
+(cherry picked from commit 75d3fc60f88e08bf953063819a8a04b881d6db23)
+---
+ src/shutdownd.c                |    6 ------
+ units/systemd-shutdownd.socket |    1 +
+ 2 files changed, 1 insertions(+), 6 deletions(-)
+
+diff --git a/src/shutdownd.c b/src/shutdownd.c
+index 0ffa8b2..46856b0 100644
+--- a/src/shutdownd.c
++++ b/src/shutdownd.c
+@@ -173,7 +173,6 @@ int main(int argc, char *argv[]) {
+         };
+ 
+         int r = EXIT_FAILURE, n_fds;
+-        int one = 1;
+         struct shutdownd_command c;
+         struct pollfd pollfd[_FD_MAX];
+         bool exec_shutdown = false, unlink_nologin = false, failed = false;
+@@ -205,11 +204,6 @@ int main(int argc, char *argv[]) {
+                 return EXIT_FAILURE;
+         }
+ 
+-        if (setsockopt(SD_LISTEN_FDS_START, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) {
+-                log_error("SO_PASSCRED failed: %m");
+-                return EXIT_FAILURE;
+-        }
+-
+         zero(c);
+         zero(pollfd);
+ 
+diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket
+index bc0358a..13b6c7a 100644
+--- a/units/systemd-shutdownd.socket
++++ b/units/systemd-shutdownd.socket
+@@ -15,3 +15,4 @@ Before=sockets.target
+ [Socket]
+ ListenDatagram=/run/systemd/shutdownd
+ SocketMode=0600
++PassCred=yes
+-- 
+1.7.7.5
+
diff --git a/0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch b/0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch
new file mode 100644
index 0000000..e2aeb25
--- /dev/null
+++ b/0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch
@@ -0,0 +1,52 @@
+From 20f36bebf9cb9655cb8ac606b70461e4db7ecbde Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 30 Nov 2011 09:37:13 +0100
+Subject: [PATCH 051/126] syslog: use PassCred=yes for the /dev/log socket
+
+Both kmsg-syslogd and the real syslog service want to receive
+SCM_CREDENTIALS. With socket activation it is too late to set
+SO_PASSCRED in the services.
+(cherry picked from commit 1a2801529e916ec31d2a8cc66cd5c3b8d9ad9caa)
+---
+ src/kmsg-syslogd.c  |    5 +----
+ units/syslog.socket |    1 +
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/kmsg-syslogd.c b/src/kmsg-syslogd.c
+index 0901a0e..7fd69f8 100644
+--- a/src/kmsg-syslogd.c
++++ b/src/kmsg-syslogd.c
+@@ -91,7 +91,7 @@ static int server_init(Server *s, unsigned n_sockets) {
+         }
+ 
+         for (i = 0; i < n_sockets; i++) {
+-                int fd, one = 1;
++                int fd;
+ 
+                 fd = SD_LISTEN_FDS_START+i;
+ 
+@@ -106,9 +106,6 @@ static int server_init(Server *s, unsigned n_sockets) {
+                         goto fail;
+                 }
+ 
+-                if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
+-                        log_error("SO_PASSCRED failed: %m");
+-
+                 zero(ev);
+                 ev.events = EPOLLIN;
+                 ev.data.fd = fd;
+diff --git a/units/syslog.socket b/units/syslog.socket
+index 500bb7c..e74b559 100644
+--- a/units/syslog.socket
++++ b/units/syslog.socket
+@@ -18,6 +18,7 @@ Wants=syslog.target
+ [Socket]
+ ListenDatagram=/dev/log
+ SocketMode=0666
++PassCred=yes
+ 
+ # The service we activate on incoming traffic is
+ # systemd-kmsg-syslogd.service. That doesn't mean however, that this
+-- 
+1.7.7.5
+
diff --git a/0052-man-document-the-PassCred-option.patch b/0052-man-document-the-PassCred-option.patch
new file mode 100644
index 0000000..56303d7
--- /dev/null
+++ b/0052-man-document-the-PassCred-option.patch
@@ -0,0 +1,36 @@
+From b1d7dbb539fcbd671ec4ddce1d162fe3543440ea Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 30 Nov 2011 11:06:35 +0100
+Subject: [PATCH 052/126] man: document the PassCred option (cherry picked
+ from commit
+ 42e87475cfe20a5e79da882012629f9d3ae63648)
+
+---
+ man/systemd.socket.xml |   11 +++++++++++
+ 1 files changed, 11 insertions(+), 0 deletions(-)
+
+diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
+index 28c8dc4..2f31242 100644
+--- a/man/systemd.socket.xml
++++ b/man/systemd.socket.xml
+@@ -525,6 +525,17 @@
+                         </varlistentry>
+ 
+                         <varlistentry>
++                                <term><varname>PassCred=</varname></term>
++                                <listitem><para>Takes a boolean
++                                value. This controls the SO_PASSCRED
++                                option, which allows UNIX sockets to
++                                receive the credentials of the sending
++                                process in an ancillary message.
++                                Defaults to
++                                <option>false</option>.</para></listitem>
++                        </varlistentry>
++
++                        <varlistentry>
+                                 <term><varname>TCPCongestion=</varname></term>
+                                 <listitem><para>Takes a string
+                                 value. Controls the TCP congestion
+-- 
+1.7.7.5
+
diff --git a/0053-add-a-generator-to-pull-rc-local.service-in.patch b/0053-add-a-generator-to-pull-rc-local.service-in.patch
new file mode 100644
index 0000000..8a5f2a7
--- /dev/null
+++ b/0053-add-a-generator-to-pull-rc-local.service-in.patch
@@ -0,0 +1,250 @@
+From a40cb5c2aaa67a66c20b17f18cb30fd7b65154d4 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 2 Dec 2011 10:18:46 +0100
+Subject: [PATCH 053/126] add a generator to pull rc-local.service in
+
+rc-local.service acts as an ordering barrier even if its condition is
+false, because conditions are evaluated when the service is about to be
+started.
+
+To avoid the ordering barrier in a legacy-free system, add a generator
+to pull rc-local.service into the transaction only if the script is
+executable.
+
+If/when we rewrite SysV compatibility into a generator, this one can become
+a part of it.
+(cherry picked from commit 156730831730701cada2750e826abbf7b113861f)
+
+Conflicts:
+
+	Makefile.am
+---
+ Makefile.am                   |   24 ++++++----
+ src/rc-local-generator.c      |  107 +++++++++++++++++++++++++++++++++++++++++
+ units/fedora/rc-local.service |    4 +-
+ units/suse/rc-local.service   |    2 +
+ 4 files changed, 127 insertions(+), 10 deletions(-)
+ create mode 100644 src/rc-local-generator.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 4416ab7..4d04db3 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -522,6 +522,8 @@ dist_systemunit_DATA += \
+ 	units/fedora/prefdm.service \
+ 	units/fedora/rc-local.service \
+ 	units/fedora/halt-local.service
++systemgenerator_PROGRAMS += \
++	systemd-rc-local-generator
+ endif
+ 
+ if TARGET_MANDRIVA
+@@ -529,6 +531,8 @@ dist_systemunit_DATA += \
+ 	units/mandriva/prefdm.service \
+ 	units/fedora/rc-local.service \
+ 	units/fedora/halt-local.service
++systemgenerator_PROGRAMS += \
++	systemd-rc-local-generator
+ endif
+ 
+ if TARGET_FRUGALWARE
+@@ -540,6 +544,8 @@ if TARGET_SUSE
+ dist_systemunit_DATA += \
+ 	units/suse/rc-local.service \
+ 	units/suse/halt-local.service
++systemgenerator_PROGRAMS += \
++	systemd-rc-local-generator
+ endif
+ 
+ if HAVE_PLYMOUTH
+@@ -1256,6 +1262,15 @@ systemd_getty_generator_CFLAGS = \
+ systemd_getty_generator_LDADD = \
+ 	libsystemd-basic.la
+ 
++systemd_rc_local_generator_SOURCES = \
++	src/rc-local-generator.c
++
++systemd_rc_local_generator_CFLAGS = \
++	$(AM_CFLAGS)
++
++systemd_rc_local_generator_LDADD = \
++	libsystemd-basic.la
++
+ systemd_user_sessions_SOURCES = \
+ 	src/user-sessions.c \
+ 	src/cgroup-util.c
+@@ -1949,9 +1964,6 @@ endif
+ 
+ if TARGET_FEDORA
+ 	$(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants
+-	( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
+-		rm -f rc-local.service && \
+-		$(LN_S) $(systemunitdir)/rc-local.service rc-local.service )
+ 	( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \
+ 		rm -f halt-local.service && \
+ 		$(LN_S) $(systemunitdir)/halt-local.service halt-local.service )
+@@ -1966,9 +1978,6 @@ endif
+ 
+ if TARGET_MANDRIVA
+ 	$(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants
+-	( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
+-		rm -f rc-local.service && \
+-		$(LN_S) $(systemunitdir)/rc-local.service rc-local.service )
+ 	( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \
+ 		rm -f halt-local.service && \
+ 		$(LN_S) $(systemunitdir)/halt-local.service halt-local.service )
+@@ -1990,9 +1999,6 @@ endif
+ 
+ if TARGET_SUSE
+ 	$(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants
+-	( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \
+-		rm -f rc-local.service && \
+-		$(LN_S) $(systemunitdir)/rc-local.service rc-local.service )
+ 	( cd $(DESTDIR)$(systemunitdir) && \
+ 		rm -f local.service && \
+ 		$(LN_S) rc-local.service local.service )
+diff --git a/src/rc-local-generator.c b/src/rc-local-generator.c
+new file mode 100644
+index 0000000..ac6424a
+--- /dev/null
++++ b/src/rc-local-generator.c
+@@ -0,0 +1,107 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++/***
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++  Copyright 2011 Michal Schmidt
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include <errno.h>
++#include <stdio.h>
++#include <unistd.h>
++
++#include "log.h"
++#include "util.h"
++
++#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
++#define SCRIPT_PATH "/etc/rc.d/rc.local"
++#elif defined(TARGET_SUSE)
++#define SCRIPT_PATH "/etc/init.d/boot.local"
++#endif
++
++const char *arg_dest = "/tmp";
++
++static int add_symlink(const char *service) {
++        char *from = NULL, *to = NULL;
++        int r;
++
++        assert(service);
++
++        asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service);
++        asprintf(&to, "%s/multi-user.target.wants/%s", arg_dest, service);
++
++        if (!from || !to) {
++                log_error("Out of memory");
++                r = -ENOMEM;
++                goto finish;
++        }
++
++        mkdir_parents(to, 0755);
++
++        r = symlink(from, to);
++        if (r < 0) {
++                if (errno == EEXIST)
++                        r = 0;
++                else {
++                        log_error("Failed to create symlink from %s to %s: %m", from, to);
++                        r = -errno;
++                }
++        }
++
++finish:
++
++        free(from);
++        free(to);
++
++        return r;
++}
++
++static bool file_is_executable(const char *f) {
++        struct stat st;
++
++        if (stat(f, &st) < 0)
++                return false;
++
++        return S_ISREG(st.st_mode) && (st.st_mode & 0111);
++}
++
++int main(int argc, char *argv[]) {
++
++        int r = EXIT_SUCCESS;
++
++        if (argc > 2) {
++                log_error("This program takes one or no arguments.");
++                return EXIT_FAILURE;
++        }
++
++        log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
++        log_parse_environment();
++        log_open();
++
++        if (argc > 1)
++                arg_dest = argv[1];
++
++        if (file_is_executable(SCRIPT_PATH)) {
++                log_debug("Automatically adding rc-local.service.");
++
++                if (add_symlink("rc-local.service") < 0)
++                        r = EXIT_FAILURE;
++
++        }
++
++        return r;
++}
+diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
+index 106b12c..fade90c 100644
+--- a/units/fedora/rc-local.service
++++ b/units/fedora/rc-local.service
+@@ -5,8 +5,10 @@
+ #  the Free Software Foundation; either version 2 of the License, or
+ #  (at your option) any later version.
+ 
++# This unit gets pulled automatically into multi-user.target by
++# systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
+ [Unit]
+-Description=/etc/rc.local Compatibility
++Description=/etc/rc.d/rc.local Compatibility
+ ConditionFileIsExecutable=/etc/rc.d/rc.local
+ 
+ [Service]
+diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
+index fe4c007..df9a09b 100644
+--- a/units/suse/rc-local.service
++++ b/units/suse/rc-local.service
+@@ -5,6 +5,8 @@
+ #  the Free Software Foundation; either version 2 of the License, or
+ #  (at your option) any later version.
+ 
++# This unit gets pulled automatically into multi-user.target by
++# systemd-rc-local-generator if /etc/init.d/boot.local is executable.
+ [Unit]
+ Description=/etc/init.d/boot.local Compatibility
+ ConditionFileIsExecutable=/etc/init.d/boot.local
+-- 
+1.7.7.5
+
diff --git a/0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch b/0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch
new file mode 100644
index 0000000..d99b790
--- /dev/null
+++ b/0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch
@@ -0,0 +1,41 @@
+From 6d3970658de8f270b651e8b4cffbc464e3774428 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 2 Dec 2011 11:32:04 +0100
+Subject: [PATCH 054/126] rc-local: no need to check if the script is
+ executable
+
+rc-local.service is pulled in by a generator only if the script is
+executable. No need to check again.
+(cherry picked from commit e951701a4d90152447e195e926e0e12c7dcc0051)
+---
+ units/fedora/rc-local.service |    1 -
+ units/suse/rc-local.service   |    1 -
+ 2 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
+index fade90c..36100df 100644
+--- a/units/fedora/rc-local.service
++++ b/units/fedora/rc-local.service
+@@ -9,7 +9,6 @@
+ # systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
+ [Unit]
+ Description=/etc/rc.d/rc.local Compatibility
+-ConditionFileIsExecutable=/etc/rc.d/rc.local
+ 
+ [Service]
+ Type=forking
+diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
+index df9a09b..11dc581 100644
+--- a/units/suse/rc-local.service
++++ b/units/suse/rc-local.service
+@@ -9,7 +9,6 @@
+ # systemd-rc-local-generator if /etc/init.d/boot.local is executable.
+ [Unit]
+ Description=/etc/init.d/boot.local Compatibility
+-ConditionFileIsExecutable=/etc/init.d/boot.local
+ 
+ [Service]
+ Type=oneshot
+-- 
+1.7.7.5
+
diff --git a/0055-rc-local-order-after-network.target.patch b/0055-rc-local-order-after-network.target.patch
new file mode 100644
index 0000000..46d104c
--- /dev/null
+++ b/0055-rc-local-order-after-network.target.patch
@@ -0,0 +1,42 @@
+From 7f0aa58747b7335c7856fb7153be6cd1e22b74b6 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 2 Dec 2011 11:32:52 +0100
+Subject: [PATCH 055/126] rc-local: order after network.target
+
+As suggested by Bill Nottingham: rc.local is often used for frobbing the
+network.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=754789
+(cherry picked from commit 91b684c7300879a8d2006038f7d9185d92c3c3bf)
+---
+ units/fedora/rc-local.service |    1 +
+ units/suse/rc-local.service   |    1 +
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
+index 36100df..0bef5c7 100644
+--- a/units/fedora/rc-local.service
++++ b/units/fedora/rc-local.service
+@@ -9,6 +9,7 @@
+ # systemd-rc-local-generator if /etc/rc.d/rc.local is executable.
+ [Unit]
+ Description=/etc/rc.d/rc.local Compatibility
++After=network.target
+ 
+ [Service]
+ Type=forking
+diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service
+index 11dc581..454095c 100644
+--- a/units/suse/rc-local.service
++++ b/units/suse/rc-local.service
+@@ -9,6 +9,7 @@
+ # systemd-rc-local-generator if /etc/init.d/boot.local is executable.
+ [Unit]
+ Description=/etc/init.d/boot.local Compatibility
++After=network.target
+ 
+ [Service]
+ Type=oneshot
+-- 
+1.7.7.5
+
diff --git a/0056-util-fix-error-checking-after-fgets.patch b/0056-util-fix-error-checking-after-fgets.patch
new file mode 100644
index 0000000..9b7965c
--- /dev/null
+++ b/0056-util-fix-error-checking-after-fgets.patch
@@ -0,0 +1,54 @@
+From 360ab562c360ec375f76fb88318546323a835459 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 3 Dec 2011 00:41:34 +0100
+Subject: [PATCH 056/126] util: fix error checking after fgets()
+
+fgets() does not set errno on EOF.
+(cherry picked from commit 35d50f55f346c71fd5e957d35ebcae1c50b1f9ce)
+---
+ src/util.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index e93e6f6..da71e4d 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -516,7 +516,7 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
+                 return -errno;
+ 
+         if (!(fgets(line, sizeof(line), f))) {
+-                r = -errno;
++                r = feof(f) ? -EIO : -errno;
+                 fclose(f);
+                 return r;
+         }
+@@ -561,7 +561,7 @@ int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
+                 return -errno;
+ 
+         if (!(fgets(line, sizeof(line), f))) {
+-                r = -errno;
++                r = feof(f) ? -EIO : -errno;
+                 fclose(f);
+                 return r;
+         }
+@@ -708,7 +708,7 @@ int read_one_line_file(const char *fn, char **line) {
+                 return -errno;
+ 
+         if (!(fgets(t, sizeof(t), f))) {
+-                r = -errno;
++                r = feof(f) ? -EIO : -errno;
+                 goto finish;
+         }
+ 
+@@ -3266,7 +3266,7 @@ int get_ctty_devnr(pid_t pid, dev_t *d) {
+                 return -errno;
+ 
+         if (!fgets(line, sizeof(line), f)) {
+-                k = -errno;
++                k = feof(f) ? -EIO : -errno;
+                 fclose(f);
+                 return k;
+         }
+-- 
+1.7.7.5
+
diff --git a/0057-path-use-m-instead-of-strerror-errno.patch b/0057-path-use-m-instead-of-strerror-errno.patch
new file mode 100644
index 0000000..1fa8d40
--- /dev/null
+++ b/0057-path-use-m-instead-of-strerror-errno.patch
@@ -0,0 +1,36 @@
+From 5971b6afa801868d4bf790727dec254588832d70 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 3 Dec 2011 01:36:05 +0100
+Subject: [PATCH 057/126] path: use %m instead of strerror(errno)
+
+and strerror(-errno) was just wrong.
+(cherry picked from commit 768147d13d0877a4c3e5f6f986c3064de62ff4f1)
+---
+ src/path.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/path.c b/src/path.c
+index f15c921..142fd2d 100644
+--- a/src/path.c
++++ b/src/path.c
+@@ -556,7 +556,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+         }
+ 
+         if (ioctl(fd, FIONREAD, &l) < 0) {
+-                log_error("FIONREAD failed: %s", strerror(errno));
++                log_error("FIONREAD failed: %m");
+                 goto fail;
+         }
+ 
+@@ -568,7 +568,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+         }
+ 
+         if ((k = read(fd, buf, l)) < 0) {
+-                log_error("Failed to read inotify event: %s", strerror(-errno));
++                log_error("Failed to read inotify event: %m");
+                 goto fail;
+         }
+ 
+-- 
+1.7.7.5
+
diff --git a/0058-path-refactor-PathSpec-usage.patch b/0058-path-refactor-PathSpec-usage.patch
new file mode 100644
index 0000000..88c9c72
--- /dev/null
+++ b/0058-path-refactor-PathSpec-usage.patch
@@ -0,0 +1,507 @@
+From 69086d0499fb8ae161ab9bd83da19f098317f6bc Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 3 Dec 2011 01:38:30 +0100
+Subject: [PATCH 058/126] path: refactor PathSpec usage
+
+path_*() functions operate on "Path *p" and they do not touch PathSpec
+internals directly.
+
+pathspec_*() functions operate on "PathSpec *s". The PathSpec class will
+be useful outside of path.c.
+(cherry picked from commit 4b562198c79e4ebfc3d84b69a1dae374bc6cf9f5)
+---
+ src/path.c |  356 +++++++++++++++++++++++++++++++++---------------------------
+ src/path.h |    8 ++
+ 2 files changed, 203 insertions(+), 161 deletions(-)
+
+diff --git a/src/path.c b/src/path.c
+index 142fd2d..db6f873 100644
+--- a/src/path.c
++++ b/src/path.c
+@@ -39,26 +39,202 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
+         [PATH_FAILED] = UNIT_FAILED
+ };
+ 
+-static void path_init(Unit *u) {
+-        Path *p = PATH(u);
++int pathspec_watch(PathSpec *s, Unit *u) {
++        static const int flags_table[_PATH_TYPE_MAX] = {
++                [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
++                [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
++                [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
++                [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
++        };
++
++        bool exists = false;
++        char *k, *slash;
++        int r;
+ 
+         assert(u);
+-        assert(u->meta.load_state == UNIT_STUB);
++        assert(s);
+ 
+-        p->directory_mode = 0755;
++        pathspec_unwatch(s, u);
++
++        if (!(k = strdup(s->path)))
++                return -ENOMEM;
++
++        if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) {
++                r = -errno;
++                goto fail;
++        }
++
++        if (unit_watch_fd(u, s->inotify_fd, EPOLLIN, &s->watch) < 0) {
++                r = -errno;
++                goto fail;
++        }
++
++        if ((s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type])) >= 0)
++                exists = true;
++
++        do {
++                int flags;
++
++                /* This assumes the path was passed through path_kill_slashes()! */
++                if (!(slash = strrchr(k, '/')))
++                        break;
++
++                /* Trim the path at the last slash. Keep the slash if it's the root dir. */
++                slash[slash == k] = 0;
++
++                flags = IN_MOVE_SELF;
++                if (!exists)
++                        flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO;
++
++                if (inotify_add_watch(s->inotify_fd, k, flags) >= 0)
++                        exists = true;
++        } while (slash != k);
++
++        return 0;
++
++fail:
++        free(k);
++
++        pathspec_unwatch(s, u);
++        return r;
+ }
+ 
+-static void path_unwatch_one(Path *p, PathSpec *s) {
++void pathspec_unwatch(PathSpec *s, Unit *u) {
+ 
+         if (s->inotify_fd < 0)
+                 return;
+ 
+-        unit_unwatch_fd(UNIT(p), &s->watch);
++        unit_unwatch_fd(u, &s->watch);
+ 
+         close_nointr_nofail(s->inotify_fd);
+         s->inotify_fd = -1;
+ }
+ 
++int pathspec_fd_event(PathSpec *s, uint32_t events) {
++        uint8_t *buf = NULL;
++        struct inotify_event *e;
++        ssize_t k;
++        int l;
++        int r = 0;
++
++        if (events != EPOLLIN) {
++                log_error("Got Invalid poll event on inotify.");
++                r = -EINVAL;
++                goto out;
++        }
++
++        if (ioctl(s->inotify_fd, FIONREAD, &l) < 0) {
++                log_error("FIONREAD failed: %m");
++                r = -errno;
++                goto out;
++        }
++
++        assert(l > 0);
++
++        if (!(buf = malloc(l))) {
++                log_error("Failed to allocate buffer: %m");
++                r = -errno;
++                goto out;
++        }
++
++        if ((k = read(s->inotify_fd, buf, l)) < 0) {
++                log_error("Failed to read inotify event: %m");
++                r = -errno;
++                goto out;
++        }
++
++        e = (struct inotify_event*) buf;
++
++        while (k > 0) {
++                size_t step;
++
++                if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
++                        r = 1;
++
++                step = sizeof(struct inotify_event) + e->len;
++                assert(step <= (size_t) k);
++
++                e = (struct inotify_event*) ((uint8_t*) e + step);
++                k -= step;
++        }
++out:
++        free(buf);
++        return r;
++}
++
++static bool pathspec_check_good(PathSpec *s, bool initial) {
++        bool good = false;
++
++        switch (s->type) {
++
++        case PATH_EXISTS:
++                good = access(s->path, F_OK) >= 0;
++                break;
++
++        case PATH_EXISTS_GLOB:
++                good = glob_exists(s->path) > 0;
++                break;
++
++        case PATH_DIRECTORY_NOT_EMPTY: {
++                int k;
++
++                k = dir_is_empty(s->path);
++                good = !(k == -ENOENT || k > 0);
++                break;
++        }
++
++        case PATH_CHANGED: {
++                bool b;
++
++                b = access(s->path, F_OK) >= 0;
++                good = !initial && b != s->previous_exists;
++                s->previous_exists = b;
++                break;
++        }
++
++        default:
++                ;
++        }
++
++        return good;
++}
++
++static bool pathspec_startswith(PathSpec *s, const char *what) {
++        return path_startswith(s->path, what);
++}
++
++static void pathspec_mkdir(PathSpec *s, mode_t mode) {
++        int r;
++
++        if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
++                return;
++
++        if ((r = mkdir_p(s->path, mode)) < 0)
++                log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
++}
++
++static void pathspec_dump(PathSpec *s, FILE *f, const char *prefix) {
++        fprintf(f,
++                "%s%s: %s\n",
++                prefix,
++                path_type_to_string(s->type),
++                s->path);
++}
++
++void pathspec_done(PathSpec *s) {
++        assert(s->inotify_fd == -1);
++        free(s->path);
++}
++
++static void path_init(Unit *u) {
++        Path *p = PATH(u);
++
++        assert(u);
++        assert(u->meta.load_state == UNIT_STUB);
++
++        p->directory_mode = 0755;
++}
++
+ static void path_done(Unit *u) {
+         Path *p = PATH(u);
+         PathSpec *s;
+@@ -66,9 +242,9 @@ static void path_done(Unit *u) {
+         assert(p);
+ 
+         while ((s = p->specs)) {
+-                path_unwatch_one(p, s);
++                pathspec_unwatch(s, u);
+                 LIST_REMOVE(PathSpec, spec, p->specs, s);
+-                free(s->path);
++                pathspec_done(s);
+                 free(s);
+         }
+ }
+@@ -86,7 +262,7 @@ int path_add_one_mount_link(Path *p, Mount *m) {
+ 
+         LIST_FOREACH(spec, s, p->specs) {
+ 
+-                if (!path_startswith(s->path, m->where))
++                if (!pathspec_startswith(s, m->where))
+                         continue;
+ 
+                 if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
+@@ -187,71 +363,7 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) {
+                 prefix, p->directory_mode);
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                fprintf(f,
+-                        "%s%s: %s\n",
+-                        prefix,
+-                        path_type_to_string(s->type),
+-                        s->path);
+-}
+-
+-static int path_watch_one(Path *p, PathSpec *s) {
+-        static const int flags_table[_PATH_TYPE_MAX] = {
+-                [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+-                [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+-                [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
+-                [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
+-        };
+-
+-        bool exists = false;
+-        char *k, *slash;
+-        int r;
+-
+-        assert(p);
+-        assert(s);
+-
+-        path_unwatch_one(p, s);
+-
+-        if (!(k = strdup(s->path)))
+-                return -ENOMEM;
+-
+-        if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) {
+-                r = -errno;
+-                goto fail;
+-        }
+-
+-        if (unit_watch_fd(UNIT(p), s->inotify_fd, EPOLLIN, &s->watch) < 0) {
+-                r = -errno;
+-                goto fail;
+-        }
+-
+-        if ((s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type])) >= 0)
+-                exists = true;
+-
+-        do {
+-                int flags;
+-
+-                /* This assumes the path was passed through path_kill_slashes()! */
+-                if (!(slash = strrchr(k, '/')))
+-                        break;
+-
+-                /* Trim the path at the last slash. Keep the slash if it's the root dir. */
+-                slash[slash == k] = 0;
+-
+-                flags = IN_MOVE_SELF;
+-                if (!exists)
+-                        flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO;
+-
+-                if (inotify_add_watch(s->inotify_fd, k, flags) >= 0)
+-                        exists = true;
+-        } while (slash != k);
+-
+-        return 0;
+-
+-fail:
+-        free(k);
+-
+-        path_unwatch_one(p, s);
+-        return r;
++                pathspec_dump(s, f, prefix);
+ }
+ 
+ static void path_unwatch(Path *p) {
+@@ -260,7 +372,7 @@ static void path_unwatch(Path *p) {
+         assert(p);
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                path_unwatch_one(p, s);
++                pathspec_unwatch(s, UNIT(p));
+ }
+ 
+ static int path_watch(Path *p) {
+@@ -270,7 +382,7 @@ static int path_watch(Path *p) {
+         assert(p);
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                if ((r = path_watch_one(p, s)) < 0)
++                if ((r = pathspec_watch(s, UNIT(p))) < 0)
+                         return r;
+ 
+         return 0;
+@@ -361,37 +473,7 @@ static bool path_check_good(Path *p, bool initial) {
+         assert(p);
+ 
+         LIST_FOREACH(spec, s, p->specs) {
+-
+-                switch (s->type) {
+-
+-                case PATH_EXISTS:
+-                        good = access(s->path, F_OK) >= 0;
+-                        break;
+-
+-                case PATH_EXISTS_GLOB:
+-                        good = glob_exists(s->path) > 0;
+-                        break;
+-
+-                case PATH_DIRECTORY_NOT_EMPTY: {
+-                        int k;
+-
+-                        k = dir_is_empty(s->path);
+-                        good = !(k == -ENOENT || k > 0);
+-                        break;
+-                }
+-
+-                case PATH_CHANGED: {
+-                        bool b;
+-
+-                        b = access(s->path, F_OK) >= 0;
+-                        good = !initial && b != s->previous_exists;
+-                        s->previous_exists = b;
+-                        break;
+-                }
+-
+-                default:
+-                        ;
+-                }
++                good = pathspec_check_good(s, initial);
+ 
+                 if (good)
+                         break;
+@@ -440,15 +522,8 @@ static void path_mkdir(Path *p) {
+         if (!p->make_directory)
+                 return;
+ 
+-        LIST_FOREACH(spec, s, p->specs) {
+-                int r;
+-
+-                if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
+-                        continue;
+-
+-                if ((r = mkdir_p(s->path, p->directory_mode)) < 0)
+-                        log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
+-        }
++        LIST_FOREACH(spec, s, p->specs)
++                pathspec_mkdir(s, p->directory_mode);
+ }
+ 
+ static int path_start(Unit *u) {
+@@ -525,12 +600,8 @@ static const char *path_sub_state_to_string(Unit *u) {
+ 
+ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+         Path *p = PATH(u);
+-        int l;
+-        ssize_t k;
+-        uint8_t *buf = NULL;
+-        struct inotify_event *e;
+         PathSpec *s;
+-        bool changed;
++        int changed;
+ 
+         assert(p);
+         assert(fd >= 0);
+@@ -541,13 +612,8 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+ 
+         /* log_debug("inotify wakeup on %s.", u->meta.id); */
+ 
+-        if (events != EPOLLIN) {
+-                log_error("Got Invalid poll event on inotify.");
+-                goto fail;
+-        }
+-
+         LIST_FOREACH(spec, s, p->specs)
+-                if (s->inotify_fd == fd)
++                if (pathspec_owns_inotify_fd(s, fd))
+                         break;
+ 
+         if (!s) {
+@@ -555,55 +621,23 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+                 goto fail;
+         }
+ 
+-        if (ioctl(fd, FIONREAD, &l) < 0) {
+-                log_error("FIONREAD failed: %m");
+-                goto fail;
+-        }
+-
+-        assert(l > 0);
+-
+-        if (!(buf = malloc(l))) {
+-                log_error("Failed to allocate buffer: %s", strerror(ENOMEM));
+-                goto fail;
+-        }
+-
+-        if ((k = read(fd, buf, l)) < 0) {
+-                log_error("Failed to read inotify event: %m");
++        changed = pathspec_fd_event(s, events);
++        if (changed < 0)
+                 goto fail;
+-        }
+ 
+         /* If we are already running, then remember that one event was
+          * dispatched so that we restart the service only if something
+          * actually changed on disk */
+         p->inotify_triggered = true;
+ 
+-        e = (struct inotify_event*) buf;
+-
+-        changed = false;
+-        while (k > 0) {
+-                size_t step;
+-
+-                if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
+-                        changed = true;
+-
+-                step = sizeof(struct inotify_event) + e->len;
+-                assert(step <= (size_t) k);
+-
+-                e = (struct inotify_event*) ((uint8_t*) e + step);
+-                k -= step;
+-        }
+-
+         if (changed)
+                 path_enter_running(p);
+         else
+                 path_enter_waiting(p, false, true);
+ 
+-        free(buf);
+-
+         return;
+ 
+ fail:
+-        free(buf);
+         path_enter_dead(p, false);
+ }
+ 
+diff --git a/src/path.h b/src/path.h
+index 116fc63..4e6ccf5 100644
+--- a/src/path.h
++++ b/src/path.h
+@@ -60,6 +60,14 @@ typedef struct PathSpec {
+ 
+ } PathSpec;
+ 
++int  pathspec_watch(PathSpec *s, Unit *u);
++void pathspec_unwatch(PathSpec *s, Unit *u);
++int  pathspec_fd_event(PathSpec *s, uint32_t events);
++void pathspec_done(PathSpec *s);
++static inline bool pathspec_owns_inotify_fd(PathSpec *s, int fd) {
++        return s->inotify_fd == fd;
++}
++
+ struct Path {
+         Meta meta;
+ 
+-- 
+1.7.7.5
+
diff --git a/0059-path-add-PathModified-PathChanged-IN_MODIFY.patch b/0059-path-add-PathModified-PathChanged-IN_MODIFY.patch
new file mode 100644
index 0000000..c1ca096
--- /dev/null
+++ b/0059-path-add-PathModified-PathChanged-IN_MODIFY.patch
@@ -0,0 +1,90 @@
+From 30fb4092d987ff81f39177461f6472e2fff225a1 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 3 Dec 2011 10:22:26 +0100
+Subject: [PATCH 059/126] path: add PathModified (= PathChanged + IN_MODIFY)
+ (cherry picked from commit
+ e92238567b9fc83ef77e359588d7b005ecae3d70)
+
+---
+ man/systemd.path.xml |   17 ++++++++++-------
+ src/path.c           |    2 ++
+ src/path.h           |    1 +
+ 3 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/man/systemd.path.xml b/man/systemd.path.xml
+index 10d8f73..5b1ff75 100644
+--- a/man/systemd.path.xml
++++ b/man/systemd.path.xml
+@@ -113,6 +113,7 @@
+                                 <term><varname>PathExists=</varname></term>
+                                 <term><varname>PathExistsGlob=</varname></term>
+                                 <term><varname>PathChanged=</varname></term>
++                                <term><varname>PathModified=</varname></term>
+                                 <term><varname>DirectoryNotEmpty=</varname></term>
+ 
+                                 <listitem><para>Defines paths to
+@@ -129,8 +130,14 @@
+                                 specified. <varname>PathChanged=</varname>
+                                 may be used to watch a file or
+                                 directory and activate the configured
+-                                unit whenever it changes or is
+-                                modified. <varname>DirectoryNotEmpty=</varname>
++                                unit whenever it changes. It is not activated
++                                on every write to the watched file but it is
++                                activated if the file which was open for writing
++                                gets closed. <varname>PathModified=</varname>
++                                is similar, but additionally it is activated
++                                also on simple writes to the watched file.
++
++                                <varname>DirectoryNotEmpty=</varname>
+                                 may be used to watch a directory and
+                                 activate the configured unit whenever
+                                 it contains at least one file.</para>
+@@ -154,11 +161,7 @@
+                                 activated, then the configured unit is
+                                 immediately activated as
+                                 well. Something similar does not apply
+-                                to
+-                                <varname>PathChanged=</varname>. The
+-                                latter is not activated on simple
+-                                writes but only if files with were
+-                                opened for writing are closed.
++                                to <varname>PathChanged=</varname>.
+                                 </para></listitem>
+                         </varlistentry>
+                         <varlistentry>
+diff --git a/src/path.c b/src/path.c
+index db6f873..1e5d825 100644
+--- a/src/path.c
++++ b/src/path.c
+@@ -44,6 +44,7 @@ int pathspec_watch(PathSpec *s, Unit *u) {
+                 [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+                 [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+                 [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO,
++                [PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY,
+                 [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO
+         };
+ 
+@@ -713,6 +714,7 @@ static const char* const path_type_table[_PATH_TYPE_MAX] = {
+         [PATH_EXISTS] = "PathExists",
+         [PATH_EXISTS_GLOB] = "PathExistsGlob",
+         [PATH_CHANGED] = "PathChanged",
++        [PATH_MODIFIED] = "PathModified",
+         [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty"
+ };
+ 
+diff --git a/src/path.h b/src/path.h
+index 4e6ccf5..1d78fe4 100644
+--- a/src/path.h
++++ b/src/path.h
+@@ -41,6 +41,7 @@ typedef enum PathType {
+         PATH_EXISTS_GLOB,
+         PATH_DIRECTORY_NOT_EMPTY,
+         PATH_CHANGED,
++        PATH_MODIFIED,
+         _PATH_TYPE_MAX,
+         _PATH_TYPE_INVALID = -1
+ } PathType;
+-- 
+1.7.7.5
+
diff --git a/0060-service-handle-services-with-racy-daemonization-grac.patch b/0060-service-handle-services-with-racy-daemonization-grac.patch
new file mode 100644
index 0000000..5239f62
--- /dev/null
+++ b/0060-service-handle-services-with-racy-daemonization-grac.patch
@@ -0,0 +1,330 @@
+From 1b2395f867d283bb08862e1ce421ab3ac1b02968 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 3 Dec 2011 02:13:30 +0100
+Subject: [PATCH 060/126] service: handle services with racy daemonization
+ gracefully
+
+There are a lot of forking daemons that do not exactly follow the
+initialization steps as described in daemon(7). It is common that they
+do not bother waiting in the parent process for the child to write the
+PID file before exiting. The daemons' developers often do not perceive
+this as a bug and they're unwilling to change.
+
+Currently systemd warns about the missing PID file and falls back to
+guessing the main PID. Being not quite deterministic, the guess can be
+wrong with bad consequences. If the guessing is disabled, determinism is
+achieved at the cost of losing the ability of noticing when the main
+process of the service dies.
+
+As long as it does not negatively affect properly written services,
+systemd should strive for compatibility even with services with racy
+daemonization. It is possible to provide determinism _and_ main process
+supervision to them.
+
+If the PID file is not there, rather than guessing and considering the
+service running immediately after getting the SIGCHLD from the ExecStart
+(or ExecStartPost) process, we can keep the service in the activating
+state for a bit longer. We can use inotify to wait for the PID file to
+appear. Only when it finally does appear and we read a valid PID from
+it, we'll move the service to the running state. If the PID file never
+appears, the usual timeout kicks in and the service fails.
+(cherry picked from commit 3a11183858af30bc9b4e9dac430dd7541deec19b)
+---
+ src/service.c |  175 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
+ src/service.h |    3 +
+ 2 files changed, 157 insertions(+), 21 deletions(-)
+
+diff --git a/src/service.c b/src/service.c
+index d51445e..0b03a8d 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -1294,8 +1294,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
+ 
+         if ((r = read_one_line_file(s->pid_file, &k)) < 0) {
+                 if (may_warn)
+-                        log_warning("Failed to read PID file %s after %s. The service might be broken.",
+-                                    s->pid_file, service_state_to_string(s->state));
++                        log_info("PID file %s not readable (yet?) after %s.",
++                                 s->pid_file, service_state_to_string(s->state));
+                 return r;
+         }
+ 
+@@ -1307,8 +1307,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
+ 
+         if (kill(pid, 0) < 0 && errno != EPERM) {
+                 if (may_warn)
+-                        log_warning("PID %lu read from file %s does not exist. Your service or init script might be broken.",
+-                                    (unsigned long) pid, s->pid_file);
++                        log_info("PID %lu read from file %s does not exist.",
++                                 (unsigned long) pid, s->pid_file);
+                 return -ESRCH;
+         }
+ 
+@@ -1320,7 +1320,8 @@ static int service_load_pid_file(Service *s, bool may_warn) {
+                           (unsigned long) s->main_pid, (unsigned long) pid);
+                 service_unwatch_main_pid(s);
+                 s->main_pid_known = false;
+-        }
++        } else
++                log_debug("Main PID loaded: %lu", (unsigned long) pid);
+ 
+         if ((r = service_set_main_pid(s, pid)) < 0)
+                 return r;
+@@ -1351,6 +1352,7 @@ static int service_search_main_pid(Service *s) {
+         if ((pid = cgroup_bonding_search_main_pid_list(s->meta.cgroup_bondings)) <= 0)
+                 return -ENOENT;
+ 
++        log_debug("Main PID guessed: %lu", (unsigned long) pid);
+         if ((r = service_set_main_pid(s, pid)) < 0)
+                 return r;
+ 
+@@ -1443,6 +1445,17 @@ static int service_notify_sockets_dead(Service *s) {
+         return 0;
+ }
+ 
++static void service_unwatch_pid_file(Service *s) {
++        if (!s->pid_file_pathspec)
++                return;
++
++        log_debug("Stopping watch for %s's PID file %s", s->meta.id, s->pid_file_pathspec->path);
++        pathspec_unwatch(s->pid_file_pathspec, UNIT(s));
++        pathspec_done(s->pid_file_pathspec);
++        free(s->pid_file_pathspec);
++        s->pid_file_pathspec = NULL;
++}
++
+ static void service_set_state(Service *s, ServiceState state) {
+         ServiceState old_state;
+         assert(s);
+@@ -1450,6 +1463,8 @@ static void service_set_state(Service *s, ServiceState state) {
+         old_state = s->state;
+         s->state = state;
+ 
++        service_unwatch_pid_file(s);
++
+         if (state != SERVICE_START_PRE &&
+             state != SERVICE_START &&
+             state != SERVICE_START_POST &&
+@@ -2594,6 +2609,95 @@ static bool service_check_snapshot(Unit *u) {
+         return !s->got_socket_fd;
+ }
+ 
++static int service_retry_pid_file(Service *s) {
++        int r;
++
++        assert(s->pid_file);
++        assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
++
++        r = service_load_pid_file(s, false);
++        if (r < 0)
++                return r;
++
++        service_unwatch_pid_file(s);
++
++        service_enter_running(s, true);
++        return 0;
++}
++
++static int service_watch_pid_file(Service *s) {
++        int r;
++
++        log_debug("Setting watch for %s's PID file %s", s->meta.id, s->pid_file_pathspec->path);
++        r = pathspec_watch(s->pid_file_pathspec, UNIT(s));
++        if (r < 0)
++                goto fail;
++
++        /* the pidfile might have appeared just before we set the watch */
++        service_retry_pid_file(s);
++
++        return 0;
++fail:
++        log_error("Failed to set a watch for %s's PID file %s: %s",
++                  s->meta.id, s->pid_file_pathspec->path, strerror(-r));
++        service_unwatch_pid_file(s);
++        return r;
++}
++
++static int service_demand_pid_file(Service *s) {
++        PathSpec *ps;
++
++        assert(s->pid_file);
++        assert(!s->pid_file_pathspec);
++
++        ps = new0(PathSpec, 1);
++        if (!ps)
++                return -ENOMEM;
++
++        ps->path = strdup(s->pid_file);
++        if (!ps->path) {
++                free(ps);
++                return -ENOMEM;
++        }
++
++        path_kill_slashes(ps->path);
++
++        /* PATH_CHANGED would not be enough. There are daemons (sendmail) that
++         * keep their PID file open all the time. */
++        ps->type = PATH_MODIFIED;
++        ps->inotify_fd = -1;
++
++        s->pid_file_pathspec = ps;
++
++        return service_watch_pid_file(s);
++}
++
++static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
++        Service *s = SERVICE(u);
++
++        assert(s);
++        assert(fd >= 0);
++        assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
++        assert(s->pid_file_pathspec);
++        assert(pathspec_owns_inotify_fd(s->pid_file_pathspec, fd));
++
++        log_debug("inotify event for %s", u->meta.id);
++
++        if (pathspec_fd_event(s->pid_file_pathspec, events) < 0)
++                goto fail;
++
++        if (service_retry_pid_file(s) == 0)
++                return;
++
++        if (service_watch_pid_file(s) < 0)
++                goto fail;
++
++        return;
++fail:
++        service_unwatch_pid_file(s);
++        service_enter_signal(s, SERVICE_STOP_SIGTERM, false);
++}
++
+ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+         Service *s = SERVICE(u);
+         bool success;
+@@ -2699,7 +2803,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+                                 success = true;
+                 }
+ 
+-               log_full(success ? LOG_DEBUG : LOG_NOTICE,
++                log_full(success ? LOG_DEBUG : LOG_NOTICE,
+                          "%s: control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
+                 s->failure = s->failure || !success;
+ 
+@@ -2734,27 +2838,41 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+                         case SERVICE_START:
+                                 assert(s->type == SERVICE_FORKING);
+ 
+-                                /* Let's try to load the pid
+-                                 * file here if we can. We
+-                                 * ignore the return value,
+-                                 * since the PID file might
+-                                 * actually be created by a
+-                                 * START_POST script */
+-
+-                                if (success) {
+-                                        service_load_pid_file(s, !s->exec_command[SERVICE_EXEC_START_POST]);
+-                                        service_search_main_pid(s);
++                                if (!success) {
++                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
++                                        break;
++                                }
+ 
+-                                        service_enter_start_post(s);
++                                if (s->pid_file) {
++                                        /* Let's try to load the pid file here if we can.
++                                         * The PID file might actually be created by a START_POST
++                                         * script. In that case don't worry if the loading fails. */
++                                        bool has_start_post = !!s->exec_command[SERVICE_EXEC_START_POST];
++                                        int r = service_load_pid_file(s, !has_start_post);
++                                        if (!has_start_post && r < 0) {
++                                                r = service_demand_pid_file(s);
++                                                if (r < 0 || !cgroup_good(s))
++                                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
++                                                break;
++                                        }
+                                 } else
+-                                        service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
++                                        service_search_main_pid(s);
+ 
++                                service_enter_start_post(s);
+                                 break;
+ 
+                         case SERVICE_START_POST:
+                                 if (success) {
+-                                        service_load_pid_file(s, true);
+-                                        service_search_main_pid(s);
++                                        if (s->pid_file) {
++                                                int r = service_load_pid_file(s, true);
++                                                if (r < 0) {
++                                                        r = service_demand_pid_file(s);
++                                                        if (r < 0 || !cgroup_good(s))
++                                                                service_enter_stop(s, false);
++                                                        break;
++                                                }
++                                        } else
++                                                service_search_main_pid(s);
+                                 }
+ 
+                                 s->reload_failure = !success;
+@@ -2899,6 +3017,20 @@ static void service_cgroup_notify_event(Unit *u) {
+                  * except when we don't know pid which to expect the
+                  * SIGCHLD for. */
+ 
++        case SERVICE_START:
++        case SERVICE_START_POST:
++                /* If we were hoping for the daemon to write its PID file,
++                 * we can give up now. */
++                if (s->pid_file_pathspec) {
++                        log_warning("%s never wrote its PID file. Failing.", s->meta.id);
++                        service_unwatch_pid_file(s);
++                        if (s->state == SERVICE_START)
++                                service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
++                        else
++                                service_enter_stop(s, false);
++                }
++                break;
++
+         case SERVICE_RUNNING:
+                 service_enter_running(s, true);
+                 break;
+@@ -3208,7 +3340,7 @@ static int service_enumerate(Manager *m) {
+         r = 0;
+ 
+ #ifdef TARGET_SUSE
+-	sysv_facility_in_insserv_conf (m);
++        sysv_facility_in_insserv_conf (m);
+ #endif
+ 
+ finish:
+@@ -3503,6 +3635,7 @@ const UnitVTable service_vtable = {
+ 
+         .sigchld_event = service_sigchld_event,
+         .timer_event = service_timer_event,
++        .fd_event = service_fd_event,
+ 
+         .reset_failed = service_reset_failed,
+ 
+diff --git a/src/service.h b/src/service.h
+index e28f74b..15d58cc 100644
+--- a/src/service.h
++++ b/src/service.h
+@@ -86,6 +86,8 @@ typedef enum NotifyAccess {
+         _NOTIFY_ACCESS_INVALID = -1
+ } NotifyAccess;
+ 
++typedef struct PathSpec PathSpec;
++
+ struct Service {
+         Meta meta;
+ 
+@@ -157,6 +159,7 @@ struct Service {
+         Set *configured_sockets;
+ 
+         Watch timer_watch;
++        PathSpec *pid_file_pathspec;
+ 
+         NotifyAccess notify_access;
+ };
+-- 
+1.7.7.5
+
diff --git a/0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch b/0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch
new file mode 100644
index 0000000..4fdd039
--- /dev/null
+++ b/0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch
@@ -0,0 +1,60 @@
+From 4035af799be35919232a68dfb0786af4f54257a1 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 3 Dec 2011 21:34:34 +0100
+Subject: [PATCH 061/126] service: stop the service if ExecStartPost ends with
+ a failure
+
+The handling of failures in ExecStartPost is inconsistent. If the
+command times out, the service is stopped. But if the command exits
+with a failure, the service keeps running.
+
+It makes more sense to stop the service when ExecStartPost fails.
+If this behaviour is not desired, the ExecStartPost command can be
+prefixed with "-".
+(cherry picked from commit 2096e009a790073a934f5cd07d17024d3b199d0b)
+---
+ src/service.c |   26 ++++++++++++++------------
+ 1 files changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/src/service.c b/src/service.c
+index 0b03a8d..175a729 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -2862,20 +2862,22 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+                                 break;
+ 
+                         case SERVICE_START_POST:
+-                                if (success) {
+-                                        if (s->pid_file) {
+-                                                int r = service_load_pid_file(s, true);
+-                                                if (r < 0) {
+-                                                        r = service_demand_pid_file(s);
+-                                                        if (r < 0 || !cgroup_good(s))
+-                                                                service_enter_stop(s, false);
+-                                                        break;
+-                                                }
+-                                        } else
+-                                                service_search_main_pid(s);
++                                if (!success) {
++                                        service_enter_stop(s, false);
++                                        break;
+                                 }
+ 
+-                                s->reload_failure = !success;
++                                if (s->pid_file) {
++                                        int r = service_load_pid_file(s, true);
++                                        if (r < 0) {
++                                                r = service_demand_pid_file(s);
++                                                if (r < 0 || !cgroup_good(s))
++                                                        service_enter_stop(s, false);
++                                                break;
++                                        }
++                                } else
++                                        service_search_main_pid(s);
++
+                                 service_enter_running(s, true);
+                                 break;
+ 
+-- 
+1.7.7.5
+
diff --git a/0062-Allow-list-unit-files-to-run-with-root.patch b/0062-Allow-list-unit-files-to-run-with-root.patch
new file mode 100644
index 0000000..190b956
--- /dev/null
+++ b/0062-Allow-list-unit-files-to-run-with-root.patch
@@ -0,0 +1,63 @@
+From 7c3d4fb80496c466d6523b88d5720a7f4ff7939d Mon Sep 17 00:00:00 2001
+From: Bill Nottingham <notting at redhat.com>
+Date: Tue, 22 Nov 2011 15:45:34 -0500
+Subject: [PATCH 062/126] Allow 'list-unit-files' to run with --root.
+
+To do so, move the check for the bus to the bus-using portion of
+list_unit_files(), and ensure that get_config_path doesn't abort when
+checking the runtime path with --root.
+(cherry picked from commit d380a3bcd14376ed72286e78dbcc871b7d6d2151)
+---
+ src/install.c   |    5 ++---
+ src/systemctl.c |    5 +++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/install.c b/src/install.c
+index cfbd50e..1fb1f9d 100644
+--- a/src/install.c
++++ b/src/install.c
+@@ -72,9 +72,8 @@ static int get_config_path(UnitFileScope scope, bool runtime, const char *root_d
+         case UNIT_FILE_SYSTEM:
+ 
+                 if (root_dir && runtime)
+-                        return -EINVAL;
+-
+-                if (runtime)
++                        asprintf(&p, "%s/run/systemd/system", root_dir);
++                else if (runtime)
+                         p = strdup("/run/systemd/system");
+                 else if (root_dir)
+                         asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
+diff --git a/src/systemctl.c b/src/systemctl.c
+index 4426f70..668641d 100644
+--- a/src/systemctl.c
++++ b/src/systemctl.c
+@@ -622,8 +622,6 @@ static int list_unit_files(DBusConnection *bus, char **args) {
+ 
+         dbus_error_init(&error);
+ 
+-        assert(bus);
+-
+         pager_open_if_enabled();
+ 
+         if (avoid_bus()) {
+@@ -659,6 +657,8 @@ static int list_unit_files(DBusConnection *bus, char **args) {
+ 
+                 hashmap_free(h);
+         } else {
++                assert(bus);
++
+                 m = dbus_message_new_method_call(
+                                 "org.freedesktop.systemd1",
+                                 "/org/freedesktop/systemd1",
+@@ -5001,6 +5001,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
+         if (!streq(verbs[i].verb, "enable") &&
+             !streq(verbs[i].verb, "disable") &&
+             !streq(verbs[i].verb, "is-enable") &&
++            !streq(verbs[i].verb, "list-unit-files") &&
+             !streq(verbs[i].verb, "reenable") &&
+             !streq(verbs[i].verb, "preset") &&
+             !streq(verbs[i].verb, "mask") &&
+-- 
+1.7.7.5
+
diff --git a/0063-unit-garbage-collect-units-with-load-error.patch b/0063-unit-garbage-collect-units-with-load-error.patch
new file mode 100644
index 0000000..5054e39
--- /dev/null
+++ b/0063-unit-garbage-collect-units-with-load-error.patch
@@ -0,0 +1,30 @@
+From 069a85095fb07d894ae1825db5f7300c5b5f092b Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 6 Dec 2011 00:47:28 +0100
+Subject: [PATCH 063/126] unit: garbage collect units with load error
+
+Units that failed to load were never cleaned up. It was possible to
+reach the 128K limit of units by attempting to load a bunch of nonsense.
+
+Bug observed by Reartes Guillermo in
+https://bugzilla.redhat.com/show_bug.cgi?id=680122
+(cherry picked from commit 9a46fc3b9014de1bf0ed1f3004a536b08a19ebb3)
+---
+ src/unit.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/src/unit.c b/src/unit.c
+index 2a549e2..018e986 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -858,6 +858,7 @@ fail:
+         u->meta.load_state = UNIT_ERROR;
+         u->meta.load_error = r;
+         unit_add_to_dbus_queue(u);
++        unit_add_to_gc_queue(u);
+ 
+         log_debug("Failed to load configuration for %s: %s", u->meta.id, strerror(-r));
+ 
+-- 
+1.7.7.5
+
diff --git a/0064-systemctl-print-error-load-state-in-red.patch b/0064-systemctl-print-error-load-state-in-red.patch
new file mode 100644
index 0000000..c559d58
--- /dev/null
+++ b/0064-systemctl-print-error-load-state-in-red.patch
@@ -0,0 +1,41 @@
+From 3fc55e7a9f4dc14ca74ed6b293e1fac03e1fec74 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 6 Dec 2011 01:14:36 +0100
+Subject: [PATCH 064/126] systemctl: print 'error' load state in red
+
+Be consistent in coloring of load states in list-units and status.
+Print only 'error' in red.
+There are no 'banned' or 'failed' states. Do not color 'masked', it's
+not an error.
+(cherry picked from commit f7b9e331ed71fb2f832ac5587fb5119dd2bfc32f)
+---
+ src/systemctl.c |    6 ++----
+ 1 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/systemctl.c b/src/systemctl.c
+index 668641d..960d3c0 100644
+--- a/src/systemctl.c
++++ b/src/systemctl.c
+@@ -377,8 +377,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
+ 
+                 n_shown++;
+ 
+-                if (!streq(u->load_state, "loaded") &&
+-                    !streq(u->load_state, "banned")) {
++                if (streq(u->load_state, "error")) {
+                         on_loaded = ansi_highlight(true);
+                         off_loaded = ansi_highlight(false);
+                 } else
+@@ -2063,8 +2062,7 @@ static void print_status_info(UnitStatusInfo *i) {
+         if (i->following)
+                 printf("\t  Follow: unit currently follows state of %s\n", i->following);
+ 
+-        if (streq_ptr(i->load_state, "failed") ||
+-            streq_ptr(i->load_state, "banned")) {
++        if (streq_ptr(i->load_state, "error")) {
+                 on = ansi_highlight(true);
+                 off = ansi_highlight(false);
+         } else
+-- 
+1.7.7.5
+
diff --git a/0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch b/0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch
new file mode 100644
index 0000000..dc012ee
--- /dev/null
+++ b/0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch
@@ -0,0 +1,27 @@
+From 0773caae1b4eae198f8e41fb8a1d46c24c99543e Mon Sep 17 00:00:00 2001
+From: Tim Waugh <twaugh at redhat.com>
+Date: Thu, 8 Dec 2011 17:32:09 +0100
+Subject: [PATCH 065/126] '@' is an 'ampersat' not an 'ampersand'; let's call
+ it 'at symbol' (cherry picked from commit
+ 7e115808a990199fe00de4cc2ef48fe96de3d3d0)
+
+---
+ man/systemd.socket.xml |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
+index 2f31242..f883543 100644
+--- a/man/systemd.socket.xml
++++ b/man/systemd.socket.xml
+@@ -156,7 +156,7 @@
+                                 family.</para>
+ 
+                                 <para>If the address starts with an
+-                                ampersand (@) it is read as abstract
++                                at symbol (@) it is read as abstract
+                                 namespace socket in the AF_UNIX
+                                 family. The @ is replaced with a NUL
+                                 character before binding. For details
+-- 
+1.7.7.5
+
diff --git a/0066-path-add-missing-pieces-for-PathModified.patch b/0066-path-add-missing-pieces-for-PathModified.patch
new file mode 100644
index 0000000..8d68968
--- /dev/null
+++ b/0066-path-add-missing-pieces-for-PathModified.patch
@@ -0,0 +1,52 @@
+From 7cae93f652dff82e998a3d1f99f1a18a3f908c30 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 8 Dec 2011 12:09:10 +0100
+Subject: [PATCH 066/126] path: add missing pieces for PathModified
+
+PATH_MODIFIED worked internally for PID files detection, but was unusable
+in units.
+(cherry picked from commit 714d943f72417f53bcb98ed45d002aa270e793c4)
+---
+ src/load-fragment-gperf.gperf.m4 |    1 +
+ src/path.c                       |    6 ++++--
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
+index 84ae28c..35ec005 100644
+--- a/src/load-fragment-gperf.gperf.m4
++++ b/src/load-fragment-gperf.gperf.m4
+@@ -210,6 +210,7 @@ m4_dnl
+ Path.PathExists,                 config_parse_path_spec,             0,                             0
+ Path.PathExistsGlob,             config_parse_path_spec,             0,                             0
+ Path.PathChanged,                config_parse_path_spec,             0,                             0
++Path.PathModified,               config_parse_path_spec,             0,                             0
+ Path.DirectoryNotEmpty,          config_parse_path_spec,             0,                             0
+ Path.Unit,                       config_parse_path_unit,             0,                             0
+ Path.MakeDirectory,              config_parse_bool,                  0,                             offsetof(Path, make_directory)
+diff --git a/src/path.c b/src/path.c
+index 1e5d825..3fee247 100644
+--- a/src/path.c
++++ b/src/path.c
+@@ -149,7 +149,8 @@ int pathspec_fd_event(PathSpec *s, uint32_t events) {
+         while (k > 0) {
+                 size_t step;
+ 
+-                if (s->type == PATH_CHANGED && s->primary_wd == e->wd)
++                if ((s->type == PATH_CHANGED || s->type == PATH_MODIFIED) &&
++                    s->primary_wd == e->wd)
+                         r = 1;
+ 
+                 step = sizeof(struct inotify_event) + e->len;
+@@ -184,7 +185,8 @@ static bool pathspec_check_good(PathSpec *s, bool initial) {
+                 break;
+         }
+ 
+-        case PATH_CHANGED: {
++        case PATH_CHANGED:
++        case PATH_MODIFIED: {
+                 bool b;
+ 
+                 b = access(s->path, F_OK) >= 0;
+-- 
+1.7.7.5
+
diff --git a/0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch b/0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch
new file mode 100644
index 0000000..a2715ff
--- /dev/null
+++ b/0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch
@@ -0,0 +1,55 @@
+From 43664cdd8565ae24b27c3f91be1de64ae9021608 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 9 Dec 2011 15:24:04 +0100
+Subject: [PATCH 067/126] unit: fix false positive in check for unneeded unit
+
+A freshly started unit A was immediately considered unneeded just because
+unit B, which Requires A, was starting later in the transaction.
+Fix it by looking not only at the state of B, but also at its pending job.
+
+Also fix a copied&pasted comment.
+(cherry picked from commit f60c2665f9ba1dd4a6b4a36b2e8195482ada9957)
+---
+ src/unit.c |   10 +++++-----
+ 1 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/unit.c b/src/unit.c
+index 018e986..56137d7 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -1032,19 +1032,19 @@ static void unit_check_unneeded(Unit *u) {
+                 return;
+ 
+         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
+-                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
++                if (unit_pending_active(other))
+                         return;
+ 
+         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
+-                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
++                if (unit_pending_active(other))
+                         return;
+ 
+         SET_FOREACH(other, u->meta.dependencies[UNIT_WANTED_BY], i)
+-                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
++                if (unit_pending_active(other))
+                         return;
+ 
+         SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
+-                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
++                if (unit_pending_active(other))
+                         return;
+ 
+         log_info("Service %s is not needed anymore. Stopping.", u->meta.id);
+@@ -2518,7 +2518,7 @@ bool unit_pending_inactive(Unit *u) {
+ bool unit_pending_active(Unit *u) {
+         assert(u);
+ 
+-        /* Returns true if the unit is inactive or going down */
++        /* Returns true if the unit is active or going up */
+ 
+         if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
+                 return true;
+-- 
+1.7.7.5
+
diff --git a/0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch b/0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch
new file mode 100644
index 0000000..58f27db
--- /dev/null
+++ b/0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch
@@ -0,0 +1,48 @@
+From c075b337c3ebfd4665f3745a66984bf2d2793a97 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 9 Dec 2011 15:25:29 +0100
+Subject: [PATCH 068/126] unit: check for unneeded dependencies even when unit
+ stop was expected
+
+systemd did not stop units marked as "StopWhenUnneeded=yes" when the requiring
+unit was stopped on user's request.
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=704197
+(cherry picked from commit cd0504d0a13d8297b97c9238fd1b94b4141c5aa8)
+---
+ src/unit.c |   12 ++++++++++++
+ 1 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/src/unit.c b/src/unit.c
+index 56137d7..03c90f5 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -1105,6 +1105,14 @@ static void retroactively_stop_dependencies(Unit *u) {
+         SET_FOREACH(other, u->meta.dependencies[UNIT_BOUND_BY], i)
+                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                         manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
++}
++
++static void check_unneeded_dependencies(Unit *u) {
++        Iterator i;
++        Unit *other;
++
++        assert(u);
++        assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
+ 
+         /* Garbage collect services that might not be needed anymore, if enabled */
+         SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
+@@ -1263,6 +1271,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
+                                 retroactively_stop_dependencies(u);
+                 }
+ 
++                /* stop unneeded units regardless if going down was expected or not */
++                if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
++                        check_unneeded_dependencies(u);
++
+                 if (ns != os && ns == UNIT_FAILED) {
+                         log_notice("Unit %s entered failed state.", u->meta.id);
+                         unit_trigger_on_failure(u);
+-- 
+1.7.7.5
+
diff --git a/0069-pam-module-add-a-couple-of-debugging-prints.patch b/0069-pam-module-add-a-couple-of-debugging-prints.patch
new file mode 100644
index 0000000..a642c0c
--- /dev/null
+++ b/0069-pam-module-add-a-couple-of-debugging-prints.patch
@@ -0,0 +1,42 @@
+From 2f9743bff6e9bfe4365c24becea68b27d06d1c0d Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 14 Dec 2011 01:25:47 +0100
+Subject: [PATCH 069/126] pam-module: add a couple of debugging prints (cherry
+ picked from commit
+ ce9593140b127ce782e2fa2f47fc55558b331126)
+
+---
+ src/pam-module.c |   10 ++++++++++
+ 1 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/src/pam-module.c b/src/pam-module.c
+index 46b7bec..9002f4e 100644
+--- a/src/pam-module.c
++++ b/src/pam-module.c
+@@ -521,6 +521,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
+                 goto finish;
+         }
+ 
++        if (debug)
++                pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: "
++                           "uid=%u pid=%u service=%s type=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
++                           uid, pid, service, type, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host);
++
+         reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+         if (!reply) {
+                 pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error));
+@@ -541,6 +546,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
+                 goto finish;
+         }
+ 
++        if (debug)
++                pam_syslog(handle, LOG_DEBUG, "Reply from logind: "
++                           "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u",
++                           id, object_path, runtime_path, session_fd, seat, vtnr);
++
+         r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0);
+         if (r != PAM_SUCCESS) {
+                 pam_syslog(handle, LOG_ERR, "Failed to set session id.");
+-- 
+1.7.7.5
+
diff --git a/0070-fsck-Fix-typo-in-comment.patch b/0070-fsck-Fix-typo-in-comment.patch
new file mode 100644
index 0000000..a335d73
--- /dev/null
+++ b/0070-fsck-Fix-typo-in-comment.patch
@@ -0,0 +1,26 @@
+From 0d380f2f2d27eabcab8167a52e2d7196720f3d6a Mon Sep 17 00:00:00 2001
+From: Gregs Gregs <gregpuppy01 at yahoo.gr>
+Date: Mon, 14 Nov 2011 19:58:03 +0200
+Subject: [PATCH 070/126] fsck: Fix typo in comment (cherry picked from commit
+ b911442003350c56673e5689328f173ed03bbabd)
+
+---
+ src/fsck.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/fsck.c b/src/fsck.c
+index c5088ad..3e66535 100644
+--- a/src/fsck.c
++++ b/src/fsck.c
+@@ -80,7 +80,7 @@ static void start_target(const char *target, bool isolate) {
+ 
+         if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
+ 
+-                /* Don't print a waring if we aren't called during
++                /* Don't print a warning if we aren't called during
+                  * startup */
+                 if (!dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB))
+                         log_error("Failed to start unit: %s", bus_error_message(&error));
+-- 
+1.7.7.5
+
diff --git a/0071-systemctl-fix-typo-in-is-enabled.patch b/0071-systemctl-fix-typo-in-is-enabled.patch
new file mode 100644
index 0000000..bec6221
--- /dev/null
+++ b/0071-systemctl-fix-typo-in-is-enabled.patch
@@ -0,0 +1,27 @@
+From b63edf0ecaab0cb26bba99b139511ac22d3bf785 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Wed, 14 Dec 2011 22:23:56 +0100
+Subject: [PATCH 071/126] systemctl: fix typo in 'is-enabled'
+
+It prevented the action from working without dbus.
+(cherry picked from commit c971700e41e0ac9883ab0744921b79dd396170dc)
+---
+ src/systemctl.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/systemctl.c b/src/systemctl.c
+index 960d3c0..c86ec80 100644
+--- a/src/systemctl.c
++++ b/src/systemctl.c
+@@ -4998,7 +4998,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
+          * enable/disable */
+         if (!streq(verbs[i].verb, "enable") &&
+             !streq(verbs[i].verb, "disable") &&
+-            !streq(verbs[i].verb, "is-enable") &&
++            !streq(verbs[i].verb, "is-enabled") &&
+             !streq(verbs[i].verb, "list-unit-files") &&
+             !streq(verbs[i].verb, "reenable") &&
+             !streq(verbs[i].verb, "preset") &&
+-- 
+1.7.7.5
+
diff --git a/0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch b/0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch
new file mode 100644
index 0000000..5328119
--- /dev/null
+++ b/0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch
@@ -0,0 +1,75 @@
+From c8be37cab131ec8a1aa54e5878483a18fc0bde6e Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 15 Dec 2011 21:31:14 +0100
+Subject: [PATCH 072/126] tmpfiles: use an enum instead of plain char for item
+ type
+
+For better safety. gcc can warn about missing values in switch statements.
+(cherry picked from commit 66ccd0387e528567dff92239e85c962d2f140ef1)
+---
+ src/tmpfiles.c |   12 +++++++-----
+ 1 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index 21bf44d..6171140 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -50,7 +50,7 @@
+  * properly owned directories beneath /tmp, /var/tmp, /run, which are
+  * volatile and hence need to be recreated on bootup. */
+ 
+-enum {
++typedef enum ItemType {
+         /* These ones take file names */
+         CREATE_FILE = 'f',
+         TRUNCATE_FILE = 'F',
+@@ -62,10 +62,10 @@ enum {
+         IGNORE_PATH = 'x',
+         REMOVE_PATH = 'r',
+         RECURSIVE_REMOVE_PATH = 'R'
+-};
++} ItemType;
+ 
+ typedef struct Item {
+-        char type;
++        ItemType type;
+ 
+         char *path;
+         uid_t uid;
+@@ -90,7 +90,7 @@ static const char *arg_prefix = NULL;
+ 
+ #define MAX_DEPTH 256
+ 
+-static bool needs_glob(int t) {
++static bool needs_glob(ItemType t) {
+         return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH;
+ }
+ 
+@@ -701,6 +701,7 @@ static bool item_equal(Item *a, Item *b) {
+ static int parse_line(const char *fname, unsigned line, const char *buffer) {
+         Item *i, *existing;
+         char *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
++        char type;
+         Hashmap *h;
+         int r;
+ 
+@@ -720,7 +721,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
+                    "%ms "
+                    "%ms "
+                    "%ms",
+-                   &i->type,
++                   &type,
+                    &i->path,
+                    &mode,
+                    &user,
+@@ -730,6 +731,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
+                 r = -EIO;
+                 goto finish;
+         }
++        i->type = type;
+ 
+         if (i->type != CREATE_FILE &&
+             i->type != TRUNCATE_FILE &&
+-- 
+1.7.7.5
+
diff --git a/0073-tmpfiles-rename-a-couple-of-functions.patch b/0073-tmpfiles-rename-a-couple-of-functions.patch
new file mode 100644
index 0000000..f1cec53
--- /dev/null
+++ b/0073-tmpfiles-rename-a-couple-of-functions.patch
@@ -0,0 +1,55 @@
+From bdd9b9807a89eb8e4789a3279253f6f845f90e9b Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 15 Dec 2011 21:32:50 +0100
+Subject: [PATCH 073/126] tmpfiles: rename a couple of functions
+
+remove_item -> remove_item_instance
+remove_item_glob -> remove_item
+(cherry picked from commit a08961233bea3bfad7776e04482d07012216b134)
+---
+ src/tmpfiles.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index 6171140..4308f7f 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -563,7 +563,7 @@ finish:
+         return r;
+ }
+ 
+-static int remove_item(Item *i, const char *instance) {
++static int remove_item_instance(Item *i, const char *instance) {
+         int r;
+ 
+         assert(i);
+@@ -599,7 +599,7 @@ static int remove_item(Item *i, const char *instance) {
+         return 0;
+ }
+ 
+-static int remove_item_glob(Item *i) {
++static int remove_item(Item *i) {
+         assert(i);
+ 
+         switch (i->type) {
+@@ -633,7 +633,7 @@ static int remove_item_glob(Item *i) {
+                 }
+ 
+                 STRV_FOREACH(fn, g.gl_pathv)
+-                        if ((k = remove_item(i, *fn)) < 0)
++                        if ((k = remove_item_instance(i, *fn)) < 0)
+                                 r = k;
+ 
+                 globfree(&g);
+@@ -650,7 +650,7 @@ static int process_item(Item *i) {
+         assert(i);
+ 
+         r = arg_create ? create_item(i) : 0;
+-        q = arg_remove ? remove_item_glob(i) : 0;
++        q = arg_remove ? remove_item(i) : 0;
+         p = arg_clean ? clean_item(i) : 0;
+ 
+         if (r < 0)
+-- 
+1.7.7.5
+
diff --git a/0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch b/0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch
new file mode 100644
index 0000000..573fb9e
--- /dev/null
+++ b/0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch
@@ -0,0 +1,211 @@
+From 35bb56b851308370435c0ff28c2d73a790043fbb Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 15 Dec 2011 23:44:23 +0100
+Subject: [PATCH 074/126] tmpfiles: use a common function to set
+ owner/group/mode/label (cherry picked from commit
+ f05bc3f7f1d85ce4d31fa9c9b2780797ef3953cd)
+
+---
+ src/tmpfiles.c |  120 +++++++++++++++++++++-----------------------------------
+ 1 files changed, 45 insertions(+), 75 deletions(-)
+
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index 4308f7f..9d07a2a 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -405,8 +405,27 @@ finish:
+         return r;
+ }
+ 
++static int item_set_perms(Item *i) {
++        if (i->mode_set)
++                if (chmod(i->path, i->mode) < 0) {
++                        log_error("chmod(%s) failed: %m", i->path);
++                        return -errno;
++                }
++
++        if (i->uid_set || i->gid_set)
++                if (chown(i->path,
++                          i->uid_set ? i->uid : (uid_t) -1,
++                          i->gid_set ? i->gid : (gid_t) -1) < 0) {
++
++                        log_error("chown(%s) failed: %m", i->path);
++                        return -errno;
++                }
++
++        return label_fix(i->path, false);
++}
++
+ static int create_item(Item *i) {
+-        int fd = -1, r;
++        int r;
+         mode_t u;
+         struct stat st;
+ 
+@@ -420,7 +439,8 @@ static int create_item(Item *i) {
+                 return 0;
+ 
+         case CREATE_FILE:
+-        case TRUNCATE_FILE:
++        case TRUNCATE_FILE: {
++                int fd;
+ 
+                 u = umask(0);
+                 fd = open(i->path, O_CREAT|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW|
+@@ -429,39 +449,27 @@ static int create_item(Item *i) {
+ 
+                 if (fd < 0) {
+                         log_error("Failed to create file %s: %m", i->path);
+-                        r = -errno;
+-                        goto finish;
++                        return -errno;
+                 }
+ 
+-                if (fstat(fd, &st) < 0) {
++                close_nointr_nofail(fd);
++
++                if (stat(i->path, &st) < 0) {
+                         log_error("stat(%s) failed: %m", i->path);
+-                        r = -errno;
+-                        goto finish;
++                        return -errno;
+                 }
+ 
+                 if (!S_ISREG(st.st_mode)) {
+                         log_error("%s is not a file.", i->path);
+-                        r = -EEXIST;
+-                        goto finish;
++                        return -EEXIST;
+                 }
+ 
+-                if (i->mode_set)
+-                        if (fchmod(fd, i->mode) < 0) {
+-                                log_error("chmod(%s) failed: %m", i->path);
+-                                r = -errno;
+-                                goto finish;
+-                        }
+-
+-                if (i->uid_set || i->gid_set)
+-                        if (fchown(fd,
+-                                   i->uid_set ? i->uid : (uid_t) -1,
+-                                   i->gid_set ? i->gid : (gid_t) -1) < 0) {
+-                                log_error("chown(%s) failed: %m", i->path);
+-                                r = -errno;
+-                                goto finish;
+-                        }
++                r = item_set_perms(i);
++                if (r < 0)
++                        return r;
+ 
+                 break;
++        }
+ 
+         case TRUNCATE_DIRECTORY:
+         case CREATE_DIRECTORY:
+@@ -473,38 +481,22 @@ static int create_item(Item *i) {
+ 
+                 if (r < 0 && errno != EEXIST) {
+                         log_error("Failed to create directory %s: %m", i->path);
+-                        r = -errno;
+-                        goto finish;
++                        return -errno;
+                 }
+ 
+                 if (stat(i->path, &st) < 0) {
+                         log_error("stat(%s) failed: %m", i->path);
+-                        r = -errno;
+-                        goto finish;
++                        return -errno;
+                 }
+ 
+                 if (!S_ISDIR(st.st_mode)) {
+                         log_error("%s is not a directory.", i->path);
+-                        r = -EEXIST;
+-                        goto finish;
++                        return -EEXIST;
+                 }
+ 
+-                if (i->mode_set)
+-                        if (chmod(i->path, i->mode) < 0) {
+-                                log_error("chmod(%s) failed: %m", i->path);
+-                                r = -errno;
+-                                goto finish;
+-                        }
+-
+-                if (i->uid_set || i->gid_set)
+-                        if (chown(i->path,
+-                                  i->uid_set ? i->uid : (uid_t) -1,
+-                                  i->gid_set ? i->gid : (gid_t) -1) < 0) {
+-
+-                                log_error("chown(%s) failed: %m", i->path);
+-                                r = -errno;
+-                                goto finish;
+-                        }
++                r = item_set_perms(i);
++                if (r < 0)
++                        return r;
+ 
+                 break;
+ 
+@@ -516,51 +508,29 @@ static int create_item(Item *i) {
+ 
+                 if (r < 0 && errno != EEXIST) {
+                         log_error("Failed to create fifo %s: %m", i->path);
+-                        r = -errno;
+-                        goto finish;
++                        return -errno;
+                 }
+ 
+                 if (stat(i->path, &st) < 0) {
+                         log_error("stat(%s) failed: %m", i->path);
+-                        r = -errno;
+-                        goto finish;
++                        return -errno;
+                 }
+ 
+                 if (!S_ISFIFO(st.st_mode)) {
+                         log_error("%s is not a fifo.", i->path);
+-                        r = -EEXIST;
+-                        goto finish;
++                        return -EEXIST;
+                 }
+ 
+-                if (i->mode_set)
+-                        if (chmod(i->path, i->mode) < 0) {
+-                                log_error("chmod(%s) failed: %m", i->path);
+-                                r = -errno;
+-                                goto finish;
+-                        }
+-
+-                if (i->uid_set || i->gid_set)
+-                        if (chown(i->path,
+-                                   i->uid_set ? i->uid : (uid_t) -1,
+-                                   i->gid_set ? i->gid : (gid_t) -1) < 0) {
+-                                log_error("chown(%s) failed: %m", i->path);
+-                                r = -errno;
+-                                goto finish;
+-                        }
++                r = item_set_perms(i);
++                if (r < 0)
++                        return r;
+ 
+                 break;
+         }
+ 
+-        if ((r = label_fix(i->path, false)) < 0)
+-                goto finish;
+-
+         log_debug("%s created successfully.", i->path);
+ 
+-finish:
+-        if (fd >= 0)
+-                close_nointr_nofail(fd);
+-
+-        return r;
++        return 0;
+ }
+ 
+ static int remove_item_instance(Item *i, const char *instance) {
+-- 
+1.7.7.5
+
diff --git a/0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch b/0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch
new file mode 100644
index 0000000..d19e058
--- /dev/null
+++ b/0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch
@@ -0,0 +1,102 @@
+From ef754c81da83d1a1d9b2a3eb41b545196800f59f Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 15 Dec 2011 23:45:26 +0100
+Subject: [PATCH 075/126] tmpfiles: separate a generic item glob processing
+ function
+
+Item glob processing will be useful for more than just removing.
+(cherry picked from commit 99e68c0b2d6ca9d491036920fcbca4c8d54404a8)
+---
+ src/tmpfiles.c |   60 ++++++++++++++++++++++++++++++-------------------------
+ 1 files changed, 33 insertions(+), 27 deletions(-)
+
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index 9d07a2a..d655bc3 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -405,6 +405,33 @@ finish:
+         return r;
+ }
+ 
++static int glob_item(Item *i, int (*action)(Item *, const char *)) {
++        int r = 0, k;
++        glob_t g;
++        char **fn;
++
++        zero(g);
++
++        errno = 0;
++        if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
++
++                if (k != GLOB_NOMATCH) {
++                        if (errno != 0)
++                                errno = EIO;
++
++                        log_error("glob(%s) failed: %m", i->path);
++                        return -errno;
++                }
++        }
++
++        STRV_FOREACH(fn, g.gl_pathv)
++                if ((k = action(i, *fn)) < 0)
++                        r = k;
++
++        globfree(&g);
++        return r;
++}
++
+ static int item_set_perms(Item *i) {
+         if (i->mode_set)
+                 if (chmod(i->path, i->mode) < 0) {
+@@ -570,6 +597,8 @@ static int remove_item_instance(Item *i, const char *instance) {
+ }
+ 
+ static int remove_item(Item *i) {
++        int r = 0;
++
+         assert(i);
+ 
+         switch (i->type) {
+@@ -583,35 +612,12 @@ static int remove_item(Item *i) {
+ 
+         case REMOVE_PATH:
+         case TRUNCATE_DIRECTORY:
+-        case RECURSIVE_REMOVE_PATH: {
+-                int r = 0, k;
+-                glob_t g;
+-                char **fn;
+-
+-                zero(g);
+-
+-                errno = 0;
+-                if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) {
+-
+-                        if (k != GLOB_NOMATCH) {
+-                                if (errno != 0)
+-                                        errno = EIO;
+-
+-                                log_error("glob(%s) failed: %m", i->path);
+-                                return -errno;
+-                        }
+-                }
+-
+-                STRV_FOREACH(fn, g.gl_pathv)
+-                        if ((k = remove_item_instance(i, *fn)) < 0)
+-                                r = k;
+-
+-                globfree(&g);
+-                return r;
+-        }
++        case RECURSIVE_REMOVE_PATH:
++                r = glob_item(i, remove_item_instance);
++                break;
+         }
+ 
+-        return 0;
++        return r;
+ }
+ 
+ static int process_item(Item *i) {
+-- 
+1.7.7.5
+
diff --git a/0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch b/0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch
new file mode 100644
index 0000000..a50fcc3
--- /dev/null
+++ b/0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch
@@ -0,0 +1,195 @@
+From 265c05c53ac71337feb5db53eb8c7acf13901a31 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 15 Dec 2011 23:11:07 +0100
+Subject: [PATCH 076/126] tmpfiles: add RECURSIVE_RELABEL_PATH ('Z')
+
+Feature requested by Dan Walsh.
+(cherry picked from commit a8d8878329893d19106053e5008f0075f149aa16)
+---
+ src/tmpfiles.c |  124 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 files changed, 112 insertions(+), 12 deletions(-)
+
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index d655bc3..18067c4 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -61,7 +61,8 @@ typedef enum ItemType {
+         /* These ones take globs */
+         IGNORE_PATH = 'x',
+         REMOVE_PATH = 'r',
+-        RECURSIVE_REMOVE_PATH = 'R'
++        RECURSIVE_REMOVE_PATH = 'R',
++        RECURSIVE_RELABEL_PATH = 'Z'
+ } ItemType;
+ 
+ typedef struct Item {
+@@ -91,7 +92,7 @@ static const char *arg_prefix = NULL;
+ #define MAX_DEPTH 256
+ 
+ static bool needs_glob(ItemType t) {
+-        return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH;
++        return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RECURSIVE_RELABEL_PATH;
+ }
+ 
+ static struct Item* find_glob(Hashmap *h, const char *match) {
+@@ -405,6 +406,96 @@ finish:
+         return r;
+ }
+ 
++static int recursive_relabel_children(const char *path) {
++        DIR *d;
++        int ret = 0;
++
++        /* This returns the first error we run into, but nevertheless
++         * tries to go on */
++
++        d = opendir(path);
++        if (!d)
++                return errno == ENOENT ? 0 : -errno;
++
++        for (;;) {
++                struct dirent buf, *de;
++                bool is_dir;
++                int r;
++                char *entry_path;
++
++                r = readdir_r(d, &buf, &de);
++                if (r != 0) {
++                        if (ret == 0)
++                                ret = -r;
++                        break;
++                }
++
++                if (!de)
++                        break;
++
++                if (streq(de->d_name, ".") || streq(de->d_name, ".."))
++                        continue;
++
++                if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) {
++                        if (ret == 0)
++                                ret = -ENOMEM;
++                        continue;
++                }
++
++                if (de->d_type == DT_UNKNOWN) {
++                        struct stat st;
++
++                        if (lstat(entry_path, &st) < 0) {
++                                if (ret == 0 && errno != ENOENT)
++                                        ret = -errno;
++                                free(entry_path);
++                                continue;
++                        }
++
++                        is_dir = S_ISDIR(st.st_mode);
++
++                } else
++                        is_dir = de->d_type == DT_DIR;
++
++                r = label_fix(entry_path, false);
++                if (r < 0) {
++                        if (ret == 0 && r != -ENOENT)
++                                ret = r;
++                        free(entry_path);
++                        continue;
++                }
++
++                if (is_dir) {
++                        r = recursive_relabel_children(entry_path);
++                        if (r < 0 && ret == 0)
++                                ret = r;
++                }
++
++                free(entry_path);
++        }
++
++        closedir(d);
++
++        return ret;
++}
++
++static int recursive_relabel(Item *i, const char *path) {
++        int r;
++        struct stat st;
++
++        r = label_fix(path, false);
++        if (r < 0)
++                return r;
++
++        if (lstat(path, &st) < 0)
++                return -errno;
++
++        if (S_ISDIR(st.st_mode))
++                r = recursive_relabel_children(path);
++
++        return r;
++}
++
+ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
+         int r = 0, k;
+         glob_t g;
+@@ -553,6 +644,12 @@ static int create_item(Item *i) {
+                         return r;
+ 
+                 break;
++
++        case RECURSIVE_RELABEL_PATH:
++
++                r = glob_item(i, recursive_relabel);
++                if (r < 0)
++                        return r;
+         }
+ 
+         log_debug("%s created successfully.", i->path);
+@@ -572,6 +669,7 @@ static int remove_item_instance(Item *i, const char *instance) {
+         case CREATE_DIRECTORY:
+         case CREATE_FIFO:
+         case IGNORE_PATH:
++        case RECURSIVE_RELABEL_PATH:
+                 break;
+ 
+         case REMOVE_PATH:
+@@ -608,6 +706,7 @@ static int remove_item(Item *i) {
+         case CREATE_DIRECTORY:
+         case CREATE_FIFO:
+         case IGNORE_PATH:
++        case RECURSIVE_RELABEL_PATH:
+                 break;
+ 
+         case REMOVE_PATH:
+@@ -707,20 +806,21 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
+                 r = -EIO;
+                 goto finish;
+         }
+-        i->type = type;
+ 
+-        if (i->type != CREATE_FILE &&
+-            i->type != TRUNCATE_FILE &&
+-            i->type != CREATE_DIRECTORY &&
+-            i->type != TRUNCATE_DIRECTORY &&
+-            i->type != CREATE_FIFO &&
+-            i->type != IGNORE_PATH &&
+-            i->type != REMOVE_PATH &&
+-            i->type != RECURSIVE_REMOVE_PATH) {
+-                log_error("[%s:%u] Unknown file type '%c'.", fname, line, i->type);
++        if (type != CREATE_FILE &&
++            type != TRUNCATE_FILE &&
++            type != CREATE_DIRECTORY &&
++            type != TRUNCATE_DIRECTORY &&
++            type != CREATE_FIFO &&
++            type != IGNORE_PATH &&
++            type != REMOVE_PATH &&
++            type != RECURSIVE_REMOVE_PATH &&
++            type != RECURSIVE_RELABEL_PATH) {
++                log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
+                 r = -EBADMSG;
+                 goto finish;
+         }
++        i->type = type;
+ 
+         if (!path_is_absolute(i->path)) {
+                 log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
+-- 
+1.7.7.5
+
diff --git a/0077-man-document-Z-in-tmpfiles.patch b/0077-man-document-Z-in-tmpfiles.patch
new file mode 100644
index 0000000..8dc8ffc
--- /dev/null
+++ b/0077-man-document-Z-in-tmpfiles.patch
@@ -0,0 +1,49 @@
+From e5c58e069271013582b9de91859aaa5fef70f079 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 15 Dec 2011 23:04:37 +0100
+Subject: [PATCH 077/126] man: document 'Z' in tmpfiles (cherry picked from
+ commit 462d63db0680c2b69d5426ded197342372ebe309)
+
+---
+ man/systemd-tmpfiles.xml |    3 ++-
+ man/tmpfiles.d.xml       |   10 ++++++++++
+ 2 files changed, 12 insertions(+), 1 deletions(-)
+
+diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
+index 08d5c73..20e399b 100644
+--- a/man/systemd-tmpfiles.xml
++++ b/man/systemd-tmpfiles.xml
+@@ -84,7 +84,8 @@
+                                 <listitem><para>If this option is passed all
+                                 files and directories marked with f,
+                                 F, d, D in the configuration files are
+-                                created.</para></listitem>
++                                created. Files and directories marked with Z
++                                are relabeled.</para></listitem>
+                         </varlistentry>
+ 
+                         <varlistentry>
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index 7f4c45c..580d99c 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -155,6 +155,16 @@ d    /run/user 0755 root root 10d</programlisting>
+                                         place of normal path
+                                         names.</para></listitem>
+                                 </varlistentry>
++
++                                <varlistentry>
++                                        <term><varname>Z</varname></term>
++                                        <listitem><para>Recursively
++                                        relabel security context of a path and
++                                        all its subdirectories (if it is a
++                                        directory). Lines of this type accept
++                                        shell-style globs in place of normal
++                                        path names.</para></listitem>
++                                </varlistentry>
+                         </variablelist>
+                 </refsect2>
+ 
+-- 
+1.7.7.5
+
diff --git a/0078-man-mention-that-Z-ignores-uid-gid-mode.patch b/0078-man-mention-that-Z-ignores-uid-gid-mode.patch
new file mode 100644
index 0000000..de444b5
--- /dev/null
+++ b/0078-man-mention-that-Z-ignores-uid-gid-mode.patch
@@ -0,0 +1,36 @@
+From a783d0af2d7a5a40942c8c2355a9119e3344dcc2 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 16 Dec 2011 00:38:22 +0100
+Subject: [PATCH 078/126] man: mention that 'Z' ignores uid/gid/mode (cherry
+ picked from commit
+ a37b560a63f9b48980b94fc1cf9cd4fe25e3b904)
+
+---
+ man/tmpfiles.d.xml |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index 580d99c..6a2a377 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -175,7 +175,7 @@ d    /run/user 0755 root root 10d</programlisting>
+                         creating this file or directory. If omitted or
+                         when set to - the default is used: 0755 for
+                         directories, 0644 for files. This parameter is
+-                        ignored for x, r, R lines.</para>
++                        ignored for x, r, R, Z lines.</para>
+                 </refsect2>
+ 
+                 <refsect2>
+@@ -186,7 +186,7 @@ d    /run/user 0755 root root 10d</programlisting>
+                         user/group ID or a user or group name. If
+                         omitted or when set to - the default 0 (root)
+                         is used. . These parameters are ignored for x,
+-                        r, R lines.</para>
++                        r, R, Z lines.</para>
+                 </refsect2>
+ 
+                 <refsect2>
+-- 
+1.7.7.5
+
diff --git a/0079-service-use-syslog-console-for-sysv_console.patch b/0079-service-use-syslog-console-for-sysv_console.patch
new file mode 100644
index 0000000..1266bba
--- /dev/null
+++ b/0079-service-use-syslog-console-for-sysv_console.patch
@@ -0,0 +1,28 @@
+From d18d8b40a2c65a551d2954cea701631a5db323e7 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 16 Dec 2011 17:38:01 +0100
+Subject: [PATCH 079/126] service: use 'syslog+console' for sysv_console
+
+The default output to 'tty' for SysV service was making it hard to debug
+problems because error messages were missing from syslog.
+(cherry picked from commit 18d01523c88d59293d5bd1c199d41ce587e4856e)
+---
+ src/service.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/service.c b/src/service.c
+index 175a729..d229301 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -833,7 +833,7 @@ static int service_load_sysv_path(Service *s, const char *path) {
+         s->restart = SERVICE_RESTART_NO;
+ 
+         if (s->meta.manager->sysv_console)
+-                s->exec_context.std_output = EXEC_OUTPUT_TTY;
++                s->exec_context.std_output = EXEC_OUTPUT_SYSLOG_AND_CONSOLE;
+ 
+         s->exec_context.kill_mode = KILL_PROCESS;
+ 
+-- 
+1.7.7.5
+
diff --git a/0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch b/0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch
new file mode 100644
index 0000000..1811f01
--- /dev/null
+++ b/0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch
@@ -0,0 +1,194 @@
+From 2c023ff55f1449a841aa8449f03792a8436c2481 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 16 Dec 2011 18:00:11 +0100
+Subject: [PATCH 080/126] tmpfiles: apply chown, chmod for 'Z' entries too
+
+If changing ownership or permissions is not desired, they can be
+configured to '-' or omitted entirely.
+(cherry picked from commit 062e01bbdbc3201e4c99bc0b702cb04a0ae2190c)
+---
+ man/systemd-tmpfiles.xml |    3 +-
+ man/tmpfiles.d.xml       |   16 ++++++++-----
+ src/tmpfiles.c           |   55 +++++++++++++++++++++++----------------------
+ 3 files changed, 40 insertions(+), 34 deletions(-)
+
+diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
+index 20e399b..74dfd5a 100644
+--- a/man/systemd-tmpfiles.xml
++++ b/man/systemd-tmpfiles.xml
+@@ -85,7 +85,8 @@
+                                 files and directories marked with f,
+                                 F, d, D in the configuration files are
+                                 created. Files and directories marked with Z
+-                                are relabeled.</para></listitem>
++                                have their ownership, access mode and security
++                                labels set.</para></listitem>
+                         </varlistentry>
+ 
+                         <varlistentry>
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index 6a2a377..e137967 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -158,8 +158,9 @@ d    /run/user 0755 root root 10d</programlisting>
+ 
+                                 <varlistentry>
+                                         <term><varname>Z</varname></term>
+-                                        <listitem><para>Recursively
+-                                        relabel security context of a path and
++                                        <listitem><para>Recursively set
++                                        ownership, access mode and relabel
++                                        security context of a path and
+                                         all its subdirectories (if it is a
+                                         directory). Lines of this type accept
+                                         shell-style globs in place of normal
+@@ -174,8 +175,10 @@ d    /run/user 0755 root root 10d</programlisting>
+                         <para>The file access mode to use when
+                         creating this file or directory. If omitted or
+                         when set to - the default is used: 0755 for
+-                        directories, 0644 for files. This parameter is
+-                        ignored for x, r, R, Z lines.</para>
++                        directories, 0644 for files. For Z lines
++                        if omitted or when set to - the file access mode will
++                        not be modified. This parameter is ignored for x, r, R
++                        lines.</para>
+                 </refsect2>
+ 
+                 <refsect2>
+@@ -185,8 +188,9 @@ d    /run/user 0755 root root 10d</programlisting>
+                         or directory. This may either be a numeric
+                         user/group ID or a user or group name. If
+                         omitted or when set to - the default 0 (root)
+-                        is used. . These parameters are ignored for x,
+-                        r, R, Z lines.</para>
++                        is used. For Z lines when omitted or when set to -
++                        the file ownership will not be modified.
++                        These parameters are ignored for x, r, R lines.</para>
+                 </refsect2>
+ 
+                 <refsect2>
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index 18067c4..1395082 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -406,7 +406,27 @@ finish:
+         return r;
+ }
+ 
+-static int recursive_relabel_children(const char *path) {
++static int item_set_perms(Item *i, const char *path) {
++        /* not using i->path directly because it may be a glob */
++        if (i->mode_set)
++                if (chmod(path, i->mode) < 0) {
++                        log_error("chmod(%s) failed: %m", path);
++                        return -errno;
++                }
++
++        if (i->uid_set || i->gid_set)
++                if (chown(path,
++                          i->uid_set ? i->uid : (uid_t) -1,
++                          i->gid_set ? i->gid : (gid_t) -1) < 0) {
++
++                        log_error("chown(%s) failed: %m", path);
++                        return -errno;
++                }
++
++        return label_fix(path, false);
++}
++
++static int recursive_relabel_children(Item *i, const char *path) {
+         DIR *d;
+         int ret = 0;
+ 
+@@ -457,7 +477,7 @@ static int recursive_relabel_children(const char *path) {
+                 } else
+                         is_dir = de->d_type == DT_DIR;
+ 
+-                r = label_fix(entry_path, false);
++                r = item_set_perms(i, entry_path);
+                 if (r < 0) {
+                         if (ret == 0 && r != -ENOENT)
+                                 ret = r;
+@@ -466,7 +486,7 @@ static int recursive_relabel_children(const char *path) {
+                 }
+ 
+                 if (is_dir) {
+-                        r = recursive_relabel_children(entry_path);
++                        r = recursive_relabel_children(i, entry_path);
+                         if (r < 0 && ret == 0)
+                                 ret = r;
+                 }
+@@ -483,7 +503,7 @@ static int recursive_relabel(Item *i, const char *path) {
+         int r;
+         struct stat st;
+ 
+-        r = label_fix(path, false);
++        r = item_set_perms(i, path);
+         if (r < 0)
+                 return r;
+ 
+@@ -491,7 +511,7 @@ static int recursive_relabel(Item *i, const char *path) {
+                 return -errno;
+ 
+         if (S_ISDIR(st.st_mode))
+-                r = recursive_relabel_children(path);
++                r = recursive_relabel_children(i, path);
+ 
+         return r;
+ }
+@@ -523,25 +543,6 @@ static int glob_item(Item *i, int (*action)(Item *, const char *)) {
+         return r;
+ }
+ 
+-static int item_set_perms(Item *i) {
+-        if (i->mode_set)
+-                if (chmod(i->path, i->mode) < 0) {
+-                        log_error("chmod(%s) failed: %m", i->path);
+-                        return -errno;
+-                }
+-
+-        if (i->uid_set || i->gid_set)
+-                if (chown(i->path,
+-                          i->uid_set ? i->uid : (uid_t) -1,
+-                          i->gid_set ? i->gid : (gid_t) -1) < 0) {
+-
+-                        log_error("chown(%s) failed: %m", i->path);
+-                        return -errno;
+-                }
+-
+-        return label_fix(i->path, false);
+-}
+-
+ static int create_item(Item *i) {
+         int r;
+         mode_t u;
+@@ -582,7 +583,7 @@ static int create_item(Item *i) {
+                         return -EEXIST;
+                 }
+ 
+-                r = item_set_perms(i);
++                r = item_set_perms(i, i->path);
+                 if (r < 0)
+                         return r;
+ 
+@@ -612,7 +613,7 @@ static int create_item(Item *i) {
+                         return -EEXIST;
+                 }
+ 
+-                r = item_set_perms(i);
++                r = item_set_perms(i, i->path);
+                 if (r < 0)
+                         return r;
+ 
+@@ -639,7 +640,7 @@ static int create_item(Item *i) {
+                         return -EEXIST;
+                 }
+ 
+-                r = item_set_perms(i);
++                r = item_set_perms(i, i->path);
+                 if (r < 0)
+                         return r;
+ 
+-- 
+1.7.7.5
+
diff --git a/0081-tmpfiles-add-z-like-Z-but-not-recursive.patch b/0081-tmpfiles-add-z-like-Z-but-not-recursive.patch
new file mode 100644
index 0000000..c312015
--- /dev/null
+++ b/0081-tmpfiles-add-z-like-Z-but-not-recursive.patch
@@ -0,0 +1,150 @@
+From 4f0399974eb67bc9420c3bd700465190e38d92d6 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 16 Dec 2011 18:27:35 +0100
+Subject: [PATCH 081/126] tmpfiles: add 'z', like 'Z' but not recursive
+ (cherry picked from commit
+ 777b87e702197ad1f2d0f2a3aea5271d18062c5c)
+
+---
+ man/systemd-tmpfiles.xml |    4 ++--
+ man/tmpfiles.d.xml       |   14 ++++++++++++--
+ src/tmpfiles.c           |   34 ++++++++++++++++++++++++----------
+ 3 files changed, 38 insertions(+), 14 deletions(-)
+
+diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
+index 74dfd5a..bbb80b2 100644
+--- a/man/systemd-tmpfiles.xml
++++ b/man/systemd-tmpfiles.xml
+@@ -84,8 +84,8 @@
+                                 <listitem><para>If this option is passed all
+                                 files and directories marked with f,
+                                 F, d, D in the configuration files are
+-                                created. Files and directories marked with Z
+-                                have their ownership, access mode and security
++                                created. Files and directories marked with z,
++                                Z have their ownership, access mode and security
+                                 labels set.</para></listitem>
+                         </varlistentry>
+ 
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index e137967..4a8e831 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -157,6 +157,16 @@ d    /run/user 0755 root root 10d</programlisting>
+                                 </varlistentry>
+ 
+                                 <varlistentry>
++                                        <term><varname>z</varname></term>
++                                        <listitem><para>Set ownership, access
++                                        mode and relabel security context of
++                                        a file or directory if it exists.
++                                        Lines of this type accept shell-style
++                                        globs in place of normal path names.
++                                        </para></listitem>
++                                </varlistentry>
++
++                                <varlistentry>
+                                         <term><varname>Z</varname></term>
+                                         <listitem><para>Recursively set
+                                         ownership, access mode and relabel
+@@ -175,7 +185,7 @@ d    /run/user 0755 root root 10d</programlisting>
+                         <para>The file access mode to use when
+                         creating this file or directory. If omitted or
+                         when set to - the default is used: 0755 for
+-                        directories, 0644 for files. For Z lines
++                        directories, 0644 for files. For z, Z lines
+                         if omitted or when set to - the file access mode will
+                         not be modified. This parameter is ignored for x, r, R
+                         lines.</para>
+@@ -188,7 +198,7 @@ d    /run/user 0755 root root 10d</programlisting>
+                         or directory. This may either be a numeric
+                         user/group ID or a user or group name. If
+                         omitted or when set to - the default 0 (root)
+-                        is used. For Z lines when omitted or when set to -
++                        is used. For z, Z lines when omitted or when set to -
+                         the file ownership will not be modified.
+                         These parameters are ignored for x, r, R lines.</para>
+                 </refsect2>
+diff --git a/src/tmpfiles.c b/src/tmpfiles.c
+index 1395082..19a7c08 100644
+--- a/src/tmpfiles.c
++++ b/src/tmpfiles.c
+@@ -62,6 +62,7 @@ typedef enum ItemType {
+         IGNORE_PATH = 'x',
+         REMOVE_PATH = 'r',
+         RECURSIVE_REMOVE_PATH = 'R',
++        RELABEL_PATH = 'z',
+         RECURSIVE_RELABEL_PATH = 'Z'
+ } ItemType;
+ 
+@@ -92,7 +93,7 @@ static const char *arg_prefix = NULL;
+ #define MAX_DEPTH 256
+ 
+ static bool needs_glob(ItemType t) {
+-        return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RECURSIVE_RELABEL_PATH;
++        return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH;
+ }
+ 
+ static struct Item* find_glob(Hashmap *h, const char *match) {
+@@ -646,6 +647,13 @@ static int create_item(Item *i) {
+ 
+                 break;
+ 
++        case RELABEL_PATH:
++
++                r = glob_item(i, item_set_perms);
++                if (r < 0)
++                        return 0;
++                break;
++
+         case RECURSIVE_RELABEL_PATH:
+ 
+                 r = glob_item(i, recursive_relabel);
+@@ -670,6 +678,7 @@ static int remove_item_instance(Item *i, const char *instance) {
+         case CREATE_DIRECTORY:
+         case CREATE_FIFO:
+         case IGNORE_PATH:
++        case RELABEL_PATH:
+         case RECURSIVE_RELABEL_PATH:
+                 break;
+ 
+@@ -707,6 +716,7 @@ static int remove_item(Item *i) {
+         case CREATE_DIRECTORY:
+         case CREATE_FIFO:
+         case IGNORE_PATH:
++        case RELABEL_PATH:
+         case RECURSIVE_RELABEL_PATH:
+                 break;
+ 
+@@ -808,15 +818,19 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
+                 goto finish;
+         }
+ 
+-        if (type != CREATE_FILE &&
+-            type != TRUNCATE_FILE &&
+-            type != CREATE_DIRECTORY &&
+-            type != TRUNCATE_DIRECTORY &&
+-            type != CREATE_FIFO &&
+-            type != IGNORE_PATH &&
+-            type != REMOVE_PATH &&
+-            type != RECURSIVE_REMOVE_PATH &&
+-            type != RECURSIVE_RELABEL_PATH) {
++        switch(type) {
++        case CREATE_FILE:
++        case TRUNCATE_FILE:
++        case CREATE_DIRECTORY:
++        case TRUNCATE_DIRECTORY:
++        case CREATE_FIFO:
++        case IGNORE_PATH:
++        case REMOVE_PATH:
++        case RECURSIVE_REMOVE_PATH:
++        case RELABEL_PATH:
++        case RECURSIVE_RELABEL_PATH:
++                break;
++        default:
+                 log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
+                 r = -EBADMSG;
+                 goto finish;
+-- 
+1.7.7.5
+
diff --git a/0082-man-fix-misplaced-remark-in-description-of-Sockets.patch b/0082-man-fix-misplaced-remark-in-description-of-Sockets.patch
new file mode 100644
index 0000000..388b42b
--- /dev/null
+++ b/0082-man-fix-misplaced-remark-in-description-of-Sockets.patch
@@ -0,0 +1,32 @@
+From f2a7f81850607590c5d64efe5beedadc85be9909 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 17 Dec 2011 00:39:19 +0100
+Subject: [PATCH 082/126] man: fix misplaced remark in description of Sockets=
+ (cherry picked from commit
+ 4f025f4c4f9e043a06a05bcd4fc9fa65ee232ecc)
+
+---
+ man/systemd.service.xml |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/man/systemd.service.xml b/man/systemd.service.xml
+index 7b6f12d..0baddd1 100644
+--- a/man/systemd.service.xml
++++ b/man/systemd.service.xml
+@@ -671,11 +671,11 @@
+                                 <listitem><para>Specifies the name of
+                                 the socket units this service shall
+                                 inherit the sockets from when the
+-                                service (ignoring the different suffix
+-                                of course) is started. Normally it
++                                service is started. Normally it
+                                 should not be necessary to use this
+                                 setting as all sockets whose unit
+                                 shares the same name as the service
++                                (ignoring the different suffix of course)
+                                 are passed to the spawned
+                                 process.</para>
+ 
+-- 
+1.7.7.5
+
diff --git a/0083-execute-fix-losing-of-start-timestamps.patch b/0083-execute-fix-losing-of-start-timestamps.patch
new file mode 100644
index 0000000..3809c06
--- /dev/null
+++ b/0083-execute-fix-losing-of-start-timestamps.patch
@@ -0,0 +1,29 @@
+From ef50636c71f16165e58b38c25890213e2a6b073b Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sat, 17 Dec 2011 01:33:40 +0100
+Subject: [PATCH 083/126] execute: fix losing of start timestamps
+
+Start timestamps were always cleared before saving exit timestamps.
+Fix it by removing a condition that makes no sense any way I look at it.
+(cherry picked from commit 0b1f4ae63548c627decd80e3e2fd030c2d4f3af6)
+---
+ src/execute.c |    3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/src/execute.c b/src/execute.c
+index 481725d..abbbfdd 100644
+--- a/src/execute.c
++++ b/src/execute.c
+@@ -1860,8 +1860,7 @@ void exec_status_start(ExecStatus *s, pid_t pid) {
+ void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
+         assert(s);
+ 
+-        if ((s->pid && s->pid != pid) ||
+-            !s->start_timestamp.realtime <= 0)
++        if (s->pid && s->pid != pid)
+                 zero(*s);
+ 
+         s->pid = pid;
+-- 
+1.7.7.5
+
diff --git a/0084-label-fix-labeling-of-symbolic-links.patch b/0084-label-fix-labeling-of-symbolic-links.patch
new file mode 100644
index 0000000..f7f8528
--- /dev/null
+++ b/0084-label-fix-labeling-of-symbolic-links.patch
@@ -0,0 +1,27 @@
+From afa63b4de8367c2c48c639471e18962c1e1b5ad5 Mon Sep 17 00:00:00 2001
+From: Dan Walsh <dwalsh at redhat.com>
+Date: Mon, 19 Dec 2011 23:55:29 +0100
+Subject: [PATCH 084/126] label: fix labeling of symbolic links (cherry picked
+ from commit
+ 81c3f1f6aba52ac5e95241b51083b61c7401be44)
+
+---
+ src/label.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/label.c b/src/label.c
+index d9d195b..2c887a0 100644
+--- a/src/label.c
++++ b/src/label.c
+@@ -109,7 +109,7 @@ int label_fix(const char *path, bool ignore_enoent) {
+                         return 0;
+ 
+                 if (r == 0) {
+-                        r = setfilecon(path, fcon);
++                        r = lsetfilecon(path, fcon);
+                         freecon(fcon);
+ 
+                         /* If the FS doesn't support labels, then exit without warning */
+-- 
+1.7.7.5
+
diff --git a/0085-dbus-register-to-DBus-asynchronously.patch b/0085-dbus-register-to-DBus-asynchronously.patch
new file mode 100644
index 0000000..d127dc1
--- /dev/null
+++ b/0085-dbus-register-to-DBus-asynchronously.patch
@@ -0,0 +1,563 @@
+From 6e1da63130bb563b5cce89c2a7d66e98e79c5ec4 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sun, 18 Dec 2011 14:58:10 +0100
+Subject: [PATCH 085/126] dbus: register to DBus asynchronously
+
+Chen Jie observed and analyzed a deadlock. Assuming systemd-kmsg-syslogd
+is already stopped, but rsyslogd is not started yet:
+ 1. systemd makes a synchronous call to dbus-daemon.
+ 2. dbus-daemon wants to write something to syslog.
+ 3. syslog needs to be started by systemd.
+   ... but cannot be, because systemd is waiting in 1.
+
+Solve this by avoiding synchronous D-Bus calls. I had to write an async
+bus registration call. Interestingly, D-Bus authors anticipated this, in
+documentation to dbus_bus_set_unique_name():
+> The only reason to use this function is to re-implement the equivalent
+> of dbus_bus_register() yourself. One (probably unusual) reason to do
+> that might be to do the bus registration call asynchronously instead
+> of synchronously.
+
+Lennart's comments from IRC:
+> though I think this doesn't fix the problem in its entirety
+> simply because dbus_connection_open_private() itself is still synchronous
+> i.e. the connect() call behind it is not async
+> I think I listed that issue actually on some D-Bus todo list
+> i.e. to make dbus_connection_get() fully async
+> but that's going to be hard
+> so your patch looks good
+
+So it may not be perfect, but it's clearly an improvement.
+I did not manage to reproduce the original deadlock with the patch.
+(cherry picked from commit cbd37330bcd039587121a767280fc9fee597af6e)
+---
+ src/dbus.c    |  378 +++++++++++++++++++++++++++++++++++++++------------------
+ src/manager.c |    2 +-
+ src/manager.h |    1 +
+ 3 files changed, 262 insertions(+), 119 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index daa2c84..81b4f53 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -48,6 +48,11 @@
+ 
+ #define CONNECTIONS_MAX 52
+ 
++/* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */
++#define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
++/* Only used as a fallback */
++#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
++
+ static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE;
+ static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE;
+ 
+@@ -767,37 +772,19 @@ static void bus_new_connection(
+         dbus_connection_ref(new_connection);
+ }
+ 
+-static int bus_init_system(Manager *m) {
+-        DBusError error;
+-        int r;
+-
+-        assert(m);
+-
+-        dbus_error_init(&error);
+-
+-        if (m->system_bus)
+-                return 0;
+-
+-        if (m->running_as == MANAGER_SYSTEM && m->api_bus)
+-                m->system_bus = m->api_bus;
+-        else {
+-                if (!(m->system_bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) {
+-                        log_debug("Failed to get system D-Bus connection, retrying later: %s", bus_error_message(&error));
+-                        r = 0;
+-                        goto fail;
+-                }
+-
+-                if ((r = bus_setup_loop(m, m->system_bus)) < 0)
+-                        goto fail;
+-        }
++static int init_registered_system_bus(Manager *m) {
++        char *id;
+ 
+         if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) {
+                 log_error("Not enough memory");
+-                r = -ENOMEM;
+-                goto fail;
++                return -ENOMEM;
+         }
+ 
+         if (m->running_as != MANAGER_SYSTEM) {
++                DBusError error;
++
++                dbus_error_init(&error);
++
+                 dbus_bus_add_match(m->system_bus,
+                                    "type='signal',"
+                                    "interface='org.freedesktop.systemd1.Agent',"
+@@ -807,59 +794,28 @@ static int bus_init_system(Manager *m) {
+ 
+                 if (dbus_error_is_set(&error)) {
+                         log_error("Failed to register match: %s", bus_error_message(&error));
+-                        r = -EIO;
+-                        goto fail;
++                        dbus_error_free(&error);
++                        return -1;
+                 }
+         }
+ 
+-        if (m->api_bus != m->system_bus) {
+-                char *id;
+-                log_debug("Successfully connected to system D-Bus bus %s as %s",
+-                         strnull((id = dbus_connection_get_server_id(m->system_bus))),
+-                         strnull(dbus_bus_get_unique_name(m->system_bus)));
+-                dbus_free(id);
+-        }
++        log_debug("Successfully connected to system D-Bus bus %s as %s",
++                 strnull((id = dbus_connection_get_server_id(m->system_bus))),
++                 strnull(dbus_bus_get_unique_name(m->system_bus)));
++        dbus_free(id);
+ 
+         return 0;
+-
+-fail:
+-        bus_done_system(m);
+-        dbus_error_free(&error);
+-
+-        return r;
+ }
+ 
+-static int bus_init_api(Manager *m) {
+-        DBusError error;
++static int init_registered_api_bus(Manager *m) {
+         int r;
+ 
+-        assert(m);
+-
+-        dbus_error_init(&error);
+-
+-        if (m->api_bus)
+-                return 0;
+-
+-        if (m->running_as == MANAGER_SYSTEM && m->system_bus)
+-                m->api_bus = m->system_bus;
+-        else {
+-                if (!(m->api_bus = dbus_bus_get_private(m->running_as == MANAGER_USER ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error))) {
+-                        log_debug("Failed to get API D-Bus connection, retrying later: %s", bus_error_message(&error));
+-                        r = 0;
+-                        goto fail;
+-                }
+-
+-                if ((r = bus_setup_loop(m, m->api_bus)) < 0)
+-                        goto fail;
+-        }
+-
+         if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
+             !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
+             !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
+             !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) {
+                 log_error("Not enough memory");
+-                r = -ENOMEM;
+-                goto fail;
++                return -ENOMEM;
+         }
+ 
+         /* Get NameOwnerChange messages */
+@@ -869,13 +825,7 @@ static int bus_init_api(Manager *m) {
+                            "interface='"DBUS_INTERFACE_DBUS"',"
+                            "member='NameOwnerChanged',"
+                            "path='"DBUS_PATH_DBUS"'",
+-                           &error);
+-
+-        if (dbus_error_is_set(&error)) {
+-                log_error("Failed to register match: %s", bus_error_message(&error));
+-                r = -EIO;
+-                goto fail;
+-        }
++                           NULL);
+ 
+         /* Get activation requests */
+         dbus_bus_add_match(m->api_bus,
+@@ -884,33 +834,225 @@ static int bus_init_api(Manager *m) {
+                            "interface='org.freedesktop.systemd1.Activator',"
+                            "member='ActivationRequest',"
+                            "path='"DBUS_PATH_DBUS"'",
+-                           &error);
+-
+-        if (dbus_error_is_set(&error)) {
+-                log_error("Failed to register match: %s", bus_error_message(&error));
+-                r = -EIO;
+-                goto fail;
+-        }
++                           NULL);
+ 
+-        if ((r = request_name(m)) < 0)
+-                goto fail;
++        r = request_name(m);
++        if (r < 0)
++                return r;
+ 
+-        if ((r = query_name_list(m)) < 0)
+-                goto fail;
++        r = query_name_list(m);
++        if (r < 0)
++                return r;
+ 
+-        if (m->api_bus != m->system_bus) {
++        if (m->running_as == MANAGER_USER) {
+                 char *id;
+                 log_debug("Successfully connected to API D-Bus bus %s as %s",
+                          strnull((id = dbus_connection_get_server_id(m->api_bus))),
+                          strnull(dbus_bus_get_unique_name(m->api_bus)));
+                 dbus_free(id);
++        } else
++                log_debug("Successfully initialized API on the system bus");
++
++        return 0;
++}
++
++static void bus_register_cb(DBusPendingCall *pending, void *userdata) {
++        Manager *m = userdata;
++        DBusConnection **conn;
++        DBusMessage *reply;
++        DBusError error;
++        const char *name;
++        int r = 0;
++
++        dbus_error_init(&error);
++
++        conn = dbus_pending_call_get_data(pending, m->conn_data_slot);
++        assert(conn == &m->system_bus || conn == &m->api_bus);
++
++        reply = dbus_pending_call_steal_reply(pending);
++
++        switch (dbus_message_get_type(reply)) {
++        case DBUS_MESSAGE_TYPE_ERROR:
++                assert_se(dbus_set_error_from_message(&error, reply));
++                log_warning("Failed to register to bus: %s", bus_error_message(&error));
++                r = -1;
++                break;
++        case DBUS_MESSAGE_TYPE_METHOD_RETURN:
++                if (!dbus_message_get_args(reply, &error,
++                                           DBUS_TYPE_STRING, &name,
++                                           DBUS_TYPE_INVALID)) {
++                        log_error("Failed to parse Hello reply: %s", bus_error_message(&error));
++                        r = -1;
++                        break;
++                }
++
++                log_debug("Received name %s in reply to Hello", name);
++                if (!dbus_bus_set_unique_name(*conn, name)) {
++                        log_error("Failed to set unique name");
++                        r = -1;
++                        break;
++                }
++
++                if (conn == &m->system_bus) {
++                        r = init_registered_system_bus(m);
++                        if (r == 0 && m->running_as == MANAGER_SYSTEM)
++                                r = init_registered_api_bus(m);
++                } else
++                        r = init_registered_api_bus(m);
++
++                break;
++        default:
++                assert_not_reached("Invalid reply message");
++        }
++
++        dbus_message_unref(reply);
++        dbus_error_free(&error);
++
++        if (r < 0) {
++                if (conn == &m->system_bus) {
++                        log_debug("Failed setting up the system bus");
++                        bus_done_system(m);
++                } else {
++                        log_debug("Failed setting up the API bus");
++                        bus_done_api(m);
++                }
++        }
++}
++
++static int manager_bus_async_register(Manager *m, DBusConnection **conn) {
++        DBusMessage *message = NULL;
++        DBusPendingCall *pending = NULL;
++
++        message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
++                                               DBUS_PATH_DBUS,
++                                               DBUS_INTERFACE_DBUS,
++                                               "Hello");
++        if (!message)
++                goto oom;
++
++        if (!dbus_connection_send_with_reply(*conn, message, &pending, -1))
++                goto oom;
++
++        if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL))
++                goto oom;
++
++        if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL))
++                goto oom;
++
++        dbus_message_unref(message);
++        dbus_pending_call_unref(pending);
++
++        return 0;
++oom:
++        if (pending) {
++                dbus_pending_call_cancel(pending);
++                dbus_pending_call_unref(pending);
++        }
++
++        if (message)
++                dbus_message_unref(message);
++
++        return -ENOMEM;
++}
++
++static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) {
++        const char *address;
++        DBusConnection *connection;
++        DBusError error;
++
++        switch (type) {
++        case DBUS_BUS_SYSTEM:
++                address = getenv("DBUS_SYSTEM_BUS_ADDRESS");
++                if (!address || !address[0])
++                        address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
++                break;
++        case DBUS_BUS_SESSION:
++                address = getenv("DBUS_SESSION_BUS_ADDRESS");
++                if (!address || !address[0])
++                        address = DBUS_SESSION_BUS_DEFAULT_ADDRESS;
++                break;
++        default:
++                assert_not_reached("Invalid bus type");
++        }
++
++        dbus_error_init(&error);
++
++        connection = dbus_connection_open_private(address, &error);
++        if (!connection) {
++                log_warning("Failed to open private bus connection: %s", bus_error_message(&error));
++                goto fail;
++        }
++
++        return connection;
++fail:
++        if (connection)
++                dbus_connection_close(connection);
++        dbus_error_free(&error);
++        return NULL;
++}
++
++static int bus_init_system(Manager *m) {
++        int r;
++
++        if (m->system_bus)
++                return 0;
++
++        m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM);
++        if (!m->system_bus) {
++                log_debug("Failed to connect to system D-Bus, retrying later");
++                r = 0;
++                goto fail;
+         }
+ 
++        r = bus_setup_loop(m, m->system_bus);
++        if (r < 0)
++                goto fail;
++
++        r = manager_bus_async_register(m, &m->system_bus);
++        if (r < 0)
++                goto fail;
++
+         return 0;
++fail:
++        bus_done_system(m);
++
++        return r;
++}
++
++static int bus_init_api(Manager *m) {
++        int r;
++
++        if (m->api_bus)
++                return 0;
++
++        if (m->running_as == MANAGER_SYSTEM) {
++                m->api_bus = m->system_bus;
++                /* In this mode there is no distinct connection to the API bus,
++                 * the API is published on the system bus.
++                 * bus_register_cb() is aware of that and will init the API
++                 * when the system bus gets registered.
++                 * No need to setup anything here. */
++                return 0;
++        }
++
++        m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION);
++        if (!m->api_bus) {
++                log_debug("Failed to connect to API D-Bus, retrying later");
++                r = 0;
++                goto fail;
++        }
++
++        r = bus_setup_loop(m, m->api_bus);
++        if (r < 0)
++                goto fail;
+ 
++        r = manager_bus_async_register(m, &m->api_bus);
++        if (r < 0)
++                goto fail;
++
++        return 0;
+ fail:
+         bus_done_api(m);
+-        dbus_error_free(&error);
+ 
+         return r;
+ }
+@@ -989,22 +1131,20 @@ int bus_init(Manager *m, bool try_bus_connect) {
+         int r;
+ 
+         if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 ||
+-            set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0) {
+-                log_error("Not enough memory");
+-                return -ENOMEM;
+-        }
++            set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0)
++                goto oom;
+ 
+         if (m->name_data_slot < 0)
+-                if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) {
+-                        log_error("Not enough memory");
+-                        return -ENOMEM;
+-                }
++                if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot))
++                        goto oom;
++
++        if (m->conn_data_slot < 0)
++                if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot))
++                        goto oom;
+ 
+         if (m->subscribed_data_slot < 0)
+-                if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot)) {
+-                        log_error("Not enough memory");
+-                        return -ENOMEM;
+-                }
++                if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot))
++                        goto oom;
+ 
+         if (try_bus_connect) {
+                 if ((r = bus_init_system(m)) < 0 ||
+@@ -1016,6 +1156,9 @@ int bus_init(Manager *m, bool try_bus_connect) {
+                 return r;
+ 
+         return 0;
++oom:
++        log_error("Not enough memory");
++        return -ENOMEM;
+ }
+ 
+ static void shutdown_connection(Manager *m, DBusConnection *c) {
+@@ -1059,42 +1202,38 @@ static void shutdown_connection(Manager *m, DBusConnection *c) {
+ }
+ 
+ static void bus_done_api(Manager *m) {
+-        assert(m);
+-
+-        if (m->api_bus) {
+-                if (m->system_bus == m->api_bus)
+-                        m->system_bus = NULL;
++        if (!m->api_bus)
++                return;
+ 
++        if (m->running_as == MANAGER_USER)
+                 shutdown_connection(m, m->api_bus);
+-                m->api_bus = NULL;
+-        }
+ 
++        m->api_bus = NULL;
+ 
+-       if (m->queued_message) {
+-               dbus_message_unref(m->queued_message);
+-               m->queued_message = NULL;
+-       }
++        if (m->queued_message) {
++                dbus_message_unref(m->queued_message);
++                m->queued_message = NULL;
++        }
+ }
+ 
+ static void bus_done_system(Manager *m) {
+-        assert(m);
++        if (!m->system_bus)
++                return;
+ 
+-        if (m->system_bus == m->api_bus)
++        if (m->running_as == MANAGER_SYSTEM)
+                 bus_done_api(m);
+ 
+-        if (m->system_bus) {
+-                shutdown_connection(m, m->system_bus);
+-                m->system_bus = NULL;
+-        }
++        shutdown_connection(m, m->system_bus);
++        m->system_bus = NULL;
+ }
+ 
+ static void bus_done_private(Manager *m) {
++        if (!m->private_bus)
++                return;
+ 
+-        if (m->private_bus) {
+-                dbus_server_disconnect(m->private_bus);
+-                dbus_server_unref(m->private_bus);
+-                m->private_bus = NULL;
+-        }
++        dbus_server_disconnect(m->private_bus);
++        dbus_server_unref(m->private_bus);
++        m->private_bus = NULL;
+ }
+ 
+ void bus_done(Manager *m) {
+@@ -1116,6 +1255,9 @@ void bus_done(Manager *m) {
+         if (m->name_data_slot >= 0)
+                dbus_pending_call_free_data_slot(&m->name_data_slot);
+ 
++        if (m->conn_data_slot >= 0)
++               dbus_pending_call_free_data_slot(&m->conn_data_slot);
++
+         if (m->subscribed_data_slot >= 0)
+                 dbus_connection_free_data_slot(&m->subscribed_data_slot);
+ }
+diff --git a/src/manager.c b/src/manager.c
+index 111167a..6acc821 100644
+--- a/src/manager.c
++++ b/src/manager.c
+@@ -231,7 +231,7 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) {
+         dual_timestamp_get(&m->startup_timestamp);
+ 
+         m->running_as = running_as;
+-        m->name_data_slot = m->subscribed_data_slot = -1;
++        m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
+         m->exit_code = _MANAGER_EXIT_CODE_INVALID;
+         m->pin_cgroupfs_fd = -1;
+ 
+diff --git a/src/manager.h b/src/manager.h
+index 5deb569..6e7558e 100644
+--- a/src/manager.h
++++ b/src/manager.h
+@@ -179,6 +179,7 @@ struct Manager {
+ 
+         Hashmap *watch_bus;  /* D-Bus names => Unit object n:1 */
+         int32_t name_data_slot;
++        int32_t conn_data_slot;
+         int32_t subscribed_data_slot;
+ 
+         uint32_t current_job_id;
+-- 
+1.7.7.5
+
diff --git a/0086-dbus-no-sync-D-Bus-connection-flushing.patch b/0086-dbus-no-sync-D-Bus-connection-flushing.patch
new file mode 100644
index 0000000..a79400e
--- /dev/null
+++ b/0086-dbus-no-sync-D-Bus-connection-flushing.patch
@@ -0,0 +1,29 @@
+From 8787a5577aef2703a1484a57db4fe3afb196fc73 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Mon, 19 Dec 2011 18:32:10 +0100
+Subject: [PATCH 086/126] dbus: no sync D-Bus connection flushing
+
+Blocking on D-Bus in a system manager could lead to deadlock.
+(cherry picked from commit 9721b19968dd80ad187d03da214a2a8d28ead3ad)
+---
+ src/dbus.c |    4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/src/dbus.c b/src/dbus.c
+index 81b4f53..f9250f1 100644
+--- a/src/dbus.c
++++ b/src/dbus.c
+@@ -1196,7 +1196,9 @@ static void shutdown_connection(Manager *m, DBusConnection *c) {
+         }
+ 
+         dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
+-        dbus_connection_flush(c);
++        /* system manager cannot afford to block on DBus */
++        if (m->running_as != MANAGER_SYSTEM)
++                dbus_connection_flush(c);
+         dbus_connection_close(c);
+         dbus_connection_unref(c);
+ }
+-- 
+1.7.7.5
+
diff --git a/0087-log-never-block-on-syslog-in-PID-1.patch b/0087-log-never-block-on-syslog-in-PID-1.patch
new file mode 100644
index 0000000..f0c3939
--- /dev/null
+++ b/0087-log-never-block-on-syslog-in-PID-1.patch
@@ -0,0 +1,77 @@
+From 58a06a6dfb11121bc1220c1c21fdf11ae65ac895 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Sun, 18 Dec 2011 14:57:54 +0100
+Subject: [PATCH 087/126] log: never block on syslog in PID 1
+
+Use a non-blocking syslog socket if logging from PID 1.
+If sendmsg fails with EAGAIN, fall back to kmsg or console only for the
+current message. Next message will try syslog again.
+(cherry picked from commit 8f7f7a1bd3a26f501b2d6546cce1c669b59dcc87)
+---
+ src/log.c |   23 ++++++++++++++++-------
+ 1 files changed, 16 insertions(+), 7 deletions(-)
+
+diff --git a/src/log.c b/src/log.c
+index 5c5b734..4f57821 100644
+--- a/src/log.c
++++ b/src/log.c
+@@ -118,6 +118,9 @@ static int create_log_socket(int type) {
+         struct timeval tv;
+         int fd;
+ 
++        if (getpid() == 1)
++                /* systemd should not block on syslog */
++                type |= SOCK_NONBLOCK;
+         if ((fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0)) < 0)
+                 return -errno;
+ 
+@@ -330,7 +333,8 @@ static int write_to_syslog(
+         for (;;) {
+                 ssize_t n;
+ 
+-                if ((n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL)) < 0)
++                n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL);
++                if (n < 0)
+                         return -errno;
+ 
+                 if (!syslog_is_stream ||
+@@ -407,8 +411,10 @@ static int log_dispatch(
+                     log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                     log_target == LOG_TARGET_SYSLOG) {
+ 
+-                        if ((k = write_to_syslog(level, file, line, func, buffer)) < 0) {
+-                                log_close_syslog();
++                        k = write_to_syslog(level, file, line, func, buffer);
++                        if (k < 0) {
++                                if (k != -EAGAIN)
++                                        log_close_syslog();
+                                 log_open_kmsg();
+                         } else if (k > 0)
+                                 r++;
+@@ -419,16 +425,19 @@ static int log_dispatch(
+                      log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
+                      log_target == LOG_TARGET_KMSG)) {
+ 
+-                        if ((k = write_to_kmsg(level, file, line, func, buffer)) < 0) {
++                        k = write_to_kmsg(level, file, line, func, buffer);
++                        if (k < 0) {
+                                 log_close_kmsg();
+                                 log_open_console();
+                         } else if (k > 0)
+                                 r++;
+                 }
+ 
+-                if (k <= 0 &&
+-                    (k = write_to_console(level, file, line, func, buffer)) < 0)
+-                        return k;
++                if (k <= 0) {
++                        k = write_to_console(level, file, line, func, buffer);
++                        if (k < 0)
++                                return k;
++                }
+ 
+                 buffer = e;
+         } while (buffer);
+-- 
+1.7.7.5
+
diff --git a/0088-macro-fix-ALIGN_TO-macro-definition.patch b/0088-macro-fix-ALIGN_TO-macro-definition.patch
new file mode 100644
index 0000000..13a4f3f
--- /dev/null
+++ b/0088-macro-fix-ALIGN_TO-macro-definition.patch
@@ -0,0 +1,27 @@
+From 410c7e298a2937bd3c69e70b31d6ee0c4754c566 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 8 Nov 2011 18:18:48 +0100
+Subject: [PATCH 088/126] macro: fix ALIGN_TO macro definition (cherry picked
+ from commit
+ 9b3c575ed90bb1165a192dfae2fb2330baab583c)
+
+---
+ src/macro.h |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/macro.h b/src/macro.h
+index e7a4d2c..3f30aa7 100644
+--- a/src/macro.h
++++ b/src/macro.h
+@@ -149,7 +149,7 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
+                 char *_s = (char *)(s);         \
+                 _i->iov_base = _s;              \
+                 _i->iov_len = strlen(_s);       \
+-        } while(false);
++        } while(false)
+ 
+ static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
+         unsigned j;
+-- 
+1.7.7.5
+
diff --git a/0089-man-document-the-sd-login-interfaces.patch b/0089-man-document-the-sd-login-interfaces.patch
new file mode 100644
index 0000000..be97580
--- /dev/null
+++ b/0089-man-document-the-sd-login-interfaces.patch
@@ -0,0 +1,960 @@
+From caaed693b9e8b16102c794fa52850bbcb7cc6fd9 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 03:02:17 +0100
+Subject: [PATCH 089/126] man: document the sd-login interfaces (cherry picked
+ from commit
+ 0b3b020a178cf3b957fed627de13c895773995ec)
+
+---
+ man/sd_get_seats.xml         |  125 +++++++++++++++++++++++++++++
+ man/sd_login_monitor_new.xml |  172 +++++++++++++++++++++++++++++++++++++++
+ man/sd_pid_get_session.xml   |  136 +++++++++++++++++++++++++++++++
+ man/sd_seat_get_active.xml   |  150 ++++++++++++++++++++++++++++++++++
+ man/sd_session_is_active.xml |  134 +++++++++++++++++++++++++++++++
+ man/sd_uid_get_state.xml     |  182 ++++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 899 insertions(+), 0 deletions(-)
+ create mode 100644 man/sd_get_seats.xml
+ create mode 100644 man/sd_login_monitor_new.xml
+ create mode 100644 man/sd_pid_get_session.xml
+ create mode 100644 man/sd_seat_get_active.xml
+ create mode 100644 man/sd_session_is_active.xml
+ create mode 100644 man/sd_uid_get_state.xml
+
+diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
+new file mode 100644
+index 0000000..bbc396a
+--- /dev/null
++++ b/man/sd_get_seats.xml
+@@ -0,0 +1,125 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd_get_seats">
++
++        <refentryinfo>
++                <title>sd_get_seats</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd_get_seats</refentrytitle>
++                <manvolnum>3</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd_get_seats</refname>
++                <refname>sd_get_sessions</refname>
++                <refname>sd_get_uids</refname>
++                <refpurpose>Determine available seats, sessions and logged in users</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_get_seats</function></funcdef>
++                                <paramdef>char*** <parameter>seats</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_get_sessions</function></funcdef>
++                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_get_uids</function></funcdef>
++                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
++                        </funcprototype>
++
++                </funcsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><function>sd_get_seats()</function> may be used
++                to determine all currently available local
++                seats. Returns an array of seat identifiers. The
++                returned array and all strings it references need to
++                be freed with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++
++                <para>Similar, <function>sd_get_sessions()</function> may
++                be used to determine all current login sessions.</para>
++
++                <para>Similar, <function>sd_get_uids()</function> may
++                be used to determine all Unix users who currently have login sessions.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Return Value</title>
++
++                <para>On success <function>sd_get_seats()</function>,
++                <function>sd_get_sessions()</function> and
++                <function>sd_get_uids()</function> return the number
++                of entries in the arrays. On failure, these calls
++                return a negative errno-style error code.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>The <function>sd_get_seats()</function>,
++                <function>sd_get_sessions()</function> and
++                <function>sd_get_uids()</function> interfaces
++                are available as shared library, which can be compiled
++                and linked to with the
++                <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                </para>
++        </refsect1>
++
++</refentry>
+diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
+new file mode 100644
+index 0000000..2b37f00
+--- /dev/null
++++ b/man/sd_login_monitor_new.xml
+@@ -0,0 +1,172 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd_login_monitor_new">
++
++        <refentryinfo>
++                <title>sd_login_monitor_new</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd_login_monitor_new</refentrytitle>
++                <manvolnum>3</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd_login_monitor_new</refname>
++                <refname>sd_login_monitor_unref</refname>
++                <refname>sd_login_monitor_flush</refname>
++                <refname>sd_login_monitor_get_fd</refname>
++                <refpurpose>Monitor login sessions, seats and users</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_login_monitor_new</function></funcdef>
++                                <paramdef>const char* <parameter>category</parameter></paramdef>
++                                <paramdef>sd_login_monitor** <parameter>ret</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>sd_login_monitor* <function>sd_login_monitor_unref</function></funcdef>
++                                <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_login_monitor_flush</function></funcdef>
++                                <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_login_monitor_get_fd</function></funcdef>
++                                <paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
++                        </funcprototype>
++
++                </funcsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><function>sd_login_monitor_new()</function> may
++                be used to monitor login session, users and seats. Via
++                a monitor object a file descriptor can be integrated
++                into an application defined event loop which is woken
++                up each time a user logs in, logs out or a seat is
++                added or removed, or a session, user, or seat changes
++                state otherwise. The first parameter takes a string
++                which can be either <literal>seat</literal> (to get
++                only notifications about seats being added, removed or
++                changed), <literal>session</literal> (to get only
++                notifications about sessions being created or removed
++                or changed) or <literal>uid</literal> (to get only
++                notifications when a user changes state in respect to
++                logins). If notifications shall be generated in all
++                these conditions, NULL may be passed. Note that in
++                future additional categories may be defined. The
++                second parameter returns a monitor object and needs to
++                be freed with the
++                <function>sd_login_monitor_unref()</function> call
++                after use.</para>
++
++                <para><function>sd_login_monitor_unref()</function>
++                may be used to destroy a monitor object. Note that
++                this will invalidate any file descriptor returned by
++                <function>sd_login_monitor_get_fd()</function>.</para>
++
++                <para><function>sd_login_monitor_flush()</function>
++                may be used to reset the wakeup state of the monitor
++                object. Whenever an event causes the monitor to wake
++                up the event loop via the file descriptor this
++                function needs to be called to reset the wake-up
++                state. If this call is not invoked the file descriptor
++                will immediately wake up the event loop again.</para>
++
++                <para><function>sd_login_monitor_get_fd()</function>
++                may be used to retrieve the file descriptor of the
++                monitor object that may be integrated in an
++                application defined event loop, based around
++                <citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
++                or a similar interface. The application should include
++                the returned file descriptor as wake up source for
++                POLLIN events. Whenever a wake-up is triggered the
++                file descriptor needs to be reset via
++                <function>sd_login_monitor_flush()</function>. An
++                application needs to reread the login state with a
++                function like
++                <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                or similar to determine what changed.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Return Value</title>
++
++                <para>On success
++                <function>sd_login_monitor_new()</function> and
++                <function>sd_login_monitor_flush()</function> return 0
++                or a positive integer. On success
++                <function>sd_login_monitor_get_fd()</function> returns
++                a Unix file descriptor. On failure, these calls return
++                a negative errno-style error code.</para>
++
++                <para><function>sd_login_monitor_unref()</function>
++                always returns NULL.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>The <function>sd_login_monitor_new()</function>,
++                <function>sd_login_monitor_unref()</function>, <function>sd_login_monitor_flush()</function> and
++                <function>sd_login_monitor_get_fd()</function> interfaces
++                are available as shared library, which can be compiled
++                and linked to with the
++                <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                </para>
++        </refsect1>
++
++</refentry>
+diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
+new file mode 100644
+index 0000000..9176433
+--- /dev/null
++++ b/man/sd_pid_get_session.xml
+@@ -0,0 +1,136 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd_pid_get_session">
++
++        <refentryinfo>
++                <title>sd_pid_get_session</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd_pid_get_session</refentrytitle>
++                <manvolnum>3</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd_pid_get_session</refname>
++                <refname>sd_pid_get_owner_uid</refname>
++                <refpurpose>Determine session or owner of a session of a specific PID</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_pid_get_session</function></funcdef>
++                                <paramdef>pid_t <parameter>pid</parameter></paramdef>
++                                <paramdef>char** <parameter>session</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
++                                <paramdef>pid_t <parameter>pid</parameter></paramdef>
++                                <paramdef>uid_t* <parameter>uid</parameter></paramdef>
++                        </funcprototype>
++                </funcsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><function>sd_pid_get_session()</function> may be
++                used to determine the login session identifier of a
++                process identified by the specified process identifier. The session
++                identifier is a short string (up to 64 characters),
++                consisting only of the characters a-zA-Z0-9 as well as
++                '-' and '_'. It is suitable for usage in file system
++                paths. Note that not all processes are part of a login
++                session (e.g. system service processes and user
++                processes that are shared between multiple sessions of
++                the same user). For processes not being part of a
++                login session this function will fail. The returned
++                string needs to be freed with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++
++                <para><function>sd_pid_get_owner_uid()</function> may
++                be used to determine the Unix user identifier of the
++                owner of the session of a process identified the
++                specified PID. Note that this function will succeed
++                for user processes which are shared between multiple
++                login sessions of the same user, where
++                <function>sd_pid_get_session()</function> will
++                fail. For processes not being part of a login session
++                and not being a shared process of a user this function
++                will fail.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Return Value</title>
++
++                <para>On success these calls return 0 or a positive
++                integer. On failure, these calls return a negative
++                errno-style error code.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>The <function>sd_pid_get_session()</function>
++                and <function>sd_pid_get_owner_uid()</function>
++                interfaces are available as shared library, which can
++                be compiled and linked to with the
++                <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++
++                <para>Note that the login session identifier as
++                returned by <function>sd_pid_get_session()</function>
++                is completely unrelated to the process session
++                identifier as returned by
++                <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
++                </para>
++        </refsect1>
++
++</refentry>
+diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
+new file mode 100644
+index 0000000..e729a65
+--- /dev/null
++++ b/man/sd_seat_get_active.xml
+@@ -0,0 +1,150 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd_seat_get_active">
++
++        <refentryinfo>
++                <title>sd_seat_get_active</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd_seat_get_active</refentrytitle>
++                <manvolnum>3</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd_seat_get_active</refname>
++                <refname>sd_seat_get_sessions</refname>
++                <refname>sd_seat_can_multi_session</refname>
++                <refpurpose>Determine state of a specific seat</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_seat_get_active</function></funcdef>
++                                <paramdef>const char* <parameter>seat</parameter></paramdef>
++                                <paramdef>char** <parameter>session</parameter></paramdef>
++                                <paramdef>uid_t* <parameter>uid</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_seat_get_sessions</function></funcdef>
++                                <paramdef>const char* <parameter>seat</parameter></paramdef>
++                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
++                                <paramdef>uid_t** <parameter>uid</parameter></paramdef>
++                                <paramdef>unsigned* <parameter>n_uids</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_seat_can_multi_session</function></funcdef>
++                                <paramdef>const char* <parameter>session</parameter></paramdef>
++                        </funcprototype>
++                </funcsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><function>sd_seat_get_active()</function> may be
++                used to determine which session is currently active on
++                a seat, if there is any. Returns the session
++                identifier and the user identifier of the Unix user
++                the session is belonging to. Either the session or the
++                user identifier parameter can be be passed NULL, in
++                case only one of the parameters shall be queried. The
++                returned string needs to be freed with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++
++                <para><function>sd_seat_get_sessions()</function> may
++                be used to determine all sessions on the specified
++                seat. Returns two arrays, one (NULL terminated) with
++                the session identifiers of the sessions and one with
++                the user identifiers of the Unix users the sessions
++                belong to. An additional parameter may be used to
++                return the number of entries in the latter array. The
++                two arrays and the latter parameter may be passed as
++                NULL in case these values need not to be
++                determined. The arrays and the strings referenced by
++                them need to be freed with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++
++                <para><function>sd_seat_can_multi_session()</function>
++                may be used to determine whether a specific seat is
++                capable of multi-session, i.e. allows multiple login
++                sessions in parallel (whith only one being active at a
++                time).</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Return Value</title>
++
++                <para> On success
++                <function>sd_seat_get_active()</function> return
++                return 0 or a positive integer. On success
++                <function>sd_seat_get_sessions()</function> returns
++                the number of entries in the session identifier
++                array. If the test succeeds
++                <function>sd_seat_can_multi_session</function> returns
++                a positive integer, if it fails 0. On failure, these
++                calls return a negative errno-style error code.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>The <function>sd_seat_get_active()</function>,
++                <function>sd_seat_get_sessions()</function>, and
++                <function>sd_seat_can_multi_session()</function> interfaces
++                are available as shared library, which can be compiled
++                and linked to with the
++                <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                </para>
++        </refsect1>
++
++</refentry>
+diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
+new file mode 100644
+index 0000000..82919f8
+--- /dev/null
++++ b/man/sd_session_is_active.xml
+@@ -0,0 +1,134 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd_session_is_active">
++
++        <refentryinfo>
++                <title>sd_session_is_active</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd_session_is_active</refentrytitle>
++                <manvolnum>3</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd_session_is_active</refname>
++                <refname>sd_session_get_uid</refname>
++                <refname>sd_session_get_seat</refname>
++                <refpurpose>Determine state of a specific session</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_session_is_active</function></funcdef>
++                                <paramdef>const char* <parameter>session</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_session_get_uid</function></funcdef>
++                                <paramdef>const char* <parameter>session</parameter></paramdef>
++                                <paramdef>uid_t* <parameter>uid</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_session_get_seat</function></funcdef>
++                                <paramdef>const char* <parameter>session</parameter></paramdef>
++                                <paramdef>char** <parameter>seat</parameter></paramdef>
++                        </funcprototype>
++                </funcsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><function>sd_session_is_active()</function> may
++                be used to determine whether the session identified by
++                the specified session identifier is currently active
++                (i.e. currently in the foreground and available for
++                user input) or not.</para>
++
++                <para><function>sd_session_get_uid()</function> may be
++                used to determine the user identifier of the Unix user the session
++                identified by the specified session identifier belongs
++                to.</para>
++
++                <para><function>sd_session_get_seat()</function> may
++                be used to determine the seat identifier of the seat
++                the session identified by the specified session
++                identifier belongs to. Note that not all sessions are
++                attached to a seat, this call will fail for them. The
++                returned string needs to be freed with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Return Value</title>
++
++                <para>If the test succeeds
++                <function>sd_session_is_active()</function> returns a
++                positive integer, if it fails 0.  On success
++                <function>sd_session_get_uid()</function> and
++                <function>sd_session_get_seat()</function> return 0 or
++                a positive integer. On failure, these calls return a
++                negative errno-style error code.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>The <function>sd_session_is_active()</function>,
++                <function>sd_session_get_uid()</function>, and
++                <function>sd_session_get_seat()</function> interfaces
++                are available as shared library, which can be compiled
++                and linked to with the
++                <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                </para>
++        </refsect1>
++
++</refentry>
+diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
+new file mode 100644
+index 0000000..a4e9e73
+--- /dev/null
++++ b/man/sd_uid_get_state.xml
+@@ -0,0 +1,182 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd_uid_get_state">
++
++        <refentryinfo>
++                <title>sd_uid_get_state</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd_uid_get_state</refentrytitle>
++                <manvolnum>3</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd_uid_get_state</refname>
++                <refname>sd_uid_is_on_seat</refname>
++                <refname>sd_uid_get_sessions</refname>
++                <refname>sd_uid_get_seats</refname>
++                <refpurpose>Determine login state of a specific Unix user ID</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_uid_get_state</function></funcdef>
++                                <paramdef>uid_t <parameter>pid</parameter></paramdef>
++                                <paramdef>char** <parameter>state</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_uid_is_on_seat</function></funcdef>
++                                <paramdef>uid_t <parameter>pid</parameter></paramdef>
++                                <paramdef>int <parameter>require_active</parameter></paramdef>
++                                <paramdef>const char* <parameter>seat</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_uid_get_sessions</function></funcdef>
++                                <paramdef>uid_t <parameter>pid</parameter></paramdef>
++                                <paramdef>int <parameter>require_active</parameter></paramdef>
++                                <paramdef>char*** <parameter>sessions</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_uid_get_seats</function></funcdef>
++                                <paramdef>uid_t <parameter>pid</parameter></paramdef>
++                                <paramdef>int <parameter>require_active</parameter></paramdef>
++                                <paramdef>char*** <parameter>seats</parameter></paramdef>
++                        </funcprototype>
++                </funcsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><function>sd_uid_get_state()</function> may be
++                used to determine the login state of a specific Unix
++                user identifier. The following states are currently
++                known: <literal>offline</literal> (user not logged in
++                at all), <literal>lingering</literal> (user not logged
++                in, but some user services running),
++                <literal>online</literal> (user logged in, but not
++                active), <literal>active</literal> (user logged in on
++                an active seat). In the future additional states might
++                be defined, client code should be written to be robust
++                in regards to additional state strings being
++                returned. The returned string needs to be freed with
++                the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++
++                <para><function>sd_uid_is_on_seat()</function> may be
++                used to determine whether a specific user is logged in
++                or active on a specific seat. Accepts a Unix user
++                identifier and a seat identifier string as
++                parameters. The <parameter>require_active</parameter>
++                parameter is a boolean. If non-zero (true) this
++                function will test if the user is active (i.e. has a
++                session that is in the foreground and accepting user
++                input) on the specified seat, otherwise (false) only
++                if the user is logged in (and possibly inactive) on
++                the specified seat.</para>
++
++                <para><function>sd_uid_get_sessions()</function> may
++                be used to determine the current sessions of the
++                specified user. Acceptes a Unix user identifier as
++                parameter. The <parameter>require_active</parameter>
++                boolean parameter controls whether the returned list
++                shall consist of only those sessions where the user is
++                currently active (true) or where the user is currently
++                logged in at all, possibly inactive (false). The call
++                returns a NULL terminated string array of session
++                identifiers in <parameter>sessions</parameter> which
++                needs to be freed by the caller with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use, including all the strings referenced. If
++                the string array parameter is passed as NULL the array
++                will not be filled in, but the return code still
++                indicates the number of current sessions.</para>
++
++                <para>Similar, <function>sd_uid_get_seats()</function>
++                may be used to determine the list of seats on which
++                the user currently has sessions. Similar semantics
++                apply, however note that the user may have
++                multiple sessions on the same seat as well as sessions
++                with no attached seat and hence the number of entries
++                in the returned array may differ from the one returned
++                by <function>sd_uid_get_sessions()</function>.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Return Value</title>
++
++                <para>On success
++                <function>sd_uid_get_state()</function> returns 0 or a
++                positive integer. If the test succeeds
++                <function>sd_uid_is_on_seat()</function> returns a
++                positive integer, if it fails
++                0. <function>sd_uid_get_sessions()</function> and
++                <function>sd_uid_get_seats()</function> return the
++                number of entries in the returned arrays. On failure,
++                these calls return a negative errno-style error
++                code.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>The <function>sd_uid_get_state()</function>,
++                <function>sd_uid_is_on_seat()</function>,
++                <function>sd_uid_get_sessions()</function>, and
++                <function>sd_uid_get_seats()</function> interfaces are
++                available as shared library, which can be compiled and
++                linked to with the <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                </para>
++        </refsect1>
++
++</refentry>
+-- 
+1.7.7.5
+
diff --git a/0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch b/0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch
new file mode 100644
index 0000000..70016f5
--- /dev/null
+++ b/0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch
@@ -0,0 +1,83 @@
+From 76c801950d0f596ba7804088a838ecc8d8dc9d5e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 13:11:42 +0100
+Subject: [PATCH 090/126] sd-daemon: fix #include lines since we now ship a
+ shared library (cherry picked from commit
+ a822cbfa2e42d60c3cafe724a8571329ab6c632e)
+
+---
+ man/sd-daemon.xml     |    2 +-
+ man/sd_booted.xml     |    2 +-
+ man/sd_is_fifo.xml    |    2 +-
+ man/sd_listen_fds.xml |    2 +-
+ man/sd_notify.xml     |    2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml
+index cd67d99..383d77f 100644
+--- a/man/sd-daemon.xml
++++ b/man/sd-daemon.xml
+@@ -50,7 +50,7 @@
+ 
+         <refsynopsisdiv>
+                 <funcsynopsis>
+-                        <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+                 </funcsynopsis>
+ 
+                 <cmdsynopsis>
+diff --git a/man/sd_booted.xml b/man/sd_booted.xml
+index ebcde36..c9f538a 100644
+--- a/man/sd_booted.xml
++++ b/man/sd_booted.xml
+@@ -49,7 +49,7 @@
+ 
+         <refsynopsisdiv>
+                 <funcsynopsis>
+-                        <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+ 
+                         <funcprototype>
+                                 <funcdef>int <function>sd_booted</function></funcdef>
+diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml
+index f6fafab..82b89bb 100644
+--- a/man/sd_is_fifo.xml
++++ b/man/sd_is_fifo.xml
+@@ -53,7 +53,7 @@
+ 
+         <refsynopsisdiv>
+                 <funcsynopsis>
+-                        <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+ 
+                         <funcprototype>
+                                 <funcdef>int <function>sd_is_fifo</function></funcdef>
+diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
+index 3276aff..68a45cd 100644
+--- a/man/sd_listen_fds.xml
++++ b/man/sd_listen_fds.xml
+@@ -49,7 +49,7 @@
+ 
+         <refsynopsisdiv>
+                 <funcsynopsis>
+-                        <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+ 
+                         <funcsynopsisinfo>#define SD_LISTEN_FDS_START 3</funcsynopsisinfo>
+ 
+diff --git a/man/sd_notify.xml b/man/sd_notify.xml
+index 62347f8..c3791ce 100644
+--- a/man/sd_notify.xml
++++ b/man/sd_notify.xml
+@@ -50,7 +50,7 @@
+ 
+         <refsynopsisdiv>
+                 <funcsynopsis>
+-                        <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-daemon.h&gt;</funcsynopsisinfo>
+ 
+                         <funcprototype>
+                                 <funcdef>int <function>sd_notify</function></funcdef>
+-- 
+1.7.7.5
+
diff --git a/0091-man-build-new-man-pages.patch b/0091-man-build-new-man-pages.patch
new file mode 100644
index 0000000..9b34473
--- /dev/null
+++ b/0091-man-build-new-man-pages.patch
@@ -0,0 +1,30 @@
+From 271f93368eee2784ad360fe6cfed0b684f4a1032 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 13:12:36 +0100
+Subject: [PATCH 091/126] man: build new man pages (cherry picked from commit
+ f0d2e205a28e37528ef791cc2913e6664d0dde7f)
+
+---
+ Makefile.am |    6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 4d04db3..3b2cbc2 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -818,6 +818,12 @@ MANPAGES_ALIAS = \
+ 	man/sd_is_socket_unix.3 \
+ 	man/sd_is_socket_inet.3 \
+ 	man/sd_notifyf.3 \
++        man/sd_pid_get_session.3 \
++        man/sd_uid_get_state.3 \
++        man/sd_session_is_active.3 \
++        man/sd_seat_get_active.3 \
++        man/sd_get_seats.3 \
++        man/sd_login_monitor_new.3 \
+ 	man/init.1
+ 
+ man/reboot.8: man/halt.8
+-- 
+1.7.7.5
+
diff --git a/0092-man-sd_readahead-is-not-actually-available-in-libsys.patch b/0092-man-sd_readahead-is-not-actually-available-in-libsys.patch
new file mode 100644
index 0000000..7b9b21e
--- /dev/null
+++ b/0092-man-sd_readahead-is-not-actually-available-in-libsys.patch
@@ -0,0 +1,61 @@
+From d5956203ad4ed4f8183685c65cc323ae8f927820 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 13:19:01 +0100
+Subject: [PATCH 092/126] man: sd_readahead is not actually available in
+ libsystemd-daemon (cherry picked from commit
+ 559de1289000f874e23ad01edfa1b37c102a793a)
+
+---
+ man/sd_readahead.xml |   28 +++++++++++-----------------
+ 1 files changed, 11 insertions(+), 17 deletions(-)
+
+diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml
+index 88b135b..25fe5b2 100644
+--- a/man/sd_readahead.xml
++++ b/man/sd_readahead.xml
+@@ -49,7 +49,7 @@
+ 
+         <refsynopsisdiv>
+                 <funcsynopsis>
+-                        <funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
++                        <funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
+ 
+                         <funcprototype>
+                                 <funcdef>int <function>sd_readahead</function></funcdef>
+@@ -134,23 +134,17 @@
+                 url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/></para>
+ 
+                 <para><function>sd_readahead()</function> is
+-                implemented in the reference implementation's
++                implemented in the reference implementation's drop-in
+                 <filename>sd-readahead.c</filename> and
+-                <filename>sd-readahead.h</filename> files. These
+-                interfaces are available as shared library, which can
+-                be compiled and linked to with the
+-                <literal>libsystemd-daemon</literal>
+-                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+-                file. Alternatively, applications consuming this API
+-                may copy the implementation into their source
+-                tree. For more details about the reference
+-                implementation see
+-                <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+-
+-                <para>If the reference implementation is used as
+-                drop-in files and -DDISABLE_SYSTEMD is set during
+-                compilation this function will always return 0 and
+-                otherwise become a NOP.</para>
++                <filename>sd-readahead.h</filename> files. It is
++                recommended that applications consuming this API copy
++                the implementation into their source tree. For more
++                details about the reference implementation see
++                <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry></para>
++
++                <para>If -DDISABLE_SYSTEMD is set during compilation
++                this function will always return 0 and otherwise
++                become a NOP.</para>
+         </refsect1>
+ 
+         <refsect1>
+-- 
+1.7.7.5
+
diff --git a/0093-build-sys-add-rules-for-man-page-aliases.patch b/0093-build-sys-add-rules-for-man-page-aliases.patch
new file mode 100644
index 0000000..419b1e8
--- /dev/null
+++ b/0093-build-sys-add-rules-for-man-page-aliases.patch
@@ -0,0 +1,41 @@
+From 741e7c477da184725f18f928fed7174d97732419 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 13:25:00 +0100
+Subject: [PATCH 093/126] build-sys: add rules for man page aliases (cherry
+ picked from commit
+ c10eb7b02eb048eb23f0c9f239bfe1f9e7bc8e4a)
+
+---
+ Makefile.am |   14 ++++++++++++++
+ 1 files changed, 14 insertions(+), 0 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 3b2cbc2..c04125e 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -831,8 +831,22 @@ man/poweroff.8: man/halt.8
+ man/sd_is_socket.3: man/sd_is_fifo.3
+ man/sd_is_socket_unix.3: man/sd_is_fifo.3
+ man/sd_is_socket_inet.3: man/sd_is_fifo.3
++man/sd_is_mq.3: man/sd_is_fifo.3
+ man/sd_notifyf.3: man/sd_notify.3
+ man/init.1: man/systemd.1
++man/sd_session_get_uid.3: man/sd_session_is_active.3
++man/sd_session_get_seat.3: man/sd_session_is_active.3
++man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
++man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
++man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
++man/sd_uid_get_seats.3: man/sd_uid_get_state.3
++man/sd_seat_get_sessions.3: man/sd_seat_get_active.3
++man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3
++man/sd_get_sessions.3: man/sd_get_seats.3
++man/sd_get_uids.3: man/sd_get_seats.3
++man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3
++man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3
++man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
+ 
+ dist_man_MANS = \
+ 	$(MANPAGES) \
+-- 
+1.7.7.5
+
diff --git a/0094-man-add-sd-login-7-page.patch b/0094-man-add-sd-login-7-page.patch
new file mode 100644
index 0000000..cceb45b
--- /dev/null
+++ b/0094-man-add-sd-login-7-page.patch
@@ -0,0 +1,226 @@
+From 362fa48aecfac175e3601d4075bbc1eb18684625 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 13:57:07 +0100
+Subject: [PATCH 094/126] man: add sd-login(7) page (cherry picked from commit
+ 01448ff92d9549785242ffab453bf5bcde348c61)
+
+---
+ Makefile.am                |   31 +++++++++---
+ man/sd-login.xml           |  117 ++++++++++++++++++++++++++++++++++++++++++++
+ man/sd_pid_get_session.xml |   19 +++----
+ 3 files changed, 149 insertions(+), 18 deletions(-)
+ create mode 100644 man/sd-login.xml
+
+diff --git a/Makefile.am b/Makefile.am
+index c04125e..a5d9c77 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -786,6 +786,7 @@ MANPAGES = \
+ 	man/daemon.7 \
+ 	man/sd-daemon.7 \
+ 	man/sd-readahead.7 \
++	man/sd-login.7 \
+ 	man/runlevel.8 \
+ 	man/telinit.8 \
+ 	man/halt.8 \
+@@ -804,7 +805,13 @@ MANPAGES = \
+ 	man/modules-load.d.5 \
+ 	man/sysctl.d.5 \
+         man/systemd-ask-password.1 \
+-        man/systemd-loginctl.1
++        man/systemd-loginctl.1 \
++        man/sd_pid_get_session.3 \
++        man/sd_uid_get_state.3 \
++        man/sd_session_is_active.3 \
++        man/sd_seat_get_active.3 \
++        man/sd_get_seats.3 \
++        man/sd_login_monitor_new.3
+ 
+ if ENABLE_BINFMT
+ MANPAGES += \
+@@ -817,14 +824,22 @@ MANPAGES_ALIAS = \
+ 	man/sd_is_socket.3 \
+ 	man/sd_is_socket_unix.3 \
+ 	man/sd_is_socket_inet.3 \
++	man/sd_is_mq.3 \
+ 	man/sd_notifyf.3 \
+-        man/sd_pid_get_session.3 \
+-        man/sd_uid_get_state.3 \
+-        man/sd_session_is_active.3 \
+-        man/sd_seat_get_active.3 \
+-        man/sd_get_seats.3 \
+-        man/sd_login_monitor_new.3 \
+-	man/init.1
++	man/init.1 \
++        man/sd_session_get_uid.3 \
++        man/sd_session_get_seat.3 \
++        man/sd_pid_get_owner_uid.3 \
++        man/sd_uid_is_on_seat.3 \
++        man/sd_uid_get_sessions.3 \
++        man/sd_uid_get_seats.3 \
++        man/sd_seat_get_sessions.3 \
++        man/sd_seat_can_multi_session.3 \
++        man/sd_get_sessions.3 \
++        man/sd_get_uids.3 \
++        man/sd_login_monitor_unref.3 \
++        man/sd_login_monitor_flush.3 \
++        man/sd_login_monitor_get_fd.3
+ 
+ man/reboot.8: man/halt.8
+ man/poweroff.8: man/halt.8
+diff --git a/man/sd-login.xml b/man/sd-login.xml
+new file mode 100644
+index 0000000..62ec6ff
+--- /dev/null
++++ b/man/sd-login.xml
+@@ -0,0 +1,117 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
++        "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2010 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<refentry id="sd-login">
++
++        <refentryinfo>
++                <title>sd-login</title>
++                <productname>systemd</productname>
++
++                <authorgroup>
++                        <author>
++                                <contrib>Developer</contrib>
++                                <firstname>Lennart</firstname>
++                                <surname>Poettering</surname>
++                                <email>lennart at poettering.net</email>
++                        </author>
++                </authorgroup>
++        </refentryinfo>
++
++        <refmeta>
++                <refentrytitle>sd-login</refentrytitle>
++                <manvolnum>7</manvolnum>
++        </refmeta>
++
++        <refnamediv>
++                <refname>sd-login</refname>
++                <refpurpose>APIs for
++                tracking logins</refpurpose>
++        </refnamediv>
++
++        <refsynopsisdiv>
++                <funcsynopsis>
++                        <funcsynopsisinfo>#include &lt;systemd/sd-login.h&gt;</funcsynopsisinfo>
++                </funcsynopsis>
++
++                <cmdsynopsis>
++                        <command>pkg-config --cflags --libs libsystemd-login</command>
++                </cmdsynopsis>
++        </refsynopsisdiv>
++
++        <refsect1>
++                <title>Description</title>
++
++                <para><filename>sd-login.h</filename> provides APIs to
++                introspect and monitor seat, login session and user
++                status information on the local system. </para>
++
++                <para>See <ulink
++                url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
++                on Linux</ulink> for an introduction into multi-seat
++                support on Linux, the background for this set of APIs.</para>
++
++                <para>Note that these APIs only allow purely passive access
++                and monitoring of seats, sessions and users. To
++                actively make changes to the seat configuration,
++                terminate login sessions, or switch session on a seat
++                you need to utilize the D-Bus API of
++                systemd-logind.</para>
++
++                <para>See
++                <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                <citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                <citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                for more information about the functions
++                implemented.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>Notes</title>
++
++                <para>These APIs are implemented as shared library,
++                which can be compiled and linked to with the
++                <literal>libsystemd-login</literal>
++                <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                file.</para>
++        </refsect1>
++
++        <refsect1>
++                <title>See Also</title>
++                <para>
++                        <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
++                </para>
++        </refsect1>
++
++</refentry>
+diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml
+index 9176433..24e4680 100644
+--- a/man/sd_pid_get_session.xml
++++ b/man/sd_pid_get_session.xml
+@@ -71,16 +71,15 @@
+ 
+                 <para><function>sd_pid_get_session()</function> may be
+                 used to determine the login session identifier of a
+-                process identified by the specified process identifier. The session
+-                identifier is a short string (up to 64 characters),
+-                consisting only of the characters a-zA-Z0-9 as well as
+-                '-' and '_'. It is suitable for usage in file system
+-                paths. Note that not all processes are part of a login
+-                session (e.g. system service processes and user
+-                processes that are shared between multiple sessions of
+-                the same user). For processes not being part of a
+-                login session this function will fail. The returned
+-                string needs to be freed with the libc
++                process identified by the specified process
++                identifier. The session identifier is a short string,
++                suitable for usage in file system paths. Note that not
++                all processes are part of a login session (e.g. system
++                service processes and user processes that are shared
++                between multiple sessions of the same user). For
++                processes not being part of a login session this
++                function will fail. The returned string needs to be
++                freed with the libc
+                 <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                 call after use.</para>
+ 
+-- 
+1.7.7.5
+
diff --git a/0095-man-various-updates.patch b/0095-man-various-updates.patch
new file mode 100644
index 0000000..df85563
--- /dev/null
+++ b/0095-man-various-updates.patch
@@ -0,0 +1,162 @@
+From 550fab31953acced44a6e7b2acc050b8270dd558 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 14:42:59 +0100
+Subject: [PATCH 095/126] man: various updates (cherry picked from commit
+ 595aae376fae21f885ec9af2cac1aaf3ff3e9bee)
+
+---
+ man/sd-login.xml             |   21 ++++++++++++++++++++-
+ man/sd_get_seats.xml         |   12 +++++++-----
+ man/sd_login_monitor_new.xml |    2 +-
+ man/sd_seat_get_active.xml   |    6 ++++--
+ man/sd_session_is_active.xml |    2 +-
+ man/sd_uid_get_state.xml     |   13 ++++++++-----
+ 6 files changed, 41 insertions(+), 15 deletions(-)
+
+diff --git a/man/sd-login.xml b/man/sd-login.xml
+index 62ec6ff..9926d2b 100644
+--- a/man/sd-login.xml
++++ b/man/sd-login.xml
+@@ -75,7 +75,26 @@
+                 actively make changes to the seat configuration,
+                 terminate login sessions, or switch session on a seat
+                 you need to utilize the D-Bus API of
+-                systemd-logind.</para>
++                systemd-logind, instead.</para>
++
++                <para>These functions access data in
++                <filename>/proc</filename>,
++                <filename>/sys/fs/cgroup</filename> and
++                <filename>/run</filename>. All of these are virtual
++                file systems, hence the runtime cost of the accesses
++                is relatively cheap.</para>
++
++                <para>If the functions return string arrays, these are
++                generally NULL terminated and need to be freed by the
++                caller with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use, including the strings referenced
++                therein. Similar, individual strings returned need to
++                be freed, as well.</para>
++
++                <para>As a special exception, instead of an empty
++                string array NULL may be returned, which should be
++                treated equivalent to an empty string array.</para>
+ 
+                 <para>See
+                 <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml
+index bbc396a..2ac7650 100644
+--- a/man/sd_get_seats.xml
++++ b/man/sd_get_seats.xml
+@@ -76,11 +76,13 @@
+ 
+                 <para><function>sd_get_seats()</function> may be used
+                 to determine all currently available local
+-                seats. Returns an array of seat identifiers. The
+-                returned array and all strings it references need to
+-                be freed with the libc
++                seats. Returns a NULL terminated array of seat
++                identifiers. The returned array and all strings it
++                references need to be freed with the libc
+                 <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+-                call after use.</para>
++                call after use. Note that instead of an empty array
++                NULL may be returned and should be considered
++                equivalent to an empty array.</para>
+ 
+                 <para>Similar, <function>sd_get_sessions()</function> may
+                 be used to determine all current login sessions.</para>
+@@ -118,7 +120,7 @@
+                 <para>
+                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                         <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+-                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                 </para>
+         </refsect1>
+ 
+diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
+index 2b37f00..de48432 100644
+--- a/man/sd_login_monitor_new.xml
++++ b/man/sd_login_monitor_new.xml
+@@ -165,7 +165,7 @@
+                 <para>
+                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                         <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+-                        <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                 </para>
+         </refsect1>
+ 
+diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
+index e729a65..14cda60 100644
+--- a/man/sd_seat_get_active.xml
++++ b/man/sd_seat_get_active.xml
+@@ -101,7 +101,9 @@
+                 determined. The arrays and the strings referenced by
+                 them need to be freed with the libc
+                 <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+-                call after use.</para>
++                call after use. Note that instead of an empty array
++                NULL may be returned and should be considered
++                equivalent to an empty array.</para>
+ 
+                 <para><function>sd_seat_can_multi_session()</function>
+                 may be used to determine whether a specific seat is
+@@ -143,7 +145,7 @@
+                 <para>
+                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                         <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+-                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                 </para>
+         </refsect1>
+ 
+diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
+index 82919f8..88b22fd 100644
+--- a/man/sd_session_is_active.xml
++++ b/man/sd_session_is_active.xml
+@@ -127,7 +127,7 @@
+                 <para>
+                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                         <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+-                        <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                 </para>
+         </refsect1>
+ 
+diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
+index a4e9e73..6777625 100644
+--- a/man/sd_uid_get_state.xml
++++ b/man/sd_uid_get_state.xml
+@@ -126,10 +126,13 @@
+                 identifiers in <parameter>sessions</parameter> which
+                 needs to be freed by the caller with the libc
+                 <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+-                call after use, including all the strings referenced. If
+-                the string array parameter is passed as NULL the array
+-                will not be filled in, but the return code still
+-                indicates the number of current sessions.</para>
++                call after use, including all the strings
++                referenced. If the string array parameter is passed as
++                NULL the array will not be filled in, but the return
++                code still indicates the number of current
++                sessions. Note that instead of an empty array NULL may
++                be returned and should be considered equivalent to an
++                empty array.</para>
+ 
+                 <para>Similar, <function>sd_uid_get_seats()</function>
+                 may be used to determine the list of seats on which
+@@ -175,7 +178,7 @@
+                 <para>
+                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                         <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+-                        <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
++                        <citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                 </para>
+         </refsect1>
+ 
+-- 
+1.7.7.5
+
diff --git a/0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch b/0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch
new file mode 100644
index 0000000..93b724b
--- /dev/null
+++ b/0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch
@@ -0,0 +1,44 @@
+From d54ac9394336db0564b3bca712d43042486dacc1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 17:40:31 +0100
+Subject: [PATCH 096/126] man: extend sd-login(7) in regards to mixing D-Bus
+ and synchronous library calls a bit (cherry picked
+ from commit
+ 5079a105e701f17439635e76d8cb3052badbb34c)
+
+---
+ man/sd-login.xml |   12 +++++++++++-
+ 1 files changed, 11 insertions(+), 1 deletions(-)
+
+diff --git a/man/sd-login.xml b/man/sd-login.xml
+index 9926d2b..3fc0e16 100644
+--- a/man/sd-login.xml
++++ b/man/sd-login.xml
+@@ -77,13 +77,23 @@
+                 you need to utilize the D-Bus API of
+                 systemd-logind, instead.</para>
+ 
+-                <para>These functions access data in
++                <para>These functions synchronously access data in
+                 <filename>/proc</filename>,
+                 <filename>/sys/fs/cgroup</filename> and
+                 <filename>/run</filename>. All of these are virtual
+                 file systems, hence the runtime cost of the accesses
+                 is relatively cheap.</para>
+ 
++                <para>It is possible (and often a very good choice) to
++                mix calls to the synchronous interface of
++                <filename>sd-login.h</filename> with the asynchronous
++                D-Bus interface of systemd-logind. However, if this is
++                done you need to think a bit about possible races
++                since the stream of events from D-Bus and from
++                <filename>sd-login.h</filename> interfaces such as the
++                login monitor are asynchronous and not ordered against
++                each other.</para>
++
+                 <para>If the functions return string arrays, these are
+                 generally NULL terminated and need to be freed by the
+                 caller with the libc
+-- 
+1.7.7.5
+
diff --git a/0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch b/0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch
new file mode 100644
index 0000000..affe3b4
--- /dev/null
+++ b/0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch
@@ -0,0 +1,32 @@
+From d522760b761ddb9e92eb068c656c68ed60bdb50e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 19:55:54 +0100
+Subject: [PATCH 097/126] man: generate HTML instead of XHTML with XSL docbook
+ to work around 'fsfunc' noise (cherry picked from
+ commit 38c67e2a442d875c1de6f5aae46647a195230b05)
+
+---
+ Makefile.am |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index a5d9c77..9ee2c7f 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1709,11 +1709,11 @@ XSLTPROC_PROCESS_MAN_IN = \
+ 
+ XSLTPROC_PROCESS_HTML = \
+ 	$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+-	$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $<
++	$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $<
+ 
+ XSLTPROC_PROCESS_HTML_IN = \
+ 	$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+-	$(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $< && \
++	$(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< && \
+ 	mv ${@:.in=} $@
+ 
+ man/%.1: man/%.xml
+-- 
+1.7.7.5
+
diff --git a/0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch b/0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch
new file mode 100644
index 0000000..86ff000
--- /dev/null
+++ b/0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch
@@ -0,0 +1,88 @@
+From 1b6836c15717a62ef81cef8e9617fc7df6c7e605 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 19 Dec 2011 20:25:52 +0100
+Subject: [PATCH 098/126] man: switch to UTF-8 output, to work around charset
+ issues (cherry picked from commit
+ 76318284fc970b30e9dc4c079960807345331dad)
+
+---
+ Makefile.am         |    9 +++++----
+ man/custom-html.xsl |   29 +++++++++++++++++++++++++++++
+ 2 files changed, 34 insertions(+), 4 deletions(-)
+ create mode 100644 man/custom-html.xsl
+
+diff --git a/Makefile.am b/Makefile.am
+index 9ee2c7f..295944d 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -495,7 +495,8 @@ EXTRA_DIST = \
+ 	src/libsystemd-login.sym \
+ 	introspect.awk \
+ 	src/73-seat-late.rules.in \
+-        src/99-systemd.rules.in
++        src/99-systemd.rules.in \
++        man/custom-html.xsl
+ 
+ if ENABLE_BINFMT
+ EXTRA_DIST += \
+@@ -1696,7 +1697,7 @@ endif
+ if HAVE_XSLTPROC
+ XSLTPROC_FLAGS = \
+ 	--nonet \
+-	--param funcsynopsis.style "'ansi'"
++	--stringparam funcsynopsis.style ansi
+ 
+ XSLTPROC_PROCESS_MAN = \
+ 	$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+@@ -1709,11 +1710,11 @@ XSLTPROC_PROCESS_MAN_IN = \
+ 
+ XSLTPROC_PROCESS_HTML = \
+ 	$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+-	$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $<
++	$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) man/custom-html.xsl $<
+ 
+ XSLTPROC_PROCESS_HTML_IN = \
+ 	$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
+-	$(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< && \
++	$(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) man/custom-html.xsl $< && \
+ 	mv ${@:.in=} $@
+ 
+ man/%.1: man/%.xml
+diff --git a/man/custom-html.xsl b/man/custom-html.xsl
+new file mode 100644
+index 0000000..2d2f458
+--- /dev/null
++++ b/man/custom-html.xsl
+@@ -0,0 +1,29 @@
++<?xml version='1.0'?> <!--*-nxml-*-->
++
++<!--
++  This file is part of systemd.
++
++  Copyright 2011 Lennart Poettering
++
++  systemd is free software; you can redistribute it and/or modify it
++  under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  systemd is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with systemd; If not, see <http://www.gnu.org/licenses/>.
++-->
++
++<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
++
++<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
++
++<!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
++<xsl:output method="html" encoding="UTF-8" indent="no"/>
++
++</xsl:stylesheet>
+-- 
+1.7.7.5
+
diff --git a/0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch b/0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch
new file mode 100644
index 0000000..5667b45
--- /dev/null
+++ b/0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch
@@ -0,0 +1,28 @@
+From 988a59b65bcf86ed1cdf9fefb5a2ac7c16536c1b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 27 Dec 2011 22:52:15 +0100
+Subject: [PATCH 099/126] udev: exclude loopback device from udev rule based
+ sysctl application, since we can just apply that
+ directly at boot (cherry picked from commit
+ 330672957438243c8003d3a90f0e59dedbd845e9)
+
+---
+ src/99-systemd.rules.in |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/99-systemd.rules.in b/src/99-systemd.rules.in
+index b2481ae..d306f71 100644
+--- a/src/99-systemd.rules.in
++++ b/src/99-systemd.rules.in
+@@ -44,7 +44,7 @@ SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:
+ 
+ # Apply sysctl variables to network devices (and only to those) as they appear.
+ 
+-SUBSYSTEM=="net", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
++SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
+ 
+ # Asynchronously mount file systems implemented by these modules as
+ # soon as they are loaded.
+-- 
+1.7.7.5
+
diff --git a/0100-remount-api-vfs-handle-another-OOM-condition.patch b/0100-remount-api-vfs-handle-another-OOM-condition.patch
new file mode 100644
index 0000000..033692b
--- /dev/null
+++ b/0100-remount-api-vfs-handle-another-OOM-condition.patch
@@ -0,0 +1,75 @@
+From ae1e1f08b63b11eee857598076dbc5aaa9020032 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 30 Dec 2011 15:34:21 +0100
+Subject: [PATCH 100/126] remount-api-vfs: handle another OOM condition
+ (cherry picked from commit
+ adb2ce5f694cb528f9294219941b1e37dc6a9530)
+
+---
+ src/remount-api-vfs.c |   23 +++++++++++++++++------
+ 1 files changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/src/remount-api-vfs.c b/src/remount-api-vfs.c
+index 8bbc021..7b14655 100644
+--- a/src/remount-api-vfs.c
++++ b/src/remount-api-vfs.c
+@@ -54,12 +54,14 @@ int main(int argc, char *argv[]) {
+ 
+         umask(0022);
+ 
+-        if (!(f = setmntent("/etc/fstab", "r"))) {
++        f = setmntent("/etc/fstab", "r");
++        if (!f) {
+                 log_error("Failed to open /etc/fstab: %m");
+                 goto finish;
+         }
+ 
+-        if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
++        pids = hashmap_new(trivial_hash_func, trivial_compare_func);
++        if (!pids) {
+                 log_error("Failed to allocate set");
+                 goto finish;
+         }
+@@ -76,9 +78,10 @@ int main(int argc, char *argv[]) {
+ 
+                 log_debug("Remounting %s", me->mnt_dir);
+ 
+-                if ((pid = fork()) < 0) {
++                pid = fork();
++                if (pid < 0) {
+                         log_error("Failed to fork: %m");
+-                        ret = 1;
++                        ret = EXIT_FAILURE;
+                         continue;
+                 }
+ 
+@@ -101,8 +104,15 @@ int main(int argc, char *argv[]) {
+                 /* Parent */
+ 
+                 s = strdup(me->mnt_dir);
++                if (!s) {
++                        log_error("Out of memory.");
++                        ret = EXIT_FAILURE;
++                        continue;
++                }
++
+ 
+-                if ((k = hashmap_put(pids, UINT_TO_PTR(pid), s)) < 0) {
++                k = hashmap_put(pids, UINT_TO_PTR(pid), s);
++                if (k < 0) {
+                         log_error("Failed to add PID to set: %s", strerror(-k));
+                         ret = EXIT_FAILURE;
+                         continue;
+@@ -124,7 +134,8 @@ int main(int argc, char *argv[]) {
+                         break;
+                 }
+ 
+-                if ((s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
++                s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
++                if (s) {
+                         if (!is_clean_exit(si.si_code, si.si_status)) {
+                                 if (si.si_code == CLD_EXITED)
+                                         log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
+-- 
+1.7.7.5
+
diff --git a/0101-socket-rename-the-PassCred-option-to-PassCredentials.patch b/0101-socket-rename-the-PassCred-option-to-PassCredentials.patch
new file mode 100644
index 0000000..2e8cfce
--- /dev/null
+++ b/0101-socket-rename-the-PassCred-option-to-PassCredentials.patch
@@ -0,0 +1,129 @@
+From 0e984106a89ac1732a5200f7b3180454a6c3ad15 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sat, 31 Dec 2011 01:07:49 +0100
+Subject: [PATCH 101/126] socket: rename the PassCred= option to
+ PassCredentials=, since we don't want to needlessly
+ abbreviate options unless they are very well
+ established (cherry picked from commit
+ 271b032a053f9d4a1be271bb052276ae27fe36c6)
+
+Conflicts:
+
+	units/systemd-journald.socket
+---
+ man/systemd.socket.xml           |    8 ++++----
+ src/dbus-socket.c                |    4 ++--
+ src/load-fragment-gperf.gperf.m4 |    2 +-
+ src/socket.c                     |    2 +-
+ units/syslog.socket              |    2 +-
+ units/systemd-shutdownd.socket   |    2 +-
+ 6 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
+index f883543..ef5b28c 100644
+--- a/man/systemd.socket.xml
++++ b/man/systemd.socket.xml
+@@ -510,7 +510,7 @@
+                                 <term><varname>Transparent=</varname></term>
+                                 <listitem><para>Takes a boolean
+                                 value. Controls the IP_TRANSPARENT
+-                                option. Defaults to
++                                socket option. Defaults to
+                                 <option>false</option>.</para></listitem>
+                         </varlistentry>
+ 
+@@ -518,17 +518,17 @@
+                                 <term><varname>Broadcast=</varname></term>
+                                 <listitem><para>Takes a boolean
+                                 value. This controls the SO_BROADCAST
+-                                option, which allows broadcast
++                                socket option, which allows broadcast
+                                 datagrams to be sent from this
+                                 socket. Defaults to
+                                 <option>false</option>.</para></listitem>
+                         </varlistentry>
+ 
+                         <varlistentry>
+-                                <term><varname>PassCred=</varname></term>
++                                <term><varname>PassCredentials=</varname></term>
+                                 <listitem><para>Takes a boolean
+                                 value. This controls the SO_PASSCRED
+-                                option, which allows UNIX sockets to
++                                socket option, which allows UNIX sockets to
+                                 receive the credentials of the sending
+                                 process in an ancillary message.
+                                 Defaults to
+diff --git a/src/dbus-socket.c b/src/dbus-socket.c
+index 37ab7eb..c428189 100644
+--- a/src/dbus-socket.c
++++ b/src/dbus-socket.c
+@@ -51,7 +51,7 @@
+         "  <property name=\"FreeBind\" type=\"b\" access=\"read\"/>\n"  \
+         "  <property name=\"Transparent\" type=\"b\" access=\"read\"/>\n" \
+         "  <property name=\"Broadcast\" type=\"b\" access=\"read\"/>\n" \
+-        "  <property name=\"PassCred\" type=\"b\" access=\"read\"/>\n" \
++        "  <property name=\"PassCredentials\" type=\"b\" access=\"read\"/>\n" \
+         "  <property name=\"Mark\" type=\"i\" access=\"read\"/>\n"      \
+         "  <property name=\"MaxConnections\" type=\"u\" access=\"read\"/>\n" \
+         "  <property name=\"NAccepted\" type=\"u\" access=\"read\"/>\n" \
+@@ -114,7 +114,7 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes
+                 { "org.freedesktop.systemd1.Socket", "FreeBind",       bus_property_append_bool,         "b", &u->socket.free_bind       },
+                 { "org.freedesktop.systemd1.Socket", "Transparent",    bus_property_append_bool,         "b", &u->socket.transparent     },
+                 { "org.freedesktop.systemd1.Socket", "Broadcast",      bus_property_append_bool,         "b", &u->socket.broadcast       },
+-                { "org.freedesktop.systemd1.Socket", "PassCred",       bus_property_append_bool,         "b", &u->socket.pass_cred       },
++                { "org.freedesktop.systemd1.Socket", "PassCredentials",bus_property_append_bool,         "b", &u->socket.pass_cred       },
+                 { "org.freedesktop.systemd1.Socket", "Mark",           bus_property_append_int,          "i", &u->socket.mark            },
+                 { "org.freedesktop.systemd1.Socket", "MaxConnections", bus_property_append_unsigned,     "u", &u->socket.max_connections },
+                 { "org.freedesktop.systemd1.Socket", "NConnections",   bus_property_append_unsigned,     "u", &u->socket.n_connections   },
+diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
+index 35ec005..81e186c 100644
+--- a/src/load-fragment-gperf.gperf.m4
++++ b/src/load-fragment-gperf.gperf.m4
+@@ -177,7 +177,7 @@ Socket.PipeSize,                 config_parse_size,                  0,
+ Socket.FreeBind,                 config_parse_bool,                  0,                             offsetof(Socket, free_bind)
+ Socket.Transparent,              config_parse_bool,                  0,                             offsetof(Socket, transparent)
+ Socket.Broadcast,                config_parse_bool,                  0,                             offsetof(Socket, broadcast)
+-Socket.PassCred,                 config_parse_bool,                  0,                             offsetof(Socket, pass_cred)
++Socket.PassCredentials,          config_parse_bool,                  0,                             offsetof(Socket, pass_cred)
+ Socket.TCPCongestion,            config_parse_string,                0,                             offsetof(Socket, tcp_congestion)
+ Socket.MessageQueueMaxMessages,  config_parse_long,                  0,                             offsetof(Socket, mq_maxmsg)
+ Socket.MessageQueueMessageSize,  config_parse_long,                  0,                             offsetof(Socket, mq_msgsize)
+diff --git a/src/socket.c b/src/socket.c
+index 0864cce..bbfc842 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -406,7 +406,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
+                 "%sFreeBind: %s\n"
+                 "%sTransparent: %s\n"
+                 "%sBroadcast: %s\n"
+-                "%sPassCred: %s\n"
++                "%sPassCrededentials: %s\n"
+                 "%sTCPCongestion: %s\n",
+                 prefix, socket_state_to_string(s->state),
+                 prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
+diff --git a/units/syslog.socket b/units/syslog.socket
+index e74b559..ccf79fe 100644
+--- a/units/syslog.socket
++++ b/units/syslog.socket
+@@ -18,7 +18,7 @@ Wants=syslog.target
+ [Socket]
+ ListenDatagram=/dev/log
+ SocketMode=0666
+-PassCred=yes
++PassCredentials=yes
+ 
+ # The service we activate on incoming traffic is
+ # systemd-kmsg-syslogd.service. That doesn't mean however, that this
+diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket
+index 13b6c7a..532a6f0 100644
+--- a/units/systemd-shutdownd.socket
++++ b/units/systemd-shutdownd.socket
+@@ -15,4 +15,4 @@ Before=sockets.target
+ [Socket]
+ ListenDatagram=/run/systemd/shutdownd
+ SocketMode=0600
+-PassCred=yes
++PassCredentials=yes
+-- 
+1.7.7.5
+
diff --git a/0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch b/0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch
new file mode 100644
index 0000000..0364d00
--- /dev/null
+++ b/0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch
@@ -0,0 +1,49 @@
+From faa9db1ad2fe229ba90b7d75e104ead6614ea813 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 3 Jan 2012 20:33:28 +0100
+Subject: [PATCH 102/126] socket: only add dependency on kmsg socket to socket
+ units which have any kind of exec program specified
+ (cherry picked from commit
+ 4cfc6dbe52e4ff867750ce0d64f09d42c0ea6c27)
+
+---
+ src/socket.c |   16 ++++++++++++++--
+ 1 files changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/src/socket.c b/src/socket.c
+index bbfc842..1f5e067 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -323,6 +323,17 @@ static int socket_add_default_dependencies(Socket *s) {
+         return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+ }
+ 
++static bool socket_has_exec(Socket *s) {
++        unsigned i;
++        assert(s);
++
++        for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
++                if (s->exec_command[i])
++                        return true;
++
++        return false;
++}
++
+ static int socket_load(Unit *u) {
+         Socket *s = SOCKET(u);
+         int r;
+@@ -352,8 +363,9 @@ static int socket_load(Unit *u) {
+                 if ((r = socket_add_device_link(s)) < 0)
+                         return r;
+ 
+-                if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
+-                        return r;
++                if (socket_has_exec(s))
++                        if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
++                                return r;
+ 
+                 if ((r = unit_add_default_cgroups(u)) < 0)
+                         return r;
+-- 
+1.7.7.5
+
diff --git a/0103-readahead-bring-export-definition-of-sd-readahead-in.patch b/0103-readahead-bring-export-definition-of-sd-readahead-in.patch
new file mode 100644
index 0000000..afa8eea
--- /dev/null
+++ b/0103-readahead-bring-export-definition-of-sd-readahead-in.patch
@@ -0,0 +1,75 @@
+From 24954dcfd60261600c04ffdfc9cd0b1980a4b7d3 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 3 Jan 2012 20:34:09 +0100
+Subject: [PATCH 103/126] readahead: bring export definition of sd-readahead
+ in line with sd-daemon (cherry picked from commit
+ 4f3656e1cec7fe3d7d3537e23a406cb88d734502)
+
+---
+ src/sd-readahead.c |   14 +++++++++++++-
+ src/sd-readahead.h |   10 +---------
+ 2 files changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/src/sd-readahead.c b/src/sd-readahead.c
+index c5cfe67..a334066 100644
+--- a/src/sd-readahead.c
++++ b/src/sd-readahead.c
+@@ -37,6 +37,18 @@
+ 
+ #include "sd-readahead.h"
+ 
++#if (__GNUC__ >= 4)
++#ifdef SD_EXPORT_SYMBOLS
++/* Export symbols */
++#define _sd_export_ __attribute__ ((visibility("default")))
++#else
++/* Don't export the symbols */
++#define _sd_export_ __attribute__ ((visibility("hidden")))
++#endif
++#else
++#define _sd_export_
++#endif
++
+ static int touch(const char *path) {
+ 
+ #if !defined(DISABLE_SYSTEMD) && defined(__linux__)
+@@ -60,7 +72,7 @@ static int touch(const char *path) {
+         return 0;
+ }
+ 
+-int sd_readahead(const char *action) {
++_sd_export_ int sd_readahead(const char *action) {
+ 
+         if (!action)
+                 return -EINVAL;
+diff --git a/src/sd-readahead.h b/src/sd-readahead.h
+index 5bf975a..ee7e306 100644
+--- a/src/sd-readahead.h
++++ b/src/sd-readahead.h
+@@ -56,14 +56,6 @@ extern "C" {
+   See sd-readahead(7) for more information.
+ */
+ 
+-#ifndef _sd_hidden_
+-#if (__GNUC__ >= 4) && !defined(SD_EXPORT_SYMBOLS)
+-#define _sd_hidden_ __attribute__ ((visibility("hidden")))
+-#else
+-#define _sd_hidden_
+-#endif
+-#endif
+-
+ /*
+   Controls ongoing disk read-ahead operations during boot-up. The argument
+   must be a string, and either "cancel", "done" or "noreplay".
+@@ -72,7 +64,7 @@ extern "C" {
+   done = terminate read-ahead data collection, keep collected information
+   noreplay = terminate read-ahead replay
+ */
+-int sd_readahead(const char *action) _sd_hidden_;
++int sd_readahead(const char *action);
+ 
+ #ifdef __cplusplus
+ }
+-- 
+1.7.7.5
+
diff --git a/0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch b/0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch
new file mode 100644
index 0000000..743a613
--- /dev/null
+++ b/0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch
@@ -0,0 +1,55 @@
+From 79dbd0ccda06dc6b9d1a6a8a04a214895b0d91e8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 3 Jan 2012 20:41:20 +0100
+Subject: [PATCH 104/126] nspawn: get rid of BUFFER_SIZE, use LINE_MAX instead
+ (cherry picked from commit
+ b72491a2fd8c237299055c636d4f748bca2b4b1f)
+
+---
+ src/nspawn.c |   12 +++++-------
+ 1 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/src/nspawn.c b/src/nspawn.c
+index 653d7db..3ea603f 100644
+--- a/src/nspawn.c
++++ b/src/nspawn.c
+@@ -394,11 +394,9 @@ static int is_os_tree(const char *path) {
+         return r < 0 ? 0 : 1;
+ }
+ 
+-#define BUFFER_SIZE 1024
+-
+ static int process_pty(int master, sigset_t *mask) {
+ 
+-        char in_buffer[BUFFER_SIZE], out_buffer[BUFFER_SIZE];
++        char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
+         size_t in_buffer_full = 0, out_buffer_full = 0;
+         struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev;
+         bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false;
+@@ -519,9 +517,9 @@ static int process_pty(int master, sigset_t *mask) {
+                        (master_readable && out_buffer_full <= 0) ||
+                        (stdout_writable && out_buffer_full > 0)) {
+ 
+-                        if (stdin_readable && in_buffer_full < BUFFER_SIZE) {
++                        if (stdin_readable && in_buffer_full < LINE_MAX) {
+ 
+-                                if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) {
++                                if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full)) < 0) {
+ 
+                                         if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
+                                                 stdin_readable = false;
+@@ -553,9 +551,9 @@ static int process_pty(int master, sigset_t *mask) {
+                                 }
+                         }
+ 
+-                        if (master_readable && out_buffer_full < BUFFER_SIZE) {
++                        if (master_readable && out_buffer_full < LINE_MAX) {
+ 
+-                                if ((k = read(master, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) {
++                                if ((k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full)) < 0) {
+ 
+                                         if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO)
+                                                 master_readable = false;
+-- 
+1.7.7.5
+
diff --git a/0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch b/0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch
new file mode 100644
index 0000000..6200515
--- /dev/null
+++ b/0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch
@@ -0,0 +1,35 @@
+From 4cecfa6c03410e72e42b520575613c4f30253bef Mon Sep 17 00:00:00 2001
+From: Daniel Walsh <dwalsh at redhat.com>
+Date: Tue, 3 Jan 2012 21:12:10 +0100
+Subject: [PATCH 105/126] namespace: remount namespace root dir for SLAVE to
+ avoid propagation of mounts from the namespace to
+ the host
+
+https://bugzilla.redhat.com/show_bug.cgi?id=752540
+(cherry picked from commit dc4b02006455a4dddeb6ccc1f6656c89d3ebd27c)
+---
+ src/namespace.c |    8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/namespace.c b/src/namespace.c
+index 54b22f4..a06cac1 100644
+--- a/src/namespace.c
++++ b/src/namespace.c
+@@ -266,8 +266,12 @@ int setup_namespace(
+                 goto fail;
+         }
+ 
+-        /* We assume that by default mount events from us won't be
+-         * propagated to the root namespace. */
++        /* Remount / as SLAVE so that nothing mounted in the namespace
++           shows up in the parent */
++        if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
++                r = -errno;
++                goto fail;
++        }
+ 
+         for (p = paths; p < paths + n; p++)
+                 if ((r = apply_mount(p, root_dir, inaccessible_dir, private_dir, flags)) < 0)
+-- 
+1.7.7.5
+
diff --git a/0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch b/0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch
new file mode 100644
index 0000000..477f467
--- /dev/null
+++ b/0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch
@@ -0,0 +1,200 @@
+From c190c0e59e4dfa52a523a220a82b94b3bbfd3ad9 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 3 Jan 2012 21:47:54 +0100
+Subject: [PATCH 106/126] logind: if we can't open /dev/tty0, assume there is
+ no VT subsystem and don't pretend we could do VT
+ switching (cherry picked from commit
+ addedec48ba0ffc4472ef6d3b5a45c9d4239f1cd)
+
+---
+ src/logind-dbus.c      |    2 +-
+ src/logind-seat-dbus.c |    2 +-
+ src/logind-seat.c      |   28 +++++++++++++++++++++-------
+ src/logind-seat.h      |    1 +
+ src/logind-session.c   |    4 ++--
+ src/logind.c           |    7 ++++++-
+ src/sd-login.c         |    2 +-
+ 7 files changed, 33 insertions(+), 13 deletions(-)
+
+diff --git a/src/logind-dbus.c b/src/logind-dbus.c
+index 0550d1b..efbc040 100644
+--- a/src/logind-dbus.c
++++ b/src/logind-dbus.c
+@@ -301,7 +301,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
+                 return -EINVAL;
+ 
+         if (s) {
+-                if (seat_is_vtconsole(s)) {
++                if (seat_can_multi_session(s)) {
+                         if (vtnr <= 0 || vtnr > 63)
+                                 return -EINVAL;
+                 } else {
+diff --git a/src/logind-seat-dbus.c b/src/logind-seat-dbus.c
+index 3a916ee..a15689b 100644
+--- a/src/logind-seat-dbus.c
++++ b/src/logind-seat-dbus.c
+@@ -141,7 +141,7 @@ static int bus_seat_append_multi_session(DBusMessageIter *i, const char *propert
+         assert(property);
+         assert(s);
+ 
+-        b = seat_is_vtconsole(s);
++        b = seat_can_multi_session(s);
+ 
+         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
+                 return -ENOMEM;
+diff --git a/src/logind-seat.c b/src/logind-seat.c
+index 3cf3958..8c83a2c 100644
+--- a/src/logind-seat.c
++++ b/src/logind-seat.c
+@@ -101,8 +101,10 @@ int seat_save(Seat *s) {
+ 
+         fprintf(f,
+                 "# This is private data. Do not parse.\n"
+-                "IS_VTCONSOLE=%i\n",
+-                seat_is_vtconsole(s));
++                "IS_VTCONSOLE=%i\n"
++                "CAN_MULTI_SESSION=%i\n",
++                seat_is_vtconsole(s),
++                seat_can_multi_session(s));
+ 
+         if (s->active) {
+                 assert(s->active->user);
+@@ -191,7 +193,7 @@ int seat_preallocate_vts(Seat *s) {
+         if (s->manager->n_autovts <= 0)
+                 return 0;
+ 
+-        if (!seat_is_vtconsole(s))
++        if (!seat_can_multi_session(s))
+                 return 0;
+ 
+         for (i = 1; i <= s->manager->n_autovts; i++) {
+@@ -266,7 +268,7 @@ int seat_active_vt_changed(Seat *s, int vtnr) {
+         assert(s);
+         assert(vtnr >= 1);
+ 
+-        if (!seat_is_vtconsole(s))
++        if (!seat_can_multi_session(s))
+                 return -EINVAL;
+ 
+         log_debug("VT changed to %i", vtnr);
+@@ -290,7 +292,7 @@ int seat_read_active_vt(Seat *s) {
+ 
+         assert(s);
+ 
+-        if (!seat_is_vtconsole(s))
++        if (!seat_can_multi_session(s))
+                 return 0;
+ 
+         lseek(s->manager->console_active_fd, SEEK_SET, 0);
+@@ -388,7 +390,7 @@ int seat_attach_session(Seat *s, Session *session) {
+         assert(session);
+         assert(!session->seat);
+ 
+-        if (!seat_is_vtconsole(s) && s->sessions)
++        if (!seat_can_multi_session(s) && s->sessions)
+                 return -EEXIST;
+ 
+         session->seat = s;
+@@ -396,7 +398,7 @@ int seat_attach_session(Seat *s, Session *session) {
+ 
+         seat_send_changed(s, "Sessions\0");
+ 
+-        if (!seat_is_vtconsole(s)) {
++        if (!seat_can_multi_session(s)) {
+                 assert(!s->active);
+                 seat_set_active(s, session);
+         }
+@@ -410,6 +412,18 @@ bool seat_is_vtconsole(Seat *s) {
+         return s->manager->vtconsole == s;
+ }
+ 
++bool seat_can_multi_session(Seat *s) {
++        assert(s);
++
++        if (!seat_is_vtconsole(s))
++                return false;
++
++        /* If we can't watch which VT is in the foreground, we don't
++         * support VT switching */
++
++        return s->manager->console_active_fd >= 0;
++}
++
+ int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
+         Session *session;
+         bool idle_hint = true;
+diff --git a/src/logind-seat.h b/src/logind-seat.h
+index 5bce143..3b2c7f0 100644
+--- a/src/logind-seat.h
++++ b/src/logind-seat.h
+@@ -62,6 +62,7 @@ int seat_preallocate_vts(Seat *s);
+ int seat_attach_session(Seat *s, Session *session);
+ 
+ bool seat_is_vtconsole(Seat *s);
++bool seat_can_multi_session(Seat *s);
+ int seat_get_idle_hint(Seat *s, dual_timestamp *t);
+ 
+ int seat_start(Seat *s);
+diff --git a/src/logind-session.c b/src/logind-session.c
+index 63ee758..58c70c3 100644
+--- a/src/logind-session.c
++++ b/src/logind-session.c
+@@ -185,7 +185,7 @@ int session_save(Session *s) {
+                         "SERVICE=%s\n",
+                         s->service);
+ 
+-        if (s->seat && seat_is_vtconsole(s->seat))
++        if (s->seat && seat_can_multi_session(s->seat))
+                 fprintf(f,
+                         "VTNR=%i\n",
+                         s->vtnr);
+@@ -270,7 +270,7 @@ int session_load(Session *s) {
+                         seat_attach_session(o, s);
+         }
+ 
+-        if (vtnr && s->seat && seat_is_vtconsole(s->seat)) {
++        if (vtnr && s->seat && seat_can_multi_session(s->seat)) {
+                 int v;
+ 
+                 k = safe_atoi(vtnr, &v);
+diff --git a/src/logind.c b/src/logind.c
+index 4633a5e..3a1903c 100644
+--- a/src/logind.c
++++ b/src/logind.c
+@@ -655,7 +655,6 @@ int manager_dispatch_seat_udev(Manager *m) {
+         return r;
+ }
+ 
+-
+ int manager_dispatch_vcsa_udev(Manager *m) {
+         struct udev_device *d;
+         int r = 0;
+@@ -906,6 +905,12 @@ static int manager_connect_console(Manager *m) {
+ 
+         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
+         if (m->console_active_fd < 0) {
++
++                /* On certain architectures (S390 and Xen), /dev/tty0
++                   does not exist, so don't fail if we can't open it.*/
++                if (errno == ENOENT)
++                        return 0;
++
+                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
+                 return -errno;
+         }
+diff --git a/src/sd-login.c b/src/sd-login.c
+index a0a56c4..38a2ff7 100644
+--- a/src/sd-login.c
++++ b/src/sd-login.c
+@@ -547,7 +547,7 @@ _public_ int sd_seat_can_multi_session(const char *seat) {
+                 return -ENOMEM;
+ 
+         r = parse_env_file(p, NEWLINE,
+-                           "IS_VTCONSOLE", &s,
++                           "CAN_MULTI_SESSION", &s,
+                            NULL);
+         free(p);
+ 
+-- 
+1.7.7.5
+
diff --git a/0107-logind-don-t-watch-vcsa-if-nobody-cares.patch b/0107-logind-don-t-watch-vcsa-if-nobody-cares.patch
new file mode 100644
index 0000000..b4cad32
--- /dev/null
+++ b/0107-logind-don-t-watch-vcsa-if-nobody-cares.patch
@@ -0,0 +1,46 @@
+From a00aab29d1970ef575ee395b016363cf48d39a7d Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 3 Jan 2012 21:50:02 +0100
+Subject: [PATCH 107/126] logind: don't watch vcsa if nobody cares (cherry
+ picked from commit
+ 976c088a0242a1a91b8f00899a4c2ae0e621a185)
+
+---
+ src/logind.c |   11 ++++++-----
+ 1 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/src/logind.c b/src/logind.c
+index 3a1903c..333d5f8 100644
+--- a/src/logind.c
++++ b/src/logind.c
+@@ -955,7 +955,8 @@ static int manager_connect_udev(Manager *m) {
+         ev.events = EPOLLIN;
+         ev.data.u32 = FD_SEAT_UDEV;
+ 
+-        if (m->n_autovts <= 0)
++        /* Don't bother watching VCSA devices, if nobody cares */
++        if (m->n_autovts <= 0 || m->console_active_fd < 0)
+                 return 0;
+ 
+         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
+@@ -1074,13 +1075,13 @@ int manager_startup(Manager *m) {
+         if (m->epoll_fd < 0)
+                 return -errno;
+ 
+-        /* Connect to udev */
+-        r = manager_connect_udev(m);
++        /* Connect to console */
++        r = manager_connect_console(m);
+         if (r < 0)
+                 return r;
+ 
+-        /* Connect to console */
+-        r = manager_connect_console(m);
++        /* Connect to udev */
++        r = manager_connect_udev(m);
+         if (r < 0)
+                 return r;
+ 
+-- 
+1.7.7.5
+
diff --git a/0108-man-fix-SEE-ALSO-in-hostname-5.patch b/0108-man-fix-SEE-ALSO-in-hostname-5.patch
new file mode 100644
index 0000000..153c390
--- /dev/null
+++ b/0108-man-fix-SEE-ALSO-in-hostname-5.patch
@@ -0,0 +1,27 @@
+From b07ccd2e4d5fd58f9ead2e597a69711d50f7d744 Mon Sep 17 00:00:00 2001
+From: Tom Gundersen <teg at jklm.no>
+Date: Sat, 31 Dec 2011 01:15:04 +0100
+Subject: [PATCH 108/126] man: fix SEE ALSO in hostname(5)
+
+Rather than referencing itself (hostname(5)), point to hostname(7).
+(cherry picked from commit 63c52e45de6b6071d64cc4d3bb0d47357a1f5ead)
+---
+ man/hostname.xml |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/man/hostname.xml b/man/hostname.xml
+index b8b05c8..1acda1a 100644
+--- a/man/hostname.xml
++++ b/man/hostname.xml
+@@ -86,7 +86,7 @@
+                           <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                           <citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+                           <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+-                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
++                          <citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+                           <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+                           <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+                   </para>
+-- 
+1.7.7.5
+
diff --git a/0109-logind-send-out-Lock-signal-when-locking.patch b/0109-logind-send-out-Lock-signal-when-locking.patch
new file mode 100644
index 0000000..6929641
--- /dev/null
+++ b/0109-logind-send-out-Lock-signal-when-locking.patch
@@ -0,0 +1,30 @@
+From 02ed8bfecd03c02b39c0d9d04c846e7deb905381 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 3 Jan 2012 23:08:15 +0100
+Subject: [PATCH 109/126] logind: send out Lock signal when locking (cherry
+ picked from commit
+ bda061759c3baef4383a2ec0bf1b538905cb30b0)
+
+Conflicts:
+
+	TODO
+---
+ src/logind-session-dbus.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/logind-session-dbus.c b/src/logind-session-dbus.c
+index dc0ef5b..cbd6d7f 100644
+--- a/src/logind-session-dbus.c
++++ b/src/logind-session-dbus.c
+@@ -288,7 +288,7 @@ static DBusHandlerResult session_message_dispatch(
+         } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") ||
+                    dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) {
+ 
+-                if (session_send_signal(s, streq(dbus_message_get_member(message), "Lock")) < 0)
++                if (session_send_lock(s, streq(dbus_message_get_member(message), "Lock")) < 0)
+                         goto oom;
+ 
+                 reply = dbus_message_new_method_return(message);
+-- 
+1.7.7.5
+
diff --git a/0110-logind-add-needed-include-for-sd_notify.patch b/0110-logind-add-needed-include-for-sd_notify.patch
new file mode 100644
index 0000000..9503b23
--- /dev/null
+++ b/0110-logind-add-needed-include-for-sd_notify.patch
@@ -0,0 +1,26 @@
+From 427275bed23af1079fc9140459fea61e5d06e7fc Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay.sievers at vrfy.org>
+Date: Thu, 5 Jan 2012 00:52:56 +0100
+Subject: [PATCH 110/126] logind: add needed include for sd_notify() (cherry
+ picked from commit
+ 4726299357861c0ced3a53a4214e1c3809968e5e)
+
+---
+ src/logind.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/src/logind.c b/src/logind.c
+index 333d5f8..5cff2db 100644
+--- a/src/logind.c
++++ b/src/logind.c
+@@ -30,6 +30,7 @@
+ #include <linux/vt.h>
+ 
+ #include "logind.h"
++#include "sd-daemon.h"
+ #include "dbus-common.h"
+ #include "dbus-loop.h"
+ #include "strv.h"
+-- 
+1.7.7.5
+
diff --git a/0111-fix-compilation-error-with-PathSpec-redefined.patch b/0111-fix-compilation-error-with-PathSpec-redefined.patch
new file mode 100644
index 0000000..d4070b2
--- /dev/null
+++ b/0111-fix-compilation-error-with-PathSpec-redefined.patch
@@ -0,0 +1,35 @@
+From 6cddfe340771dd1c120e13379646e0cc9d012b11 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Thu, 5 Jan 2012 00:56:21 +0100
+Subject: [PATCH 111/126] fix compilation error with 'PathSpec redefined'
+ (cherry picked from commit
+ 9cf3ab0e16af7db666ca3cf7d73dc4d616deb8fa)
+
+---
+ src/service.h |    3 +--
+ 1 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/src/service.h b/src/service.h
+index 15d58cc..2102826 100644
+--- a/src/service.h
++++ b/src/service.h
+@@ -25,6 +25,7 @@
+ typedef struct Service Service;
+ 
+ #include "unit.h"
++#include "path.h"
+ #include "ratelimit.h"
+ 
+ typedef enum ServiceState {
+@@ -86,8 +87,6 @@ typedef enum NotifyAccess {
+         _NOTIFY_ACCESS_INVALID = -1
+ } NotifyAccess;
+ 
+-typedef struct PathSpec PathSpec;
+-
+ struct Service {
+         Meta meta;
+ 
+-- 
+1.7.7.5
+
diff --git a/0112-util-when-printing-status-updates-during-boot-take-t.patch b/0112-util-when-printing-status-updates-during-boot-take-t.patch
new file mode 100644
index 0000000..9a095ed
--- /dev/null
+++ b/0112-util-when-printing-status-updates-during-boot-take-t.patch
@@ -0,0 +1,219 @@
+From 36318b0838442ef35fff111910d5657c20f1a71c Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 5 Jan 2012 03:24:39 +0100
+Subject: [PATCH 112/126] util: when printing status updates during boot, take
+ terminal width into account (cherry picked from
+ commit 81beb7508e72b29ae7cec60b50231cbe0c1d582e)
+
+Conflicts:
+
+	src/util.c
+	src/util.h
+---
+ src/unit.c |   18 +-----------
+ src/util.c |   87 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
+ src/util.h |    7 +++--
+ 3 files changed, 75 insertions(+), 37 deletions(-)
+
+diff --git a/src/unit.c b/src/unit.c
+index 03c90f5..dea8f4a 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -2441,9 +2441,6 @@ int unit_coldplug(Unit *u) {
+ 
+ void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
+         va_list ap;
+-        char *s, *e;
+-        int err;
+-        const unsigned emax = status ? 80 - (sizeof("[  OK  ]")-1) : 80;
+ 
+         assert(u);
+         assert(format);
+@@ -2458,21 +2455,8 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
+                 return;
+ 
+         va_start(ap, format);
+-        err = vasprintf(&s, format, ap);
++        status_vprintf(status, format, ap);
+         va_end(ap);
+-        if (err < 0)
+-                return;
+-
+-        e = ellipsize(s, emax, 100);
+-        free(s);
+-        if (!e)
+-                return;
+-
+-        if (status)
+-                status_printf("%s%*s[%s]\n", e, emax - strlen(e), "", status);
+-        else
+-                status_printf("%s\n", e);
+-        free(e);
+ }
+ 
+ bool unit_need_daemon_reload(Unit *u) {
+diff --git a/src/util.c b/src/util.c
+index da71e4d..9ed7d13 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -3531,9 +3531,12 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+         }
+ }
+ 
+-void status_vprintf(const char *format, va_list ap) {
+-        char *s = NULL;
+-        int fd = -1;
++void status_vprintf(const char *status, const char *format, va_list ap) {
++        char *s = NULL, *spaces = NULL, *e;
++        int fd = -1, c;
++        size_t emax, sl, left;
++        struct iovec iovec[5];
++        int n = 0;
+ 
+         assert(format);
+ 
+@@ -3543,25 +3546,65 @@ void status_vprintf(const char *format, va_list ap) {
+         if (vasprintf(&s, format, ap) < 0)
+                 goto finish;
+ 
+-        if ((fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0)
++        fd = open_terminal("/dev/tty", O_WRONLY|O_NOCTTY|O_CLOEXEC);
++        if (fd < 0)
+                 goto finish;
+ 
+-        write(fd, s, strlen(s));
++        c = fd_columns(fd);
++        if (c <= 0)
++                c = 80;
++
++        if (status) {
++                sl = 2 + 6 + 1; /* " [" status "]" */
++                emax = (size_t) c > sl ? c - sl - 1 : 0;
++        } else
++                emax = c - 1;
++
++        e = ellipsize(s, emax, 75);
++        if (e) {
++                free(s);
++                s = e;
++        }
++
++        zero(iovec);
++        IOVEC_SET_STRING(iovec[n++], s);
++
++        sl = strlen(s);
++        left = emax > sl ? emax - sl : 0;
++        if (left > 0) {
++                spaces = malloc(left);
++                if (spaces) {
++                        memset(spaces, ' ', left);
++                        iovec[n].iov_base = spaces;
++                        iovec[n].iov_len = left;
++                        n++;
++                }
++        }
++
++        if (status) {
++                IOVEC_SET_STRING(iovec[n++], " [");
++                IOVEC_SET_STRING(iovec[n++], status);
++                IOVEC_SET_STRING(iovec[n++], "]\n");
++        } else
++                IOVEC_SET_STRING(iovec[n++], "\n");
++
++        writev(fd, iovec, n);
+ 
+ finish:
+         free(s);
++        free(spaces);
+ 
+         if (fd >= 0)
+                 close_nointr_nofail(fd);
+ }
+ 
+-void status_printf(const char *format, ...) {
++void status_printf(const char *status, const char *format, ...) {
+         va_list ap;
+ 
+         assert(format);
+ 
+         va_start(ap, format);
+-        status_vprintf(format, ap);
++        status_vprintf(status, format, ap);
+         va_end(ap);
+ }
+ 
+@@ -3718,7 +3761,8 @@ void status_welcome(void) {
+         if (!ansi_color && !const_color)
+                 const_color = "1";
+ 
+-        status_printf("\nWelcome to \x1B[%sm%s\x1B[0m!\n\n",
++        status_printf(NULL,
++                      "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
+                       const_color ? const_color : ansi_color,
+                       const_pretty ? const_pretty : pretty_name);
+ 
+@@ -3860,23 +3904,32 @@ char **replace_env_argv(char **argv, char **env) {
+         return r;
+ }
+ 
+-int columns(void) {
++int fd_columns(int fd) {
++        struct winsize ws;
++        zero(ws);
++
++        if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
++                return -errno;
++
++        if (ws.ws_col <= 0)
++                return -EIO;
++
++        return ws.ws_col;
++}
++
++unsigned columns(void) {
+         static __thread int parsed_columns = 0;
+         const char *e;
+ 
+         if (_likely_(parsed_columns > 0))
+                 return parsed_columns;
+ 
+-        if ((e = getenv("COLUMNS")))
++        e = getenv("COLUMNS");
++        if (e)
+                 parsed_columns = atoi(e);
+ 
+-        if (parsed_columns <= 0) {
+-                struct winsize ws;
+-                zero(ws);
+-
+-                if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) >= 0)
+-                        parsed_columns = ws.ws_col;
+-        }
++        if (parsed_columns <= 0)
++                parsed_columns = fd_columns(STDOUT_FILENO);
+ 
+         if (parsed_columns <= 0)
+                 parsed_columns = 80;
+diff --git a/src/util.h b/src/util.h
+index a71a297..e4a554a 100644
+--- a/src/util.h
++++ b/src/util.h
+@@ -370,11 +370,12 @@ int pipe_eof(int fd);
+ 
+ cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+ 
+-void status_vprintf(const char *format, va_list ap);
+-void status_printf(const char *format, ...);
++void status_vprintf(const char *status, const char *format, va_list ap);
++void status_printf(const char *status, const char *format, ...);
+ void status_welcome(void);
+ 
+-int columns(void);
++int fd_columns(int fd);
++unsigned columns(void);
+ 
+ int running_in_chroot(void);
+ 
+-- 
+1.7.7.5
+
diff --git a/0113-log-minor-optimization.patch b/0113-log-minor-optimization.patch
new file mode 100644
index 0000000..8b2d3d0
--- /dev/null
+++ b/0113-log-minor-optimization.patch
@@ -0,0 +1,48 @@
+From 3e1a7de638aec192ae7ac25baea7e8c343ab414b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 5 Jan 2012 03:25:10 +0100
+Subject: [PATCH 113/126] log: minor optimization (cherry picked from commit
+ 674f8283698517047a7c0e78cff1e18932a97b05)
+
+---
+ src/log.c |   13 ++++++++-----
+ 1 files changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/src/log.c b/src/log.c
+index 4f57821..3dfe654 100644
+--- a/src/log.c
++++ b/src/log.c
+@@ -95,7 +95,8 @@ static int log_open_kmsg(void) {
+         if (kmsg_fd >= 0)
+                 return 0;
+ 
+-        if ((kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) {
++        kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
++        if (kmsg_fd < 0) {
+                 log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno));
+                 return -errno;
+         }
+@@ -265,14 +266,16 @@ static int write_to_console(
+         if (console_fd < 0)
+                 return 0;
+ 
+-        snprintf(location, sizeof(location), "(%s:%u) ", file, line);
+-        char_array_0(location);
+-
+         highlight = LOG_PRI(level) <= LOG_ERR && show_color;
+ 
+         zero(iovec);
+-        if (show_location)
++
++        if (show_location) {
++                snprintf(location, sizeof(location), "(%s:%u) ", file, line);
++                char_array_0(location);
+                 IOVEC_SET_STRING(iovec[n++], location);
++        }
++
+         if (highlight)
+                 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_ON);
+         IOVEC_SET_STRING(iovec[n++], buffer);
+-- 
+1.7.7.5
+
diff --git a/0114-util-never-ellipsize-welcome-message.patch b/0114-util-never-ellipsize-welcome-message.patch
new file mode 100644
index 0000000..358f19f
--- /dev/null
+++ b/0114-util-never-ellipsize-welcome-message.patch
@@ -0,0 +1,146 @@
+From a8bd50e0b09cb537bb3019845560e645899960ed Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 5 Jan 2012 15:35:16 +0100
+Subject: [PATCH 114/126] util: never ellipsize welcome message (cherry picked
+ from commit
+ 67e5cc4f3ed41feaed399cfed77c6fbb41e14a8c)
+
+---
+ src/unit.c |    2 +-
+ src/util.c |   55 ++++++++++++++++++++++++++++++-------------------------
+ src/util.h |    4 ++--
+ 3 files changed, 33 insertions(+), 28 deletions(-)
+
+diff --git a/src/unit.c b/src/unit.c
+index dea8f4a..3191071 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -2455,7 +2455,7 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
+                 return;
+ 
+         va_start(ap, format);
+-        status_vprintf(status, format, ap);
++        status_vprintf(status, true, format, ap);
+         va_end(ap);
+ }
+ 
+diff --git a/src/util.c b/src/util.c
+index 9ed7d13..fce0a0c 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -3531,7 +3531,7 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
+         }
+ }
+ 
+-void status_vprintf(const char *status, const char *format, va_list ap) {
++void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
+         char *s = NULL, *spaces = NULL, *e;
+         int fd = -1, c;
+         size_t emax, sl, left;
+@@ -3546,38 +3546,42 @@ void status_vprintf(const char *status, const char *format, va_list ap) {
+         if (vasprintf(&s, format, ap) < 0)
+                 goto finish;
+ 
+-        fd = open_terminal("/dev/tty", O_WRONLY|O_NOCTTY|O_CLOEXEC);
++        fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+         if (fd < 0)
+                 goto finish;
+ 
+-        c = fd_columns(fd);
+-        if (c <= 0)
+-                c = 80;
++        if (ellipse) {
++                c = fd_columns(fd);
++                if (c <= 0)
++                        c = 80;
+ 
+-        if (status) {
+-                sl = 2 + 6 + 1; /* " [" status "]" */
+-                emax = (size_t) c > sl ? c - sl - 1 : 0;
+-        } else
+-                emax = c - 1;
++                if (status) {
++                        sl = 2 + 6 + 1; /* " [" status "]" */
++                        emax = (size_t) c > sl ? c - sl - 1 : 0;
++                } else
++                        emax = c - 1;
+ 
+-        e = ellipsize(s, emax, 75);
+-        if (e) {
+-                free(s);
+-                s = e;
++                e = ellipsize(s, emax, 75);
++                if (e) {
++                        free(s);
++                        s = e;
++                }
+         }
+ 
+         zero(iovec);
+         IOVEC_SET_STRING(iovec[n++], s);
+ 
+-        sl = strlen(s);
+-        left = emax > sl ? emax - sl : 0;
+-        if (left > 0) {
+-                spaces = malloc(left);
+-                if (spaces) {
+-                        memset(spaces, ' ', left);
+-                        iovec[n].iov_base = spaces;
+-                        iovec[n].iov_len = left;
+-                        n++;
++        if (ellipse) {
++                sl = strlen(s);
++                left = emax > sl ? emax - sl : 0;
++                if (left > 0) {
++                        spaces = malloc(left);
++                        if (spaces) {
++                                memset(spaces, ' ', left);
++                                iovec[n].iov_base = spaces;
++                                iovec[n].iov_len = left;
++                                n++;
++                        }
+                 }
+         }
+ 
+@@ -3598,13 +3602,13 @@ finish:
+                 close_nointr_nofail(fd);
+ }
+ 
+-void status_printf(const char *status, const char *format, ...) {
++void status_printf(const char *status, bool ellipse, const char *format, ...) {
+         va_list ap;
+ 
+         assert(format);
+ 
+         va_start(ap, format);
+-        status_vprintf(status, format, ap);
++        status_vprintf(status, ellipse, format, ap);
+         va_end(ap);
+ }
+ 
+@@ -3762,6 +3766,7 @@ void status_welcome(void) {
+                 const_color = "1";
+ 
+         status_printf(NULL,
++                      false,
+                       "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
+                       const_color ? const_color : ansi_color,
+                       const_pretty ? const_pretty : pretty_name);
+diff --git a/src/util.h b/src/util.h
+index e4a554a..40a2a39 100644
+--- a/src/util.h
++++ b/src/util.h
+@@ -370,8 +370,8 @@ int pipe_eof(int fd);
+ 
+ cpu_set_t* cpu_set_malloc(unsigned *ncpus);
+ 
+-void status_vprintf(const char *status, const char *format, va_list ap);
+-void status_printf(const char *status, const char *format, ...);
++void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap);
++void status_printf(const char *status, bool ellipse, const char *format, ...);
+ void status_welcome(void);
+ 
+ int fd_columns(int fd);
+-- 
+1.7.7.5
+
diff --git a/0115-headers-fix-git-URLs-for-source-files.patch b/0115-headers-fix-git-URLs-for-source-files.patch
new file mode 100644
index 0000000..51ceb12
--- /dev/null
+++ b/0115-headers-fix-git-URLs-for-source-files.patch
@@ -0,0 +1,160 @@
+From e304704addaa0ab824060b2c9612ffeee64cb5bf Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 5 Jan 2012 18:21:26 +0100
+Subject: [PATCH 115/126] headers: fix git URLs for source files (cherry
+ picked from commit
+ 8ab49c12dcab02d9d83e63a93676d4fc8f709516)
+
+---
+ man/sd-daemon.xml     |    4 ++--
+ man/sd-readahead.xml  |    4 ++--
+ man/sd_booted.xml     |    4 ++--
+ man/sd_is_fifo.xml    |    4 ++--
+ man/sd_listen_fds.xml |    4 ++--
+ man/sd_notify.xml     |    4 ++--
+ man/sd_readahead.xml  |    4 ++--
+ src/sd-daemon.h       |    2 +-
+ src/sd-readahead.h    |    4 ++--
+ 9 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml
+index 383d77f..3f3a723 100644
+--- a/man/sd-daemon.xml
++++ b/man/sd-daemon.xml
+@@ -130,8 +130,8 @@
+                 <para>In addition, for details about the algorithms
+                 check the liberally licensed reference implementation
+                 sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c"/>
+-                resp. <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.h"/></para>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c"/>
++                resp. <ulink url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/></para>
+ 
+                 <para>These APIs are implemented in the reference
+                 implementation's <filename>sd-daemon.c</filename> and
+diff --git a/man/sd-readahead.xml b/man/sd-readahead.xml
+index 819691e..7c21656 100644
+--- a/man/sd-readahead.xml
++++ b/man/sd-readahead.xml
+@@ -86,8 +86,8 @@
+                 <para>In addition, for details about the algorithms
+                 check the liberally licensed reference implementation
+                 sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.c"/>
+-                resp. <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/></para>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/readahead/sd-readahead.c"/>
++                resp. <ulink url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-readahead.h"/></para>
+ 
+                 <para>These APIs are implemented in the reference
+                 implementation's drop-in
+diff --git a/man/sd_booted.xml b/man/sd_booted.xml
+index c9f538a..c876874 100644
+--- a/man/sd_booted.xml
++++ b/man/sd_booted.xml
+@@ -93,9 +93,9 @@
+ 
+                 <para>For details about the algorithm check the
+                 liberally licensed reference implementation sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c"/>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c"/>
+                 resp. <ulink
+-                url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.h"/></para>
++                url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/></para>
+ 
+                 <para><function>sd_booted()</function> is implemented
+                 in the reference implementation's
+diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml
+index 82b89bb..6055893 100644
+--- a/man/sd_is_fifo.xml
++++ b/man/sd_is_fifo.xml
+@@ -180,9 +180,9 @@
+ 
+                 <para>For details about the algorithms check the
+                 liberally licensed reference implementation sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c"/>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c"/>
+                 resp. <ulink
+-                url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.h"/></para>
++                url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/></para>
+ 
+                 <para><function>sd_is_fifo()</function> and the
+                 related functions are implemented in the reference
+diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml
+index 68a45cd..09d0503 100644
+--- a/man/sd_listen_fds.xml
++++ b/man/sd_listen_fds.xml
+@@ -140,9 +140,9 @@
+ 
+                 <para>For details about the algorithm check the
+                 liberally licensed reference implementation sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c"/>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c"/>
+                 resp. <ulink
+-                url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.h"/></para>
++                url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/></para>
+ 
+                 <para><function>sd_listen_fds()</function> is
+                 implemented in the reference implementation's
+diff --git a/man/sd_notify.xml b/man/sd_notify.xml
+index c3791ce..0209146 100644
+--- a/man/sd_notify.xml
++++ b/man/sd_notify.xml
+@@ -208,9 +208,9 @@
+ 
+                 <para>For details about the algorithms check the
+                 liberally licensed reference implementation sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c"/>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c"/>
+                 resp. <ulink
+-                url="http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.h"/></para>
++                url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h"/></para>
+ 
+                 <para><function>sd_notify()</function> and
+                 <function>sd_notifyf()</function> are implemented in
+diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml
+index 25fe5b2..4b8c957 100644
+--- a/man/sd_readahead.xml
++++ b/man/sd_readahead.xml
+@@ -129,9 +129,9 @@
+ 
+                 <para>For details about the algorithm check the
+                 liberally licensed reference implementation sources:
+-                <ulink url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.c"/>
++                <ulink url="http://cgit.freedesktop.org/systemd/plain/src/readahead/sd-readahead.c"/>
+                 resp. <ulink
+-                url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/></para>
++                url="http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-readahead.h"/></para>
+ 
+                 <para><function>sd_readahead()</function> is
+                 implemented in the reference implementation's drop-in
+diff --git a/src/sd-daemon.h b/src/sd-daemon.h
+index 46dc7fd..eb2a606 100644
+--- a/src/sd-daemon.h
++++ b/src/sd-daemon.h
+@@ -58,7 +58,7 @@ extern "C" {
+ 
+   You may find an up-to-date version of these source files online:
+ 
+-  http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
++  http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-daemon.h
+   http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
+ 
+   This should compile on non-Linux systems, too, but with the
+diff --git a/src/sd-readahead.h b/src/sd-readahead.h
+index ee7e306..afe6768 100644
+--- a/src/sd-readahead.h
++++ b/src/sd-readahead.h
+@@ -47,8 +47,8 @@ extern "C" {
+ 
+   You may find an up-to-date version of these source files online:
+ 
+-  http://cgit.freedesktop.org/systemd/plain/src/sd-readahead.h
+-  http://cgit.freedesktop.org/systemd/plain/src/sd-readahead.c
++  http://cgit.freedesktop.org/systemd/plain/src/systemd/sd-readahead.h
++  http://cgit.freedesktop.org/systemd/plain/src/readahead/sd-readahead.c
+ 
+   This should compile on non-Linux systems, too, but all functions
+   will become NOPs.
+-- 
+1.7.7.5
+
diff --git a/0116-README-correct-license-claims.patch b/0116-README-correct-license-claims.patch
new file mode 100644
index 0000000..64ef3c5
--- /dev/null
+++ b/0116-README-correct-license-claims.patch
@@ -0,0 +1,27 @@
+From 7ac8afd6e39c4f485d3b066f61d755d0f678f4f8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 5 Jan 2012 18:24:18 +0100
+Subject: [PATCH 116/126] README: correct license claims (cherry picked from
+ commit 0df4f9d669bec2d34777735f8cdd40797b1fd753)
+
+---
+ README |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/README b/README
+index 15afb2c..17b3f49 100644
+--- a/README
++++ b/README
+@@ -27,7 +27,8 @@ AUTHOR:
+         Lennart Poettering with major support from Kay Sievers
+ 
+ LICENSE:
+-        GPLv2+ for all code, except sd-daemon.[ch] which is MIT
++        GPLv2+ for all code, except sd-daemon.[ch] and
++        sd-readahead.[ch] which are MIT
+ 
+ REQUIREMENTS:
+         Linux kernel >= 2.6.39 (with devtmpfs, cgroups; optional but strongly recommended: autofs4, ipv6)
+-- 
+1.7.7.5
+
diff --git a/0117-util-fix-switching-to-console-unicode-mode.patch b/0117-util-fix-switching-to-console-unicode-mode.patch
new file mode 100644
index 0000000..b6fe22a
--- /dev/null
+++ b/0117-util-fix-switching-to-console-unicode-mode.patch
@@ -0,0 +1,36 @@
+From 6fca919fd967a6a16405f96872228c93eb8217c3 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 6 Jan 2012 01:28:30 +0100
+Subject: [PATCH 117/126] util: fix switching to console unicode mode
+
+The KDSKBMODE ioctl wants a value directly, not its address.
+(cherry picked from commit df465b3f4419b6ba2e12bf9a5f7d7bde5a0c3531)
+---
+ src/util.c |    4 +---
+ 1 files changed, 1 insertions(+), 3 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index fce0a0c..a9d0821 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -2424,7 +2424,6 @@ int ask(char *ret, const char *replies, const char *text, ...) {
+ int reset_terminal_fd(int fd) {
+         struct termios termios;
+         int r = 0;
+-        long arg;
+ 
+         /* Set terminal to some sane defaults */
+ 
+@@ -2438,8 +2437,7 @@ int reset_terminal_fd(int fd) {
+         ioctl(fd, TIOCNXCL);
+ 
+         /* Enable console unicode mode */
+-        arg = K_UNICODE;
+-        ioctl(fd, KDSKBMODE, &arg);
++        ioctl(fd, KDSKBMODE, K_UNICODE);
+ 
+         if (tcgetattr(fd, &termios) < 0) {
+                 r = -errno;
+-- 
+1.7.7.5
+
diff --git a/0118-util-switch-the-console-to-text-mode-on-reset.patch b/0118-util-switch-the-console-to-text-mode-on-reset.patch
new file mode 100644
index 0000000..aea727d
--- /dev/null
+++ b/0118-util-switch-the-console-to-text-mode-on-reset.patch
@@ -0,0 +1,30 @@
+From 21ee8544227b293260e864c2a6bcf47a1e0d7a4c Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 6 Jan 2012 01:32:34 +0100
+Subject: [PATCH 118/126] util: switch the console to text mode on reset
+
+In case we're taking over the console after a killed X server.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=771563
+(cherry picked from commit 5c0100a53772eb7f4b11db7b071fc63e82e5a1a7)
+---
+ src/util.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index a9d0821..5bac05f 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -2436,6 +2436,9 @@ int reset_terminal_fd(int fd) {
+         /* Disable exclusive mode, just in case */
+         ioctl(fd, TIOCNXCL);
+ 
++        /* Switch to text mode */
++        ioctl(fd, KDSETMODE, KD_TEXT);
++
+         /* Enable console unicode mode */
+         ioctl(fd, KDSKBMODE, K_UNICODE);
+ 
+-- 
+1.7.7.5
+
diff --git a/0119-service-add-dependencies-on-configured-sockets.patch b/0119-service-add-dependencies-on-configured-sockets.patch
new file mode 100644
index 0000000..dd344aa
--- /dev/null
+++ b/0119-service-add-dependencies-on-configured-sockets.patch
@@ -0,0 +1,54 @@
+From 423d96b0e5e351ae6489370ebc4af1bd18008b5d Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 6 Jan 2012 19:23:03 +0100
+Subject: [PATCH 119/126] service: add dependencies on configured sockets
+ (cherry picked from commit
+ 73aa0c00df8b101bad4c3a038148a633df88610c)
+
+---
+ src/service.c |   22 ++++++++++++++++++++++
+ 1 files changed, 22 insertions(+), 0 deletions(-)
+
+diff --git a/src/service.c b/src/service.c
+index d229301..65a45e1 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -1100,6 +1100,22 @@ static int service_add_default_dependencies(Service *s) {
+         return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+ }
+ 
++static int service_add_socket_dependencies(Service *s) {
++        Iterator i;
++        Unit *u;
++        int r;
++
++        /* Make sure we pull in all explicitly configured sockets */
++
++        SET_FOREACH(u, s->configured_sockets, i) {
++                r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, u, true);
++                if (r < 0)
++                        return r;
++        }
++
++        return 0;
++}
++
+ static void service_fix_output(Service *s) {
+         assert(s);
+ 
+@@ -1173,6 +1189,12 @@ static int service_load(Unit *u) {
+                         if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0)
+                                 return r;
+ 
++                if (!set_isempty(s->configured_sockets)) {
++                        r = service_add_socket_dependencies(s);
++                        if (r < 0)
++                                return r;
++                }
++
+                 if (s->meta.default_dependencies)
+                         if ((r = service_add_default_dependencies(s)) < 0)
+                                 return r;
+-- 
+1.7.7.5
+
diff --git a/0120-unit-properly-update-references-to-units-which-are-m.patch b/0120-unit-properly-update-references-to-units-which-are-m.patch
new file mode 100644
index 0000000..496a2f4
--- /dev/null
+++ b/0120-unit-properly-update-references-to-units-which-are-m.patch
@@ -0,0 +1,1515 @@
+From a1f378075e7ff6f07031ab1d2f653110f7d0e1f2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 6 Jan 2012 23:08:54 +0100
+Subject: [PATCH 120/126] unit: properly update references to units which are
+ merged
+
+When we merge units that some kind of object points to, those pointers
+might become invalidated, and needs to be updated. Introduce a UnitRef
+struct which links up all the unit references, to ensure corrected
+references.
+
+At the same time, drop configured_sockets in the Service object, and
+replace it by proper UNIT_TRIGGERS resp. UNIT_TRIGGERED_BY dependencies,
+which allow us to simplify a lot of code.
+(cherry picked from commit 57020a3abff20f176e9f0cbb982d7977119d6f08)
+---
+ src/automount.c     |   21 +++++---
+ src/automount.h     |    3 +-
+ src/dbus-path.c     |    2 +-
+ src/dbus-service.c  |    2 -
+ src/dbus-timer.c    |    2 +-
+ src/dbus-unit.h     |    2 +
+ src/load-fragment.c |   58 ++++++++++----------
+ src/mount.c         |   20 +++----
+ src/path.c          |   93 +++++++++++++++-----------------
+ src/path.h          |   14 +++---
+ src/service.c       |  147 ++++++++++-----------------------------------------
+ src/service.h       |    6 ++-
+ src/socket.c        |   88 +++++++++++++++----------------
+ src/socket.h        |    9 ++--
+ src/timer.c         |   57 ++++++++-----------
+ src/timer.h         |    2 +-
+ src/unit.c          |   39 ++++++++++++-
+ src/unit.h          |   22 ++++++++
+ 18 files changed, 268 insertions(+), 319 deletions(-)
+
+diff --git a/src/automount.c b/src/automount.c
+index 29b807d..85558e5 100644
+--- a/src/automount.c
++++ b/src/automount.c
+@@ -105,7 +105,7 @@ static void automount_done(Unit *u) {
+         assert(a);
+ 
+         unmount_autofs(a);
+-        a->mount = NULL;
++        unit_ref_unset(&a->mount);
+ 
+         free(a->where);
+         a->where = NULL;
+@@ -205,6 +205,7 @@ static int automount_load(Unit *u) {
+                 return r;
+ 
+         if (u->meta.load_state == UNIT_LOADED) {
++                Unit *x;
+ 
+                 if (!a->where)
+                         if (!(a->where = unit_name_to_path(u->meta.id)))
+@@ -215,10 +216,14 @@ static int automount_load(Unit *u) {
+                 if ((r = automount_add_mount_links(a)) < 0)
+                         return r;
+ 
+-                if ((r = unit_load_related_unit(u, ".mount", (Unit**) &a->mount)) < 0)
++                r = unit_load_related_unit(u, ".mount", &x);
++                if (r < 0)
+                         return r;
+ 
+-                if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(a->mount), true)) < 0)
++                unit_ref_set(&a->mount, x);
++
++                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
++                if (r < 0)
+                         return r;
+ 
+                 if (a->meta.default_dependencies)
+@@ -569,7 +574,7 @@ static void automount_enter_runnning(Automount *a) {
+         DBusError error;
+ 
+         assert(a);
+-        assert(a->mount);
++        assert(UNIT_DEREF(a->mount));
+ 
+         dbus_error_init(&error);
+ 
+@@ -591,7 +596,7 @@ static void automount_enter_runnning(Automount *a) {
+ 
+         if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
+                 log_info("%s's automount point already active?", a->meta.id);
+-        else if ((r = manager_add_job(a->meta.manager, JOB_START, UNIT(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
++        else if ((r = manager_add_job(a->meta.manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
+                 log_warning("%s failed to queue mount startup job: %s", a->meta.id, bus_error(&error, r));
+                 goto fail;
+         }
+@@ -616,7 +621,7 @@ static int automount_start(Unit *u) {
+                 return -EEXIST;
+         }
+ 
+-        if (a->mount->meta.load_state != UNIT_LOADED)
++        if (UNIT_DEREF(a->mount)->meta.load_state != UNIT_LOADED)
+                 return -ENOENT;
+ 
+         a->failure = false;
+@@ -738,10 +743,10 @@ static bool automount_check_gc(Unit *u) {
+ 
+         assert(a);
+ 
+-        if (!a->mount)
++        if (!UNIT_DEREF(a->mount))
+                 return false;
+ 
+-        return UNIT_VTABLE(UNIT(a->mount))->check_gc(UNIT(a->mount));
++        return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
+ }
+ 
+ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+diff --git a/src/automount.h b/src/automount.h
+index 1a6cc98..c6326ed 100644
+--- a/src/automount.h
++++ b/src/automount.h
+@@ -42,14 +42,13 @@ struct Automount {
+ 
+         char *where;
+ 
+-        Mount *mount;
++        UnitRef mount;
+ 
+         int pipe_fd;
+         mode_t directory_mode;
+         Watch pipe_watch;
+         dev_t dev_id;
+ 
+-
+         Set *tokens;
+ 
+         bool failure:1;
+diff --git a/src/dbus-path.c b/src/dbus-path.c
+index 1523879..f67b5a2 100644
+--- a/src/dbus-path.c
++++ b/src/dbus-path.c
+@@ -86,7 +86,7 @@ static int bus_path_append_unit(DBusMessageIter *i, const char *property, void *
+         assert(property);
+         assert(u);
+ 
+-        t = u->path.unit ? u->path.unit->meta.id : "";
++        t = UNIT_DEREF(u->path.unit) ? UNIT_DEREF(u->path.unit)->meta.id : "";
+ 
+         return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM;
+ }
+diff --git a/src/dbus-service.c b/src/dbus-service.c
+index 3486623..373e3f5 100644
+--- a/src/dbus-service.c
++++ b/src/dbus-service.c
+@@ -59,7 +59,6 @@
+         "  <property name=\"BusName\" type=\"s\" access=\"read\"/>\n"   \
+         "  <property name=\"StatusText\" type=\"s\" access=\"read\"/>\n" \
+         "  <property name=\"FsckPassNo\" type=\"i\" access=\"read\"/>\n" \
+-        "  <property name=\"Sockets\" type=\"as\" access=\"read\"/>\n" \
+         BUS_SERVICE_SYSV_INTERFACE_FRAGMENT                              \
+        " </interface>\n"
+ 
+@@ -120,7 +119,6 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
+                 { "org.freedesktop.systemd1.Service", "ControlPID",             bus_property_append_pid,    "u", &u->service.control_pid               },
+                 { "org.freedesktop.systemd1.Service", "BusName",                bus_property_append_string, "s", u->service.bus_name                   },
+                 { "org.freedesktop.systemd1.Service", "StatusText",             bus_property_append_string, "s", u->service.status_text                },
+-                { "org.freedesktop.systemd1.Service", "Sockets",                bus_unit_append_dependencies, "as", u->service.configured_sockets         },
+ #ifdef HAVE_SYSV_COMPAT
+                 { "org.freedesktop.systemd1.Service", "SysVRunLevels",          bus_property_append_string, "s", u->service.sysv_runlevels             },
+                 { "org.freedesktop.systemd1.Service", "SysVStartPriority",      bus_property_append_int,    "i", &u->service.sysv_start_priority       },
+diff --git a/src/dbus-timer.c b/src/dbus-timer.c
+index abcbe6f..07d425e 100644
+--- a/src/dbus-timer.c
++++ b/src/dbus-timer.c
+@@ -107,7 +107,7 @@ static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void
+         assert(property);
+         assert(u);
+ 
+-        t = u->timer.unit ? u->timer.unit->meta.id : "";
++        t = UNIT_DEREF(u->timer.unit) ? UNIT_DEREF(u->timer.unit)->meta.id : "";
+ 
+         return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM;
+ }
+diff --git a/src/dbus-unit.h b/src/dbus-unit.h
+index 9fed6d7..20d5506 100644
+--- a/src/dbus-unit.h
++++ b/src/dbus-unit.h
+@@ -141,6 +141,8 @@
+         { "org.freedesktop.systemd1.Unit", "Before",               bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_BEFORE] }, \
+         { "org.freedesktop.systemd1.Unit", "After",                bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_AFTER]  }, \
+         { "org.freedesktop.systemd1.Unit", "OnFailure",            bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_ON_FAILURE] }, \
++        { "org.freedesktop.systemd1.Unit", "Triggers",             bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_TRIGGERS] }, \
++        { "org.freedesktop.systemd1.Unit", "TriggeredBy",          bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_TRIGGERED_BY] }, \
+         { "org.freedesktop.systemd1.Unit", "Description",          bus_unit_append_description,    "s",    u                                 }, \
+         { "org.freedesktop.systemd1.Unit", "LoadState",            bus_unit_append_load_state,     "s",    &u->meta.load_state               }, \
+         { "org.freedesktop.systemd1.Unit", "ActiveState",          bus_unit_append_active_state,   "s",    u                                 }, \
+diff --git a/src/load-fragment.c b/src/load-fragment.c
+index 12079c6..1903190 100644
+--- a/src/load-fragment.c
++++ b/src/load-fragment.c
+@@ -84,7 +84,8 @@ int config_parse_unit_deps(
+                 char *t, *k;
+                 int r;
+ 
+-                if (!(t = strndup(w, l)))
++                t = strndup(w, l);
++                if (!t)
+                         return -ENOMEM;
+ 
+                 k = unit_name_printf(u, t);
+@@ -94,12 +95,8 @@ int config_parse_unit_deps(
+                         return -ENOMEM;
+ 
+                 r = unit_add_dependency_by_name(u, d, k, NULL, true);
+-
+-                if (r < 0) {
+-                        log_error("Failed to add dependency on %s, ignoring: %s", k, strerror(-r));
+-                        free(k);
+-                        return 0;
+-                }
++                if (r < 0)
++                        log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r));
+ 
+                 free(k);
+         }
+@@ -1265,6 +1262,7 @@ int config_parse_timer_unit(
+         Timer *t = data;
+         int r;
+         DBusError error;
++        Unit *u;
+ 
+         assert(filename);
+         assert(lvalue);
+@@ -1278,12 +1276,15 @@ int config_parse_timer_unit(
+                 return 0;
+         }
+ 
+-        if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, NULL, &t->unit)) < 0) {
++        r = manager_load_unit(t->meta.manager, rvalue, NULL, NULL, &u);
++        if (r < 0) {
+                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+                 dbus_error_free(&error);
+                 return 0;
+         }
+ 
++        unit_ref_set(&t->unit, u);
++
+         return 0;
+ }
+ 
+@@ -1347,6 +1348,7 @@ int config_parse_path_unit(
+         Path *t = data;
+         int r;
+         DBusError error;
++        Unit *u;
+ 
+         assert(filename);
+         assert(lvalue);
+@@ -1360,12 +1362,14 @@ int config_parse_path_unit(
+                 return 0;
+         }
+ 
+-        if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &error, &t->unit)) < 0) {
++        if ((r = manager_load_unit(t->meta.manager, rvalue, NULL, &error, &u)) < 0) {
+                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+                 dbus_error_free(&error);
+                 return 0;
+         }
+ 
++        unit_ref_set(&t->unit, u);
++
+         return 0;
+ }
+ 
+@@ -1416,7 +1420,6 @@ int config_parse_service_sockets(
+ 
+         Service *s = data;
+         int r;
+-        DBusError error;
+         char *state, *w;
+         size_t l;
+ 
+@@ -1425,35 +1428,34 @@ int config_parse_service_sockets(
+         assert(rvalue);
+         assert(data);
+ 
+-        dbus_error_init(&error);
+-
+         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
+-                char *t;
+-                Unit *sock;
++                char *t, *k;
+ 
+-                if (!(t = strndup(w, l)))
++                t = strndup(w, l);
++                if (!t)
+                         return -ENOMEM;
+ 
+-                if (!endswith(t, ".socket")) {
+-                        log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue);
+-                        free(t);
+-                        continue;
+-                }
+-
+-                r = manager_load_unit(s->meta.manager, t, NULL, &error, &sock);
++                k = unit_name_printf(UNIT(s), t);
+                 free(t);
+ 
+-                if (r < 0) {
+-                        log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+-                        dbus_error_free(&error);
++                if (!k)
++                        return -ENOMEM;
++
++                if (!endswith(k, ".socket")) {
++                        log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue);
++                        free(k);
+                         continue;
+                 }
+ 
+-                if ((r = set_ensure_allocated(&s->configured_sockets, trivial_hash_func, trivial_compare_func)) < 0)
+-                        return r;
++                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true);
++                if (r < 0)
++                        log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r));
+ 
+-                if ((r = set_put(s->configured_sockets, sock)) < 0)
++                r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true);
++                if (r < 0)
+                         return r;
++
++                free(k);
+         }
+ 
+         return 0;
+diff --git a/src/mount.c b/src/mount.c
+index 47422cc..f72c50a 100644
+--- a/src/mount.c
++++ b/src/mount.c
+@@ -108,21 +108,12 @@ static void mount_parameters_done(MountParameters *p) {
+ 
+ static void mount_done(Unit *u) {
+         Mount *m = MOUNT(u);
+-        Meta *other;
+ 
+         assert(m);
+ 
+         free(m->where);
+         m->where = NULL;
+ 
+-        /* Try to detach us from the automount unit if there is any */
+-        LIST_FOREACH(units_by_type, other, m->meta.manager->units_by_type[UNIT_AUTOMOUNT]) {
+-                Automount *a = (Automount*) other;
+-
+-                if (a->mount == m)
+-                        a->mount = NULL;
+-        }
+-
+         mount_parameters_done(&m->parameters_etc_fstab);
+         mount_parameters_done(&m->parameters_proc_self_mountinfo);
+         mount_parameters_done(&m->parameters_fragment);
+@@ -647,13 +638,18 @@ static int mount_load(Unit *u) {
+ static int mount_notify_automount(Mount *m, int status) {
+         Unit *p;
+         int r;
++        Iterator i;
+ 
+         assert(m);
+ 
+-        if ((r = unit_get_related_unit(UNIT(m), ".automount", &p)) < 0)
+-                return r == -ENOENT ? 0 : r;
++        SET_FOREACH(p, m->meta.dependencies[UNIT_TRIGGERED_BY], i)
++                if (p->meta.type == UNIT_AUTOMOUNT) {
++                         r = automount_send_ready(AUTOMOUNT(p), status);
++                         if (r < 0)
++                                 return r;
++                }
+ 
+-        return automount_send_ready(AUTOMOUNT(p), status);
++        return 0;
+ }
+ 
+ static void mount_set_state(Mount *m, MountState state) {
+diff --git a/src/path.c b/src/path.c
+index 3fee247..957af05 100644
+--- a/src/path.c
++++ b/src/path.c
+@@ -39,7 +39,8 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
+         [PATH_FAILED] = UNIT_FAILED
+ };
+ 
+-int pathspec_watch(PathSpec *s, Unit *u) {
++int path_spec_watch(PathSpec *s, Unit *u) {
++
+         static const int flags_table[_PATH_TYPE_MAX] = {
+                 [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+                 [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB,
+@@ -55,7 +56,7 @@ int pathspec_watch(PathSpec *s, Unit *u) {
+         assert(u);
+         assert(s);
+ 
+-        pathspec_unwatch(s, u);
++        path_spec_unwatch(s, u);
+ 
+         if (!(k = strdup(s->path)))
+                 return -ENOMEM;
+@@ -96,11 +97,11 @@ int pathspec_watch(PathSpec *s, Unit *u) {
+ fail:
+         free(k);
+ 
+-        pathspec_unwatch(s, u);
++        path_spec_unwatch(s, u);
+         return r;
+ }
+ 
+-void pathspec_unwatch(PathSpec *s, Unit *u) {
++void path_spec_unwatch(PathSpec *s, Unit *u) {
+ 
+         if (s->inotify_fd < 0)
+                 return;
+@@ -111,7 +112,7 @@ void pathspec_unwatch(PathSpec *s, Unit *u) {
+         s->inotify_fd = -1;
+ }
+ 
+-int pathspec_fd_event(PathSpec *s, uint32_t events) {
++int path_spec_fd_event(PathSpec *s, uint32_t events) {
+         uint8_t *buf = NULL;
+         struct inotify_event *e;
+         ssize_t k;
+@@ -164,7 +165,7 @@ out:
+         return r;
+ }
+ 
+-static bool pathspec_check_good(PathSpec *s, bool initial) {
++static bool path_spec_check_good(PathSpec *s, bool initial) {
+         bool good = false;
+ 
+         switch (s->type) {
+@@ -202,11 +203,11 @@ static bool pathspec_check_good(PathSpec *s, bool initial) {
+         return good;
+ }
+ 
+-static bool pathspec_startswith(PathSpec *s, const char *what) {
++static bool path_spec_startswith(PathSpec *s, const char *what) {
+         return path_startswith(s->path, what);
+ }
+ 
+-static void pathspec_mkdir(PathSpec *s, mode_t mode) {
++static void path_spec_mkdir(PathSpec *s, mode_t mode) {
+         int r;
+ 
+         if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB)
+@@ -216,7 +217,7 @@ static void pathspec_mkdir(PathSpec *s, mode_t mode) {
+                 log_warning("mkdir(%s) failed: %s", s->path, strerror(-r));
+ }
+ 
+-static void pathspec_dump(PathSpec *s, FILE *f, const char *prefix) {
++static void path_spec_dump(PathSpec *s, FILE *f, const char *prefix) {
+         fprintf(f,
+                 "%s%s: %s\n",
+                 prefix,
+@@ -224,8 +225,10 @@ static void pathspec_dump(PathSpec *s, FILE *f, const char *prefix) {
+                 s->path);
+ }
+ 
+-void pathspec_done(PathSpec *s) {
++void path_spec_done(PathSpec *s) {
++        assert(s);
+         assert(s->inotify_fd == -1);
++
+         free(s->path);
+ }
+ 
+@@ -244,10 +247,12 @@ static void path_done(Unit *u) {
+ 
+         assert(p);
+ 
++        unit_ref_unset(&p->unit);
++
+         while ((s = p->specs)) {
+-                pathspec_unwatch(s, u);
++                path_spec_unwatch(s, u);
+                 LIST_REMOVE(PathSpec, spec, p->specs, s);
+-                pathspec_done(s);
++                path_spec_done(s);
+                 free(s);
+         }
+ }
+@@ -265,7 +270,7 @@ int path_add_one_mount_link(Path *p, Mount *m) {
+ 
+         LIST_FOREACH(spec, s, p->specs) {
+ 
+-                if (!pathspec_startswith(s, m->where))
++                if (!path_spec_startswith(s, m->where))
+                         continue;
+ 
+                 if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
+@@ -330,11 +335,18 @@ static int path_load(Unit *u) {
+ 
+         if (u->meta.load_state == UNIT_LOADED) {
+ 
+-                if (!p->unit)
+-                        if ((r = unit_load_related_unit(u, ".service", &p->unit)))
++                if (!UNIT_DEREF(p->unit)) {
++                        Unit *x;
++
++                        r = unit_load_related_unit(u, ".service", &x);
++                        if (r < 0)
+                                 return r;
+ 
+-                if ((r = unit_add_dependency(u, UNIT_BEFORE, p->unit, true)) < 0)
++                        unit_ref_set(&p->unit, x);
++                }
++
++                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(p->unit), true);
++                if (r < 0)
+                         return r;
+ 
+                 if ((r = path_add_mount_links(p)) < 0)
+@@ -361,12 +373,12 @@ static void path_dump(Unit *u, FILE *f, const char *prefix) {
+                 "%sMakeDirectory: %s\n"
+                 "%sDirectoryMode: %04o\n",
+                 prefix, path_state_to_string(p->state),
+-                prefix, p->unit->meta.id,
++                prefix, UNIT_DEREF(p->unit)->meta.id,
+                 prefix, yes_no(p->make_directory),
+                 prefix, p->directory_mode);
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                pathspec_dump(s, f, prefix);
++                path_spec_dump(s, f, prefix);
+ }
+ 
+ static void path_unwatch(Path *p) {
+@@ -375,7 +387,7 @@ static void path_unwatch(Path *p) {
+         assert(p);
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                pathspec_unwatch(s, UNIT(p));
++                path_spec_unwatch(s, UNIT(p));
+ }
+ 
+ static int path_watch(Path *p) {
+@@ -385,7 +397,7 @@ static int path_watch(Path *p) {
+         assert(p);
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                if ((r = pathspec_watch(s, UNIT(p))) < 0)
++                if ((r = path_spec_watch(s, UNIT(p))) < 0)
+                         return r;
+ 
+         return 0;
+@@ -451,7 +463,7 @@ static void path_enter_running(Path *p) {
+         if (p->meta.job && p->meta.job->type == JOB_STOP)
+                 return;
+ 
+-        if ((r = manager_add_job(p->meta.manager, JOB_START, p->unit, JOB_REPLACE, true, &error, NULL)) < 0)
++        if ((r = manager_add_job(p->meta.manager, JOB_START, UNIT_DEREF(p->unit), JOB_REPLACE, true, &error, NULL)) < 0)
+                 goto fail;
+ 
+         p->inotify_triggered = false;
+@@ -476,7 +488,7 @@ static bool path_check_good(Path *p, bool initial) {
+         assert(p);
+ 
+         LIST_FOREACH(spec, s, p->specs) {
+-                good = pathspec_check_good(s, initial);
++                good = path_spec_check_good(s, initial);
+ 
+                 if (good)
+                         break;
+@@ -526,7 +538,7 @@ static void path_mkdir(Path *p) {
+                 return;
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                pathspec_mkdir(s, p->directory_mode);
++                path_spec_mkdir(s, p->directory_mode);
+ }
+ 
+ static int path_start(Unit *u) {
+@@ -535,7 +547,7 @@ static int path_start(Unit *u) {
+         assert(p);
+         assert(p->state == PATH_DEAD || p->state == PATH_FAILED);
+ 
+-        if (p->unit->meta.load_state != UNIT_LOADED)
++        if (UNIT_DEREF(p->unit)->meta.load_state != UNIT_LOADED)
+                 return -ENOENT;
+ 
+         path_mkdir(p);
+@@ -616,7 +628,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+         /* log_debug("inotify wakeup on %s.", u->meta.id); */
+ 
+         LIST_FOREACH(spec, s, p->specs)
+-                if (pathspec_owns_inotify_fd(s, fd))
++                if (path_spec_owns_inotify_fd(s, fd))
+                         break;
+ 
+         if (!s) {
+@@ -624,7 +636,7 @@ static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+                 goto fail;
+         }
+ 
+-        changed = pathspec_fd_event(s, events);
++        changed = path_spec_fd_event(s, events);
+         if (changed < 0)
+                 goto fail;
+ 
+@@ -645,36 +657,22 @@ fail:
+ }
+ 
+ void path_unit_notify(Unit *u, UnitActiveState new_state) {
+-        char *n;
+-        int r;
+         Iterator i;
++        Unit *k;
+ 
+         if (u->meta.type == UNIT_PATH)
+                 return;
+ 
+-        SET_FOREACH(n, u->meta.names, i) {
+-                char *k;
+-                Unit *t;
++        SET_FOREACH(k, u->meta.dependencies[UNIT_TRIGGERED_BY], i) {
+                 Path *p;
+ 
+-                if (!(k = unit_name_change_suffix(n, ".path"))) {
+-                        r = -ENOMEM;
+-                        goto fail;
+-                }
+-
+-                t = manager_get_unit(u->meta.manager, k);
+-                free(k);
+-
+-                if (!t)
++                if (k->meta.type != UNIT_PATH)
+                         continue;
+ 
+-                if (t->meta.load_state != UNIT_LOADED)
++                if (k->meta.load_state != UNIT_LOADED)
+                         continue;
+ 
+-                p = PATH(t);
+-
+-                if (p->unit != u)
+-                        continue;
++                p = PATH(k);
+ 
+                 if (p->state == PATH_RUNNING && new_state == UNIT_INACTIVE) {
+                         log_debug("%s got notified about unit deactivation.", p->meta.id);
+@@ -685,11 +683,6 @@ void path_unit_notify(Unit *u, UnitActiveState new_state) {
+                         path_enter_waiting(p, false, p->inotify_triggered);
+                 }
+         }
+-
+-        return;
+-
+-fail:
+-        log_error("Failed find path unit: %s", strerror(-r));
+ }
+ 
+ static void path_reset_failed(Unit *u) {
+diff --git a/src/path.h b/src/path.h
+index 1d78fe4..8b3c0bc 100644
+--- a/src/path.h
++++ b/src/path.h
+@@ -58,14 +58,14 @@ typedef struct PathSpec {
+         int primary_wd;
+ 
+         bool previous_exists;
+-
+ } PathSpec;
+ 
+-int  pathspec_watch(PathSpec *s, Unit *u);
+-void pathspec_unwatch(PathSpec *s, Unit *u);
+-int  pathspec_fd_event(PathSpec *s, uint32_t events);
+-void pathspec_done(PathSpec *s);
+-static inline bool pathspec_owns_inotify_fd(PathSpec *s, int fd) {
++int path_spec_watch(PathSpec *s, Unit *u);
++void path_spec_unwatch(PathSpec *s, Unit *u);
++int path_spec_fd_event(PathSpec *s, uint32_t events);
++void path_spec_done(PathSpec *s);
++
++static inline bool path_spec_owns_inotify_fd(PathSpec *s, int fd) {
+         return s->inotify_fd == fd;
+ }
+ 
+@@ -74,7 +74,7 @@ struct Path {
+ 
+         LIST_HEAD(PathSpec, specs);
+ 
+-        Unit *unit;
++        UnitRef unit;
+ 
+         PathState state, deserialized_state;
+ 
+diff --git a/src/service.c b/src/service.c
+index 65a45e1..81a2954 100644
+--- a/src/service.c
++++ b/src/service.c
+@@ -187,11 +187,11 @@ static void service_close_socket_fd(Service *s) {
+ static void service_connection_unref(Service *s) {
+         assert(s);
+ 
+-        if (!s->accept_socket)
++        if (!UNIT_DEREF(s->accept_socket))
+                 return;
+ 
+-        socket_connection_unref(s->accept_socket);
+-        s->accept_socket = NULL;
++        socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket)));
++        unit_ref_unset(&s->accept_socket);
+ }
+ 
+ static void service_done(Unit *u) {
+@@ -232,7 +232,7 @@ static void service_done(Unit *u) {
+         service_close_socket_fd(s);
+         service_connection_unref(s);
+ 
+-        set_free(s->configured_sockets);
++        unit_ref_unset(&s->accept_socket);
+ 
+         unit_unwatch_timer(u, &s->timer_watch);
+ }
+@@ -1100,22 +1100,6 @@ static int service_add_default_dependencies(Service *s) {
+         return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+ }
+ 
+-static int service_add_socket_dependencies(Service *s) {
+-        Iterator i;
+-        Unit *u;
+-        int r;
+-
+-        /* Make sure we pull in all explicitly configured sockets */
+-
+-        SET_FOREACH(u, s->configured_sockets, i) {
+-                r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, u, true);
+-                if (r < 0)
+-                        return r;
+-        }
+-
+-        return 0;
+-}
+-
+ static void service_fix_output(Service *s) {
+         assert(s);
+ 
+@@ -1189,12 +1173,6 @@ static int service_load(Unit *u) {
+                         if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0)
+                                 return r;
+ 
+-                if (!set_isempty(s->configured_sockets)) {
+-                        r = service_add_socket_dependencies(s);
+-                        if (r < 0)
+-                                return r;
+-                }
+-
+                 if (s->meta.default_dependencies)
+                         if ((r = service_add_default_dependencies(s)) < 0)
+                                 return r;
+@@ -1385,86 +1363,22 @@ static int service_search_main_pid(Service *s) {
+         return 0;
+ }
+ 
+-static int service_get_sockets(Service *s, Set **_set) {
+-        Set *set;
++static void service_notify_sockets_dead(Service *s) {
+         Iterator i;
+-        char *t;
+-        int r;
+-
+-        assert(s);
+-        assert(_set);
+-
+-        if (s->socket_fd >= 0)
+-                return 0;
+-
+-        if (!set_isempty(s->configured_sockets))
+-                return 0;
+-
+-        /* Collects all Socket objects that belong to this
+-         * service. Note that a service might have multiple sockets
+-         * via multiple names. */
+-
+-        if (!(set = set_new(NULL, NULL)))
+-                return -ENOMEM;
+-
+-        SET_FOREACH(t, s->meta.names, i) {
+-                char *k;
+-                Unit *p;
+-
+-                /* Look for all socket objects that go by any of our
+-                 * units and collect their fds */
+-
+-                if (!(k = unit_name_change_suffix(t, ".socket"))) {
+-                        r = -ENOMEM;
+-                        goto fail;
+-                }
+-
+-                p = manager_get_unit(s->meta.manager, k);
+-                free(k);
+-
+-                if (!p)
+-                        continue;
+-
+-                if ((r = set_put(set, p)) < 0)
+-                        goto fail;
+-        }
+-
+-        *_set = set;
+-        return 0;
+-
+-fail:
+-        set_free(set);
+-        return r;
+-}
+-
+-static int service_notify_sockets_dead(Service *s) {
+-        Iterator i;
+-        Set *set, *free_set = NULL;
+-        Socket *sock;
+-        int r;
++        Unit *u;
+ 
+         assert(s);
+ 
+         /* Notifies all our sockets when we die */
+ 
+         if (s->socket_fd >= 0)
+-                return 0;
+-
+-        if (!set_isempty(s->configured_sockets))
+-                set = s->configured_sockets;
+-        else {
+-                if ((r = service_get_sockets(s, &free_set)) < 0)
+-                        return r;
+-
+-                set = free_set;
+-        }
+-
+-        SET_FOREACH(sock, set, i)
+-                socket_notify_service_dead(sock);
++                return;
+ 
+-        set_free(free_set);
++        SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERED_BY], i)
++                if (u->meta.type == UNIT_SOCKET)
++                        socket_notify_service_dead(SOCKET(u));
+ 
+-        return 0;
++        return;
+ }
+ 
+ static void service_unwatch_pid_file(Service *s) {
+@@ -1472,8 +1386,8 @@ static void service_unwatch_pid_file(Service *s) {
+                 return;
+ 
+         log_debug("Stopping watch for %s's PID file %s", s->meta.id, s->pid_file_pathspec->path);
+-        pathspec_unwatch(s->pid_file_pathspec, UNIT(s));
+-        pathspec_done(s->pid_file_pathspec);
++        path_spec_unwatch(s->pid_file_pathspec, UNIT(s));
++        path_spec_done(s->pid_file_pathspec);
+         free(s->pid_file_pathspec);
+         s->pid_file_pathspec = NULL;
+ }
+@@ -1636,8 +1550,7 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
+         int r;
+         int *rfds = NULL;
+         unsigned rn_fds = 0;
+-        Set *set, *free_set = NULL;
+-        Socket *sock;
++        Unit *u;
+ 
+         assert(s);
+         assert(fds);
+@@ -1646,18 +1559,15 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
+         if (s->socket_fd >= 0)
+                 return 0;
+ 
+-        if (!set_isempty(s->configured_sockets))
+-                set = s->configured_sockets;
+-        else {
+-                if ((r = service_get_sockets(s, &free_set)) < 0)
+-                        return r;
+-
+-                set = free_set;
+-        }
+-
+-        SET_FOREACH(sock, set, i) {
++        SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERED_BY], i) {
+                 int *cfds;
+                 unsigned cn_fds;
++                Socket *sock;
++
++                if (u->meta.type != UNIT_SOCKET)
++                        continue;
++
++                sock = SOCKET(u);
+ 
+                 if ((r = socket_collect_fds(sock, &cfds, &cn_fds)) < 0)
+                         goto fail;
+@@ -1690,12 +1600,9 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
+         *fds = rfds;
+         *n_fds = rn_fds;
+ 
+-        set_free(free_set);
+-
+         return 0;
+ 
+ fail:
+-        set_free(set);
+         free(rfds);
+ 
+         return r;
+@@ -2651,7 +2558,7 @@ static int service_watch_pid_file(Service *s) {
+         int r;
+ 
+         log_debug("Setting watch for %s's PID file %s", s->meta.id, s->pid_file_pathspec->path);
+-        r = pathspec_watch(s->pid_file_pathspec, UNIT(s));
++        r = path_spec_watch(s->pid_file_pathspec, UNIT(s));
+         if (r < 0)
+                 goto fail;
+ 
+@@ -2701,11 +2608,11 @@ static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+         assert(fd >= 0);
+         assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+         assert(s->pid_file_pathspec);
+-        assert(pathspec_owns_inotify_fd(s->pid_file_pathspec, fd));
++        assert(path_spec_owns_inotify_fd(s->pid_file_pathspec, fd));
+ 
+         log_debug("inotify event for %s", u->meta.id);
+ 
+-        if (pathspec_fd_event(s->pid_file_pathspec, events) < 0)
++        if (path_spec_fd_event(s->pid_file_pathspec, events) < 0)
+                 goto fail;
+ 
+         if (service_retry_pid_file(s) == 0)
+@@ -3450,6 +3357,7 @@ static void service_bus_query_pid_done(
+ }
+ 
+ int service_set_socket_fd(Service *s, int fd, Socket *sock) {
++
+         assert(s);
+         assert(fd >= 0);
+ 
+@@ -3468,9 +3376,10 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock) {
+ 
+         s->socket_fd = fd;
+         s->got_socket_fd = true;
+-        s->accept_socket = sock;
+ 
+-        return 0;
++        unit_ref_set(&s->accept_socket, UNIT(sock));
++
++        return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
+ }
+ 
+ static void service_reset_failed(Unit *u) {
+diff --git a/src/service.h b/src/service.h
+index 2102826..8f67ad5 100644
+--- a/src/service.h
++++ b/src/service.h
+@@ -27,6 +27,7 @@ typedef struct Service Service;
+ #include "unit.h"
+ #include "path.h"
+ #include "ratelimit.h"
++#include "service.h"
+ 
+ typedef enum ServiceState {
+         SERVICE_DEAD,
+@@ -154,8 +155,7 @@ struct Service {
+ 
+         RateLimit ratelimit;
+ 
+-        struct Socket *accept_socket;
+-        Set *configured_sockets;
++        UnitRef accept_socket;
+ 
+         Watch timer_watch;
+         PathSpec *pid_file_pathspec;
+@@ -165,6 +165,8 @@ struct Service {
+ 
+ extern const UnitVTable service_vtable;
+ 
++struct Socket;
++
+ int service_set_socket_fd(Service *s, int fd, struct Socket *socket);
+ 
+ const char* service_state_to_string(ServiceState i);
+diff --git a/src/socket.c b/src/socket.c
+index 1f5e067..7034436 100644
+--- a/src/socket.c
++++ b/src/socket.c
+@@ -98,7 +98,6 @@ static void socket_unwatch_control_pid(Socket *s) {
+ static void socket_done(Unit *u) {
+         Socket *s = SOCKET(u);
+         SocketPort *p;
+-        Meta *i;
+ 
+         assert(s);
+ 
+@@ -120,7 +119,7 @@ static void socket_done(Unit *u) {
+ 
+         socket_unwatch_control_pid(s);
+ 
+-        s->service = NULL;
++        unit_ref_unset(&s->service);
+ 
+         free(s->tcp_congestion);
+         s->tcp_congestion = NULL;
+@@ -129,16 +128,6 @@ static void socket_done(Unit *u) {
+         s->bind_to_device = NULL;
+ 
+         unit_unwatch_timer(u, &s->timer_watch);
+-
+-        /* Make sure no service instance refers to us anymore. */
+-        LIST_FOREACH(units_by_type, i, u->meta.manager->units_by_type[UNIT_SERVICE]) {
+-                Service *service = (Service *) i;
+-
+-                if (service->accept_socket == s)
+-                        service->accept_socket = NULL;
+-
+-                set_remove(service->configured_sockets, s);
+-        }
+ }
+ 
+ static int socket_instantiate_service(Socket *s) {
+@@ -153,7 +142,7 @@ static int socket_instantiate_service(Socket *s) {
+          * here. For Accept=no this is mostly a NOP since the service
+          * is figured out at load time anyway. */
+ 
+-        if (s->service)
++        if (UNIT_DEREF(s->service))
+                 return 0;
+ 
+         assert(s->accept);
+@@ -181,8 +170,9 @@ static int socket_instantiate_service(Socket *s) {
+ #endif
+ 
+         u->meta.no_gc = true;
+-        s->service = SERVICE(u);
+-        return 0;
++        unit_ref_set(&s->service, u);
++
++        return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
+ }
+ 
+ static bool have_non_accept_socket(Socket *s) {
+@@ -226,7 +216,7 @@ static int socket_verify(Socket *s) {
+                 return -EINVAL;
+         }
+ 
+-        if (s->accept && s->service) {
++        if (s->accept && UNIT_DEREF(s->service)) {
+                 log_error("Explicit service configuration for accepting sockets not supported on %s. Refusing.", s->meta.id);
+                 return -EINVAL;
+         }
+@@ -349,11 +339,18 @@ static int socket_load(Unit *u) {
+ 
+                 if (have_non_accept_socket(s)) {
+ 
+-                        if (!s->service)
+-                                if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0)
++                        if (!UNIT_DEREF(s->service)) {
++                                Unit *x;
++
++                                r = unit_load_related_unit(u, ".service", &x);
++                                if (r < 0)
+                                         return r;
+ 
+-                        if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0)
++                                unit_ref_set(&s->service, x);
++                        }
++
++                        r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
++                        if (r < 0)
+                                 return r;
+                 }
+ 
+@@ -912,8 +909,9 @@ static int socket_open_fds(Socket *s) {
+                                 if ((r = socket_instantiate_service(s)) < 0)
+                                         return r;
+ 
+-                                if (s->service && s->service->exec_command[SERVICE_EXEC_START]) {
+-                                        r = label_get_create_label_from_exe(s->service->exec_command[SERVICE_EXEC_START]->path, &label);
++                                if (UNIT_DEREF(s->service) &&
++                                    SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
++                                        r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
+ 
+                                         if (r < 0) {
+                                                 if (r != -EPERM)
+@@ -1380,26 +1378,20 @@ static void socket_enter_running(Socket *s, int cfd) {
+         }
+ 
+         if (cfd < 0) {
++                Iterator i;
++                Unit *u;
+                 bool pending = false;
+-                Meta *i;
+ 
+                 /* If there's already a start pending don't bother to
+                  * do anything */
+-                LIST_FOREACH(units_by_type, i, s->meta.manager->units_by_type[UNIT_SERVICE]) {
+-                        Service *service = (Service *) i;
+-
+-                        if (!set_get(service->configured_sockets, s))
+-                                continue;
+-
+-                        if (!unit_pending_active(UNIT(service)))
+-                                continue;
+-
+-                        pending = true;
+-                        break;
+-                }
++                SET_FOREACH(u, s->meta.dependencies[UNIT_TRIGGERS], i)
++                        if (unit_pending_active(u)) {
++                                pending = true;
++                                break;
++                        }
+ 
+                 if (!pending)
+-                        if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, &error, NULL)) < 0)
++                        if ((r = manager_add_job(s->meta.manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL)) < 0)
+                                 goto fail;
+ 
+                 socket_set_state(s, SOCKET_RUNNING);
+@@ -1434,13 +1426,13 @@ static void socket_enter_running(Socket *s, int cfd) {
+                         goto fail;
+                 }
+ 
+-                if ((r = unit_add_name(UNIT(s->service), name)) < 0) {
++                if ((r = unit_add_name(UNIT_DEREF(s->service), name)) < 0) {
+                         free(name);
+                         goto fail;
+                 }
+ 
+-                service = s->service;
+-                s->service = NULL;
++                service = SERVICE(UNIT_DEREF(s->service));
++                unit_ref_unset(&s->service);
+                 s->n_accepted ++;
+ 
+                 service->meta.no_gc = false;
+@@ -1523,23 +1515,27 @@ static int socket_start(Unit *u) {
+                 return 0;
+ 
+         /* Cannot run this without the service being around */
+-        if (s->service) {
+-                if (s->service->meta.load_state != UNIT_LOADED) {
+-                        log_error("Socket service %s not loaded, refusing.", s->service->meta.id);
++        if (UNIT_DEREF(s->service)) {
++                Service *service;
++
++                service = SERVICE(UNIT_DEREF(s->service));
++
++                if (service->meta.load_state != UNIT_LOADED) {
++                        log_error("Socket service %s not loaded, refusing.", service->meta.id);
+                         return -ENOENT;
+                 }
+ 
+                 /* If the service is already active we cannot start the
+                  * socket */
+-                if (s->service->state != SERVICE_DEAD &&
+-                    s->service->state != SERVICE_FAILED &&
+-                    s->service->state != SERVICE_AUTO_RESTART) {
+-                        log_error("Socket service %s already active, refusing.", s->service->meta.id);
++                if (service->state != SERVICE_DEAD &&
++                    service->state != SERVICE_FAILED &&
++                    service->state != SERVICE_AUTO_RESTART) {
++                        log_error("Socket service %s already active, refusing.", service->meta.id);
+                         return -EBUSY;
+                 }
+ 
+ #ifdef HAVE_SYSV_COMPAT
+-                if (s->service->sysv_path) {
++                if (service->sysv_path) {
+                         log_error("Using SysV services for socket activation is not supported. Refusing.");
+                         return -ENOENT;
+                 }
+diff --git a/src/socket.h b/src/socket.h
+index fbd29da..4fc2cbe 100644
+--- a/src/socket.h
++++ b/src/socket.h
+@@ -28,6 +28,7 @@ typedef struct Socket Socket;
+ #include "unit.h"
+ #include "socket-util.h"
+ #include "mount.h"
++#include "service.h"
+ 
+ typedef enum SocketState {
+         SOCKET_DEAD,
+@@ -93,7 +94,7 @@ struct Socket {
+         /* For Accept=no sockets refers to the one service we'll
+         activate. For Accept=yes sockets is either NULL, or filled
+         when the next service we spawn. */
+-        Service *service;
++        UnitRef service;
+ 
+         SocketState state, deserialized_state;
+ 
+@@ -103,9 +104,6 @@ struct Socket {
+         SocketExecCommand control_command_id;
+         pid_t control_pid;
+ 
+-        /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
+-        SocketAddressBindIPv6Only bind_ipv6_only;
+-
+         mode_t directory_mode;
+         mode_t socket_mode;
+ 
+@@ -130,6 +128,9 @@ struct Socket {
+         char *tcp_congestion;
+         long mq_maxmsg;
+         long mq_msgsize;
++
++        /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
++        SocketAddressBindIPv6Only bind_ipv6_only;
+ };
+ 
+ /* Called from the service code when collecting fds */
+diff --git a/src/timer.c b/src/timer.c
+index e6f207f..c732076 100644
+--- a/src/timer.c
++++ b/src/timer.c
+@@ -57,6 +57,8 @@ static void timer_done(Unit *u) {
+         }
+ 
+         unit_unwatch_timer(u, &t->timer_watch);
++
++        unit_ref_unset(&t->unit);
+ }
+ 
+ static int timer_verify(Timer *t) {
+@@ -101,11 +103,18 @@ static int timer_load(Unit *u) {
+ 
+         if (u->meta.load_state == UNIT_LOADED) {
+ 
+-                if (!t->unit)
+-                        if ((r = unit_load_related_unit(u, ".service", &t->unit)))
++                if (!UNIT_DEREF(t->unit)) {
++                        Unit *x;
++
++                        r = unit_load_related_unit(u, ".service", &x);
++                        if (r < 0)
+                                 return r;
+ 
+-                if ((r = unit_add_dependency(u, UNIT_BEFORE, t->unit, true)) < 0)
++                        unit_ref_set(&t->unit, x);
++                }
++
++                r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(t->unit), true);
++                if (r < 0)
+                         return r;
+ 
+                 if (t->meta.default_dependencies)
+@@ -126,7 +135,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
+                 "%sTimer State: %s\n"
+                 "%sUnit: %s\n",
+                 prefix, timer_state_to_string(t->state),
+-                prefix, t->unit->meta.id);
++                prefix, UNIT_DEREF(t->unit)->meta.id);
+ 
+         LIST_FOREACH(value, v, t->values)
+                 fprintf(f,
+@@ -216,18 +225,18 @@ static void timer_enter_waiting(Timer *t, bool initial) {
+ 
+                 case TIMER_UNIT_ACTIVE:
+ 
+-                        if (t->unit->meta.inactive_exit_timestamp.monotonic <= 0)
++                        if (UNIT_DEREF(t->unit)->meta.inactive_exit_timestamp.monotonic <= 0)
+                                 continue;
+ 
+-                        base = t->unit->meta.inactive_exit_timestamp.monotonic;
++                        base = UNIT_DEREF(t->unit)->meta.inactive_exit_timestamp.monotonic;
+                         break;
+ 
+                 case TIMER_UNIT_INACTIVE:
+ 
+-                        if (t->unit->meta.inactive_enter_timestamp.monotonic <= 0)
++                        if (UNIT_DEREF(t->unit)->meta.inactive_enter_timestamp.monotonic <= 0)
+                                 continue;
+ 
+-                        base = t->unit->meta.inactive_enter_timestamp.monotonic;
++                        base = UNIT_DEREF(t->unit)->meta.inactive_enter_timestamp.monotonic;
+                         break;
+ 
+                 default:
+@@ -278,7 +287,7 @@ static void timer_enter_running(Timer *t) {
+         if (t->meta.job && t->meta.job->type == JOB_STOP)
+                 return;
+ 
+-        if ((r = manager_add_job(t->meta.manager, JOB_START, t->unit, JOB_REPLACE, true, &error, NULL)) < 0)
++        if ((r = manager_add_job(t->meta.manager, JOB_START, UNIT_DEREF(t->unit), JOB_REPLACE, true, &error, NULL)) < 0)
+                 goto fail;
+ 
+         timer_set_state(t, TIMER_RUNNING);
+@@ -297,7 +306,7 @@ static int timer_start(Unit *u) {
+         assert(t);
+         assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
+ 
+-        if (t->unit->meta.load_state != UNIT_LOADED)
++        if (UNIT_DEREF(t->unit)->meta.load_state != UNIT_LOADED)
+                 return -ENOENT;
+ 
+         t->failure = false;
+@@ -374,37 +383,24 @@ static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
+ }
+ 
+ void timer_unit_notify(Unit *u, UnitActiveState new_state) {
+-        char *n;
+         int r;
+         Iterator i;
++        Unit *k;
+ 
+         if (u->meta.type == UNIT_TIMER)
+                 return;
+ 
+-        SET_FOREACH(n, u->meta.names, i) {
+-                char *k;
+-                Unit *p;
++        SET_FOREACH(k, u->meta.dependencies[UNIT_TRIGGERED_BY], i) {
+                 Timer *t;
+                 TimerValue *v;
+ 
+-                if (!(k = unit_name_change_suffix(n, ".timer"))) {
+-                        r = -ENOMEM;
+-                        goto fail;
+-                }
+-
+-                p = manager_get_unit(u->meta.manager, k);
+-                free(k);
+-
+-                if (!p)
++                if (k->meta.type != UNIT_TIMER)
+                         continue;
+ 
+-                if (p->meta.load_state != UNIT_LOADED)
++                if (k->meta.load_state != UNIT_LOADED)
+                         continue;
+ 
+-                t = TIMER(p);
+-
+-                if (t->unit != u)
+-                        continue;
++                t = TIMER(k);
+ 
+                 /* Reenable all timers that depend on unit state */
+                 LIST_FOREACH(value, v, t->values)
+@@ -438,11 +434,6 @@ void timer_unit_notify(Unit *u, UnitActiveState new_state) {
+                         assert_not_reached("Unknown timer state");
+                 }
+         }
+-
+-        return;
+-
+-fail:
+-        log_error("Failed find timer unit: %s", strerror(-r));
+ }
+ 
+ static void timer_reset_failed(Unit *u) {
+diff --git a/src/timer.h b/src/timer.h
+index 6295605..ad55cf7 100644
+--- a/src/timer.h
++++ b/src/timer.h
+@@ -63,7 +63,7 @@ struct Timer {
+         usec_t next_elapse;
+ 
+         TimerState state, deserialized_state;
+-        Unit *unit;
++        UnitRef unit;
+ 
+         Watch timer_watch;
+ 
+diff --git a/src/unit.c b/src/unit.c
+index 3191071..7ce783e 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -377,12 +377,15 @@ void unit_free(Unit *u) {
+ 
+         free(u->meta.description);
+         free(u->meta.fragment_path);
++        free(u->meta.instance);
+ 
+         set_free_free(u->meta.names);
+ 
+         condition_free_list(u->meta.conditions);
+ 
+-        free(u->meta.instance);
++        while (u->meta.refs)
++                unit_ref_unset(u->meta.refs);
++
+         free(u);
+ }
+ 
+@@ -498,6 +501,10 @@ int unit_merge(Unit *u, Unit *other) {
+         /* Merge names */
+         merge_names(u, other);
+ 
++        /* Redirect all references */
++        while (other->meta.refs)
++                unit_ref_set(other->meta.refs, u);
++
+         /* Merge dependencies */
+         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                 merge_dependencies(u, other, d);
+@@ -1526,7 +1533,9 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
+                 [UNIT_AFTER] = UNIT_BEFORE,
+                 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
+                 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
+-                [UNIT_REFERENCED_BY] = UNIT_REFERENCES
++                [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
++                [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
++                [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS
+         };
+         int r, q = 0, v = 0, w = 0;
+ 
+@@ -2588,6 +2597,28 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
+         return u->meta.unit_file_state;
+ }
+ 
++Unit* unit_ref_set(UnitRef *ref, Unit *u) {
++        assert(ref);
++        assert(u);
++
++        if (ref->unit)
++                unit_ref_unset(ref);
++
++        ref->unit = u;
++        LIST_PREPEND(UnitRef, refs, u->meta.refs, ref);
++        return u;
++}
++
++void unit_ref_unset(UnitRef *ref) {
++        assert(ref);
++
++        if (!ref->unit)
++                return;
++
++        LIST_REMOVE(UnitRef, refs, ref->unit->meta.refs, ref);
++        ref->unit = NULL;
++}
++
+ static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
+         [UNIT_STUB] = "stub",
+         [UNIT_LOADED] = "loaded",
+@@ -2626,7 +2657,9 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
+         [UNIT_AFTER] = "After",
+         [UNIT_REFERENCES] = "References",
+         [UNIT_REFERENCED_BY] = "ReferencedBy",
+-        [UNIT_ON_FAILURE] = "OnFailure"
++        [UNIT_ON_FAILURE] = "OnFailure",
++        [UNIT_TRIGGERS] = "Triggers",
++        [UNIT_TRIGGERED_BY] = "TriggeredBy"
+ };
+ 
+ DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
+diff --git a/src/unit.h b/src/unit.h
+index b32c1a7..4d83309 100644
+--- a/src/unit.h
++++ b/src/unit.h
+@@ -32,6 +32,7 @@ typedef enum UnitType UnitType;
+ typedef enum UnitLoadState UnitLoadState;
+ typedef enum UnitActiveState UnitActiveState;
+ typedef enum UnitDependency UnitDependency;
++typedef struct UnitRef UnitRef;
+ 
+ #include "set.h"
+ #include "util.h"
+@@ -119,6 +120,10 @@ enum UnitDependency {
+         /* On Failure */
+         UNIT_ON_FAILURE,
+ 
++        /* Triggers (i.e. a socket triggers a service) */
++        UNIT_TRIGGERS,
++        UNIT_TRIGGERED_BY,
++
+         /* Reference information for GC logic */
+         UNIT_REFERENCES,              /* Inverse of 'references' is 'referenced_by' */
+         UNIT_REFERENCED_BY,
+@@ -156,6 +161,9 @@ struct Meta {
+ 
+         usec_t job_timeout;
+ 
++        /* References to this */
++        LIST_HEAD(UnitRef, refs);
++
+         /* Conditions to check */
+         LIST_HEAD(Condition, conditions);
+ 
+@@ -237,6 +245,15 @@ struct Meta {
+         bool in_audit:1;
+ };
+ 
++struct UnitRef {
++        /* Keeps tracks of references to a unit. This is useful so
++         * that we can merge two units if necessary and correct all
++         * references to them */
++
++        Unit* unit;
++        LIST_FIELDS(UnitRef, refs);
++};
++
+ #include "service.h"
+ #include "timer.h"
+ #include "socket.h"
+@@ -536,6 +553,11 @@ bool unit_condition_test(Unit *u);
+ 
+ UnitFileState unit_get_unit_file_state(Unit *u);
+ 
++Unit* unit_ref_set(UnitRef *ref, Unit *u);
++void unit_ref_unset(UnitRef *ref);
++
++#define UNIT_DEREF(ref) ((ref).unit)
++
+ const char *unit_load_state_to_string(UnitLoadState i);
+ UnitLoadState unit_load_state_from_string(const char *s);
+ 
+-- 
+1.7.7.5
+
diff --git a/0121-main-fix-spelling.patch b/0121-main-fix-spelling.patch
new file mode 100644
index 0000000..112c80a
--- /dev/null
+++ b/0121-main-fix-spelling.patch
@@ -0,0 +1,87 @@
+From df9aafc94497610c8a8c9ccb0fcf5a67aa230087 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sat, 7 Jan 2012 00:59:15 +0100
+Subject: [PATCH 121/126] main: fix spelling (cherry picked from commit
+ 509b6efbbe8d0486d33036892293c575bd4d0736)
+
+---
+ src/main.c |   16 ++++++++--------
+ 1 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/src/main.c b/src/main.c
+index 5c28a6c..cdf32bf 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -270,7 +270,7 @@ static int parse_proc_cmdline_word(const char *word) {
+                 int r;
+ 
+                 if ((r = parse_boolean(word + 18)) < 0)
+-                        log_warning("Failed to parse dump core switch %s, Ignoring.", word + 18);
++                        log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
+                 else
+                         arg_dump_core = r;
+ 
+@@ -278,7 +278,7 @@ static int parse_proc_cmdline_word(const char *word) {
+                 int r;
+ 
+                 if ((r = parse_boolean(word + 20)) < 0)
+-                        log_warning("Failed to parse crash shell switch %s, Ignoring.", word + 20);
++                        log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
+                 else
+                         arg_crash_shell = r;
+ 
+@@ -286,7 +286,7 @@ static int parse_proc_cmdline_word(const char *word) {
+                 int r;
+ 
+                 if ((r = parse_boolean(word + 22)) < 0)
+-                        log_warning("Failed to parse confirm spawn switch %s, Ignoring.", word + 22);
++                        log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
+                 else
+                         arg_confirm_spawn = r;
+ 
+@@ -294,7 +294,7 @@ static int parse_proc_cmdline_word(const char *word) {
+                 int k;
+ 
+                 if (safe_atoi(word + 19, &k) < 0)
+-                        log_warning("Failed to parse crash chvt switch %s, Ignoring.", word + 19);
++                        log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
+                 else
+                         arg_crash_chvt = k;
+ 
+@@ -302,21 +302,21 @@ static int parse_proc_cmdline_word(const char *word) {
+                 int r;
+ 
+                 if ((r = parse_boolean(word + 20)) < 0)
+-                        log_warning("Failed to parse show status switch %s, Ignoring.", word + 20);
++                        log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
+                 else
+                         arg_show_status = r;
+         } else if (startswith(word, "systemd.default_standard_output=")) {
+                 int r;
+ 
+                 if ((r = exec_output_from_string(word + 32)) < 0)
+-                        log_warning("Failed to parse default standard output switch %s, Ignoring.", word + 32);
++                        log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
+                 else
+                         arg_default_std_output = r;
+         } else if (startswith(word, "systemd.default_standard_error=")) {
+                 int r;
+ 
+                 if ((r = exec_output_from_string(word + 31)) < 0)
+-                        log_warning("Failed to parse default standard error switch %s, Ignoring.", word + 31);
++                        log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
+                 else
+                         arg_default_std_error = r;
+ #ifdef HAVE_SYSV_COMPAT
+@@ -324,7 +324,7 @@ static int parse_proc_cmdline_word(const char *word) {
+                 int r;
+ 
+                 if ((r = parse_boolean(word + 21)) < 0)
+-                        log_warning("Failed to parse SysV console switch %s, Ignoring.", word + 20);
++                        log_warning("Failed to parse SysV console switch %s. Ignoring.", word + 20);
+                 else
+                         arg_sysv_console = r;
+ #endif
+-- 
+1.7.7.5
+
diff --git a/0122-load-fragment-fix-parsing-of-Socket-setting.patch b/0122-load-fragment-fix-parsing-of-Socket-setting.patch
new file mode 100644
index 0000000..84731bf
--- /dev/null
+++ b/0122-load-fragment-fix-parsing-of-Socket-setting.patch
@@ -0,0 +1,43 @@
+From 22af36b4ce7e01e0f50cd1a5679b54304bd06599 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sat, 7 Jan 2012 01:21:40 +0100
+Subject: [PATCH 122/126] load-fragment: fix parsing of Socket= setting
+ (cherry picked from commit
+ 4ff77f66af8bd3e7e403c81febb7a2471457c5da)
+
+---
+ src/load-fragment.c |    6 +++++-
+ 1 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/src/load-fragment.c b/src/load-fragment.c
+index 1903190..ef5d192 100644
+--- a/src/load-fragment.c
++++ b/src/load-fragment.c
+@@ -1386,6 +1386,7 @@ int config_parse_socket_service(
+         Socket *s = data;
+         int r;
+         DBusError error;
++        Unit *x;
+ 
+         assert(filename);
+         assert(lvalue);
+@@ -1399,12 +1400,15 @@ int config_parse_socket_service(
+                 return 0;
+         }
+ 
+-        if ((r = manager_load_unit(s->meta.manager, rvalue, NULL, &error, (Unit**) &s->service)) < 0) {
++        r = manager_load_unit(s->meta.manager, rvalue, NULL, &error, &x);
++        if (r < 0) {
+                 log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+                 dbus_error_free(&error);
+                 return 0;
+         }
+ 
++        unit_ref_set(&s->service, x);
++
+         return 0;
+ }
+ 
+-- 
+1.7.7.5
+
diff --git a/0123-fix-compiler-warning.patch b/0123-fix-compiler-warning.patch
new file mode 100644
index 0000000..83961f6
--- /dev/null
+++ b/0123-fix-compiler-warning.patch
@@ -0,0 +1,25 @@
+From e9926ed4c022cd98b6174d675546b04900df91e4 Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay.sievers at vrfy.org>
+Date: Sat, 7 Jan 2012 02:12:43 +0100
+Subject: [PATCH 123/126] fix compiler warning (cherry picked from commit
+ ebd91b34d749cf29308d15601b5fbc971b4dab89)
+
+---
+ src/timer.c |    1 -
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+
+diff --git a/src/timer.c b/src/timer.c
+index c732076..d127a11 100644
+--- a/src/timer.c
++++ b/src/timer.c
+@@ -383,7 +383,6 @@ static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
+ }
+ 
+ void timer_unit_notify(Unit *u, UnitActiveState new_state) {
+-        int r;
+         Iterator i;
+         Unit *k;
+ 
+-- 
+1.7.7.5
+
diff --git a/0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch b/0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch
new file mode 100644
index 0000000..ae35f8d
--- /dev/null
+++ b/0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch
@@ -0,0 +1,176 @@
+From 8538925add03eb761143d999baa12c11c4b6d286 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 10 Jan 2012 04:20:55 +0100
+Subject: [PATCH 124/126] shutdown: exclude processes with argv[0][0] from
+ killing (cherry picked from commit
+ 7e4ab3c5a6295193d0c58d353b6430265d842f34)
+
+Conflicts:
+
+	src/systemd/sd-journal.h
+	src/util.c
+	src/util.h
+---
+ src/shutdown.c |   44 +++++++++++++++++++++++++++++---------------
+ src/util.c     |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/util.h     |    1 +
+ 3 files changed, 81 insertions(+), 15 deletions(-)
+
+diff --git a/src/shutdown.c b/src/shutdown.c
+index 11213f9..46b5aea 100644
+--- a/src/shutdown.c
++++ b/src/shutdown.c
+@@ -47,29 +47,45 @@
+ #define FINALIZE_ATTEMPTS 50
+ 
+ static bool ignore_proc(pid_t pid) {
++        char buf[PATH_MAX];
++        FILE *f;
++        char c;
++        size_t count;
++        uid_t uid;
++        int r;
++
++        /* We are PID 1, let's not commit suicide */
+         if (pid == 1)
+                 return true;
+ 
+-        /* TODO: add more ignore rules here: device-mapper, etc */
++        r = get_process_uid(pid, &uid);
++        if (r < 0)
++                return true; /* not really, but better safe than sorry */
+ 
+-        return false;
+-}
++        /* Non-root processes otherwise are always subject to be killed */
++        if (uid != 0)
++                return false;
+ 
+-static bool is_kernel_thread(pid_t pid)
+-{
+-        char buf[PATH_MAX];
+-        FILE *f;
+-        char c;
+-        size_t count;
++        snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid);
++        char_array_0(buf);
+ 
+-        snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long)pid);
+         f = fopen(buf, "re");
+         if (!f)
+                 return true; /* not really, but has the desired effect */
+ 
+         count = fread(&c, 1, 1, f);
+         fclose(f);
+-        return count != 1;
++
++        /* Kernel threads have an empty cmdline */
++        if (count <= 0)
++                return true;
++
++        /* Processes with argv[0][0] = '@' we ignore from the killing
++         * spree. */
++        if (count == 1 && c == '@')
++                return true;
++
++        return false;
+ }
+ 
+ static int killall(int sign) {
+@@ -77,7 +93,8 @@ static int killall(int sign) {
+         struct dirent *d;
+         unsigned int n_processes = 0;
+ 
+-        if ((dir = opendir("/proc")) == NULL)
++        dir = opendir("/proc");
++        if (!dir)
+                 return -errno;
+ 
+         while ((d = readdir(dir))) {
+@@ -86,9 +103,6 @@ static int killall(int sign) {
+                 if (parse_pid(d->d_name, &pid) < 0)
+                         continue;
+ 
+-                if (is_kernel_thread(pid))
+-                        continue;
+-
+                 if (ignore_proc(pid))
+                         continue;
+ 
+diff --git a/src/util.c b/src/util.c
+index 5bac05f..497fd05 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -1090,6 +1090,57 @@ int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
+         return 0;
+ }
+ 
++int get_process_uid(pid_t pid, uid_t *uid) {
++        char *p;
++        FILE *f;
++        int r;
++
++        assert(uid);
++
++        if (pid == 0)
++                return getuid();
++
++        if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
++                return -ENOMEM;
++
++        f = fopen(p, "re");
++        free(p);
++
++        if (!f)
++                return -errno;
++
++        while (!feof(f)) {
++                char line[LINE_MAX], *l;
++
++                if (!fgets(line, sizeof(line), f)) {
++                        if (feof(f))
++                                break;
++
++                        r = -errno;
++                        goto finish;
++                }
++
++                l = strstrip(line);
++
++                if (startswith(l, "Uid:")) {
++                        l += 4;
++                        l += strspn(l, WHITESPACE);
++
++                        l[strcspn(l, WHITESPACE)] = 0;
++
++                        r = parse_uid(l, uid);
++                        goto finish;
++                }
++        }
++
++        r = -EIO;
++
++finish:
++        fclose(f);
++
++        return r;
++}
++
+ char *strnappend(const char *s, const char *suffix, size_t b) {
+         size_t a;
+         char *r;
+diff --git a/src/util.h b/src/util.h
+index 40a2a39..944c7d2 100644
+--- a/src/util.h
++++ b/src/util.h
+@@ -250,6 +250,7 @@ int rmdir_parents(const char *path, const char *stop);
+ 
+ int get_process_name(pid_t pid, char **name);
+ int get_process_cmdline(pid_t pid, size_t max_length, char **line);
++int get_process_uid(pid_t pid, uid_t *uid);
+ 
+ char hexchar(int x);
+ int unhexchar(char c);
+-- 
+1.7.7.5
+
diff --git a/0125-shutdown-add-link-to-root-storage-daemon-text.patch b/0125-shutdown-add-link-to-root-storage-daemon-text.patch
new file mode 100644
index 0000000..8cf3914
--- /dev/null
+++ b/0125-shutdown-add-link-to-root-storage-daemon-text.patch
@@ -0,0 +1,29 @@
+From cd6e5f49b99a587b256857b66d37202ae5cfe027 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 11 Jan 2012 01:51:52 +0100
+Subject: [PATCH 125/126] shutdown: add link to root storage daemon text
+ (cherry picked from commit
+ bd1a69818042e85e24ec3adaf5eb3ac30ab1d9fd)
+
+---
+ src/shutdown.c |    4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/src/shutdown.c b/src/shutdown.c
+index 46b5aea..d157e0f 100644
+--- a/src/shutdown.c
++++ b/src/shutdown.c
+@@ -81,7 +81,9 @@ static bool ignore_proc(pid_t pid) {
+                 return true;
+ 
+         /* Processes with argv[0][0] = '@' we ignore from the killing
+-         * spree. */
++         * spree.
++         *
++         * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */
+         if (count == 1 && c == '@')
+                 return true;
+ 
+-- 
+1.7.7.5
+
diff --git a/0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch b/0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch
new file mode 100644
index 0000000..bff5a87
--- /dev/null
+++ b/0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch
@@ -0,0 +1,161 @@
+From ca96079f33b100e32dd2eb624a946058b6ff49f1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 11 Jan 2012 02:47:14 +0100
+Subject: [PATCH 126/126] unit: implement new
+ PropagateReloadTo=/PropagateReloadFrom= operations
+ (cherry picked from commit
+ 4dcc1cb4155c4a72155e36a5461ab0847d4f1bf1)
+
+---
+ man/systemd.unit.xml             |   16 ++++++++++++++++
+ src/dbus-unit.h                  |    6 ++++++
+ src/load-fragment-gperf.gperf.m4 |    2 ++
+ src/manager.c                    |   18 +++++++++++++++++-
+ src/unit.c                       |    8 ++++++--
+ src/unit.h                       |    4 ++++
+ 6 files changed, 51 insertions(+), 3 deletions(-)
+
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 897f99f..30559b9 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -510,6 +510,22 @@
+                         </varlistentry>
+ 
+                         <varlistentry>
++                                <term><varname>PropagateReloadTo=</varname></term>
++                                <term><varname>PropagateReloadFrom=</varname></term>
++
++                                <listitem><para>Lists one or more
++                                units where reload requests on the
++                                unit will be propagated to/on the
++                                other unit will be propagated
++                                from. Issuing a reload request on a
++                                unit will automatically also enqueue a
++                                reload request on all units that the
++                                reload request shall be propagated to
++                                via these two
++                                settings.</para></listitem>
++                        </varlistentry>
++
++                        <varlistentry>
+                                 <term><varname>OnFailureIsolate=</varname></term>
+ 
+                                 <listitem><para>Takes a boolean
+diff --git a/src/dbus-unit.h b/src/dbus-unit.h
+index 20d5506..7a43410 100644
+--- a/src/dbus-unit.h
++++ b/src/dbus-unit.h
+@@ -80,6 +80,10 @@
+         "  <property name=\"Before\" type=\"as\" access=\"read\"/>\n"   \
+         "  <property name=\"After\" type=\"as\" access=\"read\"/>\n"    \
+         "  <property name=\"OnFailure\" type=\"as\" access=\"read\"/>\n"    \
++        "  <property name=\"Triggers\" type=\"as\" access=\"read\"/>\n"    \
++        "  <property name=\"TriggeredBy\" type=\"as\" access=\"read\"/>\n"    \
++        "  <property name=\"PropagateReloadTo\" type=\"as\" access=\"read\"/>\n" \
++        "  <property name=\"PropagateReloadFrom\" type=\"as\" access=\"read\"/>\n" \
+         "  <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
+         "  <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
+         "  <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
+@@ -143,6 +147,8 @@
+         { "org.freedesktop.systemd1.Unit", "OnFailure",            bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_ON_FAILURE] }, \
+         { "org.freedesktop.systemd1.Unit", "Triggers",             bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_TRIGGERS] }, \
+         { "org.freedesktop.systemd1.Unit", "TriggeredBy",          bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_TRIGGERED_BY] }, \
++        { "org.freedesktop.systemd1.Unit", "PropagateReloadTo",    bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_PROPAGATE_RELOAD_TO] }, \
++        { "org.freedesktop.systemd1.Unit", "PropagateReloadFrom",  bus_unit_append_dependencies,   "as",   u->meta.dependencies[UNIT_PROPAGATE_RELOAD_FROM] }, \
+         { "org.freedesktop.systemd1.Unit", "Description",          bus_unit_append_description,    "s",    u                                 }, \
+         { "org.freedesktop.systemd1.Unit", "LoadState",            bus_unit_append_load_state,     "s",    &u->meta.load_state               }, \
+         { "org.freedesktop.systemd1.Unit", "ActiveState",          bus_unit_append_active_state,   "s",    u                                 }, \
+diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
+index 81e186c..11e6324 100644
+--- a/src/load-fragment-gperf.gperf.m4
++++ b/src/load-fragment-gperf.gperf.m4
+@@ -100,6 +100,8 @@ Unit.Conflicts,                  config_parse_unit_deps,             UNIT_CONFLI
+ Unit.Before,                     config_parse_unit_deps,             UNIT_BEFORE,                   0
+ Unit.After,                      config_parse_unit_deps,             UNIT_AFTER,                    0
+ Unit.OnFailure,                  config_parse_unit_deps,             UNIT_ON_FAILURE,               0
++Unit.PropagateReloadTo,          config_parse_unit_deps,             UNIT_PROPAGATE_RELOAD_TO,      0
++Unit.PropagateReloadFrom,        config_parse_unit_deps,             UNIT_PROPAGATE_RELOAD_FROM,    0
+ Unit.StopWhenUnneeded,           config_parse_bool,                  0,                             offsetof(Meta, stop_when_unneeded)
+ Unit.RefuseManualStart,          config_parse_bool,                  0,                             offsetof(Meta, refuse_manual_start)
+ Unit.RefuseManualStop,           config_parse_bool,                  0,                             offsetof(Meta, refuse_manual_stop)
+diff --git a/src/manager.c b/src/manager.c
+index 6acc821..98106dd 100644
+--- a/src/manager.c
++++ b/src/manager.c
+@@ -1609,7 +1609,9 @@ static int transaction_add_job_and_dependencies(
+                                                 dbus_error_free(e);
+                                 }
+ 
+-                } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
++                }
++
++                if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
+ 
+                         SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
+                                 if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) {
+@@ -1632,6 +1634,20 @@ static int transaction_add_job_and_dependencies(
+                                 }
+                 }
+ 
++                if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START) {
++
++                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_PROPAGATE_RELOAD_TO], i) {
++                                r = transaction_add_job_and_dependencies(m, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e, NULL);
++
++                                if (r < 0) {
++                                        log_warning("Cannot add dependency reload job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r));
++
++                                        if (e)
++                                                dbus_error_free(e);
++                                }
++                        }
++                }
++
+                 /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */
+         }
+ 
+diff --git a/src/unit.c b/src/unit.c
+index 7ce783e..143b0e3 100644
+--- a/src/unit.c
++++ b/src/unit.c
+@@ -1535,7 +1535,9 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
+                 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
+                 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
+                 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
+-                [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS
++                [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
++                [UNIT_PROPAGATE_RELOAD_TO] = UNIT_PROPAGATE_RELOAD_FROM,
++                [UNIT_PROPAGATE_RELOAD_FROM] = UNIT_PROPAGATE_RELOAD_TO
+         };
+         int r, q = 0, v = 0, w = 0;
+ 
+@@ -2659,7 +2661,9 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
+         [UNIT_REFERENCED_BY] = "ReferencedBy",
+         [UNIT_ON_FAILURE] = "OnFailure",
+         [UNIT_TRIGGERS] = "Triggers",
+-        [UNIT_TRIGGERED_BY] = "TriggeredBy"
++        [UNIT_TRIGGERED_BY] = "TriggeredBy",
++        [UNIT_PROPAGATE_RELOAD_TO] = "PropagateReloadTo",
++        [UNIT_PROPAGATE_RELOAD_FROM] = "PropagateReloadFrom"
+ };
+ 
+ DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
+diff --git a/src/unit.h b/src/unit.h
+index 4d83309..19314d6 100644
+--- a/src/unit.h
++++ b/src/unit.h
+@@ -124,6 +124,10 @@ enum UnitDependency {
+         UNIT_TRIGGERS,
+         UNIT_TRIGGERED_BY,
+ 
++        /* Propagate reloads */
++        UNIT_PROPAGATE_RELOAD_TO,
++        UNIT_PROPAGATE_RELOAD_FROM,
++
+         /* Reference information for GC logic */
+         UNIT_REFERENCES,              /* Inverse of 'references' is 'referenced_by' */
+         UNIT_REFERENCED_BY,
+-- 
+1.7.7.5
+
diff --git a/systemd.spec b/systemd.spec
index 3bddd03..c0590b1 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -2,7 +2,7 @@ Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Version:        37
-Release:        5%{?dist}
+Release:        6%{?dist}
 License:        GPLv2+
 Group:          System Environment/Base
 Summary:        A System and Service Manager
@@ -18,6 +18,8 @@ BuildRequires:  docbook-style-xsl
 BuildRequires:  vala >= 0.11
 BuildRequires:  pkgconfig
 BuildRequires:  gtk2-devel
+BuildRequires:  glib2-devel
+BuildRequires:  libgee-devel
 BuildRequires:  libnotify-devel >= 0.7
 BuildRequires:  libacl-devel
 BuildRequires:  automake
@@ -36,7 +38,7 @@ Requires:       libudev >= 160
 Requires:       initscripts >= 9.28
 Requires:       filesystem >= 2.4.40
 Conflicts:      selinux-policy < 3.9.16-12.fc15
-Requires:       kernel >= 2.6.35.2-9.fc14
+Conflicts:      kernel < 2.6.35.2-9.fc14
 Requires:       nss-myhostname
 Source0:        http://www.freedesktop.org/software/systemd/%{name}-%{version}.tar.bz2
 # Adds support for the %%{_unitdir} macro
@@ -44,15 +46,133 @@ Source1:        macros.systemd
 Source2:        systemd-sysv-convert
 # Stop-gap, just to ensure things work out-of-the-box for this driver.
 Source3:        udlfb.conf
-# We revert this one for https://bugzilla.redhat.com/show_bug.cgi?id=741078
-# Must keep until https://bugzilla.redhat.com/show_bug.cgi?id=741115 is fixed.
-Patch0:         0001-unit-fix-complementing-of-requirement-deps-with-Afte.patch
-# some post-v37 patches from upstream:
-Patch1:         0002-manager-fix-a-crash-in-isolating.patch
-Patch2:         0005-systemctl-completion-always-invoke-with-no-legend.patch
-Patch3:         0001-mount-order-remote-mounts-after-both-network.target-.patch
-Patch4:         0001-units-drop-Install-section-from-remote-fs-pre.target.patch
-Patch5:         systemd-37-bug744415.patch
+# selected patches from v38
+Patch0001:      0001-util-properly-detect-what-the-last-capability-is.patch
+Patch0002:      0002-manager-fix-a-crash-in-isolating.patch
+Patch0003:      0003-audit-do-not-complain-if-kernel-lacks-audit.patch
+Patch0004:      0004-systemctl-completion-always-invoke-with-no-legend.patch
+Patch0005:      0005-systemctl-make-list-unit-files-output-more-economica.patch
+Patch0006:      0006-plymouth-fix-ply-proto-endianess-issues.patch
+Patch0007:      0007-random-seed-convert-poolsize-from-bits-to-bytes.patch
+Patch0008:      0008-condition-Fix-file-descriptor-leak-in-test_capabilit.patch
+Patch0009:      0009-initctl-don-t-use-dbus-connection-after-PID-1-got-re.patch
+Patch0010:      0010-cgroup-always-recreate-cgroup-before-we-try-to-apply.patch
+Patch0011:      0011-mount-order-remote-mounts-after-both-network.target-.patch
+Patch0012:      0012-units-drop-Install-section-from-remote-fs-pre.target.patch
+Patch0013:      0013-cryptsetup-generator-avoid-ordering-cycle-on-swap.patch
+Patch0014:      0014-bash-completion-update-with-new-verbs-and-arguments.patch
+Patch0015:      0015-bash-completion-add-completions-for-systemd-loginctl.patch
+Patch0016:      0016-bash-completion-rename-file-since-it-is-no-longer-fo.patch
+Patch0017:      0017-systemadm-break-timestamp-formatting-out-into-a-sepe.patch
+Patch0018:      0018-systemadm-allow-sorting-of-jobs-and-units.patch
+Patch0019:      0019-systemadm-split-the-type-status-combo-box-into-type-.patch
+Patch0020:      0020-systemadm-filter-on-swaps-paths-and-timers-too.patch
+Patch0021:      0021-systemadm-add-a-wrappable-label-and-use-it-for-statu.patch
+Patch0022:      0022-systemadm-add-libgee-as-dependency-and-use-it-for-a-.patch
+Patch0023:      0023-systemadm-display-dependencies-sorted.patch
+Patch0024:      0024-systemadm-use-color-for-dependency-links.patch
+Patch0025:      0025-systemadm-use-bold-for-requires-etc.patch
+Patch0026:      0026-systemadm-make-the-dependency-listing-selectable.patch
+Patch0027:      0027-systemadm-catch-exceptions-generated-by-dbus.patch
+Patch0028:      0028-systemadm-coalesce-id-and-decription-fields.patch
+Patch0029:      0029-systemadm-adjust-row-numbers-after-removing-aliases.patch
+Patch0030:      0030-systemadm-use-colors-for-id-too-remove-color-from-fr.patch
+Patch0031:      0031-cgroup-immediately-remove-all-cgroups-which-run-empt.patch
+Patch0032:      0032-utmp-remove-unneded-parameters.patch
+Patch0033:      0033-utmp-no-need-to-zero-a-struct-before-overwriting-it-.patch
+Patch0034:      0034-utmp-initialize-store-with-the-found-entry-not-with-.patch
+Patch0035:      0035-utmp-for-DEAD_PROCESS-write-the-current-time-to-wtmp.patch
+Patch0036:      0036-man-fix-a-typo-in-signal-number.patch
+Patch0037:      0037-units-drop-unnecessary-StandardOutput-syslog.patch
+Patch0038:      0038-units-fedora-let-rc-local.service-log-to-syslog.patch
+Patch0039:      0039-service-don-t-warn-if-the-pidfile-still-exists-after.patch
+Patch0040:      0040-job-colored-status-messages-on-boot.patch
+Patch0041:      0041-man-fix-typo-in-sd_notify.patch
+Patch0042:      0042-Fix-same-expression-on-both-sides-of.patch
+Patch0043:      0043-execute-avoid-logging-to-closed-fds.patch
+Patch0044:      0044-execute-make-setup_pam-return-errno-when-possible.patch
+Patch0045:      0045-execute-log-errors-from-sd-EXEC.patch
+Patch0046:      0046-pam-module-use-the-correct-session-type-unspecified.patch
+Patch0047:      0047-pam-module-treat-cron-in-PAM_TTY-as-empty-tty.patch
+Patch0048:      0048-let-mount-and-swap-units-log-to-the-configured-defau.patch
+Patch0049:      0049-socket-add-option-for-SO_PASSCRED.patch
+Patch0050:      0050-shutdownd-use-PassCred-yes-in-the-socket-unit.patch
+Patch0051:      0051-syslog-use-PassCred-yes-for-the-dev-log-socket.patch
+Patch0052:      0052-man-document-the-PassCred-option.patch
+Patch0053:      0053-add-a-generator-to-pull-rc-local.service-in.patch
+Patch0054:      0054-rc-local-no-need-to-check-if-the-script-is-executabl.patch
+Patch0055:      0055-rc-local-order-after-network.target.patch
+Patch0056:      0056-util-fix-error-checking-after-fgets.patch
+Patch0057:      0057-path-use-m-instead-of-strerror-errno.patch
+Patch0058:      0058-path-refactor-PathSpec-usage.patch
+Patch0059:      0059-path-add-PathModified-PathChanged-IN_MODIFY.patch
+Patch0060:      0060-service-handle-services-with-racy-daemonization-grac.patch
+Patch0061:      0061-service-stop-the-service-if-ExecStartPost-ends-with-.patch
+Patch0062:      0062-Allow-list-unit-files-to-run-with-root.patch
+Patch0063:      0063-unit-garbage-collect-units-with-load-error.patch
+Patch0064:      0064-systemctl-print-error-load-state-in-red.patch
+Patch0065:      0065-is-an-ampersat-not-an-ampersand-let-s-call-it-at-sym.patch
+Patch0066:      0066-path-add-missing-pieces-for-PathModified.patch
+Patch0067:      0067-unit-fix-false-positive-in-check-for-unneeded-unit.patch
+Patch0068:      0068-unit-check-for-unneeded-dependencies-even-when-unit-.patch
+Patch0069:      0069-pam-module-add-a-couple-of-debugging-prints.patch
+Patch0070:      0070-fsck-Fix-typo-in-comment.patch
+Patch0071:      0071-systemctl-fix-typo-in-is-enabled.patch
+Patch0072:      0072-tmpfiles-use-an-enum-instead-of-plain-char-for-item-.patch
+Patch0073:      0073-tmpfiles-rename-a-couple-of-functions.patch
+Patch0074:      0074-tmpfiles-use-a-common-function-to-set-owner-group-mo.patch
+Patch0075:      0075-tmpfiles-separate-a-generic-item-glob-processing-fun.patch
+Patch0076:      0076-tmpfiles-add-RECURSIVE_RELABEL_PATH-Z.patch
+Patch0077:      0077-man-document-Z-in-tmpfiles.patch
+Patch0078:      0078-man-mention-that-Z-ignores-uid-gid-mode.patch
+Patch0079:      0079-service-use-syslog-console-for-sysv_console.patch
+Patch0080:      0080-tmpfiles-apply-chown-chmod-for-Z-entries-too.patch
+Patch0081:      0081-tmpfiles-add-z-like-Z-but-not-recursive.patch
+Patch0082:      0082-man-fix-misplaced-remark-in-description-of-Sockets.patch
+Patch0083:      0083-execute-fix-losing-of-start-timestamps.patch
+Patch0084:      0084-label-fix-labeling-of-symbolic-links.patch
+Patch0085:      0085-dbus-register-to-DBus-asynchronously.patch
+Patch0086:      0086-dbus-no-sync-D-Bus-connection-flushing.patch
+Patch0087:      0087-log-never-block-on-syslog-in-PID-1.patch
+Patch0088:      0088-macro-fix-ALIGN_TO-macro-definition.patch
+Patch0089:      0089-man-document-the-sd-login-interfaces.patch
+Patch0090:      0090-sd-daemon-fix-include-lines-since-we-now-ship-a-shar.patch
+Patch0091:      0091-man-build-new-man-pages.patch
+Patch0092:      0092-man-sd_readahead-is-not-actually-available-in-libsys.patch
+Patch0093:      0093-build-sys-add-rules-for-man-page-aliases.patch
+Patch0094:      0094-man-add-sd-login-7-page.patch
+Patch0095:      0095-man-various-updates.patch
+Patch0096:      0096-man-extend-sd-login-7-in-regards-to-mixing-D-Bus-and.patch
+Patch0097:      0097-man-generate-HTML-instead-of-XHTML-with-XSL-docbook-.patch
+Patch0098:      0098-man-switch-to-UTF-8-output-to-work-around-charset-is.patch
+Patch0099:      0099-udev-exclude-loopback-device-from-udev-rule-based-sy.patch
+Patch0100:      0100-remount-api-vfs-handle-another-OOM-condition.patch
+Patch0101:      0101-socket-rename-the-PassCred-option-to-PassCredentials.patch
+Patch0102:      0102-socket-only-add-dependency-on-kmsg-socket-to-socket-.patch
+Patch0103:      0103-readahead-bring-export-definition-of-sd-readahead-in.patch
+Patch0104:      0104-nspawn-get-rid-of-BUFFER_SIZE-use-LINE_MAX-instead.patch
+Patch0105:      0105-namespace-remount-namespace-root-dir-for-SLAVE-to-av.patch
+Patch0106:      0106-logind-if-we-can-t-open-dev-tty0-assume-there-is-no-.patch
+Patch0107:      0107-logind-don-t-watch-vcsa-if-nobody-cares.patch
+Patch0108:      0108-man-fix-SEE-ALSO-in-hostname-5.patch
+Patch0109:      0109-logind-send-out-Lock-signal-when-locking.patch
+Patch0110:      0110-logind-add-needed-include-for-sd_notify.patch
+Patch0111:      0111-fix-compilation-error-with-PathSpec-redefined.patch
+Patch0112:      0112-util-when-printing-status-updates-during-boot-take-t.patch
+Patch0113:      0113-log-minor-optimization.patch
+Patch0114:      0114-util-never-ellipsize-welcome-message.patch
+Patch0115:      0115-headers-fix-git-URLs-for-source-files.patch
+Patch0116:      0116-README-correct-license-claims.patch
+Patch0117:      0117-util-fix-switching-to-console-unicode-mode.patch
+Patch0118:      0118-util-switch-the-console-to-text-mode-on-reset.patch
+Patch0119:      0119-service-add-dependencies-on-configured-sockets.patch
+Patch0120:      0120-unit-properly-update-references-to-units-which-are-m.patch
+Patch0121:      0121-main-fix-spelling.patch
+Patch0122:      0122-load-fragment-fix-parsing-of-Socket-setting.patch
+Patch0123:      0123-fix-compiler-warning.patch
+Patch0124:      0124-shutdown-exclude-processes-with-argv-0-0-from-killin.patch
+Patch0125:      0125-shutdown-add-link-to-root-storage-daemon-text.patch
+Patch0126:      0126-unit-implement-new-PropagateReloadTo-PropagateReload.patch
 
 # For sysvinit tools
 Obsoletes:      SysVinit < 2.86-24, sysvinit < 2.86-24
@@ -115,14 +235,15 @@ SysV compatibility tools for systemd
 
 %prep
 %setup -q
-%patch0 -p1 -R
-%patch1 -p1
-%patch2 -p1
-%patch3 -p1
-%patch4 -p1
-%patch5 -p1
+set +x
+for p in %{patches}; do
+	echo "Applying $p"
+	patch -p1 < $p
+done
+set -x
 
 %build
+autoreconf -i
 %configure --with-rootdir= --with-distro=fedora --with-rootlibdir=/%{_lib}
 make %{?_smp_mflags}
 
@@ -278,6 +399,7 @@ fi
 /lib/udev/rules.d/*.rules
 /lib/systemd/system-generators/systemd-cryptsetup-generator
 /lib/systemd/system-generators/systemd-getty-generator
+/lib/systemd/system-generators/systemd-rc-local-generator
 /%{_lib}/security/pam_systemd.so
 /%{_lib}/libsystemd-daemon.so.*
 /%{_lib}/libsystemd-login.so.*
@@ -336,7 +458,7 @@ fi
 /lib/systemd/system
 /bin/systemctl
 /bin/systemd-tmpfiles
-%{_sysconfdir}/bash_completion.d/systemctl-bash-completion.sh
+%{_sysconfdir}/bash_completion.d/systemd-bash-completion.sh
 %{_sysconfdir}/rpm/macros.systemd
 %{_mandir}/man1/systemctl.*
 %{_datadir}/pkgconfig/systemd.pc
@@ -369,7 +491,10 @@ fi
 %{_bindir}/systemd-sysv-convert
 
 %changelog
-* Thu Dec 02 2011 Karsten Hopp <karsten at redhat.com> 37-5
+* Wed Jan 11 2012 Michal Schmidt <mschmidt at redhat.com> - 37-6
+- Fixes and low-risk enhancements (no journald) from upstream v38.
+
+* Thu Dec 02 2011 Karsten Hopp <karsten at redhat.com> - 37-5
 - add upstream patch for bugzilla 744415, encrypted filesystem passphrases 
   fail on runtime systems in hvc consoles
 


More information about the scm-commits mailing list