[systemd/f17] Fixes for bugs reported in 44-10.fc17, more upstream patches
Michal Schmidt
michich at fedoraproject.org
Mon May 21 23:12:01 UTC 2012
commit eeb2ead8a126c6ba37f1b8fd238a3ed145c540ff
Author: Michal Schmidt <mschmidt at redhat.com>
Date: Tue May 22 00:21:29 2012 +0200
Fixes for bugs reported in 44-10.fc17, more upstream patches
Fix weird "TIFIER=" messages in syslog (#823498)
Revert ReleaseSession patch (#823485)
Add more patches from upstream, notably:
- Documentation= field support
- RequiredBy= in [Install] support
- configurable ulimit defaults
- switch-root fixes
...logind-close-FIFO-before-ending-sessions-.patch | 155 ++
...duce-new-Documentation-field-and-make-use.patch | 1592 ++++++++++++++++++++
0303-login-minor-typo-fix.patch | 23 +
...uce-RequiredBy-setting-in-Install-to-comp.patch | 149 ++
...setup-also-consider-one-an-unset-hostname.patch | 97 ++
0306-cryptsetup-a-few-simplifications.patch | 164 ++
...ervice-make-the-fsck-pass-no-configurable.patch | 43 +
...bit-harder-to-find-an-init-process-to-exe.patch | 59 +
0309-cryptsetup-support-discards-TRIM.patch | 41 +
0310-journalctl-fix-built-in-usage-output.patch | 26 +
...rop-uid-so-parent-signal-arrives-at-child.patch | 66 +
0312-util-fix-typo-in-newdup.patch | 23 +
0313-delta-fix-spelling-of-overridden.patch | 167 ++
0314-main-corrected-do_switch_root.patch | 123 ++
0315-util.c-add-in_initrd.patch | 46 +
...y-serialize-the-timestamps-for-the-initra.patch | 29 +
0317-core-main.c-add-switchedroot-parameter.patch | 78 +
...-do_switch_root-do-not-remove-the-old-roo.patch | 44 +
...-handle-the-initrd-timestamp-differently-.patch | 47 +
...-delta.c-initialize-bottom-for-fail-state.patch | 24 +
...til-rm_rf_children-add-root_dev-parameter.patch | 98 ++
...tch_root-do-not-recursively-remove-across.patch | 31 +
...-move-switch_root-call-into-its-own-.c-fi.patch | 339 +++++
...-a-few-fix-to-follow-general-naming-style.patch | 137 ++
0325-util-rework-in_initrd-logic.patch | 42 +
...-journald-fix-length-of-SYSLOG_IDENTIFIER.patch | 31 +
...ald-one-more-SYSLOG_IDENTIFIER-length-fix.patch | 24 +
...ain-allow-system-wide-limits-for-services.patch | 196 +++
0329-F17-fix-manpage-names.patch | 51 +
systemd.spec | 40 +-
30 files changed, 3984 insertions(+), 1 deletions(-)
---
diff --git a/0301-F17-Revert-logind-close-FIFO-before-ending-sessions-.patch b/0301-F17-Revert-logind-close-FIFO-before-ending-sessions-.patch
new file mode 100644
index 0000000..34eb942
--- /dev/null
+++ b/0301-F17-Revert-logind-close-FIFO-before-ending-sessions-.patch
@@ -0,0 +1,155 @@
+From bc83739695d72190504401026e3379d9cdabef75 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 22 May 2012 00:05:31 +0200
+Subject: [PATCH] F17: Revert "logind: close FIFO before ending sessions
+ cleanly"
+
+This reverts commit 75c8e3cffd7da8eede614cf61384957af2c82a29.
+
+It caused a regression:
+https://bugzilla.redhat.com/show_bug.cgi?id=823485
+---
+ src/login/logind-dbus.c | 30 --------------------
+ src/login/pam-module.c | 71 ++---------------------------------------------
+ 2 files changed, 3 insertions(+), 98 deletions(-)
+
+diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
+index b0bef82..9b32464 100644
+--- a/src/login/logind-dbus.c
++++ b/src/login/logind-dbus.c
+@@ -82,9 +82,6 @@
+ " <arg name=\"seat\" type=\"s\" direction=\"out\"/>\n" \
+ " <arg name=\"vtnr\" type=\"u\" direction=\"out\"/>\n" \
+ " </method>\n" \
+- " <method name=\"ReleaseSession\">\n" \
+- " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
+- " </method>\n" \
+ " <method name=\"ActivateSession\">\n" \
+ " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
+ " </method>\n" \
+@@ -1596,33 +1593,6 @@ static DBusHandlerResult manager_message_handler(
+ if (r < 0)
+ return bus_send_error_reply(connection, message, NULL, r);
+
+- } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) {
+- const char *name;
+- Session *session;
+-
+- if (!dbus_message_get_args(
+- message,
+- &error,
+- DBUS_TYPE_STRING, &name,
+- DBUS_TYPE_INVALID))
+- return bus_send_error_reply(connection, message, &error, -EINVAL);
+-
+- session = hashmap_get(m->sessions, name);
+- if (!session)
+- return bus_send_error_reply(connection, message, &error, -ENOENT);
+-
+- /* We use the FIFO to detect stray sessions where the
+- process invoking PAM dies abnormally. We need to make
+- sure that that process is not killed if at the clean
+- end of the session it closes the FIFO. Hence, with
+- this call explicitly turn off the FIFO logic, so that
+- the PAM code can finish clean up on its own */
+- session_remove_fifo(session);
+-
+- reply = dbus_message_new_method_return(message);
+- if (!reply)
+- goto oom;
+-
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSession")) {
+ const char *name;
+ Session *session;
+diff --git a/src/login/pam-module.c b/src/login/pam-module.c
+index 1edb91c..27d36f5 100644
+--- a/src/login/pam-module.c
++++ b/src/login/pam-module.c
+@@ -415,6 +415,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "CreateSession");
++
+ if (!m) {
+ pam_syslog(handle, LOG_ERR, "Could not allocate create session message.");
+ r = PAM_BUF_ERR;
+@@ -620,77 +621,11 @@ _public_ PAM_EXTERN int pam_sm_close_session(
+ int argc, const char **argv) {
+
+ const void *p = NULL;
+- const char *id;
+- DBusConnection *bus = NULL;
+- DBusMessage *m = NULL, *reply = NULL;
+- DBusError error;
+- int r;
+-
+- assert(handle);
+-
+- dbus_error_init(&error);
+-
+- id = pam_getenv(handle, "XDG_SESSION_ID");
+- if (id) {
+-
+- /* Before we go and close the FIFO we need to tell
+- * logind that this is a clean session shutdown, so
+- * that it doesn't just go and slaughter us
+- * immediately after closing the fd */
+-
+- bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+- if (!bus) {
+- pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error));
+- r = PAM_SESSION_ERR;
+- goto finish;
+- }
+-
+- m = dbus_message_new_method_call(
+- "org.freedesktop.login1",
+- "/org/freedesktop/login1",
+- "org.freedesktop.login1.Manager",
+- "ReleaseSession");
+- if (!m) {
+- pam_syslog(handle, LOG_ERR, "Could not allocate release session message.");
+- r = PAM_BUF_ERR;
+- goto finish;
+- }
+-
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, &id,
+- DBUS_TYPE_INVALID)) {
+- pam_syslog(handle, LOG_ERR, "Could not attach parameters to message.");
+- r = PAM_BUF_ERR;
+- goto finish;
+- }
+
+- reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+- if (!reply) {
+- pam_syslog(handle, LOG_ERR, "Failed to release session: %s", bus_error_message(&error));
+- r = PAM_SESSION_ERR;
+- goto finish;
+- }
+- }
+-
+- r = PAM_SUCCESS;
+-
+-finish:
+ pam_get_data(handle, "systemd.session-fd", &p);
++
+ if (p)
+ close_nointr(PTR_TO_INT(p) - 1);
+
+- dbus_error_free(&error);
+-
+- if (bus) {
+- dbus_connection_close(bus);
+- dbus_connection_unref(bus);
+- }
+-
+- if (m)
+- dbus_message_unref(m);
+-
+- if (reply)
+- dbus_message_unref(reply);
+-
+- return r;
++ return PAM_SUCCESS;
+ }
diff --git a/0302-units-introduce-new-Documentation-field-and-make-use.patch b/0302-units-introduce-new-Documentation-field-and-make-use.patch
new file mode 100644
index 0000000..31c0aa8
--- /dev/null
+++ b/0302-units-introduce-new-Documentation-field-and-make-use.patch
@@ -0,0 +1,1592 @@
+From 3cb32dbac8d02b080fe3aee1304995996b5e6009 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 15:12:18 +0200
+Subject: [PATCH] units: introduce new Documentation= field and make use of it
+ everywhere
+
+This should help making the boot process a bit easier to explore and
+understand for the administrator. The simple idea is that "systemctl
+status" now shows a link to documentation alongside the other status and
+decriptionary information of a service.
+
+This patch adds the necessary fields to all our shipped units if we have
+proper documentation for them.
+(cherry picked from commit 49dbfa7b2b0bf3906704dac1eaeb4eba91056a19)
+
+Conflicts:
+ units/systemd-udev-control.socket
+ units/systemd-udev-kernel.socket
+ units/systemd-udev-settle.service.in
+ units/systemd-udev-trigger.service.in
+ units/systemd-udev.service.in
+---
+ man/systemd.special.xml | 65 ++++++++++++++++++++++++
+ man/systemd.unit.xml | 17 +++++++
+ src/core/dbus-unit.c | 1 +
+ src/core/dbus-unit.h | 1 +
+ src/core/load-fragment-gperf.gperf.m4 | 1 +
+ src/core/load-fragment.c | 37 ++++++++++++++
+ src/core/load-fragment.h | 1 +
+ src/core/unit.c | 8 +--
+ src/core/unit.h | 1 +
+ src/shared/util.c | 21 ++++++++
+ src/shared/util.h | 2 +
+ src/systemctl/systemctl.c | 38 ++++++++++++++
+ units/basic.target | 3 +-
+ units/bluetooth.target | 3 +-
+ units/cryptsetup.target | 3 +-
+ units/dev-hugepages.mount | 1 +
+ units/dev-mqueue.mount | 1 +
+ units/emergency.service.in | 2 -
+ units/emergency.target | 3 +-
+ units/final.target | 3 +-
+ units/getty.target | 1 +
+ units/getty at .service.m4 | 1 +
+ units/graphical.target | 3 +-
+ units/halt.target | 3 +-
+ units/hibernate.target | 3 +-
+ units/http-daemon.target | 3 +-
+ units/kexec.target | 3 +-
+ units/local-fs-pre.target | 3 +-
+ units/local-fs.target | 3 +-
+ units/mail-transfer-agent.target | 3 +-
+ units/multi-user.target | 3 +-
+ units/network.target | 3 +-
+ units/nss-lookup.target | 3 +-
+ units/nss-user-lookup.target | 3 +-
+ units/poweroff.target | 3 +-
+ units/printer.target | 3 +-
+ units/proc-sys-fs-binfmt_misc.mount | 1 +
+ units/reboot.target | 3 +-
+ units/remote-fs-pre.target | 3 +-
+ units/remote-fs.target | 3 +-
+ units/rescue.service.m4.in | 2 -
+ units/rescue.target | 3 +-
+ units/rpcbind.target | 3 +-
+ units/serial-getty at .service.m4 | 1 +
+ units/shutdown.target | 3 +-
+ units/sigpwr.target | 3 +-
+ units/sleep.target | 3 +-
+ units/smartcard.target | 3 +-
+ units/sockets.target | 3 +-
+ units/sound.target | 3 +-
+ units/suspend.target | 3 +-
+ units/swap.target | 3 +-
+ units/sysinit.target | 3 +-
+ units/syslog.socket | 4 +-
+ units/syslog.target | 4 +-
+ units/systemd-ask-password-console.path | 1 +
+ units/systemd-ask-password-console.service.in | 1 +
+ units/systemd-ask-password-plymouth.path | 1 +
+ units/systemd-ask-password-plymouth.service.in | 1 +
+ units/systemd-ask-password-wall.path | 1 +
+ units/systemd-ask-password-wall.service.in | 1 +
+ units/systemd-binfmt.service.in | 2 +
+ units/systemd-hostnamed.service.in | 5 +-
+ units/systemd-initctl.service.in | 2 -
+ units/systemd-initctl.socket | 2 -
+ units/systemd-journald.service.in | 3 +-
+ units/systemd-journald.socket | 3 +-
+ units/systemd-localed.service.in | 5 +-
+ units/systemd-logind.service.in | 4 +-
+ units/systemd-modules-load.service.in | 1 +
+ units/systemd-shutdownd.service.in | 2 -
+ units/systemd-shutdownd.socket | 2 -
+ units/systemd-sysctl.service.in | 1 +
+ units/systemd-timedated-ntp.target | 1 +
+ units/systemd-timedated.service.in | 4 +-
+ units/systemd-tmpfiles-clean.service.in | 1 +
+ units/systemd-tmpfiles-clean.timer | 1 +
+ units/systemd-tmpfiles-setup.service.in | 1 +
+ units/systemd-update-utmp-runlevel.service.in | 1 +
+ units/systemd-update-utmp-shutdown.service.in | 1 +
+ units/systemd-vconsole-setup.service.in | 1 +
+ units/time-sync.target | 3 +-
+ units/umount.target | 3 +-
+ units/user/default.target | 3 +-
+ units/user/exit.service.in | 3 +-
+ units/user/exit.target | 3 +-
+ 86 files changed, 267 insertions(+), 107 deletions(-)
+
+diff --git a/man/systemd.special.xml b/man/systemd.special.xml
+index 9bb4297..27b98a2 100644
+--- a/man/systemd.special.xml
++++ b/man/systemd.special.xml
+@@ -49,7 +49,9 @@
+
+ <refsynopsisdiv>
+ <para><filename>basic.target</filename>,
++ <filename>bluetooth.target</filename>,
+ <filename>ctrl-alt-del.target</filename>,
++ <filename>cryptsetup.target</filename>,
+ <filename>dbus.service</filename>,
+ <filename>dbus.socket</filename>,
+ <filename>default.target</filename>,
+@@ -57,6 +59,7 @@
+ <filename>emergency.target</filename>,
+ <filename>exit.service</filename>,
+ <filename>final.service</filename>,
++ <filename>getty.target</filename>,
+ <filename>graphical.target</filename>,
+ <filename>hibernate.target</filename>,
+ <filename>http-daemon.target</filename>,
+@@ -69,7 +72,9 @@
+ <filename>multi-user.target</filename>,
+ <filename>network.target</filename>,
+ <filename>nss-lookup.target</filename>,
++ <filename>nss-user-lookup.target</filename>,
+ <filename>poweroff.target</filename>,
++ <filename>printer.target</filename>,
+ <filename>reboot.target</filename>,
+ <filename>remote-fs.target</filename>,
+ <filename>remote-fs-pre.target</filename>,
+@@ -82,7 +87,9 @@
+ <filename>shutdown.target</filename>,
+ <filename>sigpwr.target</filename>,
+ <filename>sleep.target</filename>,
++ <filename>smartcard.target</filename>,
+ <filename>sockets.target</filename>,
++ <filename>sound.target</filename>,
+ <filename>suspend.target</filename>,
+ <filename>swap.target</filename>,
+ <filename>sysinit.target</filename>,
+@@ -128,6 +135,16 @@
+ </listitem>
+ </varlistentry>
+ <varlistentry>
++ <term><filename>bluetooth.target</filename></term>
++ <listitem>
++ <para>This target is started
++ automatically as soon as a
++ bluetooth controller is
++ plugged in or becomes
++ available at boot.</para>
++ </listitem>
++ </varlistentry>
++ <varlistentry>
+ <term><filename>ctrl-alt-del.target</filename></term>
+ <listitem>
+ <para>systemd starts this
+@@ -140,6 +157,15 @@
+ </listitem>
+ </varlistentry>
+ <varlistentry>
++ <term><filename>cryptsetup.target</filename></term>
++ <listitem>
++ <para>A target that pulls in
++ setup services for all
++ encrypted block
++ devices.</para>
++ </listitem>
++ </varlistentry>
++ <varlistentry>
+ <term><filename>dbus.service</filename></term>
+ <listitem>
+ <para>A special unit for the
+@@ -227,6 +253,15 @@
+ </listitem>
+ </varlistentry>
+ <varlistentry>
++ <term><filename>getty.target</filename></term>
++ <listitem>
++ <para>A special target unit
++ that pulls in all local TTY
++ <filename>getty</filename> instances.
++ </para>
++ </listitem>
++ </varlistentry>
++ <varlistentry>
+ <term><filename>graphical.target</filename></term>
+ <listitem>
+ <para>A special target unit
+@@ -443,6 +478,16 @@
+ </listitem>
+ </varlistentry>
+ <varlistentry>
++ <term><filename>printer.target</filename></term>
++ <listitem>
++ <para>This target is started
++ automatically as soon as a
++ printer is plugged in or
++ becomes available at
++ boot.</para>
++ </listitem>
++ </varlistentry>
++ <varlistentry>
+ <term><filename>reboot.target</filename></term>
+ <listitem>
+ <para>A special target unit
+@@ -616,6 +661,16 @@
+ </listitem>
+ </varlistentry>
+ <varlistentry>
++ <term><filename>smartcard.target</filename></term>
++ <listitem>
++ <para>This target is started
++ automatically as soon as a
++ smartcard controller is
++ plugged in or becomes
++ available at boot.</para>
++ </listitem>
++ </varlistentry>
++ <varlistentry>
+ <term><filename>sockets.target</filename></term>
+ <listitem>
+ <para>A special target unit
+@@ -630,6 +685,16 @@
+ </listitem>
+ </varlistentry>
+ <varlistentry>
++ <term><filename>sound.target</filename></term>
++ <listitem>
++ <para>This target is started
++ automatically as soon as a
++ sound card is plugged in or
++ becomes available at
++ boot.</para>
++ </listitem>
++ </varlistentry>
++ <varlistentry>
+ <term><filename>suspend.target</filename></term>
+ <listitem>
+ <para>A special target unit
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 5975a63..88c28da 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -295,6 +295,23 @@
+ </varlistentry>
+
+ <varlistentry>
++ <term><varname>Documentation=</varname></term>
++ <listitem><para>A space separated list
++ of URIs referencing documentation for
++ this unit or its
++ configuration. Accepted are only URIs
++ of the types
++ <literal>http://</literal>,
++ <literal>https://</literal>,
++ <literal>file:</literal>,
++ <literal>info:</literal>,
++ <literal>man:</literal>. For more
++ information about the syntax of these
++ URIs see
++ <citerefentry><refentrytitle>uri</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para></listitem>
++ </varlistentry>
++
++ <varlistentry>
+ <term><varname>Requires=</varname></term>
+
+ <listitem><para>Configures requirement
+diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
+index 62484ba..23c6fa7 100644
+--- a/src/core/dbus-unit.c
++++ b/src/core/dbus-unit.c
+@@ -808,6 +808,7 @@ const BusProperty bus_unit_properties[] = {
+ { "PropagateReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]), true },
+ { "PropagateReloadFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]), true },
+ { "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true },
++ { "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), true },
+ { "Description", bus_unit_append_description, "s", 0 },
+ { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) },
+ { "ActiveState", bus_unit_append_active_state, "s", 0 },
+diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
+index 45fc813..0caecfe 100644
+--- a/src/core/dbus-unit.h
++++ b/src/core/dbus-unit.h
+@@ -87,6 +87,7 @@
+ " <property name=\"PropagateReloadFrom\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
++ " <property name=\"Documentation\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
+ " <property name=\"SubState\" type=\"s\" access=\"read\"/>\n" \
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index d929273..f0e25c0 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -92,6 +92,7 @@ $1.ControlGroupPersistent, config_parse_tristate, 0,
+ )m4_dnl
+ Unit.Names, config_parse_unit_names, 0, 0
+ Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description)
++Unit.Documentation, config_parse_documentation, 0, offsetof(Unit, documentation)
+ Unit.Requires, config_parse_unit_deps, UNIT_REQUIRES, 0
+ Unit.RequiresOverridable, config_parse_unit_deps, UNIT_REQUIRES_OVERRIDABLE, 0
+ Unit.Requisite, config_parse_unit_deps, UNIT_REQUISITE, 0
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index b5c6d0f..b59029e 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -2063,6 +2063,43 @@ int config_parse_unit_requires_mounts_for(
+ return r;
+ }
+
++int config_parse_documentation(
++ const char *filename,
++ unsigned line,
++ const char *section,
++ const char *lvalue,
++ int ltype,
++ const char *rvalue,
++ void *data,
++ void *userdata) {
++
++ Unit *u = userdata;
++ int r;
++ char **a, **b;
++
++ assert(filename);
++ assert(lvalue);
++ assert(rvalue);
++ assert(u);
++
++ r = config_parse_unit_strv_printf(filename, line, section, lvalue, ltype, rvalue, data, userdata);
++ if (r < 0)
++ return r;
++
++ for (a = b = u->documentation; a && *a; a++) {
++
++ if (is_valid_documentation_url(*a))
++ *(b++) = *a;
++ else {
++ log_error("[%s:%u] Invalid URL, ignoring: %s", filename, line, *a);
++ free(*a);
++ }
++ }
++ *b = NULL;
++
++ return r;
++}
++
+ #define FOLLOW_MAX 8
+
+ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
+diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
+index 98167b1..d0efa90 100644
+--- a/src/core/load-fragment.h
++++ b/src/core/load-fragment.h
+@@ -36,6 +36,7 @@ int config_parse_unit_names(const char *filename, unsigned line, const char *sec
+ int config_parse_unit_string_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+ int config_parse_unit_strv_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+ int config_parse_unit_path_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
++int config_parse_documentation(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+ int config_parse_socket_listen(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+ int config_parse_socket_bind(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+ int config_parse_exec_nice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 8a51d6b..15e86e9 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -397,6 +397,7 @@ void unit_free(Unit *u) {
+ cgroup_attribute_free_list(u->cgroup_attributes);
+
+ free(u->description);
++ strv_free(u->documentation);
+ free(u->fragment_path);
+ free(u->instance);
+
+@@ -624,7 +625,7 @@ const char *unit_description(Unit *u) {
+ }
+
+ void unit_dump(Unit *u, FILE *f, const char *prefix) {
+- char *t;
++ char *t, **j;
+ UnitDependency d;
+ Iterator i;
+ char *p2;
+@@ -672,6 +673,9 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
+ SET_FOREACH(t, u->names, i)
+ fprintf(f, "%s\tName: %s\n", prefix, t);
+
++ STRV_FOREACH(j, u->documentation)
++ fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
++
+ if ((following = unit_following(u)))
+ fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
+
+@@ -698,8 +702,6 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
+ }
+
+ if (!strv_isempty(u->requires_mounts_for)) {
+- char **j;
+-
+ fprintf(f,
+ "%s\tRequiresMountsFor:", prefix);
+
+diff --git a/src/core/unit.h b/src/core/unit.h
+index 3c20850..e198d07 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -157,6 +157,7 @@ struct Unit {
+ char **requires_mounts_for;
+
+ char *description;
++ char **documentation;
+
+ char *fragment_path; /* if loaded from a config file this is the primary path to it */
+ usec_t fragment_mtime;
+diff --git a/src/shared/util.c b/src/shared/util.c
+index c1fc1a7..2ce5b8c 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -5610,3 +5610,24 @@ int can_sleep(const char *type) {
+ free(p);
+ return found;
+ }
++
++bool is_valid_documentation_url(const char *url) {
++ assert(url);
++
++ if (startswith(url, "http://") && url[7])
++ return true;
++
++ if (startswith(url, "https://") && url[8])
++ return true;
++
++ if (startswith(url, "file:") && url[5])
++ return true;
++
++ if (startswith(url, "info:") && url[5])
++ return true;
++
++ if (startswith(url, "man:") && url[4])
++ return true;
++
++ return false;
++}
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 5ef8c52..024b2fc 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -508,4 +508,6 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value);
+
+ int can_sleep(const char *type);
+
++bool is_valid_documentation_url(const char *url);
++
+ #endif
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 484f7c3..2c2f637 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -2138,6 +2138,8 @@ typedef struct UnitStatusInfo {
+ const char *description;
+ const char *following;
+
++ char **documentation;
++
+ const char *path;
+ const char *default_control_group;
+
+@@ -2283,6 +2285,19 @@ static void print_status_info(UnitStatusInfo *i) {
+ if (i->what)
+ printf("\t What: %s\n", i->what);
+
++ if (!strv_isempty(i->documentation)) {
++ char **t;
++ bool first = true;
++
++ STRV_FOREACH(t, i->documentation) {
++ if (first) {
++ printf("\t Docs: %s\n", *t);
++ first = false;
++ } else
++ printf("\t %s\n", *t);
++ }
++ }
++
+ if (i->accept)
+ printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
+
+@@ -2589,6 +2604,27 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
+
+ dbus_message_iter_next(&sub);
+ }
++ } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING &&
++ streq(name, "Documentation")) {
++
++ DBusMessageIter sub;
++
++ dbus_message_iter_recurse(iter, &sub);
++ while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
++ const char *s;
++ char **l;
++
++ dbus_message_iter_get_basic(&sub, &s);
++
++ l = strv_append(i->documentation, s);
++ if (!l)
++ return -ENOMEM;
++
++ strv_free(i->documentation);
++ i->documentation = l;
++
++ dbus_message_iter_next(&sub);
++ }
+ }
+
+ break;
+@@ -2912,6 +2948,8 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
+ if (!show_properties)
+ print_status_info(&info);
+
++ strv_free(info.documentation);
++
+ if (!streq_ptr(info.active_state, "active") &&
+ !streq_ptr(info.active_state, "reloading") &&
+ streq(verb, "status"))
+diff --git a/units/basic.target b/units/basic.target
+index 0258ca0..3126384 100644
+--- a/units/basic.target
++++ b/units/basic.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Basic System
++Documentation=man:systemd.special(7)
+ Requires=sysinit.target sockets.target
+ After=sysinit.target sockets.target
+ RefuseManualStart=yes
+diff --git a/units/bluetooth.target b/units/bluetooth.target
+index c66718e..2cbd4be 100644
+--- a/units/bluetooth.target
++++ b/units/bluetooth.target
+@@ -5,8 +5,7 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Bluetooth
++Documentation=man:systemd.special(7)
+ StopWhenUnneeded=yes
+diff --git a/units/cryptsetup.target b/units/cryptsetup.target
+index 64ee8c6..8187ff6 100644
+--- a/units/cryptsetup.target
++++ b/units/cryptsetup.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Encrypted Volumes
++Documentation=man:systemd.special(7)
+diff --git a/units/dev-hugepages.mount b/units/dev-hugepages.mount
+index 72a522e..4ffc9b9 100644
+--- a/units/dev-hugepages.mount
++++ b/units/dev-hugepages.mount
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Huge Pages File System
++Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
+ DefaultDependencies=no
+ Before=sysinit.target
+ ConditionPathExists=/sys/kernel/mm/hugepages
+diff --git a/units/dev-mqueue.mount b/units/dev-mqueue.mount
+index cffdaf7..fac66b1 100644
+--- a/units/dev-mqueue.mount
++++ b/units/dev-mqueue.mount
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=POSIX Message Queue File System
++Documentation=man:mq_overview(7)
+ DefaultDependencies=no
+ Before=sysinit.target
+ ConditionPathExists=/proc/sys/fs/mqueue
+diff --git a/units/emergency.service.in b/units/emergency.service.in
+index 11ff472..a1fc2ea 100644
+--- a/units/emergency.service.in
++++ b/units/emergency.service.in
+@@ -5,8 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Emergency Shell
+ DefaultDependencies=no
+diff --git a/units/emergency.target b/units/emergency.target
+index 6a99e05..ce28234 100644
+--- a/units/emergency.target
++++ b/units/emergency.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Emergency Mode
++Documentation=man:systemd.special(7)
+ Requires=emergency.service
+ After=emergency.service
+ AllowIsolate=yes
+diff --git a/units/final.target b/units/final.target
+index 9cfda19..82ac05d 100644
+--- a/units/final.target
++++ b/units/final.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Final Step
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ RefuseManualStart=yes
+ After=shutdown.target umount.target
+diff --git a/units/getty.target b/units/getty.target
+index e4435dc..a947c20 100644
+--- a/units/getty.target
++++ b/units/getty.target
+@@ -7,3 +7,4 @@
+
+ [Unit]
+ Description=Login Prompts
++Documentation=man:systemd.special(7)
+diff --git a/units/getty at .service.m4 b/units/getty at .service.m4
+index 5f16c21..f57ba99 100644
+--- a/units/getty at .service.m4
++++ b/units/getty at .service.m4
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Getty on %I
++Documentation=man:agetty(8)
+ After=systemd-user-sessions.service plymouth-quit-wait.service
+ m4_ifdef(`TARGET_FEDORA',
+ After=rc-local.service
+diff --git a/units/graphical.target b/units/graphical.target
+index f2e3034..cb0fe05 100644
+--- a/units/graphical.target
++++ b/units/graphical.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Graphical Interface
++Documentation=man:systemd.special(7)
+ Requires=multi-user.target
+ After=multi-user.target
+ Conflicts=rescue.target
+diff --git a/units/halt.target b/units/halt.target
+index 04b42cd..6572baa 100644
+--- a/units/halt.target
++++ b/units/halt.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Halt
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ Requires=halt.service
+ After=halt.service
+diff --git a/units/hibernate.target b/units/hibernate.target
+index 05238a7..23a9f99 100644
+--- a/units/hibernate.target
++++ b/units/hibernate.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2.1 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Hibernate
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ BindTo=hibernate.service
+ After=hibernate.service
+diff --git a/units/http-daemon.target b/units/http-daemon.target
+index 45f1018..cdb244d 100644
+--- a/units/http-daemon.target
++++ b/units/http-daemon.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for compatibility with SysV/LSB units, and
+ # implementations lacking socket/bus activation.
+
+ [Unit]
+ Description=Web Server
++Documentation=man:systemd.special(7)
+diff --git a/units/kexec.target b/units/kexec.target
+index b77e6a4..ea9c6da 100644
+--- a/units/kexec.target
++++ b/units/kexec.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Reboot via kexec
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ Requires=kexec.service
+ After=kexec.service
+diff --git a/units/local-fs-pre.target b/units/local-fs-pre.target
+index 11e67ba..12998b7 100644
+--- a/units/local-fs-pre.target
++++ b/units/local-fs-pre.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Local File Systems (Pre)
++Documentation=man:systemd.special(7)
+diff --git a/units/local-fs.target b/units/local-fs.target
+index 1886f74..635f68c 100644
+--- a/units/local-fs.target
++++ b/units/local-fs.target
+@@ -5,9 +5,8 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Local File Systems
++Documentation=man:systemd.special(7)
+ OnFailure=emergency.target
+ OnFailureIsolate=yes
+diff --git a/units/mail-transfer-agent.target b/units/mail-transfer-agent.target
+index ebb1ea1..722b76f 100644
+--- a/units/mail-transfer-agent.target
++++ b/units/mail-transfer-agent.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for compatibility with SysV/LSB units, and
+ # implementations lacking socket/bus activation.
+
+ [Unit]
+ Description=Mail Transfer Agent
++Documentation=man:systemd.special(7)
+diff --git a/units/multi-user.target b/units/multi-user.target
+index 66f1a95..04f3c90 100644
+--- a/units/multi-user.target
++++ b/units/multi-user.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Multi-User
++Documentation=man:systemd.special(7)
+ Requires=basic.target
+ Conflicts=rescue.service rescue.target
+ After=basic.target rescue.service rescue.target
+diff --git a/units/network.target b/units/network.target
+index d97f64f..d326488 100644
+--- a/units/network.target
++++ b/units/network.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Network
++Documentation=man:systemd.special(7)
+diff --git a/units/nss-lookup.target b/units/nss-lookup.target
+index f7b0b5c..aa5289e 100644
+--- a/units/nss-lookup.target
++++ b/units/nss-lookup.target
+@@ -5,11 +5,10 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for compatibility with SysV/LSB units, and
+ # implementations lacking socket/bus activation.
+
+ [Unit]
+ Description=Host and Network Name Lookups
++Documentation=man:systemd.special(7)
+ After=network.target
+diff --git a/units/nss-user-lookup.target b/units/nss-user-lookup.target
+index 40e2148..32c0983 100644
+--- a/units/nss-user-lookup.target
++++ b/units/nss-user-lookup.target
+@@ -5,11 +5,10 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for implementations lacking socket/bus
+ # activation.
+
+ [Unit]
+ Description=User and Group Name Lookups
++Documentation=man:systemd.special(7)
+ After=network.target
+diff --git a/units/poweroff.target b/units/poweroff.target
+index d2ccf4b..b2390fe 100644
+--- a/units/poweroff.target
++++ b/units/poweroff.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Power-Off
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ Requires=poweroff.service
+ After=poweroff.service
+diff --git a/units/printer.target b/units/printer.target
+index 14c90ff..dc1858d 100644
+--- a/units/printer.target
++++ b/units/printer.target
+@@ -5,8 +5,7 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Printer
++Documentation=man:systemd.special(7)
+ StopWhenUnneeded=yes
+diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
+index 1829c21..1bdd835 100644
+--- a/units/proc-sys-fs-binfmt_misc.mount
++++ b/units/proc-sys-fs-binfmt_misc.mount
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Arbitrary Executable File Formats File System
++Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+ DefaultDependencies=no
+
+ [Mount]
+diff --git a/units/reboot.target b/units/reboot.target
+index 41e133c..10a77c1 100644
+--- a/units/reboot.target
++++ b/units/reboot.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Reboot
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ Requires=reboot.service
+ After=reboot.service
+diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target
+index eca271b..667a894 100644
+--- a/units/remote-fs-pre.target
++++ b/units/remote-fs-pre.target
+@@ -5,8 +5,7 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Remote File Systems (Pre)
++Documentation=man:systemd.special(7)
+ After=network.target nss-lookup.target
+diff --git a/units/remote-fs.target b/units/remote-fs.target
+index a48f87e..0be60b0 100644
+--- a/units/remote-fs.target
++++ b/units/remote-fs.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Remote File Systems
++Documentation=man:systemd.special(7)
+
+ [Install]
+ WantedBy=multi-user.target
+diff --git a/units/rescue.service.m4.in b/units/rescue.service.m4.in
+index da4c4da..76f8946 100644
+--- a/units/rescue.service.m4.in
++++ b/units/rescue.service.m4.in
+@@ -5,8 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Rescue Shell
+ DefaultDependencies=no
+diff --git a/units/rescue.target b/units/rescue.target
+index 5bf3f8e..f6aff5f 100644
+--- a/units/rescue.target
++++ b/units/rescue.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Rescue Mode
++Documentation=man:systemd.special(7)
+ Requires=basic.target rescue.service
+ After=basic.target rescue.service
+ AllowIsolate=yes
+diff --git a/units/rpcbind.target b/units/rpcbind.target
+index a5cea8c..142f855 100644
+--- a/units/rpcbind.target
++++ b/units/rpcbind.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for compatibility with SysV/LSB units, and
+ # implementations lacking socket/bus activation.
+
+ [Unit]
+ Description=RPC Port Mapper
++Documentation=man:systemd.special(7)
+diff --git a/units/serial-getty at .service.m4 b/units/serial-getty at .service.m4
+index d966f77..66dfeed 100644
+--- a/units/serial-getty at .service.m4
++++ b/units/serial-getty at .service.m4
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Serial Getty on %I
++Documentation=man:agetty(8)
+ BindTo=dev-%i.device
+ After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service
+ m4_ifdef(`TARGET_FEDORA',
+diff --git a/units/shutdown.target b/units/shutdown.target
+index 99a659e..bff4481 100644
+--- a/units/shutdown.target
++++ b/units/shutdown.target
+@@ -5,9 +5,8 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Shutdown
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ RefuseManualStart=yes
+diff --git a/units/sigpwr.target b/units/sigpwr.target
+index 0ca502d..ed729c8 100644
+--- a/units/sigpwr.target
++++ b/units/sigpwr.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Power Failure
++Documentation=man:systemd.special(7)
+diff --git a/units/sleep.target b/units/sleep.target
+index 9f4b247..d7ebd28 100644
+--- a/units/sleep.target
++++ b/units/sleep.target
+@@ -5,9 +5,8 @@
+ # the Free Software Foundation; either version 2.1 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Sleep
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ RefuseManualStart=yes
+diff --git a/units/smartcard.target b/units/smartcard.target
+index 28dd2bb..fa9d712 100644
+--- a/units/smartcard.target
++++ b/units/smartcard.target
+@@ -5,8 +5,7 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Smart Card
++Documentation=man:systemd.special(7)
+ StopWhenUnneeded=yes
+diff --git a/units/sockets.target b/units/sockets.target
+index 2296312..3230a50 100644
+--- a/units/sockets.target
++++ b/units/sockets.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Sockets
++Documentation=man:systemd.special(7)
+diff --git a/units/sound.target b/units/sound.target
+index e53221c..188738c 100644
+--- a/units/sound.target
++++ b/units/sound.target
+@@ -5,8 +5,7 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Sound Card
++Documentation=man:systemd.special(7)
+ StopWhenUnneeded=yes
+diff --git a/units/suspend.target b/units/suspend.target
+index 3ddb449..eaf79be 100644
+--- a/units/suspend.target
++++ b/units/suspend.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2.1 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Suspend
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ BindTo=suspend.service
+ After=suspend.service
+diff --git a/units/swap.target b/units/swap.target
+index 26dd261..8626ba4 100644
+--- a/units/swap.target
++++ b/units/swap.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Swap
++Documentation=man:systemd.special(7)
+diff --git a/units/sysinit.target b/units/sysinit.target
+index eb9a1c7..d1eef64 100644
+--- a/units/sysinit.target
++++ b/units/sysinit.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=System Initialization
++Documentation=man:systemd.special(7)
+ Conflicts=emergency.service emergency.target
+ Wants=local-fs.target swap.target
+ After=local-fs.target swap.target emergency.service emergency.target
+diff --git a/units/syslog.socket b/units/syslog.socket
+index 0e211e1..de22382 100644
+--- a/units/syslog.socket
++++ b/units/syslog.socket
+@@ -5,10 +5,10 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Syslog Socket
++Documentation=man:systemd.special(7)
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+ DefaultDependencies=no
+ Before=sockets.target syslog.target
+ Conflicts=shutdown.target
+diff --git a/units/syslog.target b/units/syslog.target
+index 825b26e..8772fa2 100644
+--- a/units/syslog.target
++++ b/units/syslog.target
+@@ -5,13 +5,13 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for compatibility with SysV/LSB units, and
+ # implementations lacking socket/bus activation.
+
+ [Unit]
+ Description=Syslog
++Documentation=man:systemd.special(7)
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+
+ # Avoid that we conflict with shutdown.target, so that we can stay
+ # until the very end and do not cancel shutdown.target if we should
+diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path
+index c3143d1..3a0f33e 100644
+--- a/units/systemd-ask-password-console.path
++++ b/units/systemd-ask-password-console.path
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Dispatch Password Requests to Console Directory Watch
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=plymouth-start.service
+diff --git a/units/systemd-ask-password-console.service.in b/units/systemd-ask-password-console.service.in
+index 5ff3ed5..1fc2cd2 100644
+--- a/units/systemd-ask-password-console.service.in
++++ b/units/systemd-ask-password-console.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Dispatch Password Requests to Console
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=plymouth-start.service
+diff --git a/units/systemd-ask-password-plymouth.path b/units/systemd-ask-password-plymouth.path
+index 06a5876..2cfc614 100644
+--- a/units/systemd-ask-password-plymouth.path
++++ b/units/systemd-ask-password-plymouth.path
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Forward Password Requests to Plymouth Directory Watch
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=plymouth-start.service
+diff --git a/units/systemd-ask-password-plymouth.service.in b/units/systemd-ask-password-plymouth.service.in
+index 92cbfdb..cc61fb8 100644
+--- a/units/systemd-ask-password-plymouth.service.in
++++ b/units/systemd-ask-password-plymouth.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Forward Password Requests to Plymouth
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=plymouth-start.service
+diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path
+index 050b73b..d28bb4c 100644
+--- a/units/systemd-ask-password-wall.path
++++ b/units/systemd-ask-password-wall.path
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Forward Password Requests to Wall Directory Watch
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ Before=basic.target shutdown.target
+diff --git a/units/systemd-ask-password-wall.service.in b/units/systemd-ask-password-wall.service.in
+index d8e27bf..90b3c17 100644
+--- a/units/systemd-ask-password-wall.service.in
++++ b/units/systemd-ask-password-wall.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Forward Password Requests to Wall
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents
+ After=systemd-user-sessions.service
+
+ [Service]
+diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in
+index 515c81b..1295ca0 100644
+--- a/units/systemd-binfmt.service.in
++++ b/units/systemd-binfmt.service.in
+@@ -7,6 +7,8 @@
+
+ [Unit]
+ Description=Set Up Additional Binary Formats
++Documentation=man:binfmt.d(5)
++Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount
+diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
+index 548e861..29ec113 100644
+--- a/units/systemd-hostnamed.service.in
++++ b/units/systemd-hostnamed.service.in
+@@ -5,10 +5,11 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Hostname Service
++Documentation=man:hostname(5)
++Documentation=man:machine-info(5)
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+
+ [Service]
+ ExecStart=@rootlibexecdir@/systemd-hostnamed
+diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in
+index 7df3aa6..d2f1ac6 100644
+--- a/units/systemd-initctl.service.in
++++ b/units/systemd-initctl.service.in
+@@ -5,8 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=/dev/initctl Compatibility Daemon
+ DefaultDependencies=no
+diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket
+index 7a3a023..a52d6a6 100644
+--- a/units/systemd-initctl.socket
++++ b/units/systemd-initctl.socket
+@@ -5,8 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=/dev/initctl Compatibility Named Pipe
+ DefaultDependencies=no
+diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
+index 92606b0..0c88d53 100644
+--- a/units/systemd-journald.service.in
++++ b/units/systemd-journald.service.in
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Journal Service
++Documentation=man:journald.conf(5)
+ DefaultDependencies=no
+ Requires=systemd-journald.socket
+ After=systemd-journald.socket
+diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket
+index 15fc49e..62f34f9 100644
+--- a/units/systemd-journald.socket
++++ b/units/systemd-journald.socket
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Journal Socket
++Documentation=man:journald.conf(5)
+ DefaultDependencies=no
+ Before=sockets.target syslog.target
+
+diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
+index 4f12519..0cf286e 100644
+--- a/units/systemd-localed.service.in
++++ b/units/systemd-localed.service.in
+@@ -5,10 +5,11 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Locale Service
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
++Documentation=man:locale.conf(5)
++Documentation=man:vconsole.conf(5)
+
+ [Service]
+ ExecStart=@rootlibexecdir@/systemd-localed
+diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
+index eb82e4c..8041030 100644
+--- a/units/systemd-logind.service.in
++++ b/units/systemd-logind.service.in
+@@ -5,10 +5,10 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Login Service
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
++Documentation=man:logind.conf(5)
+ After=nss-user-lookup.target
+
+ [Service]
+diff --git a/units/systemd-modules-load.service.in b/units/systemd-modules-load.service.in
+index 2f2b47f..6c2a164 100644
+--- a/units/systemd-modules-load.service.in
++++ b/units/systemd-modules-load.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Load Kernel Modules
++Documentation=man:modules-load.d(5)
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service
+diff --git a/units/systemd-shutdownd.service.in b/units/systemd-shutdownd.service.in
+index 657365a..7160f48 100644
+--- a/units/systemd-shutdownd.service.in
++++ b/units/systemd-shutdownd.service.in
+@@ -5,8 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Delayed Shutdown Service
+ DefaultDependencies=no
+diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket
+index 7f13c93..b3742de 100644
+--- a/units/systemd-shutdownd.socket
++++ b/units/systemd-shutdownd.socket
+@@ -5,8 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Delayed Shutdown Socket
+ DefaultDependencies=no
+diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in
+index ead5f6e..4794df9 100644
+--- a/units/systemd-sysctl.service.in
++++ b/units/systemd-sysctl.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Apply Kernel Variables
++Documentation=man:sysctl.d(5)
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service
+diff --git a/units/systemd-timedated-ntp.target b/units/systemd-timedated-ntp.target
+index 1284248..0837004 100644
+--- a/units/systemd-timedated-ntp.target
++++ b/units/systemd-timedated-ntp.target
+@@ -12,6 +12,7 @@
+
+ [Unit]
+ Description=Network Time Protocol
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+
+ [Install]
+ WantedBy=multi-user.target
+diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
+index 3ec3080..d0458f1 100644
+--- a/units/systemd-timedated.service.in
++++ b/units/systemd-timedated.service.in
+@@ -5,10 +5,10 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Time & Date Service
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
++Documentation=man:timezone(5)
+
+ [Service]
+ ExecStart=@rootlibexecdir@/systemd-timedated
+diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in
+index 3c8e72e..f3f33bb 100644
+--- a/units/systemd-tmpfiles-clean.service.in
++++ b/units/systemd-tmpfiles-clean.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Cleanup of Temporary Directories
++Documentation=man:tmpfiles.d(5)
+ DefaultDependencies=no
+ Wants=local-fs.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+diff --git a/units/systemd-tmpfiles-clean.timer b/units/systemd-tmpfiles-clean.timer
+index d8529a8..e1c7175 100644
+--- a/units/systemd-tmpfiles-clean.timer
++++ b/units/systemd-tmpfiles-clean.timer
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Daily Cleanup of Temporary Directories
++Documentation=man:tmpfiles.d(5)
+
+ [Timer]
+ OnBootSec=15min
+diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in
+index f90121e..bb0c9a5 100644
+--- a/units/systemd-tmpfiles-setup.service.in
++++ b/units/systemd-tmpfiles-setup.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Recreate Volatile Files and Directories
++Documentation=man:tmpfiles.d(5)
+ DefaultDependencies=no
+ Wants=local-fs.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+diff --git a/units/systemd-update-utmp-runlevel.service.in b/units/systemd-update-utmp-runlevel.service.in
+index 9bdb7a4..4a87ac1 100644
+--- a/units/systemd-update-utmp-runlevel.service.in
++++ b/units/systemd-update-utmp-runlevel.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Update UTMP about System Runlevel Changes
++Documentation=man:utmp(5)
+ DefaultDependencies=no
+ After=local-fs.target sysinit.target auditd.service runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target systemd-tmpfiles-setup.service
+ Before=poweroff.service reboot.service halt.service
+diff --git a/units/systemd-update-utmp-shutdown.service.in b/units/systemd-update-utmp-shutdown.service.in
+index 3832356..40cee16 100644
+--- a/units/systemd-update-utmp-shutdown.service.in
++++ b/units/systemd-update-utmp-shutdown.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Update UTMP about System Shutdown
++Documentation=man:utmp(5)
+ DefaultDependencies=no
+ After=local-fs.target sysinit.target auditd.service systemd-update-utmp-runlevel.service
+ Before=poweroff.service reboot.service halt.service
+diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
+index 943a982..a461997 100644
+--- a/units/systemd-vconsole-setup.service.in
++++ b/units/systemd-vconsole-setup.service.in
+@@ -7,6 +7,7 @@
+
+ [Unit]
+ Description=Setup Virtual Console
++Documentation=man:vconsole.conf(5)
+ DefaultDependencies=no
+ Conflicts=shutdown.target
+ After=systemd-readahead-collect.service systemd-readahead-replay.service
+diff --git a/units/time-sync.target b/units/time-sync.target
+index aa34ecb..8f175c1 100644
+--- a/units/time-sync.target
++++ b/units/time-sync.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ # This exists mostly for compatibility with SysV/LSB units, and
+ # implementations lacking socket/bus activation.
+
+ [Unit]
+ Description=System Time Synchronized
++Documentation=man:systemd.special(7)
+diff --git a/units/umount.target b/units/umount.target
+index b9ecca6..0cac44f 100644
+--- a/units/umount.target
++++ b/units/umount.target
+@@ -5,9 +5,8 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Unmount All Filesystems
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ RefuseManualStart=yes
+diff --git a/units/user/default.target b/units/user/default.target
+index deb310c..04bcee0 100644
+--- a/units/user/default.target
++++ b/units/user/default.target
+@@ -5,7 +5,6 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Default
++Documentation=man:systemd.special(7)
+diff --git a/units/user/exit.service.in b/units/user/exit.service.in
+index a20b089..5504601 100644
+--- a/units/user/exit.service.in
++++ b/units/user/exit.service.in
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Exit the Session
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ Requires=shutdown.target
+ After=shutdown.target
+diff --git a/units/user/exit.target b/units/user/exit.target
+index f34844c..69761ed 100644
+--- a/units/user/exit.target
++++ b/units/user/exit.target
+@@ -5,10 +5,9 @@
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+
+-# See systemd.special(7) for details
+-
+ [Unit]
+ Description=Exit the Session
++Documentation=man:systemd.special(7)
+ DefaultDependencies=no
+ Requires=exit.service
+ After=exit.service
diff --git a/0303-login-minor-typo-fix.patch b/0303-login-minor-typo-fix.patch
new file mode 100644
index 0000000..409d304
--- /dev/null
+++ b/0303-login-minor-typo-fix.patch
@@ -0,0 +1,23 @@
+From 442f55baa2cddd990d44905d4a49ced9c3bd43c4 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 15:22:28 +0200
+Subject: [PATCH] login: minor typo fix (cherry picked from commit
+ 6ccf7562da826fd82a25aacfbe193691180649d0)
+
+---
+ src/login/logind-session.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/login/logind-session.c b/src/login/logind-session.c
+index b5c6300..60b5965 100644
+--- a/src/login/logind-session.c
++++ b/src/login/logind-session.c
+@@ -382,7 +382,7 @@ static int session_link_x11_socket(Session *s) {
+ c[k] = 0;
+
+ if (access(f, F_OK) < 0) {
+- log_warning("Session %s has display %s with nonexisting socket %s.", s->id, s->display, f);
++ log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f);
+ free(f);
+ return -ENOENT;
+ }
diff --git a/0304-unit-introduce-RequiredBy-setting-in-Install-to-comp.patch b/0304-unit-introduce-RequiredBy-setting-in-Install-to-comp.patch
new file mode 100644
index 0000000..f70f2d7
--- /dev/null
+++ b/0304-unit-introduce-RequiredBy-setting-in-Install-to-comp.patch
@@ -0,0 +1,149 @@
+From 4a53fae8a28abc4c83780e0763adc3795ed3d0ed Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 15:27:26 +0200
+Subject: [PATCH] unit: introduce RequiredBy= setting in [Install], to
+ complement WantedBy= (cherry picked from commit
+ 78d54bd42b87818f5d0ef862d247f9db4844fadd)
+
+---
+ man/systemd.unit.xml | 2 ++
+ src/core/load-fragment-gperf.gperf.m4 | 1 +
+ src/shared/install.c | 57 ++++++++++++++++++++++++++++++---
+ 3 files changed, 55 insertions(+), 5 deletions(-)
+
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 88c28da..c4a8f9a 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -951,9 +951,11 @@
+
+ <varlistentry>
+ <term><varname>WantedBy=</varname></term>
++ <term><varname>RequiredBy=</varname></term>
+
+ <listitem><para>Installs a symlink in
+ the <filename>.wants/</filename>
++ resp. <filename>.requires/</filename>
+ subdirectory for a unit. This has the
+ effect that when the listed unit name
+ is activated the unit listing it is
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index f0e25c0..5be4dad 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -230,4 +230,5 @@ Path.DirectoryMode, config_parse_mode, 0,
+ m4_dnl The [Install] section is ignored here.
+ Install.Alias, NULL, 0, 0
+ Install.WantedBy, NULL, 0, 0
++Install.RequiredBy, NULL, 0, 0
+ Install.Also, NULL, 0, 0
+diff --git a/src/shared/install.c b/src/shared/install.c
+index 0f30303..54435b8 100644
+--- a/src/shared/install.c
++++ b/src/shared/install.c
+@@ -43,6 +43,7 @@ typedef struct {
+
+ char **aliases;
+ char **wanted_by;
++ char **required_by;
+ } InstallInfo;
+
+ typedef struct {
+@@ -883,6 +884,7 @@ static void install_info_free(InstallInfo *i) {
+ free(i->path);
+ strv_free(i->aliases);
+ strv_free(i->wanted_by);
++ strv_free(i->required_by);
+ free(i);
+ }
+
+@@ -1021,9 +1023,10 @@ static int unit_file_load(
+ bool allow_symlink) {
+
+ const ConfigTableItem items[] = {
+- { "Install", "Alias", config_parse_strv, 0, &info->aliases },
+- { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
+- { "Install", "Also", config_parse_also, 0, c },
++ { "Install", "Alias", config_parse_strv, 0, &info->aliases },
++ { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by },
++ { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by },
++ { "Install", "Also", config_parse_also, 0, c },
+ { NULL, NULL, NULL, 0, NULL }
+ };
+
+@@ -1050,7 +1053,10 @@ static int unit_file_load(
+ if (r < 0)
+ return r;
+
+- return strv_length(info->aliases) + strv_length(info->wanted_by);
++ return
++ strv_length(info->aliases) +
++ strv_length(info->wanted_by) +
++ strv_length(info->required_by);
+ }
+
+ static int unit_file_search(
+@@ -1121,7 +1127,10 @@ static int unit_file_can_install(
+ r = unit_file_search(&c, i, paths, root_dir, allow_symlink);
+
+ if (r >= 0)
+- r = strv_length(i->aliases) + strv_length(i->wanted_by);
++ r =
++ strv_length(i->aliases) +
++ strv_length(i->wanted_by) +
++ strv_length(i->required_by);
+
+ install_context_done(&c);
+
+@@ -1241,6 +1250,40 @@ static int install_info_symlink_wants(
+ return r;
+ }
+
++static int install_info_symlink_requires(
++ InstallInfo *i,
++ const char *config_path,
++ bool force,
++ UnitFileChange **changes,
++ unsigned *n_changes) {
++
++ char **s;
++ int r = 0, q;
++
++ assert(i);
++ assert(config_path);
++
++ STRV_FOREACH(s, i->required_by) {
++ char *path;
++
++ if (!unit_name_is_valid_no_type(*s, true)) {
++ r = -EINVAL;
++ continue;
++ }
++
++ if (asprintf(&path, "%s/%s.requires/%s", config_path, *s, i->name) < 0)
++ return -ENOMEM;
++
++ q = create_symlink(i->path, path, force, changes, n_changes);
++ free(path);
++
++ if (r == 0)
++ r = q;
++ }
++
++ return r;
++}
++
+ static int install_info_symlink_link(
+ InstallInfo *i,
+ LookupPaths *paths,
+@@ -1290,6 +1333,10 @@ static int install_info_apply(
+ if (r == 0)
+ r = q;
+
++ q = install_info_symlink_requires(i, config_path, force, changes, n_changes);
++ if (r == 0)
++ r = q;
++
+ q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes);
+ if (r == 0)
+ r = q;
diff --git a/0305-hostname-setup-also-consider-one-an-unset-hostname.patch b/0305-hostname-setup-also-consider-one-an-unset-hostname.patch
new file mode 100644
index 0000000..933664c
--- /dev/null
+++ b/0305-hostname-setup-also-consider-one-an-unset-hostname.patch
@@ -0,0 +1,97 @@
+From 0afe091e913a6f7214ef97e37fb0bd6760ebfb7a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 17:19:58 +0200
+Subject: [PATCH] =?UTF-8?q?hostname-setup:=20also=20consider=20(=C5=84one)=20?=
+ =?UTF-8?q?an=20unset=20hostname=20(cherry=20picked=20from=20commit=20344de6?=
+ =?UTF-8?q?0901f0e3ce0d2f112b7be97fc6d0e2f071)?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+---
+ src/core/hostname-setup.c | 25 +++++++------------------
+ src/shared/util.c | 10 +++++++++-
+ src/shared/util.h | 1 +
+ 3 files changed, 17 insertions(+), 19 deletions(-)
+
+diff --git a/src/core/hostname-setup.c b/src/core/hostname-setup.c
+index fda102d..503cddf 100644
+--- a/src/core/hostname-setup.c
++++ b/src/core/hostname-setup.c
+@@ -151,31 +151,20 @@ int hostname_setup(void) {
+
+ r = read_hostname(&b);
+ if (r < 0) {
++ hn = NULL;
++
+ if (r == -ENOENT)
+ enoent = true;
+ else
+ log_warning("Failed to read configured hostname: %s", strerror(-r));
+-
+- hn = NULL;
+ } else
+ hn = b;
+
+- if (!hn) {
+- /* Don't override the hostname if it is unset and not
+- * explicitly configured */
+-
+- char *old_hostname = NULL;
+-
+- old_hostname = gethostname_malloc();
+- if (old_hostname) {
+- bool already_set;
+-
+- already_set = old_hostname[0] != 0;
+- free(old_hostname);
+-
+- if (already_set)
+- goto finish;
+- }
++ if (isempty(hn)) {
++ /* Don't override the hostname if it is already set
++ * and not explicitly configured */
++ if (hostname_is_set())
++ goto finish;
+
+ if (enoent)
+ log_info("No hostname configured.");
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 2ce5b8c..29d1f04 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -2949,12 +2949,20 @@ char* gethostname_malloc(void) {
+
+ assert_se(uname(&u) >= 0);
+
+- if (u.nodename[0])
++ if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
+ return strdup(u.nodename);
+
+ return strdup(u.sysname);
+ }
+
++bool hostname_is_set(void) {
++ struct utsname u;
++
++ assert_se(uname(&u) >= 0);
++
++ return !isempty(u.nodename) && !streq(u.nodename, "(none)");
++}
++
+ char* getlogname_malloc(void) {
+ uid_t uid;
+ long bufsize;
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 024b2fc..c08c6f9 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -337,6 +337,7 @@ void rename_process(const char name[8]);
+ void sigset_add_many(sigset_t *ss, ...);
+
+ char* gethostname_malloc(void);
++bool hostname_is_set(void);
+ char* getlogname_malloc(void);
+
+ int getttyname_malloc(int fd, char **r);
diff --git a/0306-cryptsetup-a-few-simplifications.patch b/0306-cryptsetup-a-few-simplifications.patch
new file mode 100644
index 0000000..314749d
--- /dev/null
+++ b/0306-cryptsetup-a-few-simplifications.patch
@@ -0,0 +1,164 @@
+From 29396e3c5728e7e4a23c774d819c9227e663e2d1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 17:22:36 +0200
+Subject: [PATCH] cryptsetup: a few simplifications (cherry picked from commit
+ f7f21d33db5dfe88dc8175c61dada44013347729)
+
+Conflicts:
+ TODO
+---
+ src/core/mount.c | 3 ++-
+ src/cryptsetup/cryptsetup-generator.c | 44 ++++++++++++++++++---------------
+ 2 files changed, 26 insertions(+), 21 deletions(-)
+
+diff --git a/src/core/mount.c b/src/core/mount.c
+index 68792da..e7a1c58 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -1653,7 +1653,8 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
+ goto clean_up;
+ }
+
+- if (asprintf(&o, "%s,%s", options, options2) < 0) {
++ o = join(options, ",", options2, NULL);
++ if (!o) {
+ r = -ENOMEM;
+ goto finish;
+ }
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 5e92fb9..29a7bf5 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -76,31 +76,36 @@ static int create_disk(
+ noauto = has_option(options, "noauto");
+ nofail = has_option(options, "nofail");
+
+- if (!(n = unit_name_build_escape("cryptsetup", name, ".service"))) {
++ n = unit_name_build_escape("cryptsetup", name, ".service");
++ if (!n) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit name.");
+ goto fail;
+ }
+
+- if (asprintf(&p, "%s/%s", arg_dest, n) < 0) {
++ p = join(arg_dest, "/", n, NULL);
++ if (!p) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit file name.");
+ goto fail;
+ }
+
+- if (!(u = fstab_node_to_udev_node(device))) {
++ u = fstab_node_to_udev_node(device);
++ if (!u) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device node.");
+ goto fail;
+ }
+
+- if (!(d = unit_name_from_path(u, ".device"))) {
++ d = unit_name_from_path(u, ".device");
++ if (!d) {
+ r = -ENOMEM;
+ log_error("Failed to allocate device name.");
+ goto fail;
+ }
+
+- if (!(f = fopen(p, "wxe"))) {
++ f = fopen(p, "wxe");
++ if (!f) {
+ r = -errno;
+ log_error("Failed to create unit file: %m");
+ goto fail;
+@@ -164,13 +169,13 @@ static int create_disk(
+
+ if (!noauto) {
+
+- if (asprintf(&to, "%s/%s.wants/%s", arg_dest, d, n) < 0) {
++ to = join(arg_dest, "/", d, ".wants/", n, NULL);
++ if (!to) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+-
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+@@ -178,38 +183,35 @@ static int create_disk(
+ }
+
+ free(to);
+- to = NULL;
+
+ if (!nofail)
+- asprintf(&to, "%s/cryptsetup.target.requires/%s", arg_dest, n);
++ to = join(arg_dest, "/cryptsetup.target.requires/", n, NULL);
+ else
+- asprintf(&to, "%s/cryptsetup.target.wants/%s", arg_dest, n);
+-
++ to = join(arg_dest, "/cryptsetup.target.wants/", n, NULL);
+ if (!to) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+-
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+ goto fail;
+ }
+- }
+
+- free(to);
+- to = NULL;
++ free(to);
++ to = NULL;
++ }
+
+ e = unit_name_escape(name);
+- if (asprintf(&to, "%s/dev-mapper-%s.device.requires/%s", arg_dest, e, n) < 0) {
++ to = join(arg_dest, "/dev-mapper-", e, ".device.requires/", n, NULL);
++ if (!to) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ mkdir_parents(to, 0755);
+-
+ if (symlink(from, to) < 0) {
+ log_error("Failed to create symlink '%s' to '%s': %m", from, to);
+ r = -errno;
+@@ -252,7 +254,8 @@ int main(int argc, char *argv[]) {
+
+ umask(0022);
+
+- if (!(f = fopen("/etc/crypttab", "re"))) {
++ f = fopen("/etc/crypttab", "re");
++ if (!f) {
+
+ if (errno == ENOENT)
+ r = EXIT_SUCCESS;
+@@ -269,7 +272,7 @@ int main(int argc, char *argv[]) {
+ char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
+ int k;
+
+- if (!(fgets(line, sizeof(line), f)))
++ if (!fgets(line, sizeof(line), f))
+ break;
+
+ n++;
+@@ -278,7 +281,8 @@ int main(int argc, char *argv[]) {
+ if (*l == '#' || *l == 0)
+ continue;
+
+- if ((k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options)) < 2 || k > 4) {
++ k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
++ if (k < 2 || k > 4) {
+ log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
+ r = EXIT_FAILURE;
+ goto next;
diff --git a/0307-service-make-the-fsck-pass-no-configurable.patch b/0307-service-make-the-fsck-pass-no-configurable.patch
new file mode 100644
index 0000000..7ae8f9e
--- /dev/null
+++ b/0307-service-make-the-fsck-pass-no-configurable.patch
@@ -0,0 +1,43 @@
+From 8c10c743a15e2352ddf8e4ceeb52af6ac16e57af Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 17:24:26 +0200
+Subject: [PATCH] service: make the fsck pass no configurable (cherry picked
+ from commit 36140842612803d71fe771ce03f3dee7732284f0)
+
+---
+ man/systemd.service.xml | 9 +++++++++
+ src/core/load-fragment-gperf.gperf.m4 | 1 +
+ 2 files changed, 10 insertions(+)
+
+diff --git a/man/systemd.service.xml b/man/systemd.service.xml
+index 9a80dd7..430971f 100644
+--- a/man/systemd.service.xml
++++ b/man/systemd.service.xml
+@@ -824,6 +824,15 @@
+ <option>none</option>.</para></listitem>
+ </varlistentry>
+
++ <varlistentry>
++ <term><varname>FsckPassNo=</varname></term>
++
++ <listitem><para>If this is an file
++ system checking service specify the
++ pass number. This should not be used
++ for normal services.</para></listitem>
++ </varlistentry>
++
+ </variablelist>
+ </refsect1>
+
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index 5be4dad..681f2e9 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -200,6 +200,7 @@ Mount.What, config_parse_string, 0,
+ Mount.Where, config_parse_path, 0, offsetof(Mount, where)
+ Mount.Options, config_parse_string, 0, offsetof(Mount, parameters_fragment.options)
+ Mount.Type, config_parse_string, 0, offsetof(Mount, parameters_fragment.fstype)
++Mount.FsckPassNo, config_parse_int, 0, offsetof(Mount, parameters_fragment.passno)
+ Mount.TimeoutSec, config_parse_usec, 0, offsetof(Mount, timeout_usec)
+ Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
+ EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
diff --git a/0308-main-try-a-bit-harder-to-find-an-init-process-to-exe.patch b/0308-main-try-a-bit-harder-to-find-an-init-process-to-exe.patch
new file mode 100644
index 0000000..e454fa4
--- /dev/null
+++ b/0308-main-try-a-bit-harder-to-find-an-init-process-to-exe.patch
@@ -0,0 +1,59 @@
+From 4aad592811be7854bf2a682c5a1a9c83b7820ed7 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 17:26:19 +0200
+Subject: [PATCH] main: try a bit harder to find an init process to execute
+ after reexec/switch-root (cherry picked from commit
+ b8f8323268ae974288e49a7cc6c1c47531e436c9)
+
+---
+ src/core/main.c | 28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index c2a8922..3aeaa14 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1690,22 +1690,36 @@ finish:
+ * getopt() in argv[], and some cleanups in envp[],
+ * but let's hope that doesn't matter.) */
+
+- if (serialization)
++ if (serialization) {
+ fclose(serialization);
++ serialization = NULL;
++ }
+
+- if (fds)
++ if (fds) {
+ fdset_free(fds);
++ fds = NULL;
++ }
+
+- i = 0;
+- args[i++] = switch_root_init ? switch_root_init : "/sbin/init";
+- for (j = 1; j < argc; j++)
++ for (j = 1, i = 1; j < argc; j++)
+ args[i++] = argv[j];
+ args[i++] = NULL;
+-
+ assert(i <= args_size);
++
++ if (switch_root_init) {
++ args[0] = switch_root_init;
++ execv(args[0], (char* const*) args);
++ log_warning("Failed to execute configured init, trying fallback: %m");
++ }
++
++ args[0] = "/sbin/init";
+ execv(args[0], (char* const*) args);
+
+- log_error("Failed to reexecute: %m");
++ log_warning("Failed to execute /sbin/init, trying fallback: %m");
++
++ args[0] = "/bin/sh";
++ args[1] = NULL;
++ execv(args[0], (char* const*) args);
++ log_error("Failed to execute /bin/sh, giving up: %m");
+ }
+
+ if (serialization)
diff --git a/0309-cryptsetup-support-discards-TRIM.patch b/0309-cryptsetup-support-discards-TRIM.patch
new file mode 100644
index 0000000..6494524
--- /dev/null
+++ b/0309-cryptsetup-support-discards-TRIM.patch
@@ -0,0 +1,41 @@
+From d18edda2b90b533163a5eb848329414a1d8ac0bc Mon Sep 17 00:00:00 2001
+From: Matthew Monaco <matthew.monaco at 0x01b.net>
+Date: Sat, 19 May 2012 09:05:50 -0600
+Subject: [PATCH] cryptsetup: support discards (TRIM) (cherry picked from
+ commit 2a2aab602e1d8b6bf0b440730e379f9dd6586b80)
+
+---
+ src/cryptsetup/cryptsetup.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
+index f3116b7..c6ac7d2 100644
+--- a/src/cryptsetup/cryptsetup.c
++++ b/src/cryptsetup/cryptsetup.c
+@@ -41,6 +41,7 @@ static char *opt_hash = NULL;
+ static unsigned opt_tries = 0;
+ static bool opt_readonly = false;
+ static bool opt_verify = false;
++static bool opt_discards = false;
+ static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC;
+
+ /* Options Debian's crypttab knows we don't:
+@@ -98,6 +99,8 @@ static int parse_one_option(const char *option) {
+ opt_readonly = true;
+ else if (streq(option, "verify"))
+ opt_verify = true;
++ else if (streq(option, "allow-discards"))
++ opt_discards = true;
+ else if (streq(option, "luks"))
+ opt_type = CRYPT_LUKS1;
+ else if (streq(option, "plain") ||
+@@ -314,6 +317,9 @@ int main(int argc, char *argv[]) {
+ if (opt_readonly)
+ flags |= CRYPT_ACTIVATE_READONLY;
+
++ if (opt_discards)
++ flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
++
+ if (opt_timeout > 0)
+ until = now(CLOCK_MONOTONIC) + opt_timeout;
+ else
diff --git a/0310-journalctl-fix-built-in-usage-output.patch b/0310-journalctl-fix-built-in-usage-output.patch
new file mode 100644
index 0000000..9904117
--- /dev/null
+++ b/0310-journalctl-fix-built-in-usage-output.patch
@@ -0,0 +1,26 @@
+From 91dd3e2f04af31ad3666b45a9d0c46ec9214b22b Mon Sep 17 00:00:00 2001
+From: Daniel Mack <zonque at gmail.com>
+Date: Fri, 18 May 2012 21:58:35 +0200
+Subject: [PATCH] journalctl: fix built-in usage output
+
+This brings journalctl's built-in usage output in sync with the man page.
+There are no commands to pass, and the help screen should not confuse
+users.
+(cherry picked from commit 89834a7c1c5f194d072d42d1c30077f5b2c207ec)
+---
+ src/journal/journalctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
+index 01dceca..aaf455a 100644
+--- a/src/journal/journalctl.c
++++ b/src/journal/journalctl.c
+@@ -50,7 +50,7 @@ static bool arg_local = false;
+
+ static int help(void) {
+
+- printf("%s [OPTIONS...] {COMMAND} ...\n\n"
++ printf("%s [OPTIONS...] [MATCH]\n\n"
+ "Send control commands to or query the journal.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
diff --git a/0311-sd-pam-Drop-uid-so-parent-signal-arrives-at-child.patch b/0311-sd-pam-Drop-uid-so-parent-signal-arrives-at-child.patch
new file mode 100644
index 0000000..854b6b1
--- /dev/null
+++ b/0311-sd-pam-Drop-uid-so-parent-signal-arrives-at-child.patch
@@ -0,0 +1,66 @@
+From 9cc7fb8ed3f76e9156a3f8f0b9d707f2707ec980 Mon Sep 17 00:00:00 2001
+From: Auke Kok <auke-jan.h.kok at intel.com>
+Date: Thu, 17 May 2012 12:17:42 -0700
+Subject: [PATCH] sd-pam: Drop uid so parent signal arrives at child.
+
+The PAM helper thread needs to capture the death signal from the
+parent, but is prohibited from doing so since when the child dies
+as normal user, the kernel won't allow it to send a TERM to the
+PAM helper thread which is running as root.
+
+This causes the PAM threads to never exit, accumulating after
+user sessions exit.
+
+There is however really no need to keep the PAM threads running as
+root, so, we can just setresuid() to the same user as defined in the
+unit file for the parent thread (User=). This makes the TERM signal
+arrive as normal. In case setresuid() fails, we ignore the error, so
+we at least fall back to the current behaviour.
+(cherry picked from commit 940c5210344e90428287e4f8878a9064e8869e22)
+---
+ src/core/execute.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/execute.c b/src/core/execute.c
+index dad709a..bd6c781 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -703,6 +703,7 @@ static int null_conv(
+ static int setup_pam(
+ const char *name,
+ const char *user,
++ uid_t uid,
+ const char *tty,
+ char ***pam_env,
+ int fds[], unsigned n_fds) {
+@@ -781,10 +782,17 @@ static int setup_pam(
+ open here that have been opened by PAM. */
+ close_many(fds, n_fds);
+
+- /* Wait until our parent died. This will most likely
+- * not work since the kernel does not allow
+- * unprivileged parents kill their privileged children
+- * this way. We rely on the control groups kill logic
++ /* Drop privileges - we don't need any to pam_close_session
++ * and this will make PR_SET_PDEATHSIG work in most cases.
++ * If this fails, ignore the error - but expect sd-pam threads
++ * to fail to exit normally */
++ if (setresuid(uid, uid, uid) < 0)
++ log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
++
++ /* Wait until our parent died. This will only work if
++ * the above setresuid() succeeds, otherwise the kernel
++ * will not allow unprivileged parents kill their privileged
++ * children this way. We rely on the control groups kill logic
+ * to do the rest for us. */
+ if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
+ goto child_finish;
+@@ -1294,7 +1302,7 @@ int exec_spawn(ExecCommand *command,
+
+ #ifdef HAVE_PAM
+ if (context->pam_name && username) {
+- err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds);
++ err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
+ if (err < 0) {
+ r = EXIT_PAM;
+ goto fail_child;
diff --git a/0312-util-fix-typo-in-newdup.patch b/0312-util-fix-typo-in-newdup.patch
new file mode 100644
index 0000000..2b7a1dc
--- /dev/null
+++ b/0312-util-fix-typo-in-newdup.patch
@@ -0,0 +1,23 @@
+From 636337f29f6a2d146d769168a48f37c881f4e3aa Mon Sep 17 00:00:00 2001
+From: Frederic Crozat <fcrozat at suse.com>
+Date: Mon, 21 May 2012 16:53:18 +0200
+Subject: [PATCH] util: fix typo in newdup (cherry picked from commit
+ 4d768ced49dfcd53a2372b69c3187f701ce7e331)
+
+---
+ src/shared/util.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/shared/util.h b/src/shared/util.h
+index c08c6f9..a0060f7 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -103,7 +103,7 @@ bool streq_ptr(const char *a, const char *b);
+
+ #define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
+
+-#define newdup(t, p, n) ((t*) memdup(p, sizeof(t)*(n))
++#define newdup(t, p, n) ((t*) memdup(p, sizeof(t)*(n)))
+
+ #define malloc0(n) (calloc((n), 1))
+
diff --git a/0313-delta-fix-spelling-of-overridden.patch b/0313-delta-fix-spelling-of-overridden.patch
new file mode 100644
index 0000000..82f840d
--- /dev/null
+++ b/0313-delta-fix-spelling-of-overridden.patch
@@ -0,0 +1,167 @@
+From 9126d7bacbcd8f65599c8853bbe8303174c53a34 Mon Sep 17 00:00:00 2001
+From: Nis Martensen <nis.martensen at web.de>
+Date: Wed, 16 May 2012 22:49:30 +0200
+Subject: [PATCH] delta: fix spelling of overridden (cherry picked from commit
+ 386da8589b4206b7fc5f5729908473edacbee013)
+
+---
+ man/systemd-delta.xml | 12 ++++++------
+ man/systemd-journald.conf.xml | 2 +-
+ src/delta/delta.c | 24 ++++++++++++------------
+ src/systemctl/systemctl.c | 2 +-
+ 4 files changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/man/systemd-delta.xml b/man/systemd-delta.xml
+index 03c7178..523b590 100644
+--- a/man/systemd-delta.xml
++++ b/man/systemd-delta.xml
+@@ -67,7 +67,7 @@
+ <filename>systemd/system</filename>.</para>
+
+ <para>When no argument is specified a number of
+- well-known subdirectories are searched for overriden
++ well-known subdirectories are searched for overridden
+ files.</para>
+ </refsect1>
+
+@@ -121,8 +121,8 @@
+ <varlistentry>
+ <term><varname>equivalent</varname></term>
+
+- <listitem><para>Show overriden
+- files that while overriden, do
++ <listitem><para>Show overridden
++ files that while overridden, do
+ not differ in content.</para></listitem>
+ </varlistentry>
+
+@@ -134,9 +134,9 @@
+ </varlistentry>
+
+ <varlistentry>
+- <term><varname>overriden</varname></term>
++ <term><varname>overridden</varname></term>
+
+- <listitem><para>Show overriden,
++ <listitem><para>Show overridden,
+ and changed files.</para></listitem>
+ </varlistentry>
+
+@@ -154,7 +154,7 @@
+ <term><option>--diff=</option></term>
+
+ <listitem><para>When showing modified
+- files, when a file is overriden show a
++ files, when a file is overridden show a
+ diff aswell. This option takes a
+ boolean argument.</para></listitem>
+ </varlistentry>
+diff --git a/man/systemd-journald.conf.xml b/man/systemd-journald.conf.xml
+index 6206164..e96bbb1 100644
+--- a/man/systemd-journald.conf.xml
++++ b/man/systemd-journald.conf.xml
+@@ -208,7 +208,7 @@
+ is running the respective option has
+ no effect. By default only forwarding
+ to syslog is enabled. These settings
+- may be overriden at boot time with the
++ may be overridden at boot time with the
+ kernel command line options
+ <literal>systemd_journald.forward_to_syslog=</literal>,
+ <literal>systemd_journald.forward_to_kmsg=</literal>
+diff --git a/src/delta/delta.c b/src/delta/delta.c
+index 25c1f96..1a5b08a 100644
+--- a/src/delta/delta.c
++++ b/src/delta/delta.c
+@@ -39,11 +39,11 @@ static enum {
+ SHOW_MASKED = 1 << 0,
+ SHOW_EQUIVALENT = 1 << 1,
+ SHOW_REDIRECTED = 1 << 2,
+- SHOW_OVERRIDEN = 1 << 3,
++ SHOW_OVERRIDDEN = 1 << 3,
+ SHOW_UNCHANGED = 1 << 4,
+
+ SHOW_DEFAULTS =
+- (SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDEN)
++ (SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN)
+ } arg_flags = 0;
+
+ static int equivalent(const char *a, const char *b) {
+@@ -91,11 +91,11 @@ static int notify_override_redirected(const char *top, const char *bottom) {
+ return 1;
+ }
+
+-static int notify_override_overriden(const char *top, const char *bottom) {
+- if (!(arg_flags & SHOW_OVERRIDEN))
++static int notify_override_overridden(const char *top, const char *bottom) {
++ if (!(arg_flags & SHOW_OVERRIDDEN))
+ return 0;
+
+- printf(ANSI_HIGHLIGHT_ON "[OVERRIDEN]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom);
++ printf(ANSI_HIGHLIGHT_ON "[OVERRIDDEN]" ANSI_HIGHLIGHT_OFF " %s → %s\n", top, bottom);
+ return 1;
+ }
+
+@@ -131,7 +131,7 @@ static int found_override(const char *top, const char *bottom) {
+ goto finish;
+ }
+
+- notify_override_overriden(top, bottom);
++ notify_override_overridden(top, bottom);
+ if (!arg_diff)
+ goto finish;
+
+@@ -324,7 +324,7 @@ static void help(void) {
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --no-pager Do not pipe output into a pager\n"
+- " --diff[=1|0] Show a diff when overriden files differ\n"
++ " --diff[=1|0] Show a diff when overridden files differ\n"
+ " -t --type=LIST... Only display a selected set of override types\n",
+ program_invocation_short_name);
+ }
+@@ -340,8 +340,8 @@ static int parse_flags(const char *flag_str, int flags) {
+ flags |= SHOW_EQUIVALENT;
+ else if (strncmp("redirected", w, l) == 0)
+ flags |= SHOW_REDIRECTED;
+- else if (strncmp("overriden", w, l) == 0)
+- flags |= SHOW_OVERRIDEN;
++ else if (strncmp("overridden", w, l) == 0)
++ flags |= SHOW_OVERRIDDEN;
+ else if (strncmp("unchanged", w, l) == 0)
+ flags |= SHOW_UNCHANGED;
+ else if (strncmp("default", w, l) == 0)
+@@ -472,9 +472,9 @@ int main(int argc, char *argv[]) {
+ arg_flags = SHOW_DEFAULTS;
+
+ if (arg_diff < 0)
+- arg_diff = !!(arg_flags & SHOW_OVERRIDEN);
++ arg_diff = !!(arg_flags & SHOW_OVERRIDDEN);
+ else if (arg_diff)
+- arg_flags |= SHOW_OVERRIDEN;
++ arg_flags |= SHOW_OVERRIDDEN;
+
+ if (!arg_no_pager)
+ pager_open();
+@@ -503,7 +503,7 @@ int main(int argc, char *argv[]) {
+ }
+
+ if (r >= 0)
+- printf("\n%i overriden configuration files found.\n", n_found);
++ printf("\n%i overridden configuration files found.\n", n_found);
+
+ finish:
+ pager_close();
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 2c2f637..ba3d3be 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -4284,7 +4284,7 @@ static int shutdown_help(void) {
+ " -H --halt Halt the machine\n"
+ " -P --poweroff Power-off the machine\n"
+ " -r --reboot Reboot the machine\n"
+- " -h Equivalent to --poweroff, overriden by --halt\n"
++ " -h Equivalent to --poweroff, overridden by --halt\n"
+ " -k Don't halt/power-off/reboot, just send warnings\n"
+ " --no-wall Don't send wall message before halt/power-off/reboot\n"
+ " -c Cancel a pending shutdown\n",
diff --git a/0314-main-corrected-do_switch_root.patch b/0314-main-corrected-do_switch_root.patch
new file mode 100644
index 0000000..d8d8c5e
--- /dev/null
+++ b/0314-main-corrected-do_switch_root.patch
@@ -0,0 +1,123 @@
+From e047c9fb179b374b1c01e4b909a23ce0a7d53dc2 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:39 +0200
+Subject: [PATCH] main: corrected do_switch_root()
+
+do_switch_root now mount moves "/dev", "/proc", "/sys", "/run" and
+removes the old root recursively.
+(cherry picked from commit f67cc036ba92a3c71acb664ed2d548de5827cf1f)
+---
+ src/core/main.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++------
+ src/shared/util.c | 2 +-
+ src/shared/util.h | 1 +
+ 3 files changed, 51 insertions(+), 7 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 3aeaa14..242b0bb 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1172,30 +1172,73 @@ static void test_cgroups(void) {
+ }
+
+ static int do_switch_root(const char *switch_root) {
+- int r;
++ int r=0;
++ /* Don't try to unmount the old "/", there's no way to do it. */
++ const char *umounts[] = { "/dev", "/proc", "/sys", "/run", NULL };
++ int i;
++ int cfd = -1;
++ struct stat switch_root_stat, sb;
+
+ if (path_equal(switch_root, "/"))
+ return 0;
+
+- if (chdir(switch_root) < 0) {
++ if (stat(switch_root, &switch_root_stat) != 0) {
+ r = -errno;
++ log_error("failed to stat directory %s", switch_root);
+ goto fail;
+ }
+
++ for (i = 0; umounts[i] != NULL; i++) {
++ char newmount[PATH_MAX];
++
++ snprintf(newmount, sizeof(newmount), "%s%s", switch_root, umounts[i]);
++
++ if ((stat(newmount, &sb) != 0) || (sb.st_dev != switch_root_stat.st_dev)) {
++ /* mount point seems to be mounted already or stat failed */
++ umount2(umounts[i], MNT_DETACH);
++ continue;
++ }
++
++ if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) {
++ log_error("failed to mount moving %s to %s",
++ umounts[i], newmount);
++ log_error("forcing unmount of %s", umounts[i]);
++ umount2(umounts[i], MNT_FORCE);
++ }
++ }
++
++ if (chdir(switch_root)) {
++ r = -errno;
++ log_error("failed to change directory to %s", switch_root);
++ goto fail;
++ }
++
++ cfd = open("/", O_RDONLY);
++
+ if (mount(switch_root, "/", NULL, MS_MOVE, NULL) < 0) {
+ r = -errno;
+- chdir("/");
++ log_error("failed to mount moving %s to /", switch_root);
+ goto fail;
+ }
+
+- if (chroot(".") < 0)
+- log_warning("Failed to change root, ignoring: %m");
++ if (chroot(".")) {
++ r = -errno;
++ log_error("failed to change root");
++ goto fail;
++ }
+
+- /* FIXME: remove old root */
++ if (cfd >= 0) {
++ rm_rf_children(cfd, false, false);
++ close(cfd);
++ cfd=-1;
++ }
+
+ return 0;
+
+ fail:
++ if (cfd >= 0)
++ close(cfd);
++
+ log_error("Failed to switch root, ignoring: %s", strerror(-r));
+
+ return r;
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 29d1f04..61a6ad9 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -3139,7 +3139,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
+ return 0;
+ }
+
+-static int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) {
++int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) {
+ DIR *d;
+ int ret = 0;
+
+diff --git a/src/shared/util.h b/src/shared/util.h
+index a0060f7..d338b08 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -349,6 +349,7 @@ int get_ctty(pid_t, dev_t *_devnr, char **r);
+ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
+ int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
+
++int rm_rf_children(int fd, bool only_dirs, bool honour_sticky);
+ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
+
+ int pipe_eof(int fd);
diff --git a/0315-util.c-add-in_initrd.patch b/0315-util.c-add-in_initrd.patch
new file mode 100644
index 0000000..dee9304
--- /dev/null
+++ b/0315-util.c-add-in_initrd.patch
@@ -0,0 +1,46 @@
+From 1f5ddedec35efb92c30a86ae300ce6bc11050044 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:40 +0200
+Subject: [PATCH] util.c: add in_initrd()
+
+in_initrd() checks, if the stat() for the device for "/" is 1, which it
+is for the initramfs.
+(cherry picked from commit 9be346c94eab9de0edc30f08b6c6d070c3a17c79)
+---
+ src/shared/util.c | 15 +++++++++++++++
+ src/shared/util.h | 1 +
+ 2 files changed, 16 insertions(+)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 61a6ad9..1254017 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -5639,3 +5639,18 @@ bool is_valid_documentation_url(const char *url) {
+
+ return false;
+ }
++
++bool in_initrd(void) {
++ static bool checked=false;
++ static bool is_in_initrd=false;
++
++ if (!checked) {
++ struct stat sb;
++ if (stat("/", &sb) == 0) {
++ is_in_initrd = (sb.st_dev == 1);
++ checked = true;
++ }
++ }
++
++ return is_in_initrd;
++}
+diff --git a/src/shared/util.h b/src/shared/util.h
+index d338b08..a47f0b1 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -512,4 +512,5 @@ int can_sleep(const char *type);
+
+ bool is_valid_documentation_url(const char *url);
+
++bool in_initrd(void);
+ #endif
diff --git a/0316-manager-only-serialize-the-timestamps-for-the-initra.patch b/0316-manager-only-serialize-the-timestamps-for-the-initra.patch
new file mode 100644
index 0000000..3a12f61
--- /dev/null
+++ b/0316-manager-only-serialize-the-timestamps-for-the-initra.patch
@@ -0,0 +1,29 @@
+From 2d454c1d8d3f21d42ebfb2e1a3bd94b44ea75f17 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:41 +0200
+Subject: [PATCH] manager: only serialize the timestamps for the initramfs if
+ in_initrd() (cherry picked from commit
+ f38ed060600d124a68332694ab497c344bd8e089)
+
+---
+ src/core/manager.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/manager.c b/src/core/manager.c
+index 13d1ef5..c7d3e60 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -1735,8 +1735,11 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
+ fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr));
+
+ dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp);
+- dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
+- dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
++
++ if (! in_initrd()) {
++ dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp);
++ dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
++ }
+
+ fputc('\n', f);
+
diff --git a/0317-core-main.c-add-switchedroot-parameter.patch b/0317-core-main.c-add-switchedroot-parameter.patch
new file mode 100644
index 0000000..13ed887
--- /dev/null
+++ b/0317-core-main.c-add-switchedroot-parameter.patch
@@ -0,0 +1,78 @@
+From 10860202b2afc50055a8d655ca68f3ddd2b2a18e Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:42 +0200
+Subject: [PATCH] core/main.c: add "--switchedroot" parameter
+
+If systemd serializes from a switch_root, it adds "--switchedroot" to
+the systemd in the real root.
+
+If "--switchedroot" is found, then we do not skip all the stuff, which
+is skipped for normal rexecs.
+(cherry picked from commit d03bc1b814b853497120c35a9a8d6a66925963ff)
+---
+ src/core/main.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 242b0bb..02cf5cb 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -750,6 +750,7 @@ static int parse_argv(int argc, char *argv[]) {
+ ARG_SHOW_STATUS,
+ ARG_SYSV_CONSOLE,
+ ARG_DESERIALIZE,
++ ARG_SWITCHEDROOT,
+ ARG_INTROSPECT,
+ ARG_DEFAULT_STD_OUTPUT,
+ ARG_DEFAULT_STD_ERROR
+@@ -774,6 +775,7 @@ static int parse_argv(int argc, char *argv[]) {
+ { "sysv-console", optional_argument, NULL, ARG_SYSV_CONSOLE },
+ #endif
+ { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
++ { "switchedroot", no_argument, NULL, ARG_SWITCHEDROOT },
+ { "introspect", optional_argument, NULL, ARG_INTROSPECT },
+ { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
+ { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
+@@ -945,6 +947,10 @@ static int parse_argv(int argc, char *argv[]) {
+ break;
+ }
+
++ case ARG_SWITCHEDROOT:
++ /* Nothing special yet */
++ break;
++
+ case ARG_INTROSPECT: {
+ const char * const * i = NULL;
+
+@@ -1282,6 +1288,13 @@ int main(int argc, char *argv[]) {
+ break;
+ }
+
++ /* If we have switched root, do all the special things */
++ for (j = 1; j < argc; j++)
++ if (streq(argv[j], "--switchedroot")) {
++ is_reexec = false;
++ break;
++ }
++
+ /* If we get started via the /sbin/init symlink then we are
+ called 'init'. After a subsequent reexecution we are then
+ called 'systemd'. That is confusing, hence let's call us
+@@ -1699,7 +1712,7 @@ finish:
+ if (switch_root)
+ do_switch_root(switch_root);
+
+- args_size = MAX(5, argc+1);
++ args_size = MAX(6, argc+1);
+ args = newa(const char*, args_size);
+
+ if (!switch_root_init) {
+@@ -1718,6 +1731,8 @@ finish:
+
+ i = 0;
+ args[i++] = SYSTEMD_BINARY_PATH;
++ if (switch_root)
++ args[i++] = "--switchedroot";
+ args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
+ args[i++] = "--deserialize";
+ args[i++] = sfd;
diff --git a/0318-core-main.c-do_switch_root-do-not-remove-the-old-roo.patch b/0318-core-main.c-do_switch_root-do-not-remove-the-old-roo.patch
new file mode 100644
index 0000000..ad57164
--- /dev/null
+++ b/0318-core-main.c-do_switch_root-do-not-remove-the-old-roo.patch
@@ -0,0 +1,44 @@
+From d8affe22f2a7cbebe28b15a0ef32c675bdaa0550 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:43 +0200
+Subject: [PATCH] core/main.c: do_switch_root(): do not remove the old root if
+ not in initrd
+
+Only recursively remove the old root, if we have been in an
+initrd/initramfs.
+(cherry picked from commit e148ac5a6cccd1c9c23bf7b3085b50fdb1cd1cf9)
+---
+ src/core/main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 02cf5cb..b4ff358 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1184,6 +1184,7 @@ static int do_switch_root(const char *switch_root) {
+ int i;
+ int cfd = -1;
+ struct stat switch_root_stat, sb;
++ bool remove_old_root;
+
+ if (path_equal(switch_root, "/"))
+ return 0;
+@@ -1194,6 +1195,8 @@ static int do_switch_root(const char *switch_root) {
+ goto fail;
+ }
+
++ remove_old_root = in_initrd();
++
+ for (i = 0; umounts[i] != NULL; i++) {
+ char newmount[PATH_MAX];
+
+@@ -1219,7 +1222,8 @@ static int do_switch_root(const char *switch_root) {
+ goto fail;
+ }
+
+- cfd = open("/", O_RDONLY);
++ if (remove_old_root)
++ cfd = open("/", O_RDONLY);
+
+ if (mount(switch_root, "/", NULL, MS_MOVE, NULL) < 0) {
+ r = -errno;
diff --git a/0319-core-main.c-handle-the-initrd-timestamp-differently-.patch b/0319-core-main.c-handle-the-initrd-timestamp-differently-.patch
new file mode 100644
index 0000000..e102738
--- /dev/null
+++ b/0319-core-main.c-handle-the-initrd-timestamp-differently-.patch
@@ -0,0 +1,47 @@
+From 07e50f5f0cd6ef4b3aa36ec190df9860523d18bb Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:44 +0200
+Subject: [PATCH] core/main.c: handle the initrd timestamp differently, if in
+ the initrd
+
+If systemd is in the initrd/initramfs, set the initrd timestamp and do
+not try to read it from the RD_TIMESTAMP environment variable.
+(cherry picked from commit c3ba62509efe274c2bf6482056044e6fab65fec0)
+---
+ src/core/main.c | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index b4ff358..c42356d 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1314,6 +1314,19 @@ int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_INFO);
+
+ if (getpid() == 1) {
++ if (in_initrd()) {
++ char *rd_timestamp = NULL;
++
++ dual_timestamp_get(&initrd_timestamp);
++ asprintf(&rd_timestamp, "%llu %llu",
++ (unsigned long long) initrd_timestamp.realtime,
++ (unsigned long long) initrd_timestamp.monotonic);
++ if (rd_timestamp) {
++ setenv("RD_TIMESTAMP", rd_timestamp, 1);
++ free(rd_timestamp);
++ }
++ }
++
+ arg_running_as = MANAGER_SYSTEM;
+ log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_JOURNAL : LOG_TARGET_JOURNAL_OR_KMSG);
+
+@@ -1441,7 +1454,8 @@ int main(int argc, char *argv[]) {
+ /* Parse the data passed to us. We leave this
+ * variables set, but the manager later on will not
+ * pass them on to our children. */
+- parse_initrd_timestamp(&initrd_timestamp);
++ if(!in_initrd())
++ parse_initrd_timestamp(&initrd_timestamp);
+
+ /* Unset some environment variables passed in from the
+ * kernel that don't really make sense for us. */
diff --git a/0320-delta-delta.c-initialize-bottom-for-fail-state.patch b/0320-delta-delta.c-initialize-bottom-for-fail-state.patch
new file mode 100644
index 0000000..ad7bea0
--- /dev/null
+++ b/0320-delta-delta.c-initialize-bottom-for-fail-state.patch
@@ -0,0 +1,24 @@
+From 91276ef7c74d0234e2b7f52ffd15c77e969f9a59 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 14:22:45 +0200
+Subject: [PATCH] delta/delta.c: initialize bottom for fail state (cherry
+ picked from commit
+ d966a7b3631a54602297ef3bff1dcaf35cbefd12)
+
+---
+ src/delta/delta.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/delta/delta.c b/src/delta/delta.c
+index 1a5b08a..4694fc8 100644
+--- a/src/delta/delta.c
++++ b/src/delta/delta.c
+@@ -231,7 +231,7 @@ finish:
+ static int process_suffix(const char *prefixes, const char *suffix) {
+ const char *p;
+ char *f;
+- Hashmap *top, *bottom;
++ Hashmap *top, *bottom=NULL;
+ int r = 0, k;
+ Iterator i;
+ int n_found = 0;
diff --git a/0321-util-rm_rf_children-add-root_dev-parameter.patch b/0321-util-rm_rf_children-add-root_dev-parameter.patch
new file mode 100644
index 0000000..f656157
--- /dev/null
+++ b/0321-util-rm_rf_children-add-root_dev-parameter.patch
@@ -0,0 +1,98 @@
+From fac7cd41ce3744efaddd60b8d96d41b5fc83a679 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 15:08:27 +0200
+Subject: [PATCH] util: rm_rf_children() add root_dev parameter
+
+if root_dev is set, remove subdirectories only, if the device is the
+same as the root_dev. This prevents to remove files across device
+boundaries.
+(cherry picked from commit 597f43c7849dc9fc9aeb806f8d4f9679cabce8e6)
+---
+ src/shared/util.c | 39 ++++++++++++++++++++++++++-------------
+ src/shared/util.h | 2 +-
+ 2 files changed, 27 insertions(+), 14 deletions(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 1254017..83b4a24 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -3139,7 +3139,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
+ return 0;
+ }
+
+-int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) {
++int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
+ DIR *d;
+ int ret = 0;
+
+@@ -3208,24 +3208,37 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) {
+
+ if (is_dir) {
+ int subdir_fd;
+-
+- subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+- if (subdir_fd < 0) {
+- if (ret == 0 && errno != ENOENT)
+- ret = -errno;
+- continue;
++ struct stat sb;
++ if (root_dev) {
++ if (fstatat(fd, de->d_name, &sb, AT_SYMLINK_NOFOLLOW)) {
++ if (ret == 0 && errno != ENOENT)
++ ret = -errno;
++ continue;
++ }
+ }
+
+- r = rm_rf_children(subdir_fd, only_dirs, honour_sticky);
+- if (r < 0 && ret == 0)
+- ret = r;
++ /* if root_dev is set, remove subdirectories only, if device is same as dir */
++ if ((root_dev == NULL) || (sb.st_dev == root_dev->st_dev)) {
+
+- if (!keep_around)
+- if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
++ subdir_fd = openat(fd, de->d_name,
++ O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
++ if (subdir_fd < 0) {
+ if (ret == 0 && errno != ENOENT)
+ ret = -errno;
++ continue;
+ }
+
++ r = rm_rf_children(subdir_fd, only_dirs, honour_sticky, root_dev);
++ if (r < 0 && ret == 0)
++ ret = r;
++
++ if (!keep_around)
++ if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
++ if (ret == 0 && errno != ENOENT)
++ ret = -errno;
++ }
++ }
++
+ } else if (!only_dirs && !keep_around) {
+
+ if (unlinkat(fd, de->d_name, 0) < 0) {
+@@ -3259,7 +3272,7 @@ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky
+ return 0;
+ }
+
+- r = rm_rf_children(fd, only_dirs, honour_sticky);
++ r = rm_rf_children(fd, only_dirs, honour_sticky, NULL);
+
+ if (delete_root) {
+
+diff --git a/src/shared/util.h b/src/shared/util.h
+index a47f0b1..38574d9 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -349,7 +349,7 @@ int get_ctty(pid_t, dev_t *_devnr, char **r);
+ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
+ int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
+
+-int rm_rf_children(int fd, bool only_dirs, bool honour_sticky);
++int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev);
+ int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
+
+ int pipe_eof(int fd);
diff --git a/0322-main-do_switch_root-do-not-recursively-remove-across.patch b/0322-main-do_switch_root-do-not-recursively-remove-across.patch
new file mode 100644
index 0000000..d7ee7f3
--- /dev/null
+++ b/0322-main-do_switch_root-do-not-recursively-remove-across.patch
@@ -0,0 +1,31 @@
+From e88aff92ae49cb5780b1f9bb916c25f7bb270aa7 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Wed, 16 May 2012 15:08:28 +0200
+Subject: [PATCH] main: do_switch_root() do not recursively remove across
+ device boundaries (cherry picked from commit
+ 97a66e94700845239cfe628da3569ac06034fa4d)
+
+---
+ src/core/main.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index c42356d..76280ad 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1238,7 +1238,14 @@ static int do_switch_root(const char *switch_root) {
+ }
+
+ if (cfd >= 0) {
+- rm_rf_children(cfd, false, false);
++ struct stat rb;
++
++ if (fstat(cfd, &rb)) {
++ log_error("failed to stat old root directory");
++ goto fail;
++ }
++
++ rm_rf_children(cfd, false, false, &rb);
+ close(cfd);
+ cfd=-1;
+ }
diff --git a/0323-switch-root-move-switch_root-call-into-its-own-.c-fi.patch b/0323-switch-root-move-switch_root-call-into-its-own-.c-fi.patch
new file mode 100644
index 0000000..1b239cc
--- /dev/null
+++ b/0323-switch-root-move-switch_root-call-into-its-own-.c-fi.patch
@@ -0,0 +1,339 @@
+From ecb819d06faa9fe323efcbed9288a80da7d85dc1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 19:33:39 +0200
+Subject: [PATCH] switch-root: move switch_root() call into its own .c file
+ (cherry picked from commit
+ 416693175bc317ef3fa4963af51a5ee077320d09)
+
+---
+ Makefile.am | 4 +-
+ src/core/main.c | 98 ++++---------------------------------
+ src/core/switch-root.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/core/switch-root.h | 27 +++++++++++
+ 4 files changed, 164 insertions(+), 90 deletions(-)
+ create mode 100644 src/core/switch-root.c
+ create mode 100644 src/core/switch-root.h
+
+diff --git a/Makefile.am b/Makefile.am
+index 85ffa01..56fe147 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -775,7 +775,9 @@ libsystemd_core_la_SOURCES = \
+ src/core/special.h \
+ src/core/bus-errors.h \
+ src/core/build.h \
+- src/core/sysfs-show.h
++ src/core/sysfs-show.h \
++ src/core/switch-root.h \
++ src/core/switch-root.c
+
+ nodist_libsystemd_core_la_SOURCES = \
+ src/core/load-fragment-gperf.c \
+diff --git a/src/core/main.c b/src/core/main.c
+index 76280ad..3e1d4dd 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -49,6 +49,7 @@
+ #include "virt.h"
+ #include "watchdog.h"
+ #include "path-util.h"
++#include "switch-root.h"
+
+ #include "mount-setup.h"
+ #include "loopback-setup.h"
+@@ -1177,90 +1178,6 @@ static void test_cgroups(void) {
+ sleep(10);
+ }
+
+-static int do_switch_root(const char *switch_root) {
+- int r=0;
+- /* Don't try to unmount the old "/", there's no way to do it. */
+- const char *umounts[] = { "/dev", "/proc", "/sys", "/run", NULL };
+- int i;
+- int cfd = -1;
+- struct stat switch_root_stat, sb;
+- bool remove_old_root;
+-
+- if (path_equal(switch_root, "/"))
+- return 0;
+-
+- if (stat(switch_root, &switch_root_stat) != 0) {
+- r = -errno;
+- log_error("failed to stat directory %s", switch_root);
+- goto fail;
+- }
+-
+- remove_old_root = in_initrd();
+-
+- for (i = 0; umounts[i] != NULL; i++) {
+- char newmount[PATH_MAX];
+-
+- snprintf(newmount, sizeof(newmount), "%s%s", switch_root, umounts[i]);
+-
+- if ((stat(newmount, &sb) != 0) || (sb.st_dev != switch_root_stat.st_dev)) {
+- /* mount point seems to be mounted already or stat failed */
+- umount2(umounts[i], MNT_DETACH);
+- continue;
+- }
+-
+- if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) {
+- log_error("failed to mount moving %s to %s",
+- umounts[i], newmount);
+- log_error("forcing unmount of %s", umounts[i]);
+- umount2(umounts[i], MNT_FORCE);
+- }
+- }
+-
+- if (chdir(switch_root)) {
+- r = -errno;
+- log_error("failed to change directory to %s", switch_root);
+- goto fail;
+- }
+-
+- if (remove_old_root)
+- cfd = open("/", O_RDONLY);
+-
+- if (mount(switch_root, "/", NULL, MS_MOVE, NULL) < 0) {
+- r = -errno;
+- log_error("failed to mount moving %s to /", switch_root);
+- goto fail;
+- }
+-
+- if (chroot(".")) {
+- r = -errno;
+- log_error("failed to change root");
+- goto fail;
+- }
+-
+- if (cfd >= 0) {
+- struct stat rb;
+-
+- if (fstat(cfd, &rb)) {
+- log_error("failed to stat old root directory");
+- goto fail;
+- }
+-
+- rm_rf_children(cfd, false, false, &rb);
+- close(cfd);
+- cfd=-1;
+- }
+-
+- return 0;
+-
+-fail:
+- if (cfd >= 0)
+- close(cfd);
+-
+- log_error("Failed to switch root, ignoring: %s", strerror(-r));
+-
+- return r;
+-}
+-
+ int main(int argc, char *argv[]) {
+ Manager *m = NULL;
+ int r, retval = EXIT_FAILURE;
+@@ -1275,7 +1192,7 @@ int main(int argc, char *argv[]) {
+ int j;
+ bool loaded_policy = false;
+ bool arm_reboot_watchdog = false;
+- char *switch_root = NULL, *switch_root_init = NULL;
++ char *switch_root_dir = NULL, *switch_root_init = NULL;
+
+ #ifdef HAVE_SYSV_COMPAT
+ if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
+@@ -1679,7 +1596,7 @@ int main(int argc, char *argv[]) {
+
+ case MANAGER_SWITCH_ROOT:
+ /* Steal the switch root parameters */
+- switch_root = m->switch_root;
++ switch_root_dir = m->switch_root;
+ switch_root_init = m->switch_root_init;
+ m->switch_root = m->switch_root_init = NULL;
+
+@@ -1734,8 +1651,11 @@ finish:
+ * rebooted while we do that */
+ watchdog_close(true);
+
+- if (switch_root)
+- do_switch_root(switch_root);
++ if (switch_root_dir) {
++ r = switch_root(switch_root_dir);
++ if (r < 0)
++ log_error("Failed to switch root, ignoring: %s", strerror(-r));
++ }
+
+ args_size = MAX(6, argc+1);
+ args = newa(const char*, args_size);
+@@ -1756,7 +1676,7 @@ finish:
+
+ i = 0;
+ args[i++] = SYSTEMD_BINARY_PATH;
+- if (switch_root)
++ if (switch_root_dir)
+ args[i++] = "--switchedroot";
+ args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
+ args[i++] = "--deserialize";
+diff --git a/src/core/switch-root.c b/src/core/switch-root.c
+new file mode 100644
+index 0000000..ed0a31e
+--- /dev/null
++++ b/src/core/switch-root.c
+@@ -0,0 +1,125 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++/***
++ This file is part of systemd.
++
++ Copyright 2012 Harald Hoyer, Lennart Poettering
++
++ systemd is free software; you can redistribute it and/or modify it
++ under the terms of the GNU Lesser General Public License as published by
++ the Free Software Foundation; either version 2.1 of the License, or
++ (at your option) any later version.
++
++ 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include <sys/stat.h>
++#include <stdbool.h>
++#include <errno.h>
++#include <string.h>
++#include <sys/mount.h>
++#include <unistd.h>
++#include <fcntl.h>
++
++#include "util.h"
++#include "path-util.h"
++#include "switch-root.h"
++
++int switch_root(const char *new_root) {
++
++ /* Don't try to unmount/move the old "/", there's no way to do it. */
++ static const char move_mounts[] =
++ "/dev\0"
++ "/proc\0"
++ "/sys\0"
++ "/run\0";
++
++ int r, old_root_fd = -1;
++ struct stat new_root_stat;
++ bool old_root_remove;
++ const char *i;
++
++ if (path_equal(new_root, "/"))
++ return 0;
++
++ old_root_remove = in_initrd();
++
++ if (stat(new_root, &new_root_stat) < 0) {
++ r = -errno;
++ log_error("Failed to stat directory %s: %m", new_root);
++ goto fail;
++ }
++
++ NULSTR_FOREACH(i, move_mounts) {
++ char new_mount[PATH_MAX];
++ struct stat sb;
++
++ snprintf(new_mount, sizeof(new_mount), "%s%s", new_root, i);
++ char_array_0(new_mount);
++
++ if ((stat(new_mount, &sb) < 0) ||
++ sb.st_dev != new_root_stat.st_dev) {
++
++ /* Mount point seems to be mounted already or
++ * stat failed. Unmount the old mount
++ * point. */
++ if (umount2(i, MNT_DETACH) < 0)
++ log_warning("Failed to unmount %s: %m", i);
++ continue;
++ }
++
++ if (mount(i, new_mount, NULL, MS_MOVE, NULL) < 0) {
++ log_error("Failed to move mount %s to %s, forcing unmount: %m", i, new_mount);
++
++ if (umount2(i, MNT_FORCE) < 0)
++ log_warning("Failed to unmount %s: %m", i);
++ }
++ }
++
++ if (chdir(new_root) < 0) {
++ r = -errno;
++ log_error("Failed to change directory to %s: %m", new_root);
++ goto fail;
++ }
++
++ if (old_root_remove) {
++ old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY);
++ if (old_root_fd < 0)
++ log_warning("Failed to open root directory: %m");
++ }
++
++ if (mount(new_root, "/", NULL, MS_MOVE, NULL) < 0) {
++ r = -errno;
++ log_error("Failed to mount moving %s to /: %m", new_root);
++ goto fail;
++ }
++
++ if (chroot(".") < 0) {
++ r = -errno;
++ log_error("Failed to change root: %m");
++ goto fail;
++ }
++
++ if (old_root_fd >= 0) {
++ struct stat rb;
++
++ if (fstat(old_root_fd, &rb) < 0)
++ log_warning("Failed to stat old root directory, leaving: %m");
++ else
++ rm_rf_children(old_root_fd, false, false, &rb);
++ }
++
++ r = 0;
++
++fail:
++ if (old_root_fd >= 0)
++ close_nointr_nofail(old_root_fd);
++
++ return r;
++}
+diff --git a/src/core/switch-root.h b/src/core/switch-root.h
+new file mode 100644
+index 0000000..0c4cd1e
+--- /dev/null
++++ b/src/core/switch-root.h
+@@ -0,0 +1,27 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++#ifndef fooswitchroothfoo
++#define fooswitchroothfoo
++
++/***
++ This file is part of systemd.
++
++ Copyright 2012 Harald Hoyer, Lennart Poettering
++
++ systemd is free software; you can redistribute it and/or modify it
++ under the terms of the GNU Lesser General Public License as published by
++ the Free Software Foundation; either version 2.1 of the License, or
++ (at your option) any later version.
++
++ 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
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++int switch_root(const char *switch_root);
++
++#endif
diff --git a/0324-main-rename-a-few-fix-to-follow-general-naming-style.patch b/0324-main-rename-a-few-fix-to-follow-general-naming-style.patch
new file mode 100644
index 0000000..221dced
--- /dev/null
+++ b/0324-main-rename-a-few-fix-to-follow-general-naming-style.patch
@@ -0,0 +1,137 @@
+From d5ecdde02e27619f47e0f301de1eea8337c377a6 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 19:48:04 +0200
+Subject: [PATCH] main: rename a few fix to follow general naming style
+ (cherry picked from commit
+ 2660882b52ae1a5d97a2344633a999d88a3cd45b)
+
+---
+ src/core/main.c | 32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index 3e1d4dd..e06db54 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -751,7 +751,7 @@ static int parse_argv(int argc, char *argv[]) {
+ ARG_SHOW_STATUS,
+ ARG_SYSV_CONSOLE,
+ ARG_DESERIALIZE,
+- ARG_SWITCHEDROOT,
++ ARG_SWITCHED_ROOT,
+ ARG_INTROSPECT,
+ ARG_DEFAULT_STD_OUTPUT,
+ ARG_DEFAULT_STD_ERROR
+@@ -776,7 +776,7 @@ static int parse_argv(int argc, char *argv[]) {
+ { "sysv-console", optional_argument, NULL, ARG_SYSV_CONSOLE },
+ #endif
+ { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
+- { "switchedroot", no_argument, NULL, ARG_SWITCHEDROOT },
++ { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
+ { "introspect", optional_argument, NULL, ARG_INTROSPECT },
+ { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
+ { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
+@@ -948,7 +948,7 @@ static int parse_argv(int argc, char *argv[]) {
+ break;
+ }
+
+- case ARG_SWITCHEDROOT:
++ case ARG_SWITCHED_ROOT:
+ /* Nothing special yet */
+ break;
+
+@@ -1188,7 +1188,7 @@ int main(int argc, char *argv[]) {
+ const char *shutdown_verb = NULL;
+ dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
+ static char systemd[] = "systemd";
+- bool is_reexec = false;
++ bool skip_setup = false;
+ int j;
+ bool loaded_policy = false;
+ bool arm_reboot_watchdog = false;
+@@ -1209,17 +1209,17 @@ int main(int argc, char *argv[]) {
+ /* Determine if this is a reexecution or normal bootup. We do
+ * the full command line parsing much later, so let's just
+ * have a quick peek here. */
+-
+ for (j = 1; j < argc; j++)
+ if (streq(argv[j], "--deserialize")) {
+- is_reexec = true;
++ skip_setup = true;
+ break;
+ }
+
+- /* If we have switched root, do all the special things */
++ /* If we have switched root, do all the special setup
++ * things */
+ for (j = 1; j < argc; j++)
+- if (streq(argv[j], "--switchedroot")) {
+- is_reexec = false;
++ if (streq(argv[j], "--switched-root")) {
++ skip_setup = false;
+ break;
+ }
+
+@@ -1254,7 +1254,7 @@ int main(int argc, char *argv[]) {
+ arg_running_as = MANAGER_SYSTEM;
+ log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_JOURNAL : LOG_TARGET_JOURNAL_OR_KMSG);
+
+- if (!is_reexec) {
++ if (!skip_setup) {
+ if (selinux_setup(&loaded_policy) < 0)
+ goto finish;
+ if (ima_setup() < 0)
+@@ -1266,7 +1266,7 @@ int main(int argc, char *argv[]) {
+ if (label_init(NULL) < 0)
+ goto finish;
+
+- if (!is_reexec)
++ if (!skip_setup)
+ if (hwclock_is_localtime() > 0) {
+ int min;
+
+@@ -1378,7 +1378,7 @@ int main(int argc, char *argv[]) {
+ /* Parse the data passed to us. We leave this
+ * variables set, but the manager later on will not
+ * pass them on to our children. */
+- if(!in_initrd())
++ if (!in_initrd())
+ parse_initrd_timestamp(&initrd_timestamp);
+
+ /* Unset some environment variables passed in from the
+@@ -1392,7 +1392,7 @@ int main(int argc, char *argv[]) {
+ unsetenv("SHLVL");
+ unsetenv("_");
+
+- /* When we are invoked by a tool chroot-like such as
++ /* When we are invoked by a chroot-like tool such as
+ * nspawn, these might be set, but make little sense
+ * to pass on */
+ unsetenv("USER");
+@@ -1419,7 +1419,7 @@ int main(int argc, char *argv[]) {
+ /* Reset the console, but only if this is really init and we
+ * are freshly booted */
+ if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN) {
+- console_setup(getpid() == 1 && !is_reexec);
++ console_setup(getpid() == 1 && !skip_setup);
+ make_null_stdio();
+ }
+
+@@ -1440,7 +1440,7 @@ int main(int argc, char *argv[]) {
+ log_full(arg_running_as == MANAGER_SYSTEM ? LOG_INFO : LOG_DEBUG,
+ PACKAGE_STRING " running in %s mode. (" SYSTEMD_FEATURES "; " DISTRIBUTION ")", manager_running_as_to_string(arg_running_as));
+
+- if (arg_running_as == MANAGER_SYSTEM && !is_reexec) {
++ if (arg_running_as == MANAGER_SYSTEM && !skip_setup) {
+ locale_setup();
+
+ if (arg_show_status || plymouth_running())
+@@ -1677,7 +1677,7 @@ finish:
+ i = 0;
+ args[i++] = SYSTEMD_BINARY_PATH;
+ if (switch_root_dir)
+- args[i++] = "--switchedroot";
++ args[i++] = "--switched-root";
+ args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
+ args[i++] = "--deserialize";
+ args[i++] = sfd;
diff --git a/0325-util-rework-in_initrd-logic.patch b/0325-util-rework-in_initrd-logic.patch
new file mode 100644
index 0000000..61a55a5
--- /dev/null
+++ b/0325-util-rework-in_initrd-logic.patch
@@ -0,0 +1,42 @@
+From 01595b35d598ca37cc4a4823d11ce1a9404f58e8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 21 May 2012 20:00:58 +0200
+Subject: [PATCH] util: rework in_initrd() logic
+
+Checking the device major/minor is not a good idea. Let's replace this
+with an explicit flag file, which we model after /etc/os-release and
+call /etc/initrd-release.
+(cherry picked from commit 8f33b5b8b3e85f9c3b00eb004e601f7a72fa6461)
+
+Conflicts:
+ TODO
+---
+ src/shared/util.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 83b4a24..aef6ebd 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -5654,16 +5654,10 @@ bool is_valid_documentation_url(const char *url) {
+ }
+
+ bool in_initrd(void) {
+- static bool checked=false;
+- static bool is_in_initrd=false;
+-
+- if (!checked) {
+- struct stat sb;
+- if (stat("/", &sb) == 0) {
+- is_in_initrd = (sb.st_dev == 1);
+- checked = true;
+- }
+- }
++ static int saved = -1;
++
++ if (saved < 0)
++ saved = access("/etc/initrd-release", F_OK) >= 0;
+
+- return is_in_initrd;
++ return saved;
+ }
diff --git a/0326-journald-fix-length-of-SYSLOG_IDENTIFIER.patch b/0326-journald-fix-length-of-SYSLOG_IDENTIFIER.patch
new file mode 100644
index 0000000..1eca524
--- /dev/null
+++ b/0326-journald-fix-length-of-SYSLOG_IDENTIFIER.patch
@@ -0,0 +1,31 @@
+From 4141f01909b0abc02c59c4e41ef9a455da0c1306 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Mon, 21 May 2012 19:31:41 +0200
+Subject: [PATCH] journald: fix length of "SYSLOG_IDENTIFIER="
+
+Fixes weird messages like:
+May 20 22:23:30 jik2 TIFIER=systemd-logind[795]: New session 46 of user gdm.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=823498
+(cherry picked from commit fca1b90a0dd2800f8ec9e31ff0b942312b0b8bb0)
+---
+ src/journal/journald.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/journal/journald.c b/src/journal/journald.c
+index a2b9c87..d689c30 100644
+--- a/src/journal/journald.c
++++ b/src/journal/journald.c
+@@ -1235,10 +1235,10 @@ static void process_native_message(
+ priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
+
+ else if (l >= 12 &&
+- memcmp(p, "SYSLOG_IDENTIFIER=", 11) == 0) {
++ memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
+ char *t;
+
+- t = strndup(p + 11, l - 11);
++ t = strndup(p + 18, l - 18);
+ if (t) {
+ free(identifier);
+ identifier = t;
diff --git a/0327-journald-one-more-SYSLOG_IDENTIFIER-length-fix.patch b/0327-journald-one-more-SYSLOG_IDENTIFIER-length-fix.patch
new file mode 100644
index 0000000..f59b4e3
--- /dev/null
+++ b/0327-journald-one-more-SYSLOG_IDENTIFIER-length-fix.patch
@@ -0,0 +1,24 @@
+From 5e66ee89dc87ebf8359800da570494eb9db3c425 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Mon, 21 May 2012 20:21:49 +0200
+Subject: [PATCH] journald: one more SYSLOG_IDENTIFIER length fix (cherry
+ picked from commit
+ 401cc72da8e59a1e49acafee69280f7ebaa52e74)
+
+---
+ src/journal/journald.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/journal/journald.c b/src/journal/journald.c
+index d689c30..da683d6 100644
+--- a/src/journal/journald.c
++++ b/src/journal/journald.c
+@@ -1234,7 +1234,7 @@ static void process_native_message(
+ p[17] >= '0' && p[17] <= '9')
+ priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
+
+- else if (l >= 12 &&
++ else if (l >= 19 &&
+ memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) {
+ char *t;
+
diff --git a/0328-main-allow-system-wide-limits-for-services.patch b/0328-main-allow-system-wide-limits-for-services.patch
new file mode 100644
index 0000000..ebdedf3
--- /dev/null
+++ b/0328-main-allow-system-wide-limits-for-services.patch
@@ -0,0 +1,196 @@
+From c9c18713ab9c787d128ec7c041df00be3046f9e3 Mon Sep 17 00:00:00 2001
+From: Frederic Crozat <fcrozat at suse.com>
+Date: Wed, 21 Mar 2012 18:03:40 +0100
+Subject: [PATCH] main: allow system wide limits for services (cherry picked
+ from commit c93ff2e913a6da516c83c0d3f8df73004acc6c8b)
+
+---
+ man/systemd.conf.xml | 27 +++++++++++++++++++++++++++
+ src/core/main.c | 22 ++++++++++++++++++++++
+ src/core/manager.c | 22 ++++++++++++++++++++++
+ src/core/manager.h | 3 +++
+ src/core/service.c | 4 ++++
+ 5 files changed, 78 insertions(+)
+
+diff --git a/man/systemd.conf.xml b/man/systemd.conf.xml
+index c789028..d37c574 100644
+--- a/man/systemd.conf.xml
++++ b/man/systemd.conf.xml
+@@ -194,6 +194,33 @@
+ effect if a hardware watchdog is not
+ available.</para></listitem>
+ </varlistentry>
++
++ <varlistentry>
++ <term><varname>DefaultLimitCPU=</varname></term>
++ <term><varname>DefaultLimitFSIZE=</varname></term>
++ <term><varname>DefaultLimitDATA=</varname></term>
++ <term><varname>DefaultLimitSTACK=</varname></term>
++ <term><varname>DefaultLimitCORE=</varname></term>
++ <term><varname>DefaultLimitRSS=</varname></term>
++ <term><varname>DefaultLimitNOFILE=</varname></term>
++ <term><varname>DefaultLimitAS=</varname></term>
++ <term><varname>DefaultLimitNPROC=</varname></term>
++ <term><varname>DefaultLimitMEMLOCK=</varname></term>
++ <term><varname>DefaultLimitLOCKS=</varname></term>
++ <term><varname>DefaultLimitSIGPENDING=</varname></term>
++ <term><varname>DefaultLimitMSGQUEUE=</varname></term>
++ <term><varname>DefaultLimitNICE=</varname></term>
++ <term><varname>DefaultLimitRTPRIO=</varname></term>
++ <term><varname>DefaultLimitRTTIME=</varname></term>
++ <listitem><para>These settings control
++ various default resource limits for units. See
++ <citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
++ for details. Use the string
++ <varname>infinity</varname> to
++ configure no limit on a specific
++ resource. They can be overriden in units files
++ using corresponding LimitXXXX parameter.</para></listitem>
++ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+diff --git a/src/core/main.c b/src/core/main.c
+index e06db54..12679cb 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -88,6 +88,7 @@ static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
+ static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
+ static usec_t arg_runtime_watchdog = 0;
+ static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
++static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
+
+ static FILE* serialization = NULL;
+
+@@ -670,6 +671,22 @@ static int parse_config_file(void) {
+ { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
+ { "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog },
+ { "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog },
++ { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]},
++ { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]},
++ { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]},
++ { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]},
++ { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]},
++ { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]},
++ { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]},
++ { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]},
++ { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]},
++ { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
++ { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]},
++ { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
++ { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
++ { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]},
++ { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]},
++ { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]},
+ { NULL, NULL, NULL, 0, NULL }
+ };
+
+@@ -1476,6 +1493,8 @@ int main(int argc, char *argv[]) {
+ m->runtime_watchdog = arg_runtime_watchdog;
+ m->shutdown_watchdog = arg_shutdown_watchdog;
+
++ manager_set_default_rlimits(m, arg_default_rlimit);
++
+ if (dual_timestamp_is_set(&initrd_timestamp))
+ m->initrd_timestamp = initrd_timestamp;
+
+@@ -1635,6 +1654,9 @@ finish:
+ if (m)
+ manager_free(m);
+
++ for (j = 0; j < RLIMIT_NLIMITS; j++)
++ free (arg_default_rlimit[j]);
++
+ free(arg_default_unit);
+ strv_free(arg_default_controllers);
+ free_join_controllers();
+diff --git a/src/core/manager.c b/src/core/manager.c
+index c7d3e60..8af3241 100644
+--- a/src/core/manager.c
++++ b/src/core/manager.c
+@@ -476,6 +476,7 @@ static void manager_clear_jobs_and_units(Manager *m) {
+
+ void manager_free(Manager *m) {
+ UnitType c;
++ int i;
+
+ assert(m);
+
+@@ -525,6 +526,9 @@ void manager_free(Manager *m) {
+ free(m->switch_root);
+ free(m->switch_root_init);
+
++ for (i = 0; i < RLIMIT_NLIMITS; i++)
++ free(m->rlimit[i]);
++
+ free(m);
+ }
+
+@@ -2136,6 +2140,24 @@ int manager_set_default_controllers(Manager *m, char **controllers) {
+ return 0;
+ }
+
++int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit) {
++ int i;
++
++ assert(m);
++
++ for (i = 0; i < RLIMIT_NLIMITS; i++) {
++ if (default_rlimit[i]) {
++ m->rlimit[i] = newdup(struct rlimit, default_rlimit[i], 1);
++
++ if (!m->rlimit[i])
++ return -ENOMEM;
++ }
++ }
++
++ return 0;
++}
++
++
+ void manager_recheck_journal(Manager *m) {
+ Unit *u;
+
+diff --git a/src/core/manager.h b/src/core/manager.h
+index c36131e..7a79c0f 100644
+--- a/src/core/manager.h
++++ b/src/core/manager.h
+@@ -228,6 +228,8 @@ struct Manager {
+
+ ExecOutput default_std_output, default_std_error;
+
++ struct rlimit *rlimit[RLIMIT_NLIMITS];
++
+ /* non-zero if we are reloading or reexecuting, */
+ int n_reloading;
+
+@@ -270,6 +272,7 @@ unsigned manager_dispatch_run_queue(Manager *m);
+ unsigned manager_dispatch_dbus_queue(Manager *m);
+
+ int manager_set_default_controllers(Manager *m, char **controllers);
++int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
+
+ int manager_loop(Manager *m);
+
+diff --git a/src/core/service.c b/src/core/service.c
+index 18e3a67..7ce2e72 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -110,6 +110,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
+
+ static void service_init(Unit *u) {
+ Service *s = SERVICE(u);
++ int i;
+
+ assert(u);
+ assert(u->load_state == UNIT_STUB);
+@@ -129,6 +130,9 @@ static void service_init(Unit *u) {
+ s->guess_main_pid = true;
+
+ exec_context_init(&s->exec_context);
++ for (i = 0; i < RLIMIT_NLIMITS; i++)
++ if (UNIT(s)->manager->rlimit[i])
++ s->exec_context.rlimit[i] = newdup(struct rlimit, UNIT(s)->manager->rlimit[i], 1);
+
+ RATELIMIT_INIT(s->start_limit, 10*USEC_PER_SEC, 5);
+
diff --git a/0329-F17-fix-manpage-names.patch b/0329-F17-fix-manpage-names.patch
new file mode 100644
index 0000000..0b4e255
--- /dev/null
+++ b/0329-F17-fix-manpage-names.patch
@@ -0,0 +1,51 @@
+From 4ec16a7a96f10c3afaf251ae848adbeb43162fdc Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 22 May 2012 00:54:19 +0200
+Subject: [PATCH] F17: fix manpage names
+
+In F17 we still use the systemd-*.conf names.
+---
+ units/systemd-journald.service.in | 2 +-
+ units/systemd-journald.socket | 2 +-
+ units/systemd-logind.service.in | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
+index 0c88d53..809e48c 100644
+--- a/units/systemd-journald.service.in
++++ b/units/systemd-journald.service.in
+@@ -7,7 +7,7 @@
+
+ [Unit]
+ Description=Journal Service
+-Documentation=man:journald.conf(5)
++Documentation=man:systemd-journald.conf(5)
+ DefaultDependencies=no
+ Requires=systemd-journald.socket
+ After=systemd-journald.socket
+diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket
+index 62f34f9..9febdfc 100644
+--- a/units/systemd-journald.socket
++++ b/units/systemd-journald.socket
+@@ -7,7 +7,7 @@
+
+ [Unit]
+ Description=Journal Socket
+-Documentation=man:journald.conf(5)
++Documentation=man:systemd-journald.conf(5)
+ DefaultDependencies=no
+ Before=sockets.target syslog.target
+
+diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
+index 8041030..cf0aa07 100644
+--- a/units/systemd-logind.service.in
++++ b/units/systemd-logind.service.in
+@@ -8,7 +8,7 @@
+ [Unit]
+ Description=Login Service
+ Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+-Documentation=man:logind.conf(5)
++Documentation=man:systemd-logind.conf(5)
+ After=nss-user-lookup.target
+
+ [Service]
diff --git a/systemd.spec b/systemd.spec
index a8b21c9..0e671d3 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -3,7 +3,7 @@
Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 44
-Release: 10%{?gitcommit:.git%{gitcommit}}%{?dist}
+Release: 11%{?gitcommit:.git%{gitcommit}}%{?dist}
License: GPLv2+
Group: System Environment/Base
Summary: A System and Service Manager
@@ -360,6 +360,35 @@ Patch0297: 0297-delta-don-t-highlight-unchanged-files.patch
Patch0298: 0298-delta-drop-PHP-ism.patch
Patch0299: 0299-dbus-unit-always-load-the-unit-before-handling-a-mes.patch
Patch0300: 0300-systemctl-drop-useless-DBus-calls-from-systemctl-sho.patch
+Patch0301: 0301-F17-Revert-logind-close-FIFO-before-ending-sessions-.patch
+Patch0302: 0302-units-introduce-new-Documentation-field-and-make-use.patch
+Patch0303: 0303-login-minor-typo-fix.patch
+Patch0304: 0304-unit-introduce-RequiredBy-setting-in-Install-to-comp.patch
+Patch0305: 0305-hostname-setup-also-consider-one-an-unset-hostname.patch
+Patch0306: 0306-cryptsetup-a-few-simplifications.patch
+Patch0307: 0307-service-make-the-fsck-pass-no-configurable.patch
+Patch0308: 0308-main-try-a-bit-harder-to-find-an-init-process-to-exe.patch
+Patch0309: 0309-cryptsetup-support-discards-TRIM.patch
+Patch0310: 0310-journalctl-fix-built-in-usage-output.patch
+Patch0311: 0311-sd-pam-Drop-uid-so-parent-signal-arrives-at-child.patch
+Patch0312: 0312-util-fix-typo-in-newdup.patch
+Patch0313: 0313-delta-fix-spelling-of-overridden.patch
+Patch0314: 0314-main-corrected-do_switch_root.patch
+Patch0315: 0315-util.c-add-in_initrd.patch
+Patch0316: 0316-manager-only-serialize-the-timestamps-for-the-initra.patch
+Patch0317: 0317-core-main.c-add-switchedroot-parameter.patch
+Patch0318: 0318-core-main.c-do_switch_root-do-not-remove-the-old-roo.patch
+Patch0319: 0319-core-main.c-handle-the-initrd-timestamp-differently-.patch
+Patch0320: 0320-delta-delta.c-initialize-bottom-for-fail-state.patch
+Patch0321: 0321-util-rm_rf_children-add-root_dev-parameter.patch
+Patch0322: 0322-main-do_switch_root-do-not-recursively-remove-across.patch
+Patch0323: 0323-switch-root-move-switch_root-call-into-its-own-.c-fi.patch
+Patch0324: 0324-main-rename-a-few-fix-to-follow-general-naming-style.patch
+Patch0325: 0325-util-rework-in_initrd-logic.patch
+Patch0326: 0326-journald-fix-length-of-SYSLOG_IDENTIFIER.patch
+Patch0327: 0327-journald-one-more-SYSLOG_IDENTIFIER-length-fix.patch
+Patch0328: 0328-main-allow-system-wide-limits-for-services.patch
+Patch0329: 0329-F17-fix-manpage-names.patch
# For sysvinit tools
Obsoletes: SysVinit < 2.86-24, sysvinit < 2.86-24
@@ -736,6 +765,15 @@ mv /etc/systemd/system/default.target.save /etc/systemd/system/default.target >/
%{_bindir}/systemd-analyze
%changelog
+* Mon May 21 2012 Michal Schmidt <mschmidt at redhat.com> - 44-11
+- Fix weird "TIFIER=" messages in syslog (#823498)
+- Revert ReleaseSession patch (#823485)
+- Add more patches from upstream, notably:
+ - Documentation= field support
+ - RequiredBy= in [Install] support
+ - configurable ulimit defaults
+ - switch-root fixes
+
* Mon May 21 2012 Michal Schmidt <mschmidt at redhat.com> - 44-10
- Fix another cause of "Failed to issue method call" (#814966)
- minor systemd-delta updates
More information about the scm-commits
mailing list