[systemd/f17] backports from v194+
Michal Schmidt
michich at fedoraproject.org
Fri Oct 12 16:01:54 UTC 2012
commit f27ed14f670c5527e69e326bfd41ca859e3394c2
Author: Michal Schmidt <mschmidt at redhat.com>
Date: Thu Jul 26 21:22:21 2012 +0200
backports from v194+
- Fix for broken fstab mounts in 44-18.
- Revert the ntp migration code. Not going to do it in F17.
- Backports from upstream v194+:
- PartOf= dependencies
- enabling/disabling of instantiated units
- usability improvements for systemctl:
- systemctl status /home
- systemctl status /dev/foobar
- implied .service suffix
- new timeouts TimeoutStartSec=, TimeoutStopSec=
- understand PARTUUID=, PARTLABEL= in fstab
- new conditions ConditionHost=, ConditionFileNotEmpty=
- tmpfiles: globbing support with 'w' mode
- various fixes
- Resolves: #752774, #767795, #802198, #855863, #856975, #858266, #858754,
- #858771, #858777, fdo#39386, fdo#54448, fdo#54522, fdo#54766
0500-F17-fix-fstab-mounts.patch | 25 +
0501-Revert-timedate-uniq-ify-ntp-units-list.patch | 23 +
...dated-replace-ntp-units-file-with-an-ntp-.patch | 135 +++
0503-Revert-timedate-fix-ntp-units-comment.patch | 20 +
...dated-replace-systemd-timedated-ntp.targe.patch | 513 +++++++++++
0505-systemd-added-new-dependency-PartOf.patch | 117 +++
0506-man-rewrite-the-description-of-PartOf.patch | 41 +
...-unit-expose-PartOf-ConsistsOf-properties.patch | 28 +
...-make-the-table-of-inverse-deps-symmetric.patch | 36 +
...add-missing-deps-in-unit_dependency_table.patch | 49 ++
...temd-enable-disable-instances-of-template.patch | 257 ++++++
0511-logs-show-fix-OOM-path.patch | 33 +
...utomatically-turn-paths-and-unescaped-uni.patch | 896 ++++++++++++++++++++
...fix-escaping-when-generating-cryptsetup-u.patch | 374 ++++++++
...ppend-.service-to-unit-names-lacking-suff.patch | 55 ++
...stemd.rules.in-ENV-SYSTEMD_READY-0-for-in.patch | 27 +
...emd.rules.in-ignore-nbd-in-the-add-uevent.patch | 25 +
...omount-print-mount-point-in-debug-message.patch | 31 +
0518-journald-fixed-memory-leak.patch | 22 +
0519-logs-show-fix-off-by-one-error.patch | 27 +
...low-to-specify-broadcast-message-when-can.patch | 107 +++
0521-sysctl-apply-configuration-at-once.patch | 190 +++++
0522-systemd-introduced-new-timeout-types.patch | 247 ++++++
...-couple-of-issues-found-with-llvm-analyze.patch | 76 ++
0524-shared-utf8-mark-char-as-const.patch | 29 +
...red-util-refactor-fstab_node_to_udev_node.patch | 88 ++
...-add-fstab-support-for-partuuid-partlabel.patch | 29 +
...n-check-return-of-parse_pid-and-parse_uid.patch | 37 +
...allow-units-to-be-gc-ed-that-still-are-re.patch | 25 +
...unit-add-new-ConditionHost-condition-type.patch | 342 ++++++++
0530-condition-add-ConditionFileNotEmpty.patch | 101 +++
...ework-unit_name_replace_instance-function.patch | 105 +++
0532-pam-Add-session-class-to-the-debug-log.patch | 25 +
0533-tmpfiles-support-globbing-for-w-option.patch | 188 ++++
...irect-the-user-to-list-unit-files-from-th.patch | 29 +
0535-tmpfiles-plug-file-descriptor-leak.patch | 24 +
...-Don-t-error-out-on-runlevel-updates-if-u.patch | 30 +
...end-.service-when-enable-disable.-is-call.patch | 75 ++
0538-systemctl-minor-coding-style-fixes.patch | 53 ++
0539-socket-prevent-signed-integer-overflow.patch | 25 +
0540-tmpfiles-use-write-2-for-the-w-action.patch | 96 +++
...-t-hit-an-assert-if-a-service-unit-change.patch | 43 +
...-hwclock-always-set-the-kernel-s-timezone.patch | 138 +++
...-don-t-unescape-parsed-configuration-stri.patch | 86 ++
0544-log-avoid-function-loop.patch | 73 ++
...y-default-ordering-for-PartsOf-deps-as-we.patch | 77 ++
0546-unit-fix-f-resolving.patch | 41 +
...y-the-user-if-we-over-mount-a-non-empty-d.patch | 36 +
...lso-whine-if-an-automount-directory-is-no.patch | 25 +
...ount-reword-directory-empty-warning-a-bit.patch | 37 +
...imedated-unregister-the-right-bus-service.patch | 24 +
...ure-heap-allocators-fail-when-array-alloc.patch | 63 ++
...-union-dirent_storage-and-make-use-of-it-.patch | 322 +++++++
0553-util-overflow-hardening.patch | 72 ++
0554-util-fix-overflow-checks.patch | 45 +
0555-shared-call-va_end-in-all-cases.patch | 28 +
0556-cgtop-missing.patch | 26 +
...d-check-return-value-log-warning-on-error.patch | 42 +
...eck-return-value-of-session_get_idle_hint.patch | 33 +
0559-locale-make-sure-that-l-is-freed.patch | 25 +
0560-modules-load-initalize-files-to-null.patch | 23 +
0561-sysctl-fix-error-code-handling.patch | 25 +
...ng-break-for-getopt-ARG_NO_ASK_PASSWORD-i.patch | 23 +
0563-hwclock-add-missing-OOM-check.patch | 26 +
...ways-return-the-last-error-we-encountered.patch | 76 ++
...mark-MD-disks-not-partitions-with-SYSTEMD.patch | 26 +
...mpfiles-restore-previous-behavior-for-F-f.patch | 28 +
...-mkdir_p-if-the-target-exists-and-is-not-.patch | 40 +
...ctl-avoiding-exiting-with-error-on-EEXIST.patch | 34 +
systemd.spec | 95 ++-
70 files changed, 6286 insertions(+), 1 deletions(-)
---
diff --git a/0500-F17-fix-fstab-mounts.patch b/0500-F17-fix-fstab-mounts.patch
new file mode 100644
index 0000000..4c47e48
--- /dev/null
+++ b/0500-F17-fix-fstab-mounts.patch
@@ -0,0 +1,25 @@
+From 49cece83331d054f7b09b03291d18454c731ee63 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Fri, 27 Jul 2012 08:19:28 +0200
+Subject: [PATCH] F17: fix fstab mounts
+
+The backport of "mount: load only if we there's mountinfo or fragment"
+broke the loading of fstab. F17 needs this fixup patch to account for
+fstab being handled in the core, not in a generator like upstream.
+---
+ src/core/mount.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/mount.c b/src/core/mount.c
+index d939e21..3a33d93 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -676,7 +676,7 @@ static int mount_load(Unit *u) {
+ assert(u);
+ assert(u->load_state == UNIT_STUB);
+
+- if (m->from_proc_self_mountinfo)
++ if (m->from_proc_self_mountinfo || m->from_etc_fstab)
+ r = unit_load_fragment_and_dropin_optional(u);
+ else
+ r = unit_load_fragment_and_dropin(u);
diff --git a/0501-Revert-timedate-uniq-ify-ntp-units-list.patch b/0501-Revert-timedate-uniq-ify-ntp-units-list.patch
new file mode 100644
index 0000000..00f7521
--- /dev/null
+++ b/0501-Revert-timedate-uniq-ify-ntp-units-list.patch
@@ -0,0 +1,23 @@
+From 799718bac8e3ae099ec598f769d4543fe63a1df8 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 11 Oct 2012 22:38:07 +0200
+Subject: [PATCH] Revert "timedate: uniq'ify ntp units list"
+
+This reverts commit 4e9e1d80dda7c6a786d576de515327edba5942b9.
+---
+ src/timedate/timedated.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
+index e391e03..1dcf509 100644
+--- a/src/timedate/timedated.c
++++ b/src/timedate/timedated.c
+@@ -354,7 +354,7 @@ static char** get_ntp_services(void) {
+
+ strv_free(files);
+
+- return strv_uniq(r);
++ return r;
+ }
+
+ static int read_ntp(DBusConnection *bus) {
diff --git a/0502-Revert-timedated-replace-ntp-units-file-with-an-ntp-.patch b/0502-Revert-timedated-replace-ntp-units-file-with-an-ntp-.patch
new file mode 100644
index 0000000..db8426c
--- /dev/null
+++ b/0502-Revert-timedated-replace-ntp-units-file-with-an-ntp-.patch
@@ -0,0 +1,135 @@
+From dd8e09b01eda5b9b766a379b5c0722c78d8dd645 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 11 Oct 2012 22:38:26 +0200
+Subject: [PATCH] Revert "timedated: replace ntp-units file with an
+ ntp-units.d drop-in dir"
+
+This reverts commit 7ec9c50ae6e3329926dcae48c661910043701f5a.
+---
+ Makefile.am | 4 ++++
+ src/timedate/ntp-units | 4 ++++
+ src/timedate/timedated.c | 59 ++++++++++++++++++------------------------------
+ 3 files changed, 30 insertions(+), 37 deletions(-)
+ create mode 100644 src/timedate/ntp-units
+
+diff --git a/Makefile.am b/Makefile.am
+index d051b39..46cfe80 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -114,6 +114,7 @@ AM_CPPFLAGS = \
+ -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
+ -DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
+ -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
++ -DSYSTEMD_NTP_UNITS=\"$(pkgdatadir)/ntp-units\" \
+ -DX_SERVER=\"$(bindir)/X\" \
+ -DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
+ -I $(top_srcdir)/src \
+@@ -2061,6 +2062,9 @@ timedated-install-data-hook:
+ INSTALL_DATA_HOOKS += \
+ timedated-install-data-hook
+
++dist_pkgdata_DATA += \
++ src/timedate/ntp-units
++
+ EXTRA_DIST += \
+ units/systemd-timedated.service.in
+ endif
+diff --git a/src/timedate/ntp-units b/src/timedate/ntp-units
+new file mode 100644
+index 0000000..2a46f66
+--- /dev/null
++++ b/src/timedate/ntp-units
+@@ -0,0 +1,4 @@
++# NTP service implementations, in order of preference
++
++chronyd.service
++ntpd.service
+diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
+index 1dcf509..8be45d3 100644
+--- a/src/timedate/timedated.c
++++ b/src/timedate/timedated.c
+@@ -31,7 +31,6 @@
+ #include "polkit.h"
+ #include "def.h"
+ #include "hwclock.h"
+-#include "conf-files.h"
+
+ #define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
+ #define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
+@@ -305,54 +304,40 @@ static int write_data_local_rtc(void) {
+ }
+
+ static char** get_ntp_services(void) {
+- char **r = NULL, **files, **i;
+- int k;
+-
+- k = conf_files_list(&files, ".list",
+- "/etc/systemd/ntp-units.d",
+- "/run/systemd/ntp-units.d",
+- "/usr/local/lib/systemd/ntp-units.d",
+- "/usr/lib/systemd/ntp-units.d",
+- NULL);
+- if (k < 0)
+- return NULL;
+-
+- STRV_FOREACH(i, files) {
+- FILE *f;
++ char **r = NULL;
++ FILE *f;
+
+- f = fopen(*i, "re");
+- if (!f)
+- continue;
++ f = fopen(SYSTEMD_NTP_UNITS, "re");
++ if (!f)
++ return NULL;
+
+- for (;;) {
+- char line[PATH_MAX], *l, **q;
++ for (;;) {
++ char line[PATH_MAX], *l, **q;
+
+- if (!fgets(line, sizeof(line), f)) {
++ if (!fgets(line, sizeof(line), f)) {
+
+- if (ferror(f))
+- log_error("Failed to read NTP units file: %m");
++ if (ferror(f))
++ log_error("Failed to read NTP units file: %m");
+
+- break;
+- }
++ break;
++ }
+
+- l = strstrip(line);
+- if (l[0] == 0 || l[0] == '#')
+- continue;
++ l = strstrip(line);
++ if (l[0] == 0 || l[0] == '#')
++ continue;
+
+- q = strv_append(r, l);
+- if (!q) {
+- log_error("Out of memory");
+- break;
+- }
+
+- strv_free(r);
+- r = q;
++ q = strv_append(r, l);
++ if (!q) {
++ log_error("Out of memory");
++ break;
+ }
+
+- fclose(f);
++ strv_free(r);
++ r = q;
+ }
+
+- strv_free(files);
++ fclose(f);
+
+ return r;
+ }
diff --git a/0503-Revert-timedate-fix-ntp-units-comment.patch b/0503-Revert-timedate-fix-ntp-units-comment.patch
new file mode 100644
index 0000000..9c0d43f
--- /dev/null
+++ b/0503-Revert-timedate-fix-ntp-units-comment.patch
@@ -0,0 +1,20 @@
+From 4cda8d75b297012e79305d8c3dda1e5a33448a75 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 11 Oct 2012 22:38:40 +0200
+Subject: [PATCH] Revert "timedate: fix ntp-units comment"
+
+This reverts commit ab8a1ee403831f40b815802a0062439d6cb90557.
+---
+ src/timedate/ntp-units | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/timedate/ntp-units b/src/timedate/ntp-units
+index 2a46f66..6fdef44 100644
+--- a/src/timedate/ntp-units
++++ b/src/timedate/ntp-units
+@@ -1,4 +1,4 @@
+-# NTP service implementations, in order of preference
++# NTP ervice implementations, in order for preference
+
+ chronyd.service
+ ntpd.service
diff --git a/0504-Revert-timedated-replace-systemd-timedated-ntp.targe.patch b/0504-Revert-timedated-replace-systemd-timedated-ntp.targe.patch
new file mode 100644
index 0000000..bd5ab01
--- /dev/null
+++ b/0504-Revert-timedated-replace-systemd-timedated-ntp.targe.patch
@@ -0,0 +1,513 @@
+From 1eb2c8cee635ddfa66005a6eefe3e0697fb35349 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 11 Oct 2012 22:38:51 +0200
+Subject: [PATCH] Revert "timedated: replace systemd-timedated-ntp.target
+ logic with simpler scheme"
+
+This reverts commit 3fdadd7ffeab01c973e99114c14f4423884a4227.
+---
+ Makefile.am | 10 +-
+ src/timedate/ntp-units | 4 -
+ src/timedate/timedated.c | 321 +++++++++++++------------------------
+ units/systemd-timedated-ntp.target | 18 +++
+ 4 files changed, 133 insertions(+), 220 deletions(-)
+ delete mode 100644 src/timedate/ntp-units
+ create mode 100644 units/systemd-timedated-ntp.target
+
+diff --git a/Makefile.am b/Makefile.am
+index 46cfe80..bb4f774 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -79,7 +79,6 @@ pkgconfiglib_DATA =
+ polkitpolicy_in_files =
+ dist_udevrules_DATA =
+ dist_pkgsysconf_DATA =
+-dist_pkgdata_DATA =
+ dist_dbuspolicy_DATA =
+ dbusinterface_DATA =
+ dist_dbussystemservice_DATA =
+@@ -114,7 +113,6 @@ AM_CPPFLAGS = \
+ -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
+ -DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
+ -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
+- -DSYSTEMD_NTP_UNITS=\"$(pkgdatadir)/ntp-units\" \
+ -DX_SERVER=\"$(bindir)/X\" \
+ -DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
+ -I $(top_srcdir)/src \
+@@ -293,7 +291,8 @@ dist_systemunit_DATA = \
+ units/quotaon.service \
+ units/systemd-ask-password-wall.path \
+ units/systemd-ask-password-console.path \
+- units/syslog.target
++ units/syslog.target \
++ units/systemd-timedated-ntp.target
+
+ nodist_systemunit_DATA = \
+ units/getty at .service \
+@@ -2006,7 +2005,7 @@ INSTALL_DATA_HOOKS += \
+ EXTRA_DIST += \
+ units/systemd-localed.service.in
+
+-dist_pkgdata_DATA += \
++dist_pkgdata_DATA = \
+ src/locale/kbd-model-map
+
+ dist_noinst_SCRIPT = \
+@@ -2062,9 +2061,6 @@ timedated-install-data-hook:
+ INSTALL_DATA_HOOKS += \
+ timedated-install-data-hook
+
+-dist_pkgdata_DATA += \
+- src/timedate/ntp-units
+-
+ EXTRA_DIST += \
+ units/systemd-timedated.service.in
+ endif
+diff --git a/src/timedate/ntp-units b/src/timedate/ntp-units
+deleted file mode 100644
+index 6fdef44..0000000
+--- a/src/timedate/ntp-units
++++ /dev/null
+@@ -1,4 +0,0 @@
+-# NTP ervice implementations, in order for preference
+-
+-chronyd.service
+-ntpd.service
+diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
+index 8be45d3..b008f15 100644
+--- a/src/timedate/timedated.c
++++ b/src/timedate/timedated.c
+@@ -303,112 +303,62 @@ static int write_data_local_rtc(void) {
+ return r;
+ }
+
+-static char** get_ntp_services(void) {
+- char **r = NULL;
+- FILE *f;
+-
+- f = fopen(SYSTEMD_NTP_UNITS, "re");
+- if (!f)
+- return NULL;
+-
+- for (;;) {
+- char line[PATH_MAX], *l, **q;
+-
+- if (!fgets(line, sizeof(line), f)) {
+-
+- if (ferror(f))
+- log_error("Failed to read NTP units file: %m");
+-
+- break;
+- }
+-
+- l = strstrip(line);
+- if (l[0] == 0 || l[0] == '#')
+- continue;
+-
+-
+- q = strv_append(r, l);
+- if (!q) {
+- log_error("Out of memory");
+- break;
+- }
+-
+- strv_free(r);
+- r = q;
+- }
+-
+- fclose(f);
+-
+- return r;
+-}
+-
+ static int read_ntp(DBusConnection *bus) {
+ DBusMessage *m = NULL, *reply = NULL;
++ const char *name = "systemd-timedated-ntp.target", *s;
+ DBusError error;
+ int r;
+- char **i, **l;
+
+ assert(bus);
+
+ dbus_error_init(&error);
+
+- l = get_ntp_services();
+- STRV_FOREACH(i, l) {
+- const char *s;
+-
+- if (m)
+- dbus_message_unref(m);
+- m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- "GetUnitFileState");
+- if (!m) {
+- log_error("Out of memory");
+- r = -ENOMEM;
+- goto finish;
+- }
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ "GetUnitFileState");
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, i,
+- DBUS_TYPE_INVALID)) {
+- log_error("Could not append arguments to message.");
+- r = -ENOMEM;
+- goto finish;
+- }
++ if (!m) {
++ log_error("Out of memory");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- if (reply)
+- dbus_message_unref(reply);
+- reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+- if (!reply) {
+- if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
+- /* This implementation does not exist, try next one */
+- dbus_error_free(&error);
+- continue;
+- }
++ if (!dbus_message_append_args(m,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_INVALID)) {
++ log_error("Could not append arguments to message.");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- log_error("Failed to issue method call: %s", bus_error_message(&error));
+- r = -EIO;
+- goto finish;
+- }
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+
+- if (!dbus_message_get_args(reply, &error,
+- DBUS_TYPE_STRING, &s,
+- DBUS_TYPE_INVALID)) {
+- log_error("Failed to parse reply: %s", bus_error_message(&error));
+- r = -EIO;
++ if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
++ /* NTP is not installed. */
++ tz.use_ntp = false;
++ r = 0;
+ goto finish;
+ }
+
+- tz.use_ntp =
+- streq(s, "enabled") ||
+- streq(s, "enabled-runtime");
+- r = 0;
++ log_error("Failed to issue method call: %s", bus_error_message(&error));
++ r = -EIO;
++ goto finish;
++ }
++
++ if (!dbus_message_get_args(reply, &error,
++ DBUS_TYPE_STRING, &s,
++ DBUS_TYPE_INVALID)) {
++ log_error("Failed to parse reply: %s", bus_error_message(&error));
++ r = -EIO;
+ goto finish;
+ }
+
+- /* NTP is not installed. */
+- tz.use_ntp = 0;
++ tz.use_ntp =
++ streq(s, "enabled") ||
++ streq(s, "enabled-runtime");
+ r = 0;
+
+ finish:
+@@ -418,8 +368,6 @@ finish:
+ if (reply)
+ dbus_message_unref(reply);
+
+- strv_free(l);
+-
+ dbus_error_free(&error);
+
+ return r;
+@@ -427,60 +375,40 @@ finish:
+
+ static int start_ntp(DBusConnection *bus, DBusError *error) {
+ DBusMessage *m = NULL, *reply = NULL;
+- const char *mode = "replace";
+- char **i, **l;
++ const char *name = "systemd-timedated-ntp.target", *mode = "replace";
+ int r;
+
+ assert(bus);
+ assert(error);
+
+- l = get_ntp_services();
+- STRV_FOREACH(i, l) {
+- if (m)
+- dbus_message_unref(m);
+- m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- tz.use_ntp ? "StartUnit" : "StopUnit");
+- if (!m) {
+- log_error("Could not allocate message.");
+- r = -ENOMEM;
+- goto finish;
+- }
+-
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, i,
+- DBUS_TYPE_STRING, &mode,
+- DBUS_TYPE_INVALID)) {
+- log_error("Could not append arguments to message.");
+- r = -ENOMEM;
+- goto finish;
+- }
+-
+- if (reply)
+- dbus_message_unref(reply);
+- reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+- if (!reply) {
+- if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") ||
+- streq(error->name, "org.freedesktop.systemd1.LoadFailed") ||
+- streq(error->name, "org.freedesktop.systemd1.NoSuchUnit")) {
+- /* This implementation does not exist, try next one */
+- dbus_error_free(error);
+- continue;
+- }
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ tz.use_ntp ? "StartUnit" : "StopUnit");
++ if (!m) {
++ log_error("Could not allocate message.");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- log_error("Failed to issue method call: %s", bus_error_message(error));
+- r = -EIO;
+- goto finish;
+- }
++ if (!dbus_message_append_args(m,
++ DBUS_TYPE_STRING, &name,
++ DBUS_TYPE_STRING, &mode,
++ DBUS_TYPE_INVALID)) {
++ log_error("Could not append arguments to message.");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- r = 0;
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
++ if (!reply) {
++ log_error("Failed to issue method call: %s", bus_error_message(error));
++ r = -EIO;
+ goto finish;
+ }
+
+- /* No implementaiton available... */
+- r = -ENOENT;
++ r = 0;
+
+ finish:
+ if (m)
+@@ -489,105 +417,82 @@ finish:
+ if (reply)
+ dbus_message_unref(reply);
+
+- strv_free(l);
+-
+ return r;
+ }
+
+ static int enable_ntp(DBusConnection *bus, DBusError *error) {
+ DBusMessage *m = NULL, *reply = NULL;
++ const char * const names[] = { "systemd-timedated-ntp.target", NULL };
+ int r;
+ DBusMessageIter iter;
+ dbus_bool_t f = FALSE, t = TRUE;
+- char **i, **l;
+
+ assert(bus);
+ assert(error);
+
+- l = get_ntp_services();
+- STRV_FOREACH(i, l) {
+- char* k[2];
+-
+- if (m)
+- dbus_message_unref(m);
+- m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
+- if (!m) {
+- log_error("Could not allocate message.");
+- r = -ENOMEM;
+- goto finish;
+- }
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
+
+- dbus_message_iter_init_append(m, &iter);
++ if (!m) {
++ log_error("Could not allocate message.");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- k[0] = *i;
+- k[1] = NULL;
++ dbus_message_iter_init_append(m, &iter);
+
+- r = bus_append_strv_iter(&iter, k);
+- if (r < 0) {
+- log_error("Failed to append unit files.");
+- goto finish;
+- }
++ r = bus_append_strv_iter(&iter, (char**) names);
++ if (r < 0) {
++ log_error("Failed to append unit files.");
++ goto finish;
++ }
++ /* send runtime bool */
++ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
++ log_error("Failed to append runtime boolean.");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- /* send runtime bool */
+- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
+- log_error("Failed to append runtime boolean.");
++ if (tz.use_ntp) {
++ /* send force bool */
++ if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
++ log_error("Failed to append force boolean.");
+ r = -ENOMEM;
+ goto finish;
+ }
++ }
+
+- if (tz.use_ntp) {
+- /* send force bool */
+- if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
+- log_error("Failed to append force boolean.");
+- r = -ENOMEM;
+- goto finish;
+- }
+- }
+-
+- if (reply)
+- dbus_message_unref(reply);
+- reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+- if (!reply) {
+- if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) {
+- /* This implementation does not exist, try next one */
+- dbus_error_free(error);
+- continue;
+- }
+-
+- log_error("Failed to issue method call: %s", bus_error_message(error));
+- r = -EIO;
+- goto finish;
+- }
+-
+- dbus_message_unref(m);
+- m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- "Reload");
+- if (!m) {
+- log_error("Could not allocate message.");
+- r = -ENOMEM;
+- goto finish;
+- }
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
++ if (!reply) {
++ log_error("Failed to issue method call: %s", bus_error_message(error));
++ r = -EIO;
++ goto finish;
++ }
+
+- dbus_message_unref(reply);
+- reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
+- if (!reply) {
+- log_error("Failed to issue method call: %s", bus_error_message(error));
+- r = -EIO;
+- goto finish;
+- }
++ dbus_message_unref(m);
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ "Reload");
++ if (!m) {
++ log_error("Could not allocate message.");
++ r = -ENOMEM;
++ goto finish;
++ }
+
+- r = 0;
++ dbus_message_unref(reply);
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
++ if (!reply) {
++ log_error("Failed to issue method call: %s", bus_error_message(error));
++ r = -EIO;
+ goto finish;
+ }
+
+- r = -ENOENT;
++ r = 0;
+
+ finish:
+ if (m)
+@@ -596,8 +501,6 @@ finish:
+ if (reply)
+ dbus_message_unref(reply);
+
+- strv_free(l);
+-
+ return r;
+ }
+
+diff --git a/units/systemd-timedated-ntp.target b/units/systemd-timedated-ntp.target
+new file mode 100644
+index 0000000..0837004
+--- /dev/null
++++ b/units/systemd-timedated-ntp.target
+@@ -0,0 +1,18 @@
++# This file is part of systemd.
++#
++# systemd is free software; you can redistribute it and/or modify it
++# under the terms of the GNU Lesser General Public License as published by
++# the Free Software Foundation; either version 2.1 of the License, or
++# (at your option) any later version.
++
++# This target is enabled/disabled via the timedated mechanism when the
++# user asks for it via the UI. NTP implementations should hook
++# themselves into this target via .wants/ symlinks, and then add
++# BindTo= on this target so that they are stopped when it goes away.
++
++[Unit]
++Description=Network Time Protocol
++Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
++
++[Install]
++WantedBy=multi-user.target
diff --git a/0505-systemd-added-new-dependency-PartOf.patch b/0505-systemd-added-new-dependency-PartOf.patch
new file mode 100644
index 0000000..919c984
--- /dev/null
+++ b/0505-systemd-added-new-dependency-PartOf.patch
@@ -0,0 +1,117 @@
+From bbb015bed0b09ddd9e86583f15d8a9366a892c6d Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Fri, 20 Jul 2012 15:55:01 +0200
+Subject: [PATCH] systemd: added new dependency PartOf
+
+This should address TODO item "new dependency type to "group" services
+in a target". Semantic of new dependency is as follows. Once configured
+it creates dependency which will cause that all dependent units get
+stopped if unit they all depend on is stopped or restarted. Usual use
+case would be configuring PartOf=some.target in template unit file
+and WantedBy=some.target in [Install] section and enabling desired
+number of instances. In this case starting one instance won't pull in
+target but stopping or starting target(in case of WantedBy is properly
+configured) will cause stop/start of all instances.
+(cherry picked from commit 85e9a1010d16064ce435b84f02dc585bc645aade)
+---
+ man/systemd.unit.xml | 15 +++++++++++++++
+ src/core/load-fragment-gperf.gperf.m4 | 1 +
+ src/core/transaction.c | 12 ++++++++++++
+ src/core/unit.c | 3 ++-
+ src/core/unit.h | 2 ++
+ 5 files changed, 32 insertions(+), 1 deletion(-)
+
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 698cbe3..5b708b3 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -427,6 +427,21 @@
+ </varlistentry>
+
+ <varlistentry>
++ <term><varname>PartOf=</varname></term>
++
++ <listitem><para>Configures dependency
++ on other unit. When systemd stops or
++ restarts unit listed here, stop or
++ restart is propagated to dependent
++ units. Note that this is one way
++ dependency and changes to dependent
++ units does not affect listed unit. If
++ something else is desired, please
++ use some other type of dependency.
++ </para></listitem>
++ </varlistentry>
++
++ <varlistentry>
+ <term><varname>Conflicts=</varname></term>
+
+ <listitem><para>Configures negative
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index e6d0db3..1489342 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -108,6 +108,7 @@ Unit.PropagatesReloadTo, config_parse_unit_deps, UNIT_PROPAG
+ Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAGATES_RELOAD_TO, 0
+ Unit.ReloadPropagatedFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0
+ Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0
++Unit.PartOf, config_parse_unit_deps, UNIT_PART_OF, 0
+ Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, offsetof(Unit, requires_mounts_for)
+ Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded)
+ Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start)
+diff --git a/src/core/transaction.c b/src/core/transaction.c
+index a1cf706..1f8d803 100644
+--- a/src/core/transaction.c
++++ b/src/core/transaction.c
+@@ -994,6 +994,18 @@ int transaction_add_job_and_dependencies(
+ dbus_error_free(e);
+ }
+ }
++
++ SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONSISTS_OF], i) {
++ r = transaction_add_job_and_dependencies(tr, type, dep, ret, true, override, false, false, ignore_order, e);
++ if (r < 0) {
++ if (r != -EBADR)
++ goto fail;
++
++ if (e)
++ dbus_error_free(e);
++ }
++ }
++
+ }
+
+ if (type == JOB_RELOAD) {
+diff --git a/src/core/unit.c b/src/core/unit.c
+index ca3892c..f0880a3 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1606,7 +1606,8 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
+ [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
+ [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
+ [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
+- [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO
++ [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
++ [UNIT_PART_OF] = UNIT_CONSISTS_OF
+ };
+ int r, q = 0, v = 0, w = 0;
+
+diff --git a/src/core/unit.h b/src/core/unit.h
+index ed31c62..992afa2 100644
+--- a/src/core/unit.h
++++ b/src/core/unit.h
+@@ -77,12 +77,14 @@ enum UnitDependency {
+ UNIT_REQUISITE_OVERRIDABLE,
+ UNIT_WANTS,
+ UNIT_BINDS_TO,
++ UNIT_PART_OF,
+
+ /* Inverse of the above */
+ UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */
+ UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */
+ UNIT_WANTED_BY, /* inverse of 'wants' */
+ UNIT_BOUND_BY, /* inverse of 'binds_to' */
++ UNIT_CONSISTS_OF, /* inverse of 'part_of' */
+
+ /* Negative dependencies */
+ UNIT_CONFLICTS, /* inverse of 'conflicts' is 'conflicted_by' */
diff --git a/0506-man-rewrite-the-description-of-PartOf.patch b/0506-man-rewrite-the-description-of-PartOf.patch
new file mode 100644
index 0000000..1ddc18a
--- /dev/null
+++ b/0506-man-rewrite-the-description-of-PartOf.patch
@@ -0,0 +1,41 @@
+From 6aa1a75b61970693d86e4f12ec6e98fd0ca6cb8b Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 26 Jul 2012 09:34:27 +0200
+Subject: [PATCH] man: rewrite the description of PartOf (cherry picked from
+ commit f3d52e8cf23582d9150bd62a05dbedb8dd102f9c)
+
+---
+ man/systemd.unit.xml | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 5b708b3..7542052 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -429,16 +429,16 @@
+ <varlistentry>
+ <term><varname>PartOf=</varname></term>
+
+- <listitem><para>Configures dependency
+- on other unit. When systemd stops or
+- restarts unit listed here, stop or
+- restart is propagated to dependent
+- units. Note that this is one way
+- dependency and changes to dependent
+- units does not affect listed unit. If
+- something else is desired, please
+- use some other type of dependency.
+- </para></listitem>
++ <listitem><para>Configures dependencies
++ similar to <varname>Requires=</varname>,
++ but limited to stopping and restarting
++ of units. When systemd stops or restarts
++ the units listed here, the action is
++ propagated to this unit.
++ Note that this is a one way dependency -
++ changes to this unit do not affect the
++ listed units.
++ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
diff --git a/0507-dbus-unit-expose-PartOf-ConsistsOf-properties.patch b/0507-dbus-unit-expose-PartOf-ConsistsOf-properties.patch
new file mode 100644
index 0000000..eded25f
--- /dev/null
+++ b/0507-dbus-unit-expose-PartOf-ConsistsOf-properties.patch
@@ -0,0 +1,28 @@
+From 1cd70f5ae49e63ceee0c293bcce552e83dc81824 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 26 Jul 2012 09:38:39 +0200
+Subject: [PATCH] dbus-unit: expose PartOf/ConsistsOf properties (cherry
+ picked from commit
+ b05afff1afe19cf7b48d9d0d2e8b5b4aa9e949dd)
+
+---
+ src/core/dbus-unit.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
+index a7c5fa8..c7a3524 100644
+--- a/src/core/dbus-unit.c
++++ b/src/core/dbus-unit.c
+@@ -794,10 +794,12 @@ const BusProperty bus_unit_properties[] = {
+ { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true },
+ { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true },
+ { "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true },
++ { "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), true },
+ { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true },
+ { "RequiredByOverridable",bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true },
+ { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true },
+ { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true },
++ { "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), true },
+ { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true },
+ { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true },
+ { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true },
diff --git a/0508-unit-make-the-table-of-inverse-deps-symmetric.patch b/0508-unit-make-the-table-of-inverse-deps-symmetric.patch
new file mode 100644
index 0000000..2628535
--- /dev/null
+++ b/0508-unit-make-the-table-of-inverse-deps-symmetric.patch
@@ -0,0 +1,36 @@
+From 590c688056c7bc69f3f39d0cc8e47fb99a674af6 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 26 Jul 2012 09:42:26 +0200
+Subject: [PATCH] unit: make the table of inverse deps symmetric (cherry
+ picked from commit
+ 60649f17bd5ef8659dab474ace8bf42ee23ffca3)
+
+---
+ src/core/unit.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index f0880a3..6c373b3 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -1592,10 +1592,12 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
+ [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
+ [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
+ [UNIT_BINDS_TO] = UNIT_BOUND_BY,
++ [UNIT_PART_OF] = UNIT_CONSISTS_OF,
+ [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
+ [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
+ [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
+ [UNIT_BOUND_BY] = UNIT_BINDS_TO,
++ [UNIT_CONSISTS_OF] = UNIT_PART_OF,
+ [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
+ [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
+ [UNIT_BEFORE] = UNIT_AFTER,
+@@ -1607,7 +1609,6 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
+ [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
+ [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
+ [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
+- [UNIT_PART_OF] = UNIT_CONSISTS_OF
+ };
+ int r, q = 0, v = 0, w = 0;
+
diff --git a/0509-unit-add-missing-deps-in-unit_dependency_table.patch b/0509-unit-add-missing-deps-in-unit_dependency_table.patch
new file mode 100644
index 0000000..b16ec79
--- /dev/null
+++ b/0509-unit-add-missing-deps-in-unit_dependency_table.patch
@@ -0,0 +1,49 @@
+From e675d810aac128365313330c02d3e56bfe7402a3 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Thu, 26 Jul 2012 09:46:40 +0200
+Subject: [PATCH] unit: add missing deps in unit_dependency_table
+
+also reorder the table according to the enum order.
+(cherry picked from commit ac6a4abed3e69daf6795e02fa4be1719ae6ae6ab)
+---
+ src/core/unit.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 6c373b3..7b54df3 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2750,25 +2750,27 @@ DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
+ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
+ [UNIT_REQUIRES] = "Requires",
+ [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
+- [UNIT_WANTS] = "Wants",
+ [UNIT_REQUISITE] = "Requisite",
+ [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
++ [UNIT_WANTS] = "Wants",
++ [UNIT_BINDS_TO] = "BindsTo",
++ [UNIT_PART_OF] = "PartOf",
+ [UNIT_REQUIRED_BY] = "RequiredBy",
+ [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
+- [UNIT_BINDS_TO] = "BindsTo",
+ [UNIT_WANTED_BY] = "WantedBy",
++ [UNIT_BOUND_BY] = "BoundBy",
++ [UNIT_CONSISTS_OF] = "ConsistsOf",
+ [UNIT_CONFLICTS] = "Conflicts",
+ [UNIT_CONFLICTED_BY] = "ConflictedBy",
+- [UNIT_BOUND_BY] = "BoundBy",
+ [UNIT_BEFORE] = "Before",
+ [UNIT_AFTER] = "After",
+- [UNIT_REFERENCES] = "References",
+- [UNIT_REFERENCED_BY] = "ReferencedBy",
+ [UNIT_ON_FAILURE] = "OnFailure",
+ [UNIT_TRIGGERS] = "Triggers",
+ [UNIT_TRIGGERED_BY] = "TriggeredBy",
+ [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
+- [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom"
++ [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
++ [UNIT_REFERENCES] = "References",
++ [UNIT_REFERENCED_BY] = "ReferencedBy",
+ };
+
+ DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
diff --git a/0510-systemd-enable-disable-instances-of-template.patch b/0510-systemd-enable-disable-instances-of-template.patch
new file mode 100644
index 0000000..e519e9e
--- /dev/null
+++ b/0510-systemd-enable-disable-instances-of-template.patch
@@ -0,0 +1,257 @@
+From 7e896cf8a93ae698475c065ef0e847dabf3b3441 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Fri, 13 Jul 2012 15:59:26 +0200
+Subject: [PATCH] systemd: enable/disable instances of template
+
+https://bugzilla.redhat.com/show_bug.cgi?id=752774
+(cherry picked from commit 29283ea4cf5df20aa0ea9e24e3cb7035bf4c4a04)
+---
+ man/systemctl.xml | 33 ++++++++++++---------
+ src/shared/install.c | 78 +++++++++++++++++++++++++++++++++++++++++++-------
+ src/shared/unit-name.c | 12 ++++++++
+ src/shared/unit-name.h | 1 +
+ 4 files changed, 100 insertions(+), 24 deletions(-)
+
+diff --git a/man/systemctl.xml b/man/systemctl.xml
+index 9808f41..92d22ba 100644
+--- a/man/systemctl.xml
++++ b/man/systemctl.xml
+@@ -683,24 +683,29 @@
+ <varlistentry>
+ <term><command>enable [NAME...]</command></term>
+
+- <listitem><para>Enable one or more
+- unit files, as specified on the
++ <listitem><para>Enable one or
++ more unit files or unit file
++ instances, as specified on the
+ command line. This will create a
+- number of symlinks as encoded in the
+- <literal>[Install]</literal> sections
+- of the unit files. After the symlinks
+- have been created the systemd
+- configuration is reloaded (in a way
+- that is equivalent to
+- <command>daemon-reload</command>) to
+- ensure the changes are taken into
++ number of symlinks as encoded in
++ the <literal>[Install]</literal>
++ sections of the unit files. After
++ the symlinks have been created the
++ systemd configuration is reloaded
++ (in a way that is equivalent to
++ <command>daemon-reload</command>)
++ to ensure the changes are taken into
+ account immediately. Note that this
+ does not have the effect that any of
+ the units enabled are also started at
+- the same time. If this is desired a
+- separate <command>start</command>
+- command must be invoked for the
+- unit.</para>
++ the same time. If this is desired
++ a separate <command>start</command>
++ command must be invoked for the unit.
++ Also note that in case of instance
++ enablement, symlinks named same as
++ instances are created in install
++ location, however they all point to
++ the same template unit file.</para>
+
+ <para>This command will
+ print the actions executed. This
+diff --git a/src/shared/install.c b/src/shared/install.c
+index 786846e..6f0e018 100644
+--- a/src/shared/install.c
++++ b/src/shared/install.c
+@@ -195,7 +195,8 @@ static int remove_marked_symlinks_fd(
+ const char *config_path,
+ bool *deleted,
+ UnitFileChange **changes,
+- unsigned *n_changes) {
++ unsigned *n_changes,
++ char** files) {
+
+ int r = 0;
+ DIR *d;
+@@ -254,7 +255,7 @@ static int remove_marked_symlinks_fd(
+ }
+
+ /* This will close nfd, regardless whether it succeeds or not */
+- q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes);
++ q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes, files);
+ free(p);
+
+ if (r == 0)
+@@ -287,6 +288,9 @@ static int remove_marked_symlinks_fd(
+ set_get(remove_symlinks_to, dest) ||
+ set_get(remove_symlinks_to, path_get_file_name(dest));
+
++ if (unit_name_is_instance(p))
++ found = found && strv_contains(files, path_get_file_name(p));
++
+ if (found) {
+
+ if (unlink(p) < 0 && errno != ENOENT) {
+@@ -325,7 +329,8 @@ static int remove_marked_symlinks(
+ Set *remove_symlinks_to,
+ const char *config_path,
+ UnitFileChange **changes,
+- unsigned *n_changes) {
++ unsigned *n_changes,
++ char** files) {
+
+ int fd, r = 0;
+ bool deleted;
+@@ -350,7 +355,7 @@ static int remove_marked_symlinks(
+ }
+
+ /* This takes possession of cfd and closes it */
+- q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes);
++ q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes, files);
+ if (r == 0)
+ r = q;
+ } while (deleted);
+@@ -716,7 +721,7 @@ int unit_file_unmask(
+
+
+ finish:
+- q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
++ q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+ if (r == 0)
+ r = q;
+
+@@ -1093,8 +1098,48 @@ static int unit_file_search(
+
+ if (r >= 0)
+ info->path = path;
+- else
++ else {
++ if (r == -ENOENT && unit_name_is_instance(info->name)) {
++ /* unit file doesn't exist, however instance enablement was request */
++ /* we will check if it is possible to load template unit file */
++ char *template = NULL,
++ *template_path = NULL,
++ *template_dir = NULL;
++
++ template = unit_name_template(info->name);
++ if (!template) {
++ free(path);
++ return -ENOMEM;
++ }
++
++ /* we will reuse path variable since we don't need it anymore */
++ template_dir = path;
++ *(strrchr(path, '/') + 1) = '\0';
++
++ template_path = join(template_dir, template, NULL);
++ if (!template_path) {
++ free(path);
++ free(template);
++ return -ENOMEM;
++ }
++
++ /* let's try to load template unit */
++ r = unit_file_load(c, info, template_path, allow_symlink);
++ if (r >= 0) {
++ info->path = strdup(template_path);
++ if (!info->path) {
++ free(path);
++ free(template);
++ free(template_path);
++ return -ENOMEM;
++ }
++ }
++
++ free(template);
++ free(template_path);
++ }
+ free(path);
++ }
+
+ if (r != -ENOENT && r != -ELOOP)
+ return r;
+@@ -1418,7 +1463,20 @@ static int install_context_mark_for_removal(
+ } else if (r >= 0)
+ r += q;
+
+- q = mark_symlink_for_removal(remove_symlinks_to, i->name);
++ if (unit_name_is_instance(i->name)) {
++ char *unit_file = NULL;
++
++ unit_file = path_get_file_name(i->path);
++
++ if (unit_name_is_instance(unit_file))
++ /* unit file named as instance exists, thus all symlinks pointing to it, will be removed */
++ q = mark_symlink_for_removal(remove_symlinks_to, i->name);
++ else
++ /* does not exist, thus we will mark for removal symlinks to template unit file */
++ q = mark_symlink_for_removal(remove_symlinks_to, unit_file);
++ } else
++ q = mark_symlink_for_removal(remove_symlinks_to, i->name);
++
+ if (r >= 0 && q < 0)
+ r = q;
+ }
+@@ -1510,7 +1568,7 @@ int unit_file_disable(
+
+ r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir);
+
+- q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
++ q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+ if (r == 0)
+ r = q;
+
+@@ -1562,7 +1620,7 @@ int unit_file_reenable(
+ goto finish;
+ }
+
+- r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
++ r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+
+ /* Returns number of symlinks that where supposed to be installed. */
+ q = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes);
+@@ -1812,7 +1870,7 @@ int unit_file_preset(
+
+ r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir);
+
+- q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes);
++ q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes, files);
+ if (r == 0)
+ r = q;
+
+diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
+index dd15119..e9b83b7 100644
+--- a/src/shared/unit-name.c
++++ b/src/shared/unit-name.c
+@@ -336,6 +336,18 @@ bool unit_name_is_template(const char *n) {
+ return p[1] == '.';
+ }
+
++bool unit_name_is_instance(const char *n) {
++ const char *p;
++
++ assert(n);
++
++ p = strchr(n, '@');
++ if (!p)
++ return false;
++
++ return p[1] != '.';
++}
++
+ char *unit_name_replace_instance(const char *f, const char *i) {
+ const char *p, *e;
+ char *r, *k;
+diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h
+index f23d2cd..5d8c7fd 100644
+--- a/src/shared/unit-name.h
++++ b/src/shared/unit-name.h
+@@ -81,6 +81,7 @@ char *unit_name_unescape(const char *f);
+ char *unit_name_path_unescape(const char *f);
+
+ bool unit_name_is_template(const char *n);
++bool unit_name_is_instance(const char *n);
+
+ char *unit_name_replace_instance(const char *f, const char *i);
+
diff --git a/0511-logs-show-fix-OOM-path.patch b/0511-logs-show-fix-OOM-path.patch
new file mode 100644
index 0000000..141e7e4
--- /dev/null
+++ b/0511-logs-show-fix-OOM-path.patch
@@ -0,0 +1,33 @@
+From 1cc54fc48c8261b1dd22c69eeafa5d9d4a2c3155 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 26 Jul 2012 16:05:26 +0200
+Subject: [PATCH] logs-show: fix OOM path (cherry picked from commit
+ 46b0d922256b62bc8291951d9868c243ced80c9a)
+
+Conflicts:
+ src/shared/logs-show.c
+---
+ src/shared/logs-show.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
+index 6bc24fa..2219c80 100644
+--- a/src/shared/logs-show.c
++++ b/src/shared/logs-show.c
+@@ -59,13 +59,14 @@ static int parse_field(const void *data, size_t length, const char *field, char
+
+ nl = length - fl;
+ buf = malloc(nl+1);
+- memcpy(buf, (const char*) data + fl, nl);
+- ((char*)buf)[nl] = 0;
+ if (!buf) {
+ log_error("Out of memory");
+ return -ENOMEM;
+ }
+
++ memcpy(buf, (const char*) data + fl, nl);
++ ((char*)buf)[nl] = 0;
++
+ free(*target);
+ *target = buf;
+ *target_size = nl;
diff --git a/0512-systemctl-automatically-turn-paths-and-unescaped-uni.patch b/0512-systemctl-automatically-turn-paths-and-unescaped-uni.patch
new file mode 100644
index 0000000..a83027f
--- /dev/null
+++ b/0512-systemctl-automatically-turn-paths-and-unescaped-uni.patch
@@ -0,0 +1,896 @@
+From 2e2322047d4ae780f47820970b642092babee06a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 22 Jun 2012 13:08:48 +0200
+Subject: [PATCH] systemctl: automatically turn paths and unescaped unit names
+ into proper unit names
+
+This makes sure that
+
+ systemctl status /home
+
+is implicitly translated to:
+
+ systemctl status /home.mount
+
+Similar, /dev/foobar becomes dev-foobar.device.
+
+Also, all characters that cannot be part of a unit name are implicitly
+escaped.
+(cherry picked from commit b0193f1c1f1540bfccbdca02df82669b9308e4e2)
+
+Conflicts:
+ .gitignore
+ TODO
+ src/shared/unit-name.c
+---
+ Makefile.am | 9 +-
+ src/core/device.c | 6 +-
+ src/shared/unit-name.c | 73 +++++++++++---
+ src/shared/unit-name.h | 2 +
+ src/systemctl/systemctl.c | 249 +++++++++++++++++++++++++++++-----------------
+ src/test/test-hostname.c | 3 +-
+ src/test/test-unit-name.c | 82 +++++++++++++++
+ 7 files changed, 316 insertions(+), 108 deletions(-)
+ create mode 100644 src/test/test-unit-name.c
+
+diff --git a/Makefile.am b/Makefile.am
+index bb4f774..b2eac88 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -904,7 +904,8 @@ noinst_PROGRAMS += \
+ test-env-replace \
+ test-strv \
+ test-install \
+- test-watchdog
++ test-watchdog \
++ test-unit-name
+
+ TESTS += \
+ test-job-type \
+@@ -953,6 +954,12 @@ test_hostname_SOURCES = \
+ test_hostname_LDADD = \
+ libsystemd-core.la
+
++test_unit_name_SOURCES = \
++ src/test/test-unit-name.c
++
++test_unit_name_LDADD = \
++ libsystemd-core.la
++
+ test_daemon_SOURCES = \
+ src/test/test-daemon.c
+
+diff --git a/src/core/device.c b/src/core/device.c
+index a56b06b..d5df752 100644
+--- a/src/core/device.c
++++ b/src/core/device.c
+@@ -144,7 +144,8 @@ static int device_add_escaped_name(Unit *u, const char *dn) {
+ assert(dn);
+ assert(dn[0] == '/');
+
+- if (!(e = unit_name_from_path(dn, ".device")))
++ e = unit_name_from_path(dn, ".device");
++ if (!e)
+ return -ENOMEM;
+
+ r = unit_add_name(u, e);
+@@ -165,7 +166,8 @@ static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
+ assert(dn[0] == '/');
+ assert(_u);
+
+- if (!(e = unit_name_from_path(dn, ".device")))
++ e = unit_name_from_path(dn, ".device");
++ if (!e)
+ return -ENOMEM;
+
+ u = manager_get_unit(m, e);
+diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
+index e9b83b7..8db0a6e 100644
+--- a/src/shared/unit-name.c
++++ b/src/shared/unit-name.c
+@@ -168,7 +168,8 @@ char *unit_name_to_prefix_and_instance(const char *n) {
+ char *unit_name_to_prefix(const char *n) {
+ const char *p;
+
+- if ((p = strchr(n, '@')))
++ p = strchr(n, '@');
++ if (p)
+ return strndup(n, p - n);
+
+ return unit_name_to_prefix_and_instance(n);
+@@ -186,7 +187,8 @@ char *unit_name_change_suffix(const char *n, const char *suffix) {
+ a = e - n;
+ b = strlen(suffix);
+
+- if (!(r = new(char, a + b + 1)))
++ r = new(char, a + b + 1);
++ if (!r)
+ return NULL;
+
+ memcpy(r, n, a);
+@@ -262,7 +264,8 @@ char *unit_name_build_escape(const char *prefix, const char *instance, const cha
+ if (instance) {
+ b = strlen(instance);
+
+- if (!(r = new(char, a*4 + 1 + b*4 + c + 1)))
++ r = new(char, a*4 + 1 + b*4 + c + 1);
++ if (!r)
+ return NULL;
+
+ t = do_escape(prefix, r);
+@@ -283,14 +286,14 @@ char *unit_name_build_escape(const char *prefix, const char *instance, const cha
+ char *unit_name_escape(const char *f) {
+ char *r, *t;
+
+- if (!(r = new(char, strlen(f)*4+1)))
++ r = new(char, strlen(f)*4+1);
++ if (!r)
+ return NULL;
+
+ t = do_escape(f, r);
+ *t = 0;
+
+ return r;
+-
+ }
+
+ char *unit_name_unescape(const char *f) {
+@@ -298,7 +301,8 @@ char *unit_name_unescape(const char *f) {
+
+ assert(f);
+
+- if (!(r = strdup(f)))
++ r = strdup(f);
++ if (!r)
+ return NULL;
+
+ for (t = r; *f; f++) {
+@@ -387,13 +391,15 @@ char *unit_name_template(const char *f) {
+ char *r;
+ size_t a;
+
+- if (!(p = strchr(f, '@')))
++ p = strchr(f, '@');
++ if (!p)
+ return strdup(f);
+
+ assert_se(e = strrchr(f, '.'));
+ a = p - f + 1;
+
+- if (!(r = new(char, a + strlen(e) + 1)))
++ r = new(char, a + strlen(e) + 1);
++ if (!r)
+ return NULL;
+
+ strcpy(mempcpy(r, f, a), e);
+@@ -407,7 +413,8 @@ char *unit_name_from_path(const char *path, const char *suffix) {
+ assert(path);
+ assert(suffix);
+
+- if (!(p = strdup(path)))
++ p = strdup(path);
++ if (!p)
+ return NULL;
+
+ path_kill_slashes(p);
+@@ -454,7 +461,8 @@ char *unit_name_to_path(const char *name) {
+
+ assert(name);
+
+- if (!(w = unit_name_to_prefix(name)))
++ w = unit_name_to_prefix(name);
++ if (!w)
+ return NULL;
+
+ e = unit_name_unescape(w);
+@@ -470,7 +478,7 @@ char *unit_name_to_path(const char *name) {
+ if (!w)
+ return NULL;
+
+- e = w;
++ return w;
+ }
+
+ return e;
+@@ -481,7 +489,8 @@ char *unit_name_path_unescape(const char *f) {
+
+ assert(f);
+
+- if (!(e = unit_name_unescape(f)))
++ e = unit_name_unescape(f);
++ if (!e)
+ return NULL;
+
+ if (e[0] != '/') {
+@@ -493,7 +502,7 @@ char *unit_name_path_unescape(const char *f) {
+ if (!w)
+ return NULL;
+
+- e = w;
++ return w;
+ }
+
+ return e;
+@@ -512,6 +521,44 @@ char *unit_dbus_path_from_name(const char *name) {
+ return p;
+ }
+
++char *unit_name_mangle(const char *name) {
++ char *r, *t;
++ const char *f;
++
++ assert(name);
++
++ /* Try to turn a string that might not be a unit name into a
++ * sensible unit name. */
++
++ if (path_startswith(name, "/dev/") ||
++ path_startswith(name, "/sys/"))
++ return unit_name_from_path(name, ".device");
++
++ if (path_is_absolute(name))
++ return unit_name_from_path(name, ".mount");
++
++ /* We'll only escape the obvious characters here, to play
++ * safe. */
++
++ r = new(char, strlen(name) * 4 + 1);
++ if (!r)
++ return NULL;
++
++ for (f = name, t = r; *f; f++) {
++
++ if (*f == '/')
++ *(t++) = '-';
++ else if (!strchr("@" VALID_CHARS, *f))
++ t = do_escape_char(*f, t);
++ else
++ *(t++) = *f;
++ }
++
++ *t = 0;
++
++ return r;
++}
++
+ UnitType unit_name_to_type(const char *n) {
+ const char *e;
+
+diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h
+index 5d8c7fd..8e6f692 100644
+--- a/src/shared/unit-name.h
++++ b/src/shared/unit-name.h
+@@ -93,4 +93,6 @@ char *unit_name_to_path(const char *name);
+
+ char *unit_dbus_path_from_name(const char *name);
+
++char *unit_name_mangle(const char *name);
++
+ #endif
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 465832b..16e0e30 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -1126,6 +1126,8 @@ static int load_unit(DBusConnection *bus, char **args) {
+
+ STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
++ bool b;
++ char *n;
+
+ if (!(m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+@@ -1137,15 +1139,19 @@ static int load_unit(DBusConnection *bus, char **args) {
+ goto finish;
+ }
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, name,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(*name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? &n : name,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ r = -EIO;
+ goto finish;
+@@ -1269,22 +1275,29 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
+ *interface = "org.freedesktop.systemd1.Unit",
+ *property = "NeedDaemonReload",
+ *path;
++ char *n;
++ bool k;
+
+ /* We ignore all errors here, since this is used to show a warning only */
+
+- if (!(m = dbus_message_new_method_call(
++ m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+- "GetUnit")))
++ "GetUnit");
++ if (!m)
+ goto finish;
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, &unit,
+- DBUS_TYPE_INVALID))
++ n = unit_name_mangle(unit);
++ k = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? (const char**) &n : &unit,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!k)
+ goto finish;
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL)))
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL);
++ if (!reply)
+ goto finish;
+
+ if (!dbus_message_get_args(reply, NULL,
+@@ -1293,11 +1306,12 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
+ goto finish;
+
+ dbus_message_unref(m);
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- path,
+- "org.freedesktop.DBus.Properties",
+- "Get")))
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ path,
++ "org.freedesktop.DBus.Properties",
++ "Get");
++ if (!m)
+ goto finish;
+
+ if (!dbus_message_append_args(m,
+@@ -1308,7 +1322,8 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
+ }
+
+ dbus_message_unref(reply);
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL)))
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL);
++ if (!reply)
+ goto finish;
+
+ if (!dbus_message_iter_init(reply, &iter) ||
+@@ -1493,6 +1508,8 @@ static int check_one_unit(DBusConnection *bus, char *name, bool quiet) {
+ const char *path = NULL;
+ const char *state;
+ int r = 3; /* According to LSB: "program is not running" */
++ char *n;
++ bool b;
+
+ assert(bus);
+ assert(name);
+@@ -1510,9 +1527,12 @@ static int check_one_unit(DBusConnection *bus, char *name, bool quiet) {
+ goto finish;
+ }
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, &name,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? &n : &name,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+@@ -1610,12 +1630,14 @@ static void check_triggering_units(
+ const char *interface = "org.freedesktop.systemd1.Unit",
+ *triggered_by_property = "TriggeredBy";
+
+- char *unit_path = NULL;
++ char *unit_path = NULL, *n = NULL;
+ bool print_warning_label = true;
+
+ dbus_error_init(&error);
+
+- unit_path = unit_dbus_path_from_name(unit_name);
++ n = unit_name_mangle(unit_name);
++ unit_path = unit_dbus_path_from_name(n ? n : unit_name);
++ free(n);
+ if (!unit_path) {
+ log_error("Could not allocate dbus path.");
+ goto finish;
+@@ -1701,6 +1723,8 @@ static int start_unit_one(
+ DBusMessage *m = NULL, *reply = NULL;
+ const char *path;
+ int r;
++ char *n;
++ bool b;
+
+ assert(bus);
+ assert(method);
+@@ -1709,26 +1733,31 @@ static int start_unit_one(
+ assert(error);
+ assert(arg_no_block || s);
+
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- method))) {
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ method);
++ if (!m) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, &name,
+- DBUS_TYPE_STRING, &mode,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? (const char **) &n : &name,
++ DBUS_TYPE_STRING, &mode,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
++ if (!reply) {
+
+ if (arg_action != ACTION_SYSTEMCTL && error_is_no_service(error)) {
+ /* There's always a fallback possible for
+@@ -2096,29 +2125,36 @@ static int kill_unit(DBusConnection *bus, char **args) {
+
+ STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
++ char *n;
++ bool b;
+
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- "KillUnit"))) {
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ "KillUnit");
++ if (!m) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, name,
+- DBUS_TYPE_STRING, &arg_kill_who,
+- DBUS_TYPE_STRING, &arg_kill_mode,
+- DBUS_TYPE_INT32, &arg_signal,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(*name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? &n : name,
++ DBUS_TYPE_STRING, &arg_kill_who,
++ DBUS_TYPE_STRING, &arg_kill_mode,
++ DBUS_TYPE_INT32, &arg_signal,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ dbus_error_free(&error);
+ r = -EIO;
+@@ -3235,12 +3271,16 @@ static int show(DBusConnection *bus, char **args) {
+ uint32_t id;
+
+ if (safe_atou32(*name, &id) < 0) {
+-
++ char *p, *n;
+ /* Interpret as unit name */
+
+- char *p = unit_dbus_path_from_name(*name);
+- if (!p)
++ n = unit_name_mangle(*name);
++ p = unit_dbus_path_from_name(n ? n : *name);
++ free(n);
++ if (!p) {
++ log_error("Out of memory");
+ return -ENOMEM;
++ }
+
+ r = show_one(args[0], bus, p, show_properties, &new_line);
+ free(p);
+@@ -3253,8 +3293,10 @@ static int show(DBusConnection *bus, char **args) {
+ /* Interpret as job id */
+
+ char *p;
+- if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
++ if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) {
++ log_error("Out of memory");
+ return -ENOMEM;
++ }
+
+ r = show_one(args[0], bus, p, show_properties, &new_line);
+ free(p);
+@@ -3334,14 +3376,17 @@ static int snapshot(DBusConnection *bus, char **args) {
+ const char
+ *interface = "org.freedesktop.systemd1.Unit",
+ *property = "Id";
++ char *n;
++ bool b;
+
+ dbus_error_init(&error);
+
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- "CreateSnapshot"))) {
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ "CreateSnapshot");
++ if (!m) {
+ log_error("Could not allocate message.");
+ return -ENOMEM;
+ }
+@@ -3349,16 +3394,20 @@ static int snapshot(DBusConnection *bus, char **args) {
+ if (strv_length(args) > 1)
+ name = args[1];
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, &name,
+- DBUS_TYPE_BOOLEAN, &cleanup,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? (const char**) &n : &name,
++ DBUS_TYPE_BOOLEAN, &cleanup,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ r = -EIO;
+ goto finish;
+@@ -3373,11 +3422,12 @@ static int snapshot(DBusConnection *bus, char **args) {
+ }
+
+ dbus_message_unref(m);
+- if (!(m = dbus_message_new_method_call(
++ m = dbus_message_new_method_call(
+ "org.freedesktop.systemd1",
+ path,
+ "org.freedesktop.DBus.Properties",
+- "Get"))) {
++ "Get");
++ if (!m) {
+ log_error("Could not allocate message.");
+ return -ENOMEM;
+ }
+@@ -3392,7 +3442,8 @@ static int snapshot(DBusConnection *bus, char **args) {
+ }
+
+ dbus_message_unref(reply);
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ r = -EIO;
+ goto finish;
+@@ -3444,26 +3495,33 @@ static int delete_snapshot(DBusConnection *bus, char **args) {
+
+ STRV_FOREACH(name, args+1) {
+ const char *path = NULL;
++ char *n;
++ bool b;
+
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- "GetUnit"))) {
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ "GetUnit");
++ if (!m) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, name,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(*name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? &n : name,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ r = -EIO;
+ goto finish;
+@@ -3478,18 +3536,20 @@ static int delete_snapshot(DBusConnection *bus, char **args) {
+ }
+
+ dbus_message_unref(m);
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- path,
+- "org.freedesktop.systemd1.Snapshot",
+- "Remove"))) {
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ path,
++ "org.freedesktop.systemd1.Snapshot",
++ "Remove");
++ if (!m) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ dbus_message_unref(reply);
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ r = -EIO;
+ goto finish;
+@@ -3600,26 +3660,33 @@ static int reset_failed(DBusConnection *bus, char **args) {
+
+ STRV_FOREACH(name, args+1) {
+ DBusMessage *reply;
++ char *n;
++ bool b;
+
+- if (!(m = dbus_message_new_method_call(
+- "org.freedesktop.systemd1",
+- "/org/freedesktop/systemd1",
+- "org.freedesktop.systemd1.Manager",
+- "ResetFailedUnit"))) {
++ m = dbus_message_new_method_call(
++ "org.freedesktop.systemd1",
++ "/org/freedesktop/systemd1",
++ "org.freedesktop.systemd1.Manager",
++ "ResetFailedUnit");
++ if (!m) {
+ log_error("Could not allocate message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!dbus_message_append_args(m,
+- DBUS_TYPE_STRING, name,
+- DBUS_TYPE_INVALID)) {
++ n = unit_name_mangle(*name);
++ b = dbus_message_append_args(m,
++ DBUS_TYPE_STRING, n ? &n : name,
++ DBUS_TYPE_INVALID);
++ free(n);
++ if (!b) {
+ log_error("Could not append arguments to message.");
+ r = -ENOMEM;
+ goto finish;
+ }
+
+- if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) {
++ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
++ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ r = -EIO;
+ goto finish;
+@@ -4742,7 +4809,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
+ return -EINVAL;
+
+ default:
+- log_error("Unknown option code %c", c);
++ log_error("Unknown option code '%c'.", c);
+ return -EINVAL;
+ }
+ }
+@@ -4835,7 +4902,7 @@ static int halt_parse_argv(int argc, char *argv[]) {
+ return -EINVAL;
+
+ default:
+- log_error("Unknown option code %c", c);
++ log_error("Unknown option code '%c'.", c);
+ return -EINVAL;
+ }
+ }
+@@ -4972,7 +5039,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
+ return -EINVAL;
+
+ default:
+- log_error("Unknown option code %c", c);
++ log_error("Unknown option code '%c'.", c);
+ return -EINVAL;
+ }
+ }
+@@ -5048,7 +5115,7 @@ static int telinit_parse_argv(int argc, char *argv[]) {
+ return -EINVAL;
+
+ default:
+- log_error("Unknown option code %c", c);
++ log_error("Unknown option code '%c'.", c);
+ return -EINVAL;
+ }
+ }
+@@ -5073,7 +5140,7 @@ static int telinit_parse_argv(int argc, char *argv[]) {
+ break;
+
+ if (i >= ELEMENTSOF(table)) {
+- log_error("Unknown command %s.", argv[optind]);
++ log_error("Unknown command '%s'.", argv[optind]);
+ return -EINVAL;
+ }
+
+@@ -5111,7 +5178,7 @@ static int runlevel_parse_argv(int argc, char *argv[]) {
+ return -EINVAL;
+
+ default:
+- log_error("Unknown option code %c", c);
++ log_error("Unknown option code '%c'.", c);
+ return -EINVAL;
+ }
+ }
+@@ -5412,7 +5479,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
+ break;
+
+ if (i >= ELEMENTSOF(verbs)) {
+- log_error("Unknown operation %s", argv[optind]);
++ log_error("Unknown operation '%s'.", argv[optind]);
+ return -EINVAL;
+ }
+ }
+diff --git a/src/test/test-hostname.c b/src/test/test-hostname.c
+index 0a08416..19a9a29 100644
+--- a/src/test/test-hostname.c
++++ b/src/test/test-hostname.c
+@@ -30,7 +30,8 @@
+ int main(int argc, char* argv[]) {
+ int r;
+
+- if ((r = hostname_setup()) < 0)
++ r = hostname_setup();
++ if (r < 0)
+ fprintf(stderr, "hostname: %s\n", strerror(-r));
+
+ return 0;
+diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
+new file mode 100644
+index 0000000..9d636af
+--- /dev/null
++++ b/src/test/test-unit-name.c
+@@ -0,0 +1,82 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++/***
++ This file is part of systemd.
++
++ Copyright 2012 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 <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "unit-name.h"
++#include "util.h"
++
++int main(int argc, char* argv[]) {
++ char *t, *k;
++
++ assert_se(t = unit_name_mangle("/home"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ assert_se(t = unit_name_mangle("/dev/sda"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ assert_se(t = unit_name_mangle("üxknürz.service"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ assert_se(t = unit_name_mangle("foobar-meh...waldi.service"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ assert_se(t = unit_name_mangle("_____####----.....service"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ assert_se(t = unit_name_mangle("_____##@;;;,,,##----.....service"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ assert_se(t = unit_name_mangle("xxx@@@@/////\\\\\\\\\\yyy.service"));
++ assert_se(k = unit_name_mangle(t));
++ puts(t);
++ assert_se(streq(t, k));
++ free(t);
++ free(k);
++
++ return 0;
++}
diff --git a/0513-cryptsetup-fix-escaping-when-generating-cryptsetup-u.patch b/0513-cryptsetup-fix-escaping-when-generating-cryptsetup-u.patch
new file mode 100644
index 0000000..e8e2e30
--- /dev/null
+++ b/0513-cryptsetup-fix-escaping-when-generating-cryptsetup-u.patch
@@ -0,0 +1,374 @@
+From 58a8868845195a6621e2daffe7d53eb5a79bdba2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 25 Jun 2012 20:16:15 +0200
+Subject: [PATCH] cryptsetup: fix escaping when generating cryptsetup units
+ (cherry picked from commit
+ 35eb6b124ebdf82bd77aad6e44962a9a039c4d33)
+
+Conflicts:
+ TODO
+ src/cryptsetup/cryptsetup-generator.c
+---
+ src/core/unit.c | 3 +-
+ src/cryptsetup/cryptsetup-generator.c | 2 +-
+ src/shared/unit-name.c | 168 ++++++++++++----------------------
+ src/shared/unit-name.h | 3 +-
+ src/test/test-unit-name.c | 51 +++++++++++
+ 5 files changed, 115 insertions(+), 112 deletions(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 7b54df3..b810f8f 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2507,7 +2507,8 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
+ if (!is_device_path(what))
+ return 0;
+
+- if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
++ e = unit_name_from_path(what, ".device");
++ if (!e)
+ return -ENOMEM;
+
+ r = manager_load_unit(u->manager, e, NULL, NULL, &device);
+diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
+index 4c1d04c..48f9fa4 100644
+--- a/src/cryptsetup/cryptsetup-generator.c
++++ b/src/cryptsetup/cryptsetup-generator.c
+@@ -76,7 +76,7 @@ static int create_disk(
+ noauto = has_option(options, "noauto");
+ nofail = has_option(options, "nofail");
+
+- n = unit_name_build_escape("cryptsetup", name, ".service");
++ n = unit_name_from_path_instance("cryptsetup", name, ".service");
+ if (!n) {
+ r = -ENOMEM;
+ log_error("Failed to allocate unit name.");
+diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
+index 8db0a6e..fb31d19 100644
+--- a/src/shared/unit-name.c
++++ b/src/shared/unit-name.c
+@@ -140,7 +140,8 @@ int unit_name_to_instance(const char *n, char **instance) {
+ assert(instance);
+
+ /* Everything past the first @ and before the last . is the instance */
+- if (!(p = strchr(n, '@'))) {
++ p = strchr(n, '@');
++ if (!p) {
+ *instance = NULL;
+ return 0;
+ }
+@@ -148,7 +149,8 @@ int unit_name_to_instance(const char *n, char **instance) {
+ assert_se(d = strrchr(n, '.'));
+ assert(p < d);
+
+- if (!(i = strndup(p+1, d-p-1)))
++ i = strndup(p+1, d-p-1);
++ if (!i)
+ return -ENOMEM;
+
+ *instance = i;
+@@ -239,50 +241,6 @@ static char *do_escape(const char *f, char *t) {
+ return t;
+ }
+
+-char *unit_name_build_escape(const char *prefix, const char *instance, const char *suffix) {
+- char *r, *t;
+- size_t a, b, c;
+-
+- assert(prefix);
+- assert(suffix);
+-
+- /* Takes a arbitrary string for prefix and instance plus a
+- * suffix and makes a nice string suitable as unit name of it,
+- * escaping all weird chars on the way.
+- *
+- * / becomes -, and all chars not allowed in a unit name get
+- * escaped as \xFF, including \ and -, of course. This
+- * escaping is hence reversible.
+- *
+- * This is primarily useful to make nice unit names from
+- * strings, but is actually useful for any kind of string.
+- */
+-
+- a = strlen(prefix);
+- c = strlen(suffix);
+-
+- if (instance) {
+- b = strlen(instance);
+-
+- r = new(char, a*4 + 1 + b*4 + c + 1);
+- if (!r)
+- return NULL;
+-
+- t = do_escape(prefix, r);
+- *(t++) = '@';
+- t = do_escape(instance, t);
+- } else {
+-
+- if (!(r = new(char, a*4 + c + 1)))
+- return NULL;
+-
+- t = do_escape(prefix, r);
+- }
+-
+- strcpy(t, suffix);
+- return r;
+-}
+-
+ char *unit_name_escape(const char *f) {
+ char *r, *t;
+
+@@ -329,6 +287,49 @@ char *unit_name_unescape(const char *f) {
+ return r;
+ }
+
++char *unit_name_path_escape(const char *f) {
++ char *p, *e;
++
++ assert(f);
++
++ p = strdup(f);
++ if (!p)
++ return NULL;
++
++ path_kill_slashes(p);
++
++ if (streq(p, "/")) {
++ free(p);
++ return strdup("-");
++ }
++
++ e = unit_name_escape(p[0] == '/' ? p + 1 : p);
++ free(p);
++
++ return e;
++}
++
++char *unit_name_path_unescape(const char *f) {
++ char *e;
++
++ assert(f);
++
++ e = unit_name_unescape(f);
++ if (!e)
++ return NULL;
++
++ if (e[0] != '/') {
++ char *w;
++
++ w = strappend("/", e);
++ free(e);
++
++ return w;
++ }
++
++ return e;
++}
++
+ bool unit_name_is_template(const char *n) {
+ const char *p;
+
+@@ -369,14 +370,16 @@ char *unit_name_replace_instance(const char *f, const char *i) {
+
+ b = strlen(i);
+
+- if (!(r = new(char, a + 1 + b + strlen(e) + 1)))
++ r = new(char, a + 1 + b + strlen(e) + 1);
++ if (!r)
+ return NULL;
+
+ k = mempcpy(r, f, a + 1);
+ k = mempcpy(k, i, b);
+ } else {
+
+- if (!(r = new(char, a + strlen(e) + 1)))
++ r = new(char, a + strlen(e) + 1);
++ if (!r)
+ return NULL;
+
+ k = mempcpy(r, f, a);
+@@ -413,20 +416,11 @@ char *unit_name_from_path(const char *path, const char *suffix) {
+ assert(path);
+ assert(suffix);
+
+- p = strdup(path);
++ p = unit_name_path_escape(path);
+ if (!p)
+ return NULL;
+
+- path_kill_slashes(p);
+-
+- path = p[0] == '/' ? p + 1 : p;
+-
+- if (path[0] == 0) {
+- free(p);
+- return strappend("-", suffix);
+- }
+-
+- r = unit_name_build_escape(path, NULL, suffix);
++ r = strappend(p, suffix);
+ free(p);
+
+ return r;
+@@ -435,22 +429,15 @@ char *unit_name_from_path(const char *path, const char *suffix) {
+ char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) {
+ char *p, *r;
+
++ assert(prefix);
+ assert(path);
+ assert(suffix);
+
+- if (!(p = strdup(path)))
++ p = unit_name_path_escape(path);
++ if (!p)
+ return NULL;
+
+- path_kill_slashes(p);
+-
+- path = p[0] == '/' ? p + 1 : p;
+-
+- if (path[0] == 0) {
+- free(p);
+- return unit_name_build_escape(prefix, "-", suffix);
+- }
+-
+- r = unit_name_build_escape(prefix, path, suffix);
++ r = join(prefix, "@", p, suffix, NULL);
+ free(p);
+
+ return r;
+@@ -465,52 +452,17 @@ char *unit_name_to_path(const char *name) {
+ if (!w)
+ return NULL;
+
+- e = unit_name_unescape(w);
++ e = unit_name_path_unescape(w);
+ free(w);
+
+- if (!e)
+- return NULL;
+-
+- if (e[0] != '/') {
+- w = strappend("/", e);
+- free(e);
+-
+- if (!w)
+- return NULL;
+-
+- return w;
+- }
+-
+- return e;
+-}
+-
+-char *unit_name_path_unescape(const char *f) {
+- char *e;
+-
+- assert(f);
+-
+- e = unit_name_unescape(f);
+- if (!e)
+- return NULL;
+-
+- if (e[0] != '/') {
+- char *w;
+-
+- w = strappend("/", e);
+- free(e);
+-
+- if (!w)
+- return NULL;
+-
+- return w;
+- }
+-
+ return e;
+ }
+
+ char *unit_dbus_path_from_name(const char *name) {
+ char *e, *p;
+
++ assert(name);
++
+ e = bus_path_escape(name);
+ if (!e)
+ return NULL;
+diff --git a/src/shared/unit-name.h b/src/shared/unit-name.h
+index 8e6f692..fb6bdef 100644
+--- a/src/shared/unit-name.h
++++ b/src/shared/unit-name.h
+@@ -73,11 +73,10 @@ UnitType unit_name_to_type(const char *n);
+ char *unit_name_change_suffix(const char *n, const char *suffix);
+
+ char *unit_name_build(const char *prefix, const char *instance, const char *suffix);
+-char *unit_name_build_escape(const char *prefix, const char *instance, const char *suffix);
+
+ char *unit_name_escape(const char *f);
+ char *unit_name_unescape(const char *f);
+-
++char *unit_name_path_escape(const char *f);
+ char *unit_name_path_unescape(const char *f);
+
+ bool unit_name_is_template(const char *n);
+diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
+index 9d636af..392e358 100644
+--- a/src/test/test-unit-name.c
++++ b/src/test/test-unit-name.c
+@@ -29,6 +29,57 @@
+ int main(int argc, char* argv[]) {
+ char *t, *k;
+
++ t = unit_name_from_path("/waldo", ".mount");
++ puts(t);
++ k = unit_name_to_path(t);
++ puts(k);
++ free(k);
++ free(t);
++
++ t = unit_name_from_path("/waldo/quuix", ".mount");
++ puts(t);
++ k = unit_name_to_path(t);
++ puts(k);
++ free(k);
++ free(t);
++
++ t = unit_name_from_path("/waldo/quuix/", ".mount");
++ puts(t);
++ k = unit_name_to_path(t);
++ puts(k);
++ free(k);
++ free(t);
++
++ t = unit_name_from_path("/", ".mount");
++ puts(t);
++ k = unit_name_to_path(t);
++ puts(k);
++ free(k);
++ free(t);
++
++ t = unit_name_from_path("///", ".mount");
++ puts(t);
++ k = unit_name_to_path(t);
++ puts(k);
++ free(k);
++ free(t);
++
++ t = unit_name_from_path_instance("waldo", "/waldo", ".mount");
++ puts(t);
++ free(t);
++
++ t = unit_name_from_path_instance("waldo", "/waldo////quuix////", ".mount");
++ puts(t);
++ free(t);
++
++ t = unit_name_from_path_instance("waldo", "/", ".mount");
++ puts(t);
++ free(t);
++
++ t = unit_name_from_path_instance("wa--ldo", "/--", ".mount");
++ puts(t);
++ free(t);
++
+ assert_se(t = unit_name_mangle("/home"));
+ assert_se(k = unit_name_mangle(t));
+ puts(t);
diff --git a/0514-systemctl-append-.service-to-unit-names-lacking-suff.patch b/0514-systemctl-append-.service-to-unit-names-lacking-suff.patch
new file mode 100644
index 0000000..38fd2df
--- /dev/null
+++ b/0514-systemctl-append-.service-to-unit-names-lacking-suff.patch
@@ -0,0 +1,55 @@
+From 253a02e5f3f88aad7382cd5d460419082753b75d Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Sat, 28 Jul 2012 13:20:35 +0200
+Subject: [PATCH] systemctl: append .service to unit names lacking suffix
+
+https://bugs.freedesktop.org/show_bug.cgi?id=39386
+(cherry picked from commit 56d4fbf92eb6d8eb31c910e137224308c40dd909)
+
+Conflicts:
+ TODO
+---
+ src/shared/unit-name.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
+index fb31d19..28e3e76 100644
+--- a/src/shared/unit-name.c
++++ b/src/shared/unit-name.c
+@@ -476,6 +476,7 @@ char *unit_dbus_path_from_name(const char *name) {
+ char *unit_name_mangle(const char *name) {
+ char *r, *t;
+ const char *f;
++ bool dot = false;
+
+ assert(name);
+
+@@ -492,12 +493,15 @@ char *unit_name_mangle(const char *name) {
+ /* We'll only escape the obvious characters here, to play
+ * safe. */
+
+- r = new(char, strlen(name) * 4 + 1);
++ r = new(char, strlen(name) * 4 + 1 + sizeof(".service")-1);
+ if (!r)
+ return NULL;
+
+ for (f = name, t = r; *f; f++) {
+
++ if (*f == '.')
++ dot = true;
++
+ if (*f == '/')
+ *(t++) = '-';
+ else if (!strchr("@" VALID_CHARS, *f))
+@@ -506,7 +510,10 @@ char *unit_name_mangle(const char *name) {
+ *(t++) = *f;
+ }
+
+- *t = 0;
++ if (!dot)
++ strcpy(t, ".service");
++ else
++ *t = 0;
+
+ return r;
+ }
diff --git a/0515-rules-99-systemd.rules.in-ENV-SYSTEMD_READY-0-for-in.patch b/0515-rules-99-systemd.rules.in-ENV-SYSTEMD_READY-0-for-in.patch
new file mode 100644
index 0000000..c7ea03d
--- /dev/null
+++ b/0515-rules-99-systemd.rules.in-ENV-SYSTEMD_READY-0-for-in.patch
@@ -0,0 +1,27 @@
+From 979912f035d5841e76252f8cd2d0f7696148dc3b Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Mon, 30 Jul 2012 20:27:52 +0200
+Subject: [PATCH] rules/99-systemd.rules.in: ENV{SYSTEMD_READY}="0" for
+ incomplete md (cherry picked from commit
+ 44b5651f19b60a84dbfdbb0ea13196b784080c8b)
+
+---
+ src/99-systemd.rules.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/99-systemd.rules.in b/src/99-systemd.rules.in
+index ea305b1..023a459 100644
+--- a/src/99-systemd.rules.in
++++ b/src/99-systemd.rules.in
+@@ -17,10 +17,10 @@ SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=
+
+ # Ignore encrypted devices with no identified superblock on it, since
+ # we are probably still calling mke2fs or mkswap on it.
+-
+ SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0"
+
+ # Ignore raid devices that are not yet assembled and started
++SUBSYSTEM=="block", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
+ SUBSYSTEM=="block", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
+
+ # We need a hardware independent way to identify network devices. We
diff --git a/0516-99-systemd.rules.in-ignore-nbd-in-the-add-uevent.patch b/0516-99-systemd.rules.in-ignore-nbd-in-the-add-uevent.patch
new file mode 100644
index 0000000..cc2f067
--- /dev/null
+++ b/0516-99-systemd.rules.in-ignore-nbd-in-the-add-uevent.patch
@@ -0,0 +1,25 @@
+From 37dc4f1427200d1b1da68c4cd7a289cf51ce9b26 Mon Sep 17 00:00:00 2001
+From: Harald Hoyer <harald at redhat.com>
+Date: Mon, 30 Jul 2012 21:21:37 +0200
+Subject: [PATCH] 99-systemd.rules.in: ignore nbd in the "add" uevent (cherry
+ picked from commit
+ 45646bb0d1ac8f17a8401cf5c51034475719c7e1)
+
+---
+ src/99-systemd.rules.in | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/99-systemd.rules.in b/src/99-systemd.rules.in
+index 023a459..8ef7b8f 100644
+--- a/src/99-systemd.rules.in
++++ b/src/99-systemd.rules.in
+@@ -23,6 +23,9 @@ SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_T
+ SUBSYSTEM=="block", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
+ SUBSYSTEM=="block", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
+
++# Ignore nbd devices in the "add" event, with "change" the nbd is ready
++ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0"
++
+ # We need a hardware independent way to identify network devices. We
+ # use the /sys/subsystem path for this. Current vanilla kernels don't
+ # actually support that hierarchy right now, however upcoming kernels
diff --git a/0517-automount-print-mount-point-in-debug-message.patch b/0517-automount-print-mount-point-in-debug-message.patch
new file mode 100644
index 0000000..d072e2c
--- /dev/null
+++ b/0517-automount-print-mount-point-in-debug-message.patch
@@ -0,0 +1,31 @@
+From 5ab84d8c9bb5473af7524b133163ccf6207b48e7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Wed, 13 Jul 2011 14:06:42 +0200
+Subject: [PATCH] automount: print mount point in debug message
+
+Old: systemd[1]: Got direct mount request for ffff88003bb10c00, triggered by 14476 (fuser)
+New: systemd[1]: Got direct mount request on /dev/mqueue, triggered by 2177 (ls)
+(cherry picked from commit 2cc58876202b06fabcdb1b0ab1cf7beb1945a3f3)
+---
+ src/core/automount.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/automount.c b/src/core/automount.c
+index 27ca887..5c716ee 100644
+--- a/src/core/automount.c
++++ b/src/core/automount.c
+@@ -782,11 +782,12 @@ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
+ char *p = NULL;
+
+ get_process_comm(packet.v5_packet.pid, &p);
+- log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p));
++ log_debug("Got direct mount request on %s, triggered by %lu (%s)",
++ a->where, (unsigned long) packet.v5_packet.pid, strna(p));
+ free(p);
+
+ } else
+- log_debug("Got direct mount request for %s", packet.v5_packet.name);
++ log_debug("Got direct mount request on %s", a->where);
+
+ if (!a->tokens)
+ if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) {
diff --git a/0518-journald-fixed-memory-leak.patch b/0518-journald-fixed-memory-leak.patch
new file mode 100644
index 0000000..c801cab
--- /dev/null
+++ b/0518-journald-fixed-memory-leak.patch
@@ -0,0 +1,22 @@
+From 7f75f59bcab871549b73325fcf837981fb12ac9a Mon Sep 17 00:00:00 2001
+From: Artur Zaprzala <zybi at talex.pl>
+Date: Tue, 31 Jul 2012 14:14:51 +0200
+Subject: [PATCH] journald: fixed memory leak (cherry picked from commit
+ 4cdc45994a9444820ae0d11b1a8b29dc5641ba15)
+
+---
+ src/journal/journald.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/journal/journald.c b/src/journal/journald.c
+index 3b50cd8..a538047 100644
+--- a/src/journal/journald.c
++++ b/src/journal/journald.c
+@@ -1134,6 +1134,7 @@ static void process_syslog_message(Server *s, const char *buf, struct ucred *ucr
+ free(syslog_priority);
+ free(syslog_facility);
+ free(syslog_identifier);
++ free(syslog_pid);
+ }
+
+ static bool valid_user_field(const char *p, size_t l) {
diff --git a/0519-logs-show-fix-off-by-one-error.patch b/0519-logs-show-fix-off-by-one-error.patch
new file mode 100644
index 0000000..8a6b3ec
--- /dev/null
+++ b/0519-logs-show-fix-off-by-one-error.patch
@@ -0,0 +1,27 @@
+From da0cf4105dea7b5701fdbcce68421a2251f1abb6 Mon Sep 17 00:00:00 2001
+From: Shawn Landen <shawnlandden at gmail.com>
+Date: Fri, 3 Aug 2012 02:28:28 +0000
+Subject: [PATCH] logs-show: fix off-by-one error
+
+Ellipsize lines that are one character too long.
+(cherry picked from commit 193556b69e982fd37f88209c26a5783245cf2437)
+
+Conflicts:
+ src/shared/logs-show.c
+---
+ src/shared/logs-show.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
+index 2219c80..9c6dcbf 100644
+--- a/src/shared/logs-show.c
++++ b/src/shared/logs-show.c
+@@ -230,7 +230,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
+ else if (contains_unprintable(message, message_len)) {
+ char bytes[FORMAT_BYTES_MAX];
+ printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
+- } else if (message_len + n < n_columns)
++ } else if (message_len + n + 1 < n_columns)
+ printf(": %.*s\n", (int) message_len, message);
+ else if (n < n_columns && n_columns - n - 2 >= 3) {
+ char *e;
diff --git a/0520-shutdown-allow-to-specify-broadcast-message-when-can.patch b/0520-shutdown-allow-to-specify-broadcast-message-when-can.patch
new file mode 100644
index 0000000..d091678
--- /dev/null
+++ b/0520-shutdown-allow-to-specify-broadcast-message-when-can.patch
@@ -0,0 +1,107 @@
+From 3cf7dd4d56b49993f5bfdd17d1bab18a92080e51 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Mon, 30 Jul 2012 17:25:39 +0200
+Subject: [PATCH] shutdown: allow to specify broadcast message when cancelling
+ shutdown
+
+makes shutdown behaviour more compatible
+(cherry picked from commit dfcc5c33f42554a5293e68e7093da2403e363997)
+---
+ src/shutdownd/shutdownd.c | 4 ++++
+ src/systemctl/systemctl.c | 39 ++++++++++++++++++++++++++++-----------
+ 2 files changed, 32 insertions(+), 11 deletions(-)
+
+diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c
+index 0e4b21e..f3aaaa6 100644
+--- a/src/shutdownd/shutdownd.c
++++ b/src/shutdownd/shutdownd.c
+@@ -136,6 +136,8 @@ static void warn_wall(usec_t n, struct sd_shutdown_command *c) {
+ prefix = "The system is going down for reboot at ";
+ else if (c->mode == SD_SHUTDOWN_KEXEC)
+ prefix = "The system is going down for kexec reboot at ";
++ else if (c->mode == SD_SHUTDOWN_NONE)
++ prefix = "The system shutdown has been cancelled at ";
+ else
+ assert_not_reached("Unknown mode!");
+
+@@ -356,6 +358,8 @@ int main(int argc, char *argv[]) {
+
+ if (!scheduled(&b.command)) {
+ log_info("Shutdown canceled.");
++ if (b.command.warn_wall)
++ warn_wall(0, &b.command);
+ break;
+ }
+
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 16e0e30..e7eb9e7 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -248,12 +248,13 @@ static int translate_bus_error_to_exit_status(int r, const DBusError *error) {
+
+ static void warn_wall(enum action a) {
+ static const char *table[_ACTION_MAX] = {
+- [ACTION_HALT] = "The system is going down for system halt NOW!",
+- [ACTION_REBOOT] = "The system is going down for reboot NOW!",
+- [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
+- [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
+- [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
+- [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!"
++ [ACTION_HALT] = "The system is going down for system halt NOW!",
++ [ACTION_REBOOT] = "The system is going down for reboot NOW!",
++ [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
++ [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
++ [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
++ [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
++ [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
+ };
+
+ if (arg_no_wall)
+@@ -5044,7 +5045,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
+ }
+ }
+
+- if (argc > optind) {
++ if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
+ r = parse_time_spec(argv[optind], &arg_when);
+ if (r < 0) {
+ log_error("Failed to parse time specification: %s", argv[optind]);
+@@ -5053,8 +5054,11 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
+ } else
+ arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
+
+- /* We skip the time argument */
+- if (argc > optind + 1)
++ if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
++ /* No time argument for shutdown cancel */
++ arg_wall = argv + optind;
++ else if (argc > optind + 1)
++ /* We skip the time argument */
+ arg_wall = argv + optind + 1;
+
+ optind = argc;
+@@ -5833,9 +5837,22 @@ int main(int argc, char*argv[]) {
+ r = reload_with_fallback(bus);
+ break;
+
+- case ACTION_CANCEL_SHUTDOWN:
+- r = send_shutdownd(0, 0, false, false, NULL);
++ case ACTION_CANCEL_SHUTDOWN: {
++ char *m = NULL;
++
++ if (arg_wall) {
++ m = strv_join(arg_wall, " ");
++ if (!m) {
++ retval = EXIT_FAILURE;
++ goto finish;
++ }
++ }
++ r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
++ if (r < 0)
++ log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
++ free(m);
+ break;
++ }
+
+ case ACTION_INVALID:
+ case ACTION_RUNLEVEL:
diff --git a/0521-sysctl-apply-configuration-at-once.patch b/0521-sysctl-apply-configuration-at-once.patch
new file mode 100644
index 0000000..bbed997
--- /dev/null
+++ b/0521-sysctl-apply-configuration-at-once.patch
@@ -0,0 +1,190 @@
+From fab617fde47a793bf711efecdb3888c168485618 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Fri, 3 Aug 2012 16:20:31 +0200
+Subject: [PATCH] sysctl: apply configuration at once
+
+https://bugzilla.redhat.com/show_bug.cgi?id=767795
+
+[ Simplified by iterating the config files in the backwards order -
+ no need for hashmap_update(). Other minor cleanups. -- michich ]
+(cherry picked from commit 86fc77c47f2d22cd01d0871866869cb194af0884)
+---
+ src/sysctl/sysctl.c | 92 +++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 76 insertions(+), 16 deletions(-)
+
+diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
+index 19709cf..04773a3 100644
+--- a/src/sysctl/sysctl.c
++++ b/src/sysctl/sysctl.c
+@@ -31,12 +31,14 @@
+ #include "strv.h"
+ #include "util.h"
+ #include "strv.h"
++#include "hashmap.h"
+ #include "path-util.h"
+ #include "conf-files.h"
+
+ #define PROC_SYS_PREFIX "/proc/sys/"
+
+-static char **arg_prefixes = NULL;
++static char **arg_prefixes;
++static Hashmap *sysctl_options;
+
+ static int apply_sysctl(const char *property, const char *value) {
+ char *p, *n;
+@@ -89,13 +91,29 @@ static int apply_sysctl(const char *property, const char *value) {
+ return r;
+ }
+
+-static int apply_file(const char *path, bool ignore_enoent) {
++static int apply_all(void) {
++ int r = 0;
++ char *property, *value;
++ Iterator i;
++
++ HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) {
++ int k;
++
++ k = apply_sysctl(property, value);
++ if (k < 0 && r == 0)
++ r = k;
++ }
++ return r;
++}
++
++static int parse_file(const char *path, bool ignore_enoent) {
+ FILE *f;
+ int r = 0;
+
+ assert(path);
+
+- if (!(f = fopen(path, "re"))) {
++ f = fopen(path, "re");
++ if (!f) {
+ if (ignore_enoent && errno == ENOENT)
+ return 0;
+
+@@ -103,10 +121,9 @@ static int apply_file(const char *path, bool ignore_enoent) {
+ return -errno;
+ }
+
+- log_debug("apply: %s\n", path);
++ log_debug("parse: %s\n", path);
+ while (!feof(f)) {
+- char l[LINE_MAX], *p, *value;
+- int k;
++ char l[LINE_MAX], *p, *value, *new_value, *property;
+
+ if (!fgets(l, sizeof(l), f)) {
+ if (feof(f))
+@@ -125,7 +142,8 @@ static int apply_file(const char *path, bool ignore_enoent) {
+ if (strchr(COMMENTS, *p))
+ continue;
+
+- if (!(value = strchr(p, '='))) {
++ value = strchr(p, '=');
++ if (!value) {
+ log_error("Line is not an assignment in file '%s': %s", path, value);
+
+ if (r == 0)
+@@ -136,8 +154,31 @@ static int apply_file(const char *path, bool ignore_enoent) {
+ *value = 0;
+ value++;
+
+- if ((k = apply_sysctl(strstrip(p), strstrip(value))) < 0 && r == 0)
+- r = k;
++ property = strdup(strstrip(p));
++ if (!property) {
++ r = -ENOMEM;
++ goto finish;
++ }
++
++ new_value = strdup(strstrip(value));
++ if (!new_value) {
++ free(property);
++ r = -ENOMEM;
++ goto finish;
++ }
++
++ r = hashmap_put(sysctl_options, property, new_value);
++ if (r < 0) {
++ if (r == -EEXIST)
++ log_debug("Skipping previously assigned sysctl variable %s", property);
++ else
++ log_error("Failed to add sysctl variable %s to hashmap: %s", property, strerror(-r));
++
++ free(property);
++ free(new_value);
++ if (r != -EEXIST)
++ goto finish;
++ }
+ }
+
+ finish:
+@@ -216,6 +257,8 @@ static int parse_argv(int argc, char *argv[]) {
+
+ int main(int argc, char *argv[]) {
+ int r = 0;
++ char *property, *value;
++ Iterator it;
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+@@ -227,13 +270,19 @@ int main(int argc, char *argv[]) {
+
+ umask(0022);
+
++ sysctl_options = hashmap_new(string_hash_func, string_compare_func);
++ if (!sysctl_options) {
++ r = -ENOMEM;
++ goto finish;
++ }
++
+ if (argc > optind) {
+ int i;
+
+ for (i = optind; i < argc; i++) {
+ int k;
+
+- k = apply_file(argv[i], false);
++ k = parse_file(argv[i], false);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+@@ -255,19 +304,30 @@ int main(int argc, char *argv[]) {
+ goto finish;
+ }
+
+- STRV_FOREACH(f, files) {
+- k = apply_file(*f, true);
++ /* We parse the files in decreasing order of precedence.
++ * parse_file() will skip keys that were already assigned. */
++
++ r = parse_file("/etc/sysctl.conf", true);
++
++ f = files + strv_length(files) - 1;
++ STRV_FOREACH_BACKWARDS(f, files) {
++ k = parse_file(*f, true);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+
+- k = apply_file("/etc/sysctl.conf", true);
+- if (k < 0 && r == 0)
+- r = k;
+-
+ strv_free(files);
+ }
++
++ r = apply_all();
+ finish:
++ HASHMAP_FOREACH_KEY(value, property, sysctl_options, it) {
++ hashmap_remove(sysctl_options, property);
++ free(property);
++ free(value);
++ }
++ hashmap_free(sysctl_options);
++
+ strv_free(arg_prefixes);
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/0522-systemd-introduced-new-timeout-types.patch b/0522-systemd-introduced-new-timeout-types.patch
new file mode 100644
index 0000000..1365d1e
--- /dev/null
+++ b/0522-systemd-introduced-new-timeout-types.patch
@@ -0,0 +1,247 @@
+From 6dcded71e67f2d1afbca520be7cce2579ba71fca Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta at redhat.com>
+Date: Tue, 7 Aug 2012 14:41:48 +0200
+Subject: [PATCH] systemd: introduced new timeout types
+
+Makes possible to specify separate timeout for start and stop of
+the service.
+
+[ Improved the manpage. Coding style fix. -- michich ]
+(cherry picked from commit d568a3350ee8a45877eef87cd026a954124e2cf8)
+
+Conflicts:
+ man/systemd.service.xml
+---
+ man/systemd.service.xml | 43 ++++++++++++++++++++++++++---------
+ src/core/dbus-service.c | 4 +++-
+ src/core/load-fragment-gperf.gperf.m4 | 4 +++-
+ src/core/load-fragment.c | 12 +++++++---
+ src/core/service.c | 35 ++++++++++++++++------------
+ src/core/service.h | 5 ++--
+ 6 files changed, 71 insertions(+), 32 deletions(-)
+
+diff --git a/man/systemd.service.xml b/man/systemd.service.xml
+index c615db1..3c1e011 100644
+--- a/man/systemd.service.xml
++++ b/man/systemd.service.xml
+@@ -441,27 +441,48 @@
+ </varlistentry>
+
+ <varlistentry>
+- <term><varname>TimeoutSec=</varname></term>
++ <term><varname>TimeoutStartSec=</varname></term>
+ <listitem><para>Configures the time to
+- wait for start-up and stop. If a
++ wait for start-up. If a
+ daemon service does not signal
+ start-up completion within the
+- configured time the service will be
++ configured time, the service will be
+ considered failed and be shut down
+- again. If a service is asked to stop
+- but does not terminate in the
+- specified time it will be terminated
++ again.
++ Takes a unit-less value in seconds, or a
++ time span value such as "5min
++ 20s". Pass 0 to disable the timeout
++ logic. Defaults to 90s, except when
++ <varname>Type=oneshot</varname> is
++ used in which case the timeout
++ is disabled by default.
++ </para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><varname>TimeoutStopSec=</varname></term>
++ <listitem><para>Configures the time to
++ wait for stop. If a service is asked
++ to stop but does not terminate in the
++ specified time, it will be terminated
+ forcibly via SIGTERM, and after
+ another delay of this time with
+- SIGKILL. (See
++ SIGKILL (See
+ <varname>KillMode=</varname>
+ below.) Takes a unit-less value in seconds, or a
+ time span value such as "5min
+ 20s". Pass 0 to disable the timeout
+- logic. Defaults to
+- 90s, except when <varname>Type=oneshot</varname> is
+- used in which case the timeout
+- is disabled by default.</para></listitem>
++ logic. Defaults to 90s.
++ </para></listitem>
++ </varlistentry>
++
++ <varlistentry>
++ <term><varname>TimeoutSec=</varname></term>
++ <listitem><para>A shorthand for configuring
++ both <varname>TimeoutStartSec=</varname>
++ and <varname>TimeoutStopSec=</varname>
++ to the specified value.
++ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
+index d840415..42c8a34 100644
+--- a/src/core/dbus-service.c
++++ b/src/core/dbus-service.c
+@@ -124,7 +124,9 @@ static const BusProperty bus_service_properties[] = {
+ { "PIDFile", bus_property_append_string, "s", offsetof(Service, pid_file), true },
+ { "NotifyAccess", bus_service_append_notify_access, "s", offsetof(Service, notify_access) },
+ { "RestartUSec", bus_property_append_usec, "t", offsetof(Service, restart_usec) },
+- { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Service, timeout_usec) },
++ { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) },
++ { "TimeoutStartUSec", bus_property_append_usec, "t", offsetof(Service, timeout_start_usec) },
++ { "TimeoutStopUSec", bus_property_append_usec, "t", offsetof(Service, timeout_stop_usec) },
+ { "WatchdogUSec", bus_property_append_usec, "t", offsetof(Service, watchdog_usec) },
+ { "WatchdogTimestamp", bus_property_append_usec, "t", offsetof(Service, watchdog_timestamp.realtime) },
+ { "WatchdogTimestampMonotonic",bus_property_append_usec, "t", offsetof(Service, watchdog_timestamp.monotonic) },
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index 1489342..c878476 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -141,7 +141,9 @@ Service.ExecReload, config_parse_exec, SERVICE_EXE
+ Service.ExecStop, config_parse_exec, SERVICE_EXEC_STOP, offsetof(Service, exec_command)
+ Service.ExecStopPost, config_parse_exec, SERVICE_EXEC_STOP_POST, offsetof(Service, exec_command)
+ Service.RestartSec, config_parse_usec, 0, offsetof(Service, restart_usec)
+-Service.TimeoutSec, config_parse_service_timeout, 0, offsetof(Service, timeout_usec)
++Service.TimeoutSec, config_parse_service_timeout, 0, offsetof(Service, timeout_start_usec)
++Service.TimeoutStartSec, config_parse_service_timeout, 0, offsetof(Service, timeout_start_usec)
++Service.TimeoutStopSec, config_parse_service_timeout, 0, offsetof(Service, timeout_stop_usec)
+ Service.WatchdogSec, config_parse_usec, 0, offsetof(Service, watchdog_usec)
+ Service.StartLimitInterval, config_parse_usec, 0, offsetof(Service, start_limit.interval)
+ Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Service, start_limit.burst)
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index 2003e1d..099c9c2 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -1418,10 +1418,16 @@ int config_parse_service_timeout(
+
+ r = config_parse_usec(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+
+- if (!r)
+- s->timeout_defined = true;
++ if (r)
++ return r;
+
+- return r;
++ if (streq(lvalue, "TimeoutSec")) {
++ s->start_timeout_defined = true;
++ s->timeout_stop_usec = s->timeout_start_usec;
++ } else if (streq(lvalue, "TimeoutStartSec"))
++ s->start_timeout_defined = true;
++
++ return 0;
+ }
+
+ int config_parse_unit_env_file(
+diff --git a/src/core/service.c b/src/core/service.c
+index 2e38d13..d300e34 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -135,7 +135,8 @@ static void service_init(Unit *u) {
+ assert(u);
+ assert(u->load_state == UNIT_STUB);
+
+- s->timeout_usec = DEFAULT_TIMEOUT_USEC;
++ s->timeout_start_usec = DEFAULT_TIMEOUT_USEC;
++ s->timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
+ s->restart_usec = DEFAULT_RESTART_USEC;
+ s->type = _SERVICE_TYPE_INVALID;
+
+@@ -914,9 +915,13 @@ static int service_load_sysv_path(Service *s, const char *path) {
+ UNIT(s)->default_dependencies = false;
+
+ /* Don't timeout special services during boot (like fsck) */
+- s->timeout_usec = 0;
+- } else
+- s->timeout_usec = DEFAULT_SYSV_TIMEOUT_USEC;
++ s->timeout_start_usec = 0;
++ s->timeout_stop_usec = 0;
++ } else {
++ s->timeout_start_usec = DEFAULT_SYSV_TIMEOUT_USEC;
++ s->timeout_stop_usec = DEFAULT_SYSV_TIMEOUT_USEC;
++ }
++
+
+ /* Special setting for all SysV services */
+ s->type = SERVICE_FORKING;
+@@ -1245,9 +1250,9 @@ static int service_load(Unit *u) {
+ if (s->type == _SERVICE_TYPE_INVALID)
+ s->type = s->bus_name ? SERVICE_DBUS : SERVICE_SIMPLE;
+
+- /* Oneshot services have disabled timeout by default */
+- if (s->type == SERVICE_ONESHOT && !s->timeout_defined)
+- s->timeout_usec = 0;
++ /* Oneshot services have disabled start timeout by default */
++ if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
++ s->timeout_start_usec = 0;
+
+ service_fix_output(s);
+
+@@ -1604,11 +1609,10 @@ static int service_coldplug(Unit *u) {
+ s->deserialized_state == SERVICE_FINAL_SIGTERM ||
+ s->deserialized_state == SERVICE_FINAL_SIGKILL ||
+ s->deserialized_state == SERVICE_AUTO_RESTART) {
+-
+- if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_usec > 0) {
++ if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) {
+ usec_t k;
+
+- k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_usec;
++ k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_start_usec;
+
+ if ((r = unit_watch_timer(UNIT(s), k, &s->timer_watch)) < 0)
+ return r;
+@@ -1754,8 +1758,9 @@ static int service_spawn(
+ }
+ }
+
+- if (timeout && s->timeout_usec) {
+- if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
++ if (timeout && s->timeout_start_usec) {
++ r = unit_watch_timer(UNIT(s), s->timeout_start_usec, &s->timer_watch);
++ if (r < 0)
+ goto fail;
+ } else
+ unit_unwatch_timer(UNIT(s), &s->timer_watch);
+@@ -2010,9 +2015,11 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
+ }
+
+ if (wait_for_exit) {
+- if (s->timeout_usec > 0)
+- if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
++ if (s->timeout_stop_usec > 0) {
++ r = unit_watch_timer(UNIT(s), s->timeout_stop_usec, &s->timer_watch);
++ if (r < 0)
+ goto fail;
++ }
+
+ service_set_state(s, state);
+ } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL)
+diff --git a/src/core/service.h b/src/core/service.h
+index 48f4dbb..0531fec 100644
+--- a/src/core/service.h
++++ b/src/core/service.h
+@@ -120,7 +120,8 @@ struct Service {
+ char *pid_file;
+
+ usec_t restart_usec;
+- usec_t timeout_usec;
++ usec_t timeout_start_usec;
++ usec_t timeout_stop_usec;
+
+ dual_timestamp watchdog_timestamp;
+ usec_t watchdog_usec;
+@@ -164,7 +165,7 @@ struct Service {
+ bool bus_name_good:1;
+ bool forbid_restart:1;
+ bool got_socket_fd:1;
+- bool timeout_defined:1;
++ bool start_timeout_defined:1;
+ #ifdef HAVE_SYSV_COMPAT
+ bool sysv_has_lsb:1;
+ bool sysv_enabled:1;
diff --git a/0523-fix-a-couple-of-issues-found-with-llvm-analyze.patch b/0523-fix-a-couple-of-issues-found-with-llvm-analyze.patch
new file mode 100644
index 0000000..fd6a42a
--- /dev/null
+++ b/0523-fix-a-couple-of-issues-found-with-llvm-analyze.patch
@@ -0,0 +1,76 @@
+From 0cd754e00ecfb06b42d549a6d337240784181ccf Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 8 Aug 2012 23:54:21 +0200
+Subject: [PATCH] fix a couple of issues found with llvm-analyze (cherry
+ picked from commit
+ 64825d3c589cd8742887f30acde8c57eceac2001)
+
+Conflicts:
+ src/cryptsetup/cryptsetup-generator.c
+ src/libudev/libudev-list.c
+ src/readahead/readahead-analyze.c
+---
+ src/core/namespace.c | 2 ++
+ src/journal/journal-file.c | 8 +++++---
+ src/shared/utf8.c | 2 +-
+ 3 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/namespace.c b/src/core/namespace.c
+index d27ffb1..0148f5f 100644
+--- a/src/core/namespace.c
++++ b/src/core/namespace.c
+@@ -312,6 +312,8 @@ int setup_namespace(
+ goto undo_mounts;
+ }
+
++ free(paths);
++
+ t = old_root_dir + sizeof(root_dir) - 1;
+ if (umount2(t, MNT_DETACH) < 0)
+ /* At this point it's too late to turn anything back,
+diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
+index 8390ea2..ac0d547 100644
+--- a/src/journal/journal-file.c
++++ b/src/journal/journal-file.c
+@@ -766,7 +766,7 @@ static int journal_file_append_data(
+ }
+ #endif
+
+- if (!compressed)
++ if (!compressed && size > 0)
+ memcpy(o->data.payload, data, size);
+
+ r = journal_file_link_data(f, o, p, hash);
+@@ -1035,7 +1035,8 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
+ ts->monotonic < le64toh(f->header->tail_entry_monotonic))
+ return -EINVAL;
+
+- items = alloca(sizeof(EntryItem) * n_iovec);
++ /* alloca() can't take 0, hence let's allocate at least one */
++ items = alloca(sizeof(EntryItem) * MAX(1, n_iovec));
+
+ for (i = 0; i < n_iovec; i++) {
+ uint64_t p;
+@@ -2105,7 +2106,8 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m
+ n_list ++;
+ }
+
+- qsort(list, n_list, sizeof(struct vacuum_info), vacuum_compare);
++ if (n_list > 0)
++ qsort(list, n_list, sizeof(struct vacuum_info), vacuum_compare);
+
+ for(i = 0; i < n_list; i++) {
+ struct statvfs ss;
+diff --git a/src/shared/utf8.c b/src/shared/utf8.c
+index 11619dc..562c570 100644
+--- a/src/shared/utf8.c
++++ b/src/shared/utf8.c
+@@ -204,7 +204,7 @@ char *ascii_filter(const char *str) {
+ if (!r)
+ return NULL;
+
+- for (s = r, d = r; *s; s++)
++ for (s = str, d = r; *s; s++)
+ if ((unsigned char) *s < 128)
+ *(d++) = *s;
+
diff --git a/0524-shared-utf8-mark-char-as-const.patch b/0524-shared-utf8-mark-char-as-const.patch
new file mode 100644
index 0000000..3d5be23
--- /dev/null
+++ b/0524-shared-utf8-mark-char-as-const.patch
@@ -0,0 +1,29 @@
+From 241b40331d1b3c4d3e30af2d1dd4fe718fdea5f3 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Fri, 10 Aug 2012 11:02:04 -0400
+Subject: [PATCH] shared/utf8: mark char* as const
+
+Avoids compiler warning:
+
+ src/shared/utf8.c: In function 'ascii_filter':
+ src/shared/utf8.c:278:16: warning: assignment discards 'const' qualifier
+ from pointer target type [enabled by default]
+(cherry picked from commit fd5b4ca11ea2b8a82343bc0db6a2f422beb305f1)
+---
+ src/shared/utf8.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/shared/utf8.c b/src/shared/utf8.c
+index 562c570..0a6a17f 100644
+--- a/src/shared/utf8.c
++++ b/src/shared/utf8.c
+@@ -194,7 +194,8 @@ char *ascii_is_valid(const char *str) {
+ }
+
+ char *ascii_filter(const char *str) {
+- char *r, *s, *d;
++ const char *s;
++ char *r, *d;
+ size_t l;
+
+ assert(str);
diff --git a/0525-shared-util-refactor-fstab_node_to_udev_node.patch b/0525-shared-util-refactor-fstab_node_to_udev_node.patch
new file mode 100644
index 0000000..d919ec6
--- /dev/null
+++ b/0525-shared-util-refactor-fstab_node_to_udev_node.patch
@@ -0,0 +1,88 @@
+From 247f00d1d7d2972e29607eb3ee70e52b671f3fde Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Sat, 11 Aug 2012 13:31:50 -0400
+Subject: [PATCH] shared/util: refactor fstab_node_to_udev_node
+
+Since this is purely duplicated logic, separate it out into a small
+static function.
+(cherry picked from commit 383182b5c435dca06a3f4ba32c6d1be2d1e35881)
+---
+ src/shared/util.c | 52 +++++++++++++++++++---------------------------------
+ 1 file changed, 19 insertions(+), 33 deletions(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 9dc64a0..d89833f 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -4011,52 +4011,38 @@ void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
+ }
+ }
+
+-char *fstab_node_to_udev_node(const char *p) {
++static char *tag_to_udev_node(const char *tagvalue, const char *by) {
+ char *dn, *t, *u;
+ int r;
+
+ /* FIXME: to follow udev's logic 100% we need to leave valid
+ * UTF8 chars unescaped */
+
+- if (startswith(p, "LABEL=")) {
+-
+- if (!(u = unquote(p+6, "\"\'")))
+- return NULL;
+-
+- t = xescape(u, "/ ");
+- free(u);
+-
+- if (!t)
+- return NULL;
+-
+- r = asprintf(&dn, "/dev/disk/by-label/%s", t);
+- free(t);
+-
+- if (r < 0)
+- return NULL;
+-
+- return dn;
+- }
++ u = unquote(tagvalue, "\"\'");
++ if (u == NULL)
++ return NULL;
+
+- if (startswith(p, "UUID=")) {
++ t = xescape(u, "/ ");
++ free(u);
+
+- if (!(u = unquote(p+5, "\"\'")))
+- return NULL;
++ if (t == NULL)
++ return NULL;
+
+- t = xescape(u, "/ ");
+- free(u);
++ r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
++ free(t);
+
+- if (!t)
+- return NULL;
++ if (r < 0)
++ return NULL;
+
+- r = asprintf(&dn, "/dev/disk/by-uuid/%s", t);
+- free(t);
++ return dn;
++}
+
+- if (r < 0)
+- return NULL;
++char *fstab_node_to_udev_node(const char *p) {
++ if (startswith(p, "LABEL="))
++ return tag_to_udev_node(p+6, "label");
+
+- return dn;
+- }
++ if (startswith(p, "UUID="))
++ return tag_to_udev_node(p+5, "uuid");
+
+ return strdup(p);
+ }
diff --git a/0526-shared-util-add-fstab-support-for-partuuid-partlabel.patch b/0526-shared-util-add-fstab-support-for-partuuid-partlabel.patch
new file mode 100644
index 0000000..5baa9ff
--- /dev/null
+++ b/0526-shared-util-add-fstab-support-for-partuuid-partlabel.patch
@@ -0,0 +1,29 @@
+From e59808f894df3054f3a012ac7257fd09261ada2f Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Sat, 11 Aug 2012 13:32:29 -0400
+Subject: [PATCH] shared/util: add fstab support for partuuid/partlabel
+
+udev has supported this since 172, so it should be a safe (and welcome)
+addition for users of GPT partitioned disks.
+(cherry picked from commit 84cc2abf3472b6dddd54b046b24f559ec8807ee4)
+---
+ src/shared/util.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index d89833f..2bdf4a5 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -4044,6 +4044,12 @@ char *fstab_node_to_udev_node(const char *p) {
+ if (startswith(p, "UUID="))
+ return tag_to_udev_node(p+5, "uuid");
+
++ if (startswith(p, "PARTUUID="))
++ return tag_to_udev_node(p+9, "partuuid");
++
++ if (startswith(p, "PARTLABEL="))
++ return tag_to_udev_node(p+10, "partlabel");
++
+ return strdup(p);
+ }
+
diff --git a/0527-login-check-return-of-parse_pid-and-parse_uid.patch b/0527-login-check-return-of-parse_pid-and-parse_uid.patch
new file mode 100644
index 0000000..ebf97b6
--- /dev/null
+++ b/0527-login-check-return-of-parse_pid-and-parse_uid.patch
@@ -0,0 +1,37 @@
+From f6187c097f569269fcbfcf603888fa5af3e2af90 Mon Sep 17 00:00:00 2001
+From: Lukas Nykryn <lnykryn at redhat.com>
+Date: Mon, 20 Aug 2012 14:39:08 +0200
+Subject: [PATCH] login: check return of parse_pid and parse_uid (cherry
+ picked from commit
+ a34faf579d2be139b0b9e8cd0c73ad4d918ef736)
+
+---
+ src/login/logind-inhibit.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
+index 721b38d..6deecd3 100644
+--- a/src/login/logind-inhibit.c
++++ b/src/login/logind-inhibit.c
+@@ -219,11 +219,17 @@ int inhibitor_load(Inhibitor *i) {
+ if (mm >= 0)
+ i->mode = mm;
+
+- if (uid)
+- parse_uid(uid, &i->uid);
++ if (uid) {
++ r = parse_uid(uid, &i->uid);
++ if (r < 0)
++ goto finish;
++ }
+
+- if (pid)
+- parse_pid(pid, &i->pid);
++ if (pid) {
++ r = parse_pid(pid, &i->pid);
++ if (r < 0)
++ goto finish;
++ }
+
+ if (who) {
+ cc = cunescape(who);
diff --git a/0528-unit-don-t-allow-units-to-be-gc-ed-that-still-are-re.patch b/0528-unit-don-t-allow-units-to-be-gc-ed-that-still-are-re.patch
new file mode 100644
index 0000000..557895c
--- /dev/null
+++ b/0528-unit-don-t-allow-units-to-be-gc-ed-that-still-are-re.patch
@@ -0,0 +1,25 @@
+From 37e9419bf4f2f905a0aeeed2bf500c8b9be29da2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 10 Sep 2012 10:12:10 +0200
+Subject: [PATCH] unit: don't allow units to be gc'ed that still are
+ referenced via UnitRef (cherry picked from commit
+ 9d576438a1ee932bde1fb0f1be1aa5cae646fd4e)
+
+---
+ src/core/unit.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index b810f8f..5865405 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -256,6 +256,9 @@ bool unit_check_gc(Unit *u) {
+ if (unit_active_state(u) != UNIT_INACTIVE)
+ return true;
+
++ if (u->refs)
++ return true;
++
+ if (UNIT_VTABLE(u)->check_gc)
+ if (UNIT_VTABLE(u)->check_gc(u))
+ return true;
diff --git a/0529-unit-add-new-ConditionHost-condition-type.patch b/0529-unit-add-new-ConditionHost-condition-type.patch
new file mode 100644
index 0000000..75b4cf4
--- /dev/null
+++ b/0529-unit-add-new-ConditionHost-condition-type.patch
@@ -0,0 +1,342 @@
+From 567df5544e3fb6d4e79aaca99f93381df332798a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 22 Aug 2012 01:51:53 +0200
+Subject: [PATCH] unit: add new ConditionHost= condition type (cherry picked
+ from commit c0d6e764d107a81a6439c41edbe92790623ed7de)
+
+Conflicts:
+ TODO
+---
+ man/systemd.unit.xml | 112 +++++++++++++++++++++++-----------
+ src/core/condition.c | 31 ++++++++++
+ src/core/condition.h | 1 +
+ src/core/load-fragment-gperf.gperf.m4 | 1 +
+ src/core/load-fragment.c | 9 ++-
+ 5 files changed, 117 insertions(+), 37 deletions(-)
+
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 7542052..5f942b9 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -561,7 +561,7 @@
+ <term><varname>RequiresMountsFor=</varname></term>
+
+ <listitem><para>Takes a space
+- separated list of paths. Automatically
++ separated list of absolute paths. Automatically
+ adds dependencies of type
+ <varname>Requires=</varname> and
+ <varname>After=</varname> for all
+@@ -735,65 +735,86 @@
+ <term><varname>ConditionVirtualization=</varname></term>
+ <term><varname>ConditionSecurity=</varname></term>
+ <term><varname>ConditionCapability=</varname></term>
++ <term><varname>ConditionHost=</varname></term>
+ <term><varname>ConditionNull=</varname></term>
+
+ <listitem><para>Before starting a unit
+ verify that the specified condition is
+- true. With
++ true. If it is not true the starting
++ of the unit will be skipped, however
++ all ordering dependencies of it are
++ still respected. A failing condition
++ will not result in the unit being
++ moved into a failure state. The
++ condition is checked at the time the
++ queued start job is to be
++ executed.</para>
++
++ <para>With
+ <varname>ConditionPathExists=</varname>
+- a file existence condition can be
++ a file existence condition is
+ checked before a unit is started. If
+ the specified absolute path name does
+- not exist, startup of a unit will not
+- actually happen, however the unit is
+- still useful for ordering purposes in
+- this case. The condition is checked at
+- the time the queued start job is to be
+- executed. If the absolute path name
+- passed to
++ not exist the condition will
++ fail. If the absolute path name passed
++ to
+ <varname>ConditionPathExists=</varname>
+ is prefixed with an exclamation mark
+- (!), the test is negated, and the unit
++ ('!'), the test is negated, and the unit
+ is only started if the path does not
+- exist.
+- <varname>ConditionPathExistsGlob=</varname>
+- works in a similar way, but checks for
+- the existence of at least one file or
+- directory matching the specified
+- globbing
+- pattern. <varname>ConditionPathIsDirectory=</varname>
++ exist.</para>
++
++ <para><varname>ConditionPathExistsGlob=</varname>
++ is similar to
++ <varname>ConditionPathExists=</varname>,
++ but checks for the existence of at
++ least one file or directory matching
++ the specified globbing pattern.</para>
++
++ <para><varname>ConditionPathIsDirectory=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+ exists and is a
+- directory. <varname>ConditionPathIsSymbolicLink=</varname>
++ directory.</para>
++
++ <para><varname>ConditionPathIsSymbolicLink=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+ exists and is a symbolic
+- link. <varname>ConditionPathIsMountPoint=</varname>
++ link.</para>
++
++ <para><varname>ConditionPathIsMountPoint=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+ exists and is a mount
+- point. <varname>ConditionPathIsReadWrite=</varname>
++ point.</para>
++
++ <para><varname>ConditionPathIsReadWrite=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether the underlying
+- file system is read and writable
++ file system is readable and writable
+ (i.e. not mounted
+- read-only). <varname>ConditionFileIsExecutable=</varname>
++ read-only).</para>
++
++ <para><varname>ConditionFileIsExecutable=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+ exists, is a regular file and marked
+- executable.
+- <varname>ConditionDirectoryNotEmpty=</varname>
++ executable.</para>
++
++ <para><varname>ConditionDirectoryNotEmpty=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+ exists and is a non-empty
+- directory. Similarly
++ directory.</para>
++
++ <para>Similarly,
+ <varname>ConditionKernelCommandLine=</varname>
+ may be used to check whether a
+ specific kernel command line option is
+@@ -801,14 +822,16 @@
+ exclamation mark unset). The argument
+ must either be a single word, or an
+ assignment (i.e. two words, separated
+- by the equality sign). In the former
++ '='). In the former
+ case the kernel command line is
+ searched for the word appearing as is,
+ or as left hand side of an
+ assignment. In the latter case the
+ exact assignment is looked for with
+ right and left hand side
+- matching. <varname>ConditionVirtualization=</varname>
++ matching.</para>
++
++ <para><varname>ConditionVirtualization=</varname>
+ may be used to check whether the
+ system is executed in a virtualized
+ environment and optionally test
+@@ -818,7 +841,7 @@
+ any virtualized environment, or one of
+ <varname>vm</varname> and
+ <varname>container</varname> to test
+- against a specific type of
++ against a generic type of
+ virtualization solution, or one of
+ <varname>qemu</varname>,
+ <varname>kvm</varname>,
+@@ -837,15 +860,18 @@
+ virtualization technologies are nested
+ only the innermost is considered. The
+ test may be negated by prepending an
+- exclamation mark.
+- <varname>ConditionSecurity=</varname>
++ exclamation mark.</para>
++
++ <para><varname>ConditionSecurity=</varname>
+ may be used to check whether the given
+ security module is enabled on the
+ system. Currently the only recognized
+ value is <varname>selinux</varname>.
+ The test may be negated by prepending
+ an exclamation
+- mark. <varname>ConditionCapability=</varname>
++ mark.</para>
++
++ <para><varname>ConditionCapability=</varname>
+ may be used to check whether the given
+ capability exists in the capability
+ bounding set of the service manager
+@@ -856,14 +882,32 @@
+ for details). Pass a capability name
+ such as <literal>CAP_MKNOD</literal>,
+ possibly prefixed with an exclamation
+- mark to negate the check. Finally,
++ mark to negate the check.</para>
++
++ <para><varname>ConditionHost=</varname>
++ may be used to match against the
++ host name or machine ID of the
++ host. This either takes a host name
++ string (optionally with shell style
++ globs) which is tested against the
++ locally set host name as returned by
++ <citerefentry><refentrytitle>gethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
++ or a machine ID formatted as string
++ (see
++ <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
++ The test may be negated by prepending
++ an exclamation mark.</para>
++
++ <para>Finally,
+ <varname>ConditionNull=</varname> may
+ be used to add a constant condition
+ check value to the unit. It takes a
+ boolean argument. If set to
+ <varname>false</varname> the condition
+ will always fail, otherwise
+- succeed. If multiple conditions are
++ succeed.</para>
++
++ <para>If multiple conditions are
+ specified the unit will be executed if
+ all of them apply (i.e. a logical AND
+ is applied). Condition checks can be
+diff --git a/src/core/condition.c b/src/core/condition.c
+index ae82abd..b4ed2da 100644
+--- a/src/core/condition.c
++++ b/src/core/condition.c
+@@ -25,11 +25,13 @@
+ #include <unistd.h>
+ #include <sys/capability.h>
+ #include <sys/statvfs.h>
++#include <fnmatch.h>
+
+ #ifdef HAVE_SELINUX
+ #include <selinux/selinux.h>
+ #endif
+
++#include <systemd/sd-id128.h>
+ #include "util.h"
+ #include "condition.h"
+ #include "virt.h"
+@@ -194,6 +196,31 @@ static bool test_capability(const char *parameter) {
+ return !!(capabilities & (1ULL << value));
+ }
+
++static bool test_host(const char *parameter) {
++ sd_id128_t x, y;
++ char *h;
++ int r;
++ bool b;
++
++ if (sd_id128_from_string(parameter, &x) >= 0) {
++
++ r = sd_id128_get_machine(&y);
++ if (r < 0)
++ return false;
++
++ return sd_id128_equal(x, y);
++ }
++
++ h = gethostname_malloc();
++ if (!h)
++ return false;
++
++ b = fnmatch(parameter, h, FNM_CASEFOLD) == 0;
++ free(h);
++
++ return b;
++}
++
+ bool condition_test(Condition *c) {
+ assert(c);
+
+@@ -255,6 +282,9 @@ bool condition_test(Condition *c) {
+ case CONDITION_CAPABILITY:
+ return test_capability(c->parameter) == !c->negate;
+
++ case CONDITION_HOST:
++ return test_host(c->parameter) == !c->negate;
++
+ case CONDITION_NULL:
+ return !c->negate;
+
+@@ -323,6 +353,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
+ [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
+ [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
+ [CONDITION_SECURITY] = "ConditionSecurity",
++ [CONDITION_HOST] = "ConditionHost",
+ [CONDITION_NULL] = "ConditionNull"
+ };
+
+diff --git a/src/core/condition.h b/src/core/condition.h
+index 087010c..0162c22 100644
+--- a/src/core/condition.h
++++ b/src/core/condition.h
+@@ -39,6 +39,7 @@ typedef enum ConditionType {
+ CONDITION_VIRTUALIZATION,
+ CONDITION_SECURITY,
+ CONDITION_CAPABILITY,
++ CONDITION_HOST,
+ CONDITION_NULL,
+ _CONDITION_TYPE_MAX,
+ _CONDITION_TYPE_INVALID = -1
+diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
+index c878476..997bd92 100644
+--- a/src/core/load-fragment-gperf.gperf.m4
++++ b/src/core/load-fragment-gperf.gperf.m4
+@@ -131,6 +131,7 @@ Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_K
+ Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0
+ Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0
+ Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, 0
++Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_HOST, 0
+ Unit.ConditionNull, config_parse_unit_condition_null, 0, 0
+ m4_dnl
+ Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file)
+diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
+index 099c9c2..9fa749f 100644
+--- a/src/core/load-fragment.c
++++ b/src/core/load-fragment.c
+@@ -1558,13 +1558,16 @@ int config_parse_unit_condition_string(
+ assert(rvalue);
+ assert(data);
+
+- if ((trigger = rvalue[0] == '|'))
++ trigger = rvalue[0] == '|';
++ if (trigger)
+ rvalue++;
+
+- if ((negate = rvalue[0] == '!'))
++ negate = rvalue[0] == '!';
++ if (negate)
+ rvalue++;
+
+- if (!(c = condition_new(cond, rvalue, trigger, negate)))
++ c = condition_new(cond, rvalue, trigger, negate);
++ if (!c)
+ return -ENOMEM;
+
+ LIST_PREPEND(Condition, conditions, u->conditions, c);
diff --git a/0530-condition-add-ConditionFileNotEmpty.patch b/0530-condition-add-ConditionFileNotEmpty.patch
new file mode 100644
index 0000000..bb644be
--- /dev/null
+++ b/0530-condition-add-ConditionFileNotEmpty.patch
@@ -0,0 +1,101 @@
+From 8f4e96fb4823991334c03d13623af2af2ad4bde8 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 11 Sep 2012 01:29:46 +0200
+Subject: [PATCH] condition: add ConditionFileNotEmpty=
+
+https://bugs.freedesktop.org/show_bug.cgi?id=54448
+(cherry picked from commit 742a862bb803641b78a40f6b498486397a321294)
+---
+ man/systemd.unit.xml | 22 +++++++++++++++-------
+ src/core/condition.c | 10 ++++++++++
+ src/core/condition.h | 1 +
+ 3 files changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
+index 5f942b9..2ac0ef7 100644
+--- a/man/systemd.unit.xml
++++ b/man/systemd.unit.xml
+@@ -730,6 +730,7 @@
+ <term><varname>ConditionPathIsMountPoint=</varname></term>
+ <term><varname>ConditionPathIsReadWrite=</varname></term>
+ <term><varname>ConditionDirectoryNotEmpty=</varname></term>
++ <term><varname>ConditionFileNotEmpty=</varname></term>
+ <term><varname>ConditionFileIsExecutable=</varname></term>
+ <term><varname>ConditionKernelCommandLine=</varname></term>
+ <term><varname>ConditionVirtualization=</varname></term>
+@@ -800,21 +801,28 @@
+ (i.e. not mounted
+ read-only).</para>
+
+- <para><varname>ConditionFileIsExecutable=</varname>
++ <para><varname>ConditionDirectoryNotEmpty=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+- exists, is a regular file and marked
+- executable.</para>
++ exists and is a non-empty
++ directory.</para>
+
+- <para><varname>ConditionDirectoryNotEmpty=</varname>
++ <para><varname>ConditionFileNotEmpty=</varname>
+ is similar to
+ <varname>ConditionPathExists=</varname>
+ but verifies whether a certain path
+- exists and is a non-empty
+- directory.</para>
++ exists and refers to a regular file
++ with a non-zero size.</para>
++
++ <para><varname>ConditionFileIsExecutable=</varname>
++ is similar to
++ <varname>ConditionPathExists=</varname>
++ but verifies whether a certain path
++ exists, is a regular file and marked
++ executable.</para>
+
+- <para>Similarly,
++ <para>Similar,
+ <varname>ConditionKernelCommandLine=</varname>
+ may be used to check whether a
+ specific kernel command line option is
+diff --git a/src/core/condition.c b/src/core/condition.c
+index b4ed2da..ff6292c 100644
+--- a/src/core/condition.c
++++ b/src/core/condition.c
+@@ -261,6 +261,15 @@ bool condition_test(Condition *c) {
+ return !(k == -ENOENT || k > 0) == !c->negate;
+ }
+
++ case CONDITION_FILE_NOT_EMPTY: {
++ struct stat st;
++
++ if (stat(c->parameter, &st) < 0)
++ return c->negate;
++
++ return (S_ISREG(st.st_mode) && st.st_size > 0) == !c->negate;
++ }
++
+ case CONDITION_FILE_IS_EXECUTABLE: {
+ struct stat st;
+
+@@ -350,6 +359,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
+ [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
+ [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
+ [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
++ [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
+ [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
+ [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
+ [CONDITION_SECURITY] = "ConditionSecurity",
+diff --git a/src/core/condition.h b/src/core/condition.h
+index 0162c22..f4a5801 100644
+--- a/src/core/condition.h
++++ b/src/core/condition.h
+@@ -34,6 +34,7 @@ typedef enum ConditionType {
+ CONDITION_PATH_IS_MOUNT_POINT,
+ CONDITION_PATH_IS_READ_WRITE,
+ CONDITION_DIRECTORY_NOT_EMPTY,
++ CONDITION_FILE_NOT_EMPTY,
+ CONDITION_FILE_IS_EXECUTABLE,
+ CONDITION_KERNEL_COMMAND_LINE,
+ CONDITION_VIRTUALIZATION,
diff --git a/0531-unit-name-rework-unit_name_replace_instance-function.patch b/0531-unit-name-rework-unit_name_replace_instance-function.patch
new file mode 100644
index 0000000..9e173a4
--- /dev/null
+++ b/0531-unit-name-rework-unit_name_replace_instance-function.patch
@@ -0,0 +1,105 @@
+From 22bfd2637d4c82c87ce049848902fd1a3b442e0b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 12 Sep 2012 04:46:38 +0200
+Subject: [PATCH] unit-name: rework unit_name_replace_instance function()
+
+https://bugzilla.redhat.com/show_bug.cgi?id=855863
+(cherry picked from commit 8556879e0d14925ce897875c6c264368e2d048c2)
+
+Conflicts:
+ TODO
+---
+ src/shared/unit-name.c | 35 ++++++++++++++---------------------
+ src/test/test-unit-name.c | 24 ++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+), 21 deletions(-)
+
+diff --git a/src/shared/unit-name.c b/src/shared/unit-name.c
+index 28e3e76..90f5842 100644
+--- a/src/shared/unit-name.c
++++ b/src/shared/unit-name.c
+@@ -356,36 +356,29 @@ bool unit_name_is_instance(const char *n) {
+ char *unit_name_replace_instance(const char *f, const char *i) {
+ const char *p, *e;
+ char *r, *k;
+- size_t a;
++ size_t a, b;
+
+ assert(f);
+
+ p = strchr(f, '@');
+- assert_se(e = strrchr(f, '.'));
+-
+- a = p - f;
+-
+- if (p) {
+- size_t b;
+-
+- b = strlen(i);
+-
+- r = new(char, a + 1 + b + strlen(e) + 1);
+- if (!r)
+- return NULL;
++ if (!p)
++ return strdup(f);
+
+- k = mempcpy(r, f, a + 1);
+- k = mempcpy(k, i, b);
+- } else {
++ e = strrchr(f, '.');
++ if (!e)
++ assert_se(e = strchr(f, 0));
+
+- r = new(char, a + strlen(e) + 1);
+- if (!r)
+- return NULL;
++ a = p - f;
++ b = strlen(i);
+
+- k = mempcpy(r, f, a);
+- }
++ r = new(char, a + 1 + b + strlen(e) + 1);
++ if (!r)
++ return NULL;
+
++ k = mempcpy(r, f, a + 1);
++ k = mempcpy(k, i, b);
+ strcpy(k, e);
++
+ return r;
+ }
+
+diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
+index 392e358..cf43455 100644
+--- a/src/test/test-unit-name.c
++++ b/src/test/test-unit-name.c
+@@ -29,6 +29,30 @@
+ int main(int argc, char* argv[]) {
+ char *t, *k;
+
++ t = unit_name_replace_instance("foo at .service", "waldo");
++ puts(t);
++ free(t);
++
++ t = unit_name_replace_instance("foo at xyz.service", "waldo");
++ puts(t);
++ free(t);
++
++ t = unit_name_replace_instance("xyz", "waldo");
++ puts(t);
++ free(t);
++
++ t = unit_name_replace_instance("", "waldo");
++ puts(t);
++ free(t);
++
++ t = unit_name_replace_instance("", "");
++ puts(t);
++ free(t);
++
++ t = unit_name_replace_instance("foo.service", "waldo");
++ puts(t);
++ free(t);
++
+ t = unit_name_from_path("/waldo", ".mount");
+ puts(t);
+ k = unit_name_to_path(t);
diff --git a/0532-pam-Add-session-class-to-the-debug-log.patch b/0532-pam-Add-session-class-to-the-debug-log.patch
new file mode 100644
index 0000000..0bcfab0
--- /dev/null
+++ b/0532-pam-Add-session-class-to-the-debug-log.patch
@@ -0,0 +1,25 @@
+From 383f87c16e75ac12b27e25783d8b4d810b28c3c0 Mon Sep 17 00:00:00 2001
+From: Colin Guthrie <colin at mageia.org>
+Date: Mon, 3 Sep 2012 23:47:00 +0100
+Subject: [PATCH] pam: Add session class to the debug log. (cherry picked from
+ commit f904bdf2e9f6f858802489ab07ff070d4677bccb)
+
+---
+ src/login/pam-module.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/login/pam-module.c b/src/login/pam-module.c
+index 27d36f5..be20328 100644
+--- a/src/login/pam-module.c
++++ b/src/login/pam-module.c
+@@ -518,8 +518,8 @@ _public_ PAM_EXTERN int pam_sm_open_session(
+
+ if (debug)
+ pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: "
+- "uid=%u pid=%u service=%s type=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
+- uid, pid, service, type, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host);
++ "uid=%u pid=%u service=%s type=%s class=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
++ uid, pid, service, type, class, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host);
+
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
diff --git a/0533-tmpfiles-support-globbing-for-w-option.patch b/0533-tmpfiles-support-globbing-for-w-option.patch
new file mode 100644
index 0000000..42a0e4a
--- /dev/null
+++ b/0533-tmpfiles-support-globbing-for-w-option.patch
@@ -0,0 +1,188 @@
+From 952f5b33798082e5bc50059f62cfe5a774c04026 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Mon, 3 Sep 2012 17:13:18 -0400
+Subject: [PATCH] tmpfiles: support globbing for w option
+
+Break out the write logic into a separate function and simply use it as
+a callback to glob_item.
+
+This allows users to consolidate writes to sysfs with multiple similar
+pathnames, e.g.
+
+ w /sys/class/block/sd[a-z]/queue/read_ahead_kb - - - - 1024
+(cherry picked from commit d4e9eb91ea12e11bff7d8c6265b067a20ccf37b8)
+---
+ man/tmpfiles.d.xml | 2 +-
+ src/tmpfiles/tmpfiles.c | 135 +++++++++++++++++++++++++-----------------------
+ 2 files changed, 72 insertions(+), 65 deletions(-)
+
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index 3b69968..5dd196b 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -114,7 +114,7 @@ L /tmp/foobar - - - - /dev/null</programlisting>
+
+ <varlistentry>
+ <term><varname>w</varname></term>
+- <listitem><para>Write the argument parameter to a file, if it exists.</para></listitem>
++ <listitem><para>Write the argument parameter to a file, if it exists. Lines of this type accept shell-style globs in place of normal path names.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index a9a60c7..dfbd6ea 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -454,6 +454,75 @@ static int item_set_perms(Item *i, const char *path) {
+ return label_fix(path, false, false);
+ }
+
++static int write_one_file(Item *i, const char *path) {
++ int r, e, fd, flags;
++ struct stat st;
++ mode_t u;
++
++ flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
++ i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
++
++ u = umask(0);
++ label_context_set(path, S_IFREG);
++ fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
++ e = errno;
++ label_context_clear();
++ umask(u);
++ errno = e;
++
++ if (fd < 0) {
++ if (i->type == WRITE_FILE && errno == ENOENT)
++ return 0;
++
++ log_error("Failed to create file %s: %m", path);
++ return -errno;
++ }
++
++ if (i->argument) {
++ ssize_t n;
++ size_t l;
++ struct iovec iovec[2];
++ static const char new_line = '\n';
++
++ l = strlen(i->argument);
++
++ zero(iovec);
++ iovec[0].iov_base = i->argument;
++ iovec[0].iov_len = l;
++
++ iovec[1].iov_base = (void*) &new_line;
++ iovec[1].iov_len = 1;
++
++ n = writev(fd, iovec, 2);
++
++ /* It's OK if we don't write the trailing
++ * newline, hence we check for l, instead of
++ * l+1 here. Files in /sys often refuse
++ * writing of the trailing newline. */
++ if (n < 0 || (size_t) n < l) {
++ log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
++ close_nointr_nofail(fd);
++ return n < 0 ? n : -EIO;
++ }
++ }
++
++ if (stat(path, &st) < 0) {
++ log_error("stat(%s) failed: %m", path);
++ return -errno;
++ }
++
++ if (!S_ISREG(st.st_mode)) {
++ log_error("%s is not a file.", path);
++ return -EEXIST;
++ }
++
++ r = item_set_perms(i, path);
++ if (r < 0)
++ return r;
++
++ return 0;
++}
++
+ static int recursive_relabel_children(Item *i, const char *path) {
+ DIR *d;
+ int ret = 0;
+@@ -587,74 +656,12 @@ static int create_item(Item *i) {
+
+ case CREATE_FILE:
+ case TRUNCATE_FILE:
+- case WRITE_FILE: {
+- int fd, flags;
+-
+- flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
+- i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
+-
+- u = umask(0);
+- label_context_set(i->path, S_IFREG);
+- fd = open(i->path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
+- e = errno;
+- label_context_clear();
+- umask(u);
+- errno = e;
+-
+- if (fd < 0) {
+- if (i->type == WRITE_FILE && errno == ENOENT)
+- break;
+-
+- log_error("Failed to create file %s: %m", i->path);
+- return -errno;
+- }
+-
+- if (i->argument) {
+- ssize_t n;
+- size_t l;
+- struct iovec iovec[2];
+- static const char new_line = '\n';
+-
+- l = strlen(i->argument);
+-
+- zero(iovec);
+- iovec[0].iov_base = i->argument;
+- iovec[0].iov_len = l;
+-
+- iovec[1].iov_base = (void*) &new_line;
+- iovec[1].iov_len = 1;
+-
+- n = writev(fd, iovec, 2);
+-
+- /* It's OK if we don't write the trailing
+- * newline, hence we check for l, instead of
+- * l+1 here. Files in /sys often refuse
+- * writing of the trailing newline. */
+- if (n < 0 || (size_t) n < l) {
+- log_error("Failed to write file %s: %s", i->path, n < 0 ? strerror(-n) : "Short write");
+- close_nointr_nofail(fd);
+- return n < 0 ? n : -EIO;
+- }
+- }
+-
+- close_nointr_nofail(fd);
+-
+- if (stat(i->path, &st) < 0) {
+- log_error("stat(%s) failed: %m", i->path);
+- return -errno;
+- }
+-
+- if (!S_ISREG(st.st_mode)) {
+- log_error("%s is not a file.", i->path);
+- return -EEXIST;
+- }
+-
+- r = item_set_perms(i, i->path);
++ case WRITE_FILE:
++ r = glob_item(i, write_one_file);
+ if (r < 0)
+ return r;
+
+ break;
+- }
+
+ case TRUNCATE_DIRECTORY:
+ case CREATE_DIRECTORY:
diff --git a/0534-systemctl-direct-the-user-to-list-unit-files-from-th.patch b/0534-systemctl-direct-the-user-to-list-unit-files-from-th.patch
new file mode 100644
index 0000000..434d27c
--- /dev/null
+++ b/0534-systemctl-direct-the-user-to-list-unit-files-from-th.patch
@@ -0,0 +1,29 @@
+From 4d8296c7cb9607ed7103aabf73d4a48ca04d0f2a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 12 Sep 2012 08:56:57 +0200
+Subject: [PATCH] systemctl: direct the user to list-unit-files from the
+ list-units output (cherry picked from commit
+ bb3241614a1a3a3ef68329dadc56e8fec090ff64)
+
+---
+ src/systemctl/systemctl.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index e7eb9e7..340efbb 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -442,9 +442,11 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
+ "JOB = Pending job for the unit.\n");
+
+ if (arg_all)
+- printf("\n%u units listed.\n", n_shown);
++ printf("\n%u loaded units listed.\n"
++ "To show all installed unit files use 'systemctl list-unit-files'.\n", n_shown);
+ else
+- printf("\n%u units listed. Pass --all to see inactive units, too.\n", n_shown);
++ printf("\n%u loaded units listed. Pass --all to see loaded but inactive units, too.\n"
++ "To show all installed unit files use 'systemctl list-unit-files'.\n", n_shown);
+ }
+ }
+
diff --git a/0535-tmpfiles-plug-file-descriptor-leak.patch b/0535-tmpfiles-plug-file-descriptor-leak.patch
new file mode 100644
index 0000000..52a190d
--- /dev/null
+++ b/0535-tmpfiles-plug-file-descriptor-leak.patch
@@ -0,0 +1,24 @@
+From 1c8ef96fcfbcd108f5f024a159a5104fe5f84f39 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Wed, 12 Sep 2012 16:21:00 -0400
+Subject: [PATCH] tmpfiles: plug file descriptor leak.
+
+Introduced in d4e9eb91.
+(cherry picked from commit 3612fbc1e4ae57af0783cc82a56917bcd29a0431)
+---
+ src/tmpfiles/tmpfiles.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index dfbd6ea..0540572 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -506,6 +506,8 @@ static int write_one_file(Item *i, const char *path) {
+ }
+ }
+
++ close_nointr_nofail(fd);
++
+ if (stat(path, &st) < 0) {
+ log_error("stat(%s) failed: %m", path);
+ return -errno;
diff --git a/0536-update-utmp-Don-t-error-out-on-runlevel-updates-if-u.patch b/0536-update-utmp-Don-t-error-out-on-runlevel-updates-if-u.patch
new file mode 100644
index 0000000..cbe05a5
--- /dev/null
+++ b/0536-update-utmp-Don-t-error-out-on-runlevel-updates-if-u.patch
@@ -0,0 +1,30 @@
+From de3ae467f065df30b425e65294be8cac4ed3bcc0 Mon Sep 17 00:00:00 2001
+From: Colin Walters <walters at verbum.org>
+Date: Thu, 13 Sep 2012 10:51:30 -0400
+Subject: [PATCH] update-utmp: Don't error out on runlevel updates if utmp
+ doesn't exist
+
+Other parts of the code handle utmp not existing, so let's be
+consistent. At the moment my GNOME-OSTree builds don't have utmp.
+(cherry picked from commit 55f2dca329afd0dcdc4793ce3e945cb8af653937)
+---
+ src/update-utmp/update-utmp.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
+index 4b38a78..a71bfaa 100644
+--- a/src/update-utmp/update-utmp.c
++++ b/src/update-utmp/update-utmp.c
+@@ -343,8 +343,10 @@ static int on_runlevel(Context *c) {
+ #endif
+
+ if ((q = utmp_put_runlevel(runlevel, previous)) < 0) {
+- log_error("Failed to write utmp record: %s", strerror(-q));
+- r = q;
++ if (q != -ESRCH && q != -ENOENT) {
++ log_error("Failed to write utmp record: %s", strerror(-q));
++ r = q;
++ }
+ }
+
+ return r;
diff --git a/0537-install-append-.service-when-enable-disable.-is-call.patch b/0537-install-append-.service-when-enable-disable.-is-call.patch
new file mode 100644
index 0000000..63e3fb7
--- /dev/null
+++ b/0537-install-append-.service-when-enable-disable.-is-call.patch
@@ -0,0 +1,75 @@
+From f820ff1ccf87333a6668eaf252cd0eec631a35fb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= <vpavlin at redhat.com>
+Date: Thu, 13 Sep 2012 22:35:18 +0200
+Subject: [PATCH] install: append .service when enable/disable... is called
+
+https://bugzilla.redhat.com/show_bug.cgi?id=856975
+(cherry picked from commit 37370d0cbe7c79d3f5b44a9ddbfac87c59dc09dd)
+---
+ src/systemctl/systemctl.c | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index 340efbb..a3810de 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -4096,6 +4096,28 @@ finish:
+ return r;
+ }
+
++static int mangle_names(char **original_names, char ***mangled_names) {
++ char **names_it = NULL;
++ char **name = NULL;
++
++ (*mangled_names) = new(char*, strv_length(original_names)+1);
++ if(!(*mangled_names))
++ return log_oom();
++
++ names_it = *mangled_names;
++
++ STRV_FOREACH(name, original_names) {
++ char *n = unit_name_mangle(*name);
++ (*names_it) = n ? n : strdup(*name);
++ if(!(*names_it))
++ return log_oom();
++ names_it++;
++ }
++ *names_it = NULL;
++
++ return 0;
++}
++
+ static int enable_unit(DBusConnection *bus, char **args) {
+ const char *verb = args[0];
+ UnitFileChange *changes = NULL;
+@@ -4104,6 +4126,7 @@ static int enable_unit(DBusConnection *bus, char **args) {
+ DBusMessage *m = NULL, *reply = NULL;
+ int r;
+ DBusError error;
++ char **mangled_names = NULL;
+
+ r = enable_sysv_units(args);
+ if (r < 0)
+@@ -4190,7 +4213,11 @@ static int enable_unit(DBusConnection *bus, char **args) {
+
+ dbus_message_iter_init_append(m, &iter);
+
+- r = bus_append_strv_iter(&iter, args+1);
++ r = mangle_names(args+1, &mangled_names);
++ if(r < 0)
++ goto finish;
++
++ r = bus_append_strv_iter(&iter, mangled_names);
+ if (r < 0) {
+ log_error("Failed to append unit files.");
+ goto finish;
+@@ -4290,6 +4317,9 @@ finish:
+ unit_file_changes_free(changes, n_changes);
+
+ dbus_error_free(&error);
++
++ strv_free(mangled_names);
++
+ return r;
+ }
+
diff --git a/0538-systemctl-minor-coding-style-fixes.patch b/0538-systemctl-minor-coding-style-fixes.patch
new file mode 100644
index 0000000..7322f1f
--- /dev/null
+++ b/0538-systemctl-minor-coding-style-fixes.patch
@@ -0,0 +1,53 @@
+From cdd880c67b144852c05716dd226449c40a4f5d9e Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 13 Sep 2012 22:42:22 +0200
+Subject: [PATCH] systemctl: minor coding style fixes (cherry picked from
+ commit a33fdebb30cac102db7037a5bcdc85d6c49d4aad)
+
+---
+ src/systemctl/systemctl.c | 28 +++++++++++++++-------------
+ 1 file changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
+index a3810de..23977ac 100644
+--- a/src/systemctl/systemctl.c
++++ b/src/systemctl/systemctl.c
+@@ -4097,23 +4097,25 @@ finish:
+ }
+
+ static int mangle_names(char **original_names, char ***mangled_names) {
+- char **names_it = NULL;
+- char **name = NULL;
++ char **i, **l, **name;
+
+- (*mangled_names) = new(char*, strv_length(original_names)+1);
+- if(!(*mangled_names))
+- return log_oom();
+-
+- names_it = *mangled_names;
++ l = new(char*, strv_length(original_names) + 1);
++ if (!l)
++ return -ENOMEM;
+
++ i = l;
+ STRV_FOREACH(name, original_names) {
+- char *n = unit_name_mangle(*name);
+- (*names_it) = n ? n : strdup(*name);
+- if(!(*names_it))
+- return log_oom();
+- names_it++;
++ *i = unit_name_mangle(*name);
++ if (!*i) {
++ strv_free(l);
++ return -ENOMEM;
++ }
++
++ i++;
+ }
+- *names_it = NULL;
++
++ *i = NULL;
++ *mangled_names = l;
+
+ return 0;
+ }
diff --git a/0539-socket-prevent-signed-integer-overflow.patch b/0539-socket-prevent-signed-integer-overflow.patch
new file mode 100644
index 0000000..c0bd1d5
--- /dev/null
+++ b/0539-socket-prevent-signed-integer-overflow.patch
@@ -0,0 +1,25 @@
+From 71041ee5a4c35078194f4a1a07a6ef5add230d24 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Sat, 15 Sep 2012 12:58:48 -0400
+Subject: [PATCH] socket: prevent signed integer overflow
+
+src/core/socket.c:588:25: error: overflow in implicit constant conversion
+src/core/socket.c:589:17: error: overflow in implicit constant conversion
+(cherry picked from commit c65a0b146652cac52fe3c43f7cb8fe6a2ac3e063)
+---
+ src/core/socket.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/socket.c b/src/core/socket.c
+index 1196e64..2b1cf52 100644
+--- a/src/core/socket.c
++++ b/src/core/socket.c
+@@ -578,7 +578,7 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
+ }
+
+ case AF_INET6: {
+- static const char ipv4_prefix[] = {
++ static const unsigned char ipv4_prefix[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
+ };
+
diff --git a/0540-tmpfiles-use-write-2-for-the-w-action.patch b/0540-tmpfiles-use-write-2-for-the-w-action.patch
new file mode 100644
index 0000000..b04272a
--- /dev/null
+++ b/0540-tmpfiles-use-write-2-for-the-w-action.patch
@@ -0,0 +1,96 @@
+From c2b14be2c3791aed363db398a9bb488967ec9dc5 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Sat, 15 Sep 2012 12:58:49 -0400
+Subject: [PATCH] tmpfiles: use write(2) for the 'w' action
+
+This resolves problems with filesystems which do not implement the
+aio_write file operation. In this case, the kernel will fall back using
+a loop writing technique for each pointer in a received iovec. The
+result is strange errors in dmesg such as:
+
+[ 31.855871] elevator: type not found
+[ 31.856262] elevator: switch to
+[ 31.856262] failed
+
+It does not make sense to implement a synchronous aio_write method for
+sysfs as this isn't a real filesystem where a reasonable use case for
+using writev exists, nor is there an expectation that tmpfiles will be
+used to write more data than can be reasonably written in a single write
+syscall.
+
+In addition, some sysfs attrs are currently buggy and will NOT reject
+the second write with the newline, causing the sysfs value to be zeroed
+out. This of course should be fixed in the kernel regardless of any
+wrongdoing in userspace, but this simple change makes us immune to such
+a bug.
+
+This change means that we do not write a trailing newline by default, as
+the expected use case of 'w' is for sysfs and procfs. In exchange, honor
+C-style backslash escapes so that if the newline is really needed, the
+user can add it.
+(cherry picked from commit 54693d9bfa855841e8097d7a6b8c8d7acc068004)
+---
+ man/tmpfiles.d.xml | 5 ++++-
+ src/tmpfiles/tmpfiles.c | 23 ++++++++---------------
+ 2 files changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
+index 5dd196b..9fae638 100644
+--- a/man/tmpfiles.d.xml
++++ b/man/tmpfiles.d.xml
+@@ -114,7 +114,10 @@ L /tmp/foobar - - - - /dev/null</programlisting>
+
+ <varlistentry>
+ <term><varname>w</varname></term>
+- <listitem><para>Write the argument parameter to a file, if it exists. Lines of this type accept shell-style globs in place of normal path names.</para></listitem>
++ <listitem><para>Write the argument parameter to a file, if the file exists.
++ Lines of this type accept shell-style globs in place of normal path
++ names. The argument parameter will be written without a trailing
++ newline. C-style backslash escapes are interpreted.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index 0540572..a8f464a 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -41,6 +41,7 @@
+
+ #include "log.h"
+ #include "util.h"
++#include "macro.h"
+ #include "mkdir.h"
+ #include "path-util.h"
+ #include "strv.h"
+@@ -481,24 +482,16 @@ static int write_one_file(Item *i, const char *path) {
+ if (i->argument) {
+ ssize_t n;
+ size_t l;
+- struct iovec iovec[2];
+- static const char new_line = '\n';
++ char *unescaped;
+
+- l = strlen(i->argument);
++ unescaped = cunescape(i->argument);
++ if (unescaped == NULL)
++ return -ENOMEM;
+
+- zero(iovec);
+- iovec[0].iov_base = i->argument;
+- iovec[0].iov_len = l;
++ l = strlen(unescaped);
++ n = write(fd, unescaped, l);
++ free(unescaped);
+
+- iovec[1].iov_base = (void*) &new_line;
+- iovec[1].iov_len = 1;
+-
+- n = writev(fd, iovec, 2);
+-
+- /* It's OK if we don't write the trailing
+- * newline, hence we check for l, instead of
+- * l+1 here. Files in /sys often refuse
+- * writing of the trailing newline. */
+ if (n < 0 || (size_t) n < l) {
+ log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
+ close_nointr_nofail(fd);
diff --git a/0541-service-don-t-hit-an-assert-if-a-service-unit-change.patch b/0541-service-don-t-hit-an-assert-if-a-service-unit-change.patch
new file mode 100644
index 0000000..c473f99
--- /dev/null
+++ b/0541-service-don-t-hit-an-assert-if-a-service-unit-change.patch
@@ -0,0 +1,43 @@
+From b667a525077329c2ddd8bb3a646839a1acf98201 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 17 Sep 2012 14:55:56 +0200
+Subject: [PATCH] service: don't hit an assert if a service unit changes type
+ and we get a spurious event from before (cherry picked from
+ commit bfba3256a02a0871579c4ee48d787dfe4585fd8d)
+
+Conflicts:
+ TODO
+---
+ src/core/service.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/core/service.c b/src/core/service.c
+index d300e34..b2d493a 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -2944,12 +2944,10 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+ else
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
+ break;
+- } else {
+- assert(s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY);
+-
+- /* Fall through */
+ }
+
++ /* Fall through */
++
+ case SERVICE_RUNNING:
+ service_enter_running(s, f);
+ break;
+@@ -3019,7 +3017,9 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+ break;
+
+ case SERVICE_START:
+- assert(s->type == SERVICE_FORKING);
++ if (s->type != SERVICE_FORKING)
++ /* Maybe spurious event due to a reload that changed the type? */
++ break;
+
+ if (f != SERVICE_SUCCESS) {
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, f);
diff --git a/0542-hwclock-always-set-the-kernel-s-timezone.patch b/0542-hwclock-always-set-the-kernel-s-timezone.patch
new file mode 100644
index 0000000..1042c9f
--- /dev/null
+++ b/0542-hwclock-always-set-the-kernel-s-timezone.patch
@@ -0,0 +1,138 @@
+From 9f77c263bcc7ba8af78dd3f49af91c5bf7e9eb2a Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay at vrfy.org>
+Date: Mon, 17 Sep 2012 16:41:13 +0200
+Subject: [PATCH] hwclock: always set the kernel's timezone
+
+Properly tell the kernel at bootup, and any later time zone changes,
+the actual system time zone.
+
+Things like the kernel's FAT filesystem driver needs the actual time
+zone to calculate the proper local time to use for the on-disk time
+stamps.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=802198
+(cherry picked from commit 72edcff5db936e54cfc322d9392ec46e2428fd9b)
+---
+ src/core/main.c | 15 ++++++++++++---
+ src/shared/hwclock.c | 9 +++++++--
+ src/shared/hwclock.h | 4 ++--
+ src/timedate/timedated.c | 13 +++++--------
+ 4 files changed, 26 insertions(+), 15 deletions(-)
+
+diff --git a/src/core/main.c b/src/core/main.c
+index ecb17d4..06f14c3 100644
+--- a/src/core/main.c
++++ b/src/core/main.c
+@@ -1300,17 +1300,26 @@ int main(int argc, char *argv[]) {
+ if (label_init(NULL) < 0)
+ goto finish;
+
+- if (!skip_setup)
++ if (!skip_setup) {
+ if (hwclock_is_localtime() > 0) {
+ int min;
+
+- r = hwclock_apply_localtime_delta(&min);
++ /* The first-time call to settimeofday() does a time warp in the kernel */
++ r = hwclock_set_timezone(&min);
+ if (r < 0)
+ log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
+ else
+ log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
+- }
++ } else {
++ /* Do dummy first-time call to seal the kernel's time warp magic */
++ hwclock_reset_timezone();
+
++ /* Tell the kernel our time zone */
++ r = hwclock_set_timezone(NULL);
++ if (r < 0)
++ log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
++ }
++ }
+ } else {
+ arg_running_as = MANAGER_USER;
+ log_set_target(LOG_TARGET_AUTO);
+diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c
+index d40bb26..e536a8d 100644
+--- a/src/shared/hwclock.c
++++ b/src/shared/hwclock.c
+@@ -188,7 +188,7 @@ int hwclock_is_localtime(void) {
+ return local;
+ }
+
+-int hwclock_apply_localtime_delta(int *min) {
++int hwclock_set_timezone(int *min) {
+ const struct timeval *tv_null = NULL;
+ struct timespec ts;
+ struct tm *tm;
+@@ -214,13 +214,18 @@ int hwclock_apply_localtime_delta(int *min) {
+ return 0;
+ }
+
+-int hwclock_reset_localtime_delta(void) {
++int hwclock_reset_timezone(void) {
+ const struct timeval *tv_null = NULL;
+ struct timezone tz;
+
+ tz.tz_minuteswest = 0;
+ tz.tz_dsttime = 0; /* DST_NONE*/
+
++ /*
++ * The very first time we set the kernel's timezone, it will warp
++ * the clock. Do a dummy call here, so the time warping is sealed
++ * and we set only the time zone with next call.
++ */
+ if (settimeofday(tv_null, &tz) < 0)
+ return -errno;
+
+diff --git a/src/shared/hwclock.h b/src/shared/hwclock.h
+index 26d1b44..b2bdc78 100644
+--- a/src/shared/hwclock.h
++++ b/src/shared/hwclock.h
+@@ -23,8 +23,8 @@
+ ***/
+
+ int hwclock_is_localtime(void);
+-int hwclock_apply_localtime_delta(int *min);
+-int hwclock_reset_localtime_delta(void);
++int hwclock_set_timezone(int *min);
++int hwclock_reset_timezone(void);
+ int hwclock_get_time(struct tm *tm);
+ int hwclock_set_time(const struct tm *tm);
+
+diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
+index b008f15..191c974 100644
+--- a/src/timedate/timedated.c
++++ b/src/timedate/timedated.c
+@@ -580,13 +580,13 @@ static DBusHandlerResult timedate_message_handler(
+ return bus_send_error_reply(connection, message, NULL, r);
+ }
+
++ /* 2. Tell the kernel our time zone */
++ hwclock_set_timezone(NULL);
++
+ if (tz.local_rtc) {
+ struct timespec ts;
+ struct tm *tm;
+
+- /* 2. Teach kernel new timezone */
+- hwclock_apply_localtime_delta(NULL);
+-
+ /* 3. Sync RTC from system clock, with the new delta */
+ assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
+ assert_se(tm = localtime(&ts.tv_sec));
+@@ -633,11 +633,8 @@ static DBusHandlerResult timedate_message_handler(
+ return bus_send_error_reply(connection, message, NULL, r);
+ }
+
+- /* 2. Teach kernel new timezone */
+- if (tz.local_rtc)
+- hwclock_apply_localtime_delta(NULL);
+- else
+- hwclock_reset_localtime_delta();
++ /* 2. Tell the kernel our time zone */
++ hwclock_set_timezone(NULL);
+
+ /* 3. Synchronize clocks */
+ assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
diff --git a/0543-conf-parser-don-t-unescape-parsed-configuration-stri.patch b/0543-conf-parser-don-t-unescape-parsed-configuration-stri.patch
new file mode 100644
index 0000000..6167c9c
--- /dev/null
+++ b/0543-conf-parser-don-t-unescape-parsed-configuration-stri.patch
@@ -0,0 +1,86 @@
+From ed13e6cb0f7ff95a5d5dd0150cda236c29ca814d Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 17 Sep 2012 21:58:03 +0200
+Subject: [PATCH] conf-parser: don't unescape parsed configuration strings by
+ default
+
+In many cases this might have a negative effect since we drop escaping
+from strings where we better shouldn't have dropped it.
+
+If unescaping makes sense for some settings we can readd it later again,
+on a per-case basis.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=54522
+(cherry picked from commit faa368e3376cb5e3e3c27550fdde652f1d3c9584)
+---
+ src/core/service.c | 1 -
+ src/core/unit.c | 10 ++++++----
+ src/shared/conf-parser.c | 2 +-
+ src/shared/util.c | 2 ++
+ 4 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/src/core/service.c b/src/core/service.c
+index b2d493a..d0369da 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -922,7 +922,6 @@ static int service_load_sysv_path(Service *s, const char *path) {
+ s->timeout_stop_usec = DEFAULT_SYSV_TIMEOUT_USEC;
+ }
+
+-
+ /* Special setting for all SysV services */
+ s->type = SERVICE_FORKING;
+ s->remain_after_exit = !s->pid_file;
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 5865405..857b92d 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2516,16 +2516,18 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
+
+ r = manager_load_unit(u->manager, e, NULL, NULL, &device);
+ free(e);
+-
+ if (r < 0)
+ return r;
+
+- if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true)) < 0)
++ r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
++ if (r < 0)
+ return r;
+
+- if (wants)
+- if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0)
++ if (wants) {
++ r = unit_add_dependency(device, UNIT_WANTS, u, false);
++ if (r < 0)
+ return r;
++ }
+
+ return 0;
+ }
+diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
+index 8582f6d..24a853c 100644
+--- a/src/shared/conf-parser.c
++++ b/src/shared/conf-parser.c
+@@ -591,7 +591,7 @@ int config_parse_string(
+ assert(rvalue);
+ assert(data);
+
+- n = cunescape(rvalue);
++ n = strdup(rvalue);
+ if (!n)
+ return -ENOMEM;
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 2bdf4a5..af1c9c0 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -4038,6 +4038,8 @@ static char *tag_to_udev_node(const char *tagvalue, const char *by) {
+ }
+
+ char *fstab_node_to_udev_node(const char *p) {
++ assert(p);
++
+ if (startswith(p, "LABEL="))
+ return tag_to_udev_node(p+6, "label");
+
diff --git a/0544-log-avoid-function-loop.patch b/0544-log-avoid-function-loop.patch
new file mode 100644
index 0000000..afcb9fa
--- /dev/null
+++ b/0544-log-avoid-function-loop.patch
@@ -0,0 +1,73 @@
+From 49bf9200bdd680a02ea5c6107716fdb5e2d4b4e2 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Mon, 17 Sep 2012 22:14:24 +0200
+Subject: [PATCH] log: avoid function loop
+
+https://bugs.freedesktop.org/show_bug.cgi?id=54766
+(cherry picked from commit cd15c4182b2e39bac51afc1c839f9a9f64d1d78f)
+---
+ src/shared/log.c | 19 ++-----------------
+ 1 file changed, 2 insertions(+), 17 deletions(-)
+
+diff --git a/src/shared/log.c b/src/shared/log.c
+index a2fa653..4ec7b8f 100644
+--- a/src/shared/log.c
++++ b/src/shared/log.c
+@@ -72,14 +72,9 @@ static int log_open_console(void) {
+ return 0;
+
+ if (getpid() == 1) {
+-
+ console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+- if (console_fd < 0) {
+- log_error("Failed to open /dev/console for logging: %s", strerror(-console_fd));
++ if (console_fd < 0)
+ return console_fd;
+- }
+-
+- log_debug("Successfully opened /dev/console for logging.");
+ } else
+ console_fd = STDERR_FILENO;
+
+@@ -101,12 +96,8 @@ static int log_open_kmsg(void) {
+ return 0;
+
+ kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+- if (kmsg_fd < 0) {
+- log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno));
++ if (kmsg_fd < 0)
+ return -errno;
+- }
+-
+- log_debug("Successfully opened /dev/kmsg for logging.");
+
+ return 0;
+ }
+@@ -173,13 +164,10 @@ static int log_open_syslog(void) {
+ } else
+ syslog_is_stream = false;
+
+- log_debug("Successfully opened syslog for logging.");
+-
+ return 0;
+
+ fail:
+ log_close_syslog();
+- log_debug("Failed to open syslog for logging: %s", strerror(-r));
+ return r;
+ }
+
+@@ -214,13 +202,10 @@ static int log_open_journal(void) {
+ goto fail;
+ }
+
+- log_debug("Successfully opened journal for logging.");
+-
+ return 0;
+
+ fail:
+ log_close_journal();
+- log_debug("Failed to open journal for logging: %s", strerror(-r));
+ return r;
+ }
+
diff --git a/0545-target-imply-default-ordering-for-PartsOf-deps-as-we.patch b/0545-target-imply-default-ordering-for-PartsOf-deps-as-we.patch
new file mode 100644
index 0000000..5f87ad9
--- /dev/null
+++ b/0545-target-imply-default-ordering-for-PartsOf-deps-as-we.patch
@@ -0,0 +1,77 @@
+From ff8a0f68ab5f2a3fdf6dff4ad2a2ea41c2e8f69a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 18 Sep 2012 11:01:34 +0200
+Subject: [PATCH] target: imply default ordering for PartsOf deps as well
+ (cherry picked from commit
+ 1850161f29f2ee23afce0ad571d80033f97388ad)
+
+---
+ src/core/target.c | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/src/core/target.c b/src/core/target.c
+index d1625a1..b09b355 100644
+--- a/src/core/target.c
++++ b/src/core/target.c
+@@ -53,13 +53,15 @@ static void target_set_state(Target *t, TargetState state) {
+ }
+
+ static int target_add_default_dependencies(Target *t) {
++
+ static const UnitDependency deps[] = {
+ UNIT_REQUIRES,
+ UNIT_REQUIRES_OVERRIDABLE,
+ UNIT_REQUISITE,
+ UNIT_REQUISITE_OVERRIDABLE,
+ UNIT_WANTS,
+- UNIT_BINDS_TO
++ UNIT_BINDS_TO,
++ UNIT_PART_OF
+ };
+
+ Iterator i;
+@@ -75,9 +77,11 @@ static int target_add_default_dependencies(Target *t) {
+ * sure we don't create a loop. */
+
+ for (k = 0; k < ELEMENTSOF(deps); k++)
+- SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i)
+- if ((r = unit_add_default_target_dependency(other, UNIT(t))) < 0)
++ SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i) {
++ r = unit_add_default_target_dependency(other, UNIT(t));
++ if (r < 0)
+ return r;
++ }
+
+ /* Make sure targets are unloaded on shutdown */
+ return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+@@ -89,14 +93,15 @@ static int target_load(Unit *u) {
+
+ assert(t);
+
+- if ((r = unit_load_fragment_and_dropin(u)) < 0)
++ r = unit_load_fragment_and_dropin(u);
++ if (r < 0)
+ return r;
+
+ /* This is a new unit? Then let's add in some extras */
+- if (u->load_state == UNIT_LOADED) {
+- if (u->default_dependencies)
+- if ((r = target_add_default_dependencies(t)) < 0)
+- return r;
++ if (u->load_state == UNIT_LOADED && u->default_dependencies) {
++ r = target_add_default_dependencies(t);
++ if (r < 0)
++ return r;
+ }
+
+ return 0;
+@@ -167,7 +172,8 @@ static int target_deserialize_item(Unit *u, const char *key, const char *value,
+ if (streq(key, "state")) {
+ TargetState state;
+
+- if ((state = target_state_from_string(value)) < 0)
++ state = target_state_from_string(value);
++ if (state < 0)
+ log_debug("Failed to parse state value %s", value);
+ else
+ s->deserialized_state = state;
diff --git a/0546-unit-fix-f-resolving.patch b/0546-unit-fix-f-resolving.patch
new file mode 100644
index 0000000..30bfb2a
--- /dev/null
+++ b/0546-unit-fix-f-resolving.patch
@@ -0,0 +1,41 @@
+From daeb571274741a10bfb3c95c528b38470a51c665 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 18 Sep 2012 11:18:37 +0200
+Subject: [PATCH] unit: fix %f resolving (cherry picked from commit
+ 99006251161aee07b6a099e3186b4360be66eeaa)
+
+Conflicts:
+ src/core/unit.c
+---
+ src/core/unit.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/unit.c b/src/core/unit.c
+index 857b92d..fe4fa77 100644
+--- a/src/core/unit.c
++++ b/src/core/unit.c
+@@ -2178,7 +2178,7 @@ static char *specifier_filename(char specifier, void *data, void *userdata) {
+ if (u->instance)
+ return unit_name_path_unescape(u->instance);
+
+- return unit_name_to_path(u->instance);
++ return unit_name_to_path(u->id);
+ }
+
+ static char *specifier_cgroup(char specifier, void *data, void *userdata) {
+@@ -2253,6 +2253,7 @@ char *unit_full_printf(Unit *u, const char *format) {
+ /* This is similar to unit_name_printf() but also supports
+ * unescaping. Also, adds a couple of additional codes:
+ *
++ * %f the the instance if set, otherwise the id
+ * %c cgroup path of unit
+ * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711")
+ * %R parent of root cgroup path (e.g. "/usr/lennart/shared")
+@@ -2266,6 +2267,7 @@ char *unit_full_printf(Unit *u, const char *format) {
+ { 'P', specifier_prefix_unescaped, NULL },
+ { 'i', specifier_string, u->instance },
+ { 'I', specifier_instance_unescaped, NULL },
++
+ { 'f', specifier_filename, NULL },
+ { 'c', specifier_cgroup, NULL },
+ { 'r', specifier_cgroup_root, NULL },
diff --git a/0547-mount-notify-the-user-if-we-over-mount-a-non-empty-d.patch b/0547-mount-notify-the-user-if-we-over-mount-a-non-empty-d.patch
new file mode 100644
index 0000000..5753b7f
--- /dev/null
+++ b/0547-mount-notify-the-user-if-we-over-mount-a-non-empty-d.patch
@@ -0,0 +1,36 @@
+From 15f925c53fa42c8f9808d85dad6698a17b0ae41a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 18 Sep 2012 18:40:31 +0200
+Subject: [PATCH] mount: notify the user if we over-mount a non-empty
+ directory
+
+https://bugzilla.redhat.com/show_bug.cgi?id=858266
+(cherry picked from commit 257f1d8ec49046c7b481801acfdd5bf57c9efa5c)
+---
+ src/core/mount.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/core/mount.c b/src/core/mount.c
+index 3a33d93..5ebf5d7 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -1011,6 +1011,9 @@ static void mount_enter_mounting(Mount *m) {
+
+ mkdir_p_label(m->where, m->directory_mode);
+
++ if (dir_is_empty(m->where) <= 0)
++ log_notice("%s: Directory %s to mount over is not empty, ignoring. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", m->meta.id, m->where);
++
+ /* Create the source directory for bind-mounts if needed */
+ p = get_mount_parameters_configured(m);
+ if (p && mount_is_bind(p))
+@@ -1039,7 +1042,8 @@ static void mount_enter_mounting(Mount *m) {
+
+ mount_unwatch_control_pid(m);
+
+- if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
++ r = mount_spawn(m, m->control_command, &m->control_pid);
++ if (r < 0)
+ goto fail;
+
+ mount_set_state(m, MOUNT_MOUNTING);
diff --git a/0548-automount-also-whine-if-an-automount-directory-is-no.patch b/0548-automount-also-whine-if-an-automount-directory-is-no.patch
new file mode 100644
index 0000000..7186afe
--- /dev/null
+++ b/0548-automount-also-whine-if-an-automount-directory-is-no.patch
@@ -0,0 +1,25 @@
+From 607c7f865e59ca9c286c448f3b6bfaded1df3389 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Tue, 18 Sep 2012 18:59:01 +0200
+Subject: [PATCH] automount: also whine if an automount directory is not empty
+ (cherry picked from commit
+ e872b43c7ee51efb6bd6ca31d79e02af8cc3cb82)
+
+---
+ src/core/automount.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/core/automount.c b/src/core/automount.c
+index 5c716ee..7312f86 100644
+--- a/src/core/automount.c
++++ b/src/core/automount.c
+@@ -503,6 +503,9 @@ static void automount_enter_waiting(Automount *a) {
+ /* We knowingly ignore the results of this call */
+ mkdir_p_label(a->where, 0555);
+
++ if (dir_is_empty(a->where) <= 0)
++ log_notice("%s: Directory %s to mount over is not empty, ignoring. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", a->meta.id, a->where);
++
+ if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
+ r = -errno;
+ goto fail;
diff --git a/0549-mount-reword-directory-empty-warning-a-bit.patch b/0549-mount-reword-directory-empty-warning-a-bit.patch
new file mode 100644
index 0000000..463f824
--- /dev/null
+++ b/0549-mount-reword-directory-empty-warning-a-bit.patch
@@ -0,0 +1,37 @@
+From ad0c112c72e6ad3c5af510b7d54606edf5c0c044 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 19 Sep 2012 09:55:56 +0200
+Subject: [PATCH] mount: reword directory empty warning a bit (cherry picked
+ from commit a99124d92f8a60215f5ea5ed95de9792c1fb3324)
+
+---
+ src/core/automount.c | 2 +-
+ src/core/mount.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/core/automount.c b/src/core/automount.c
+index 7312f86..76d99f8 100644
+--- a/src/core/automount.c
++++ b/src/core/automount.c
+@@ -504,7 +504,7 @@ static void automount_enter_waiting(Automount *a) {
+ mkdir_p_label(a->where, 0555);
+
+ if (dir_is_empty(a->where) <= 0)
+- log_notice("%s: Directory %s to mount over is not empty, ignoring. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", a->meta.id, a->where);
++ log_notice("%s: Directory %s to mount over is not empty, mounting anyway. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", a->meta.id, a->where);
+
+ if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
+ r = -errno;
+diff --git a/src/core/mount.c b/src/core/mount.c
+index 5ebf5d7..86bf16c 100644
+--- a/src/core/mount.c
++++ b/src/core/mount.c
+@@ -1012,7 +1012,7 @@ static void mount_enter_mounting(Mount *m) {
+ mkdir_p_label(m->where, m->directory_mode);
+
+ if (dir_is_empty(m->where) <= 0)
+- log_notice("%s: Directory %s to mount over is not empty, ignoring. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", m->meta.id, m->where);
++ log_notice("%s: Directory %s to mount over is not empty, mounting anyway. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", m->meta.id, m->where);
+
+ /* Create the source directory for bind-mounts if needed */
+ p = get_mount_parameters_configured(m);
diff --git a/0550-timedated-unregister-the-right-bus-service.patch b/0550-timedated-unregister-the-right-bus-service.patch
new file mode 100644
index 0000000..d60ff9b
--- /dev/null
+++ b/0550-timedated-unregister-the-right-bus-service.patch
@@ -0,0 +1,24 @@
+From e89977c192428db435609133fce0e0bc19257a90 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 19 Sep 2012 19:09:22 +0200
+Subject: [PATCH] timedated: unregister the right bus service
+
+https://bugzilla.redhat.com/show_bug.cgi?id=858771
+(cherry picked from commit c68df23956455129087fb0ddc588ca492771555b)
+---
+ src/timedate/timedated.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
+index 191c974..8b1fefd 100644
+--- a/src/timedate/timedated.c
++++ b/src/timedate/timedated.c
+@@ -909,7 +909,7 @@ int main(int argc, char *argv[]) {
+
+ if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
+ exiting = true;
+- bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1");
++ bus_async_unregister_and_exit(bus, "org.freedesktop.timedated1");
+ }
+ }
+
diff --git a/0551-util-make-sure-heap-allocators-fail-when-array-alloc.patch b/0551-util-make-sure-heap-allocators-fail-when-array-alloc.patch
new file mode 100644
index 0000000..d2a0116
--- /dev/null
+++ b/0551-util-make-sure-heap-allocators-fail-when-array-alloc.patch
@@ -0,0 +1,63 @@
+From 013896fee97e70a00438ef3db35e528f47d91b11 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 20 Sep 2012 00:02:01 +0200
+Subject: [PATCH] util: make sure heap allocators fail when array allocations
+ are out of bounds
+
+https://bugzilla.redhat.com/show_bug.cgi?id=858777
+(cherry picked from commit 4b8772bf5f2887aa2bdb74efa2f5dfd40fff946d)
+
+Conflicts:
+ src/shared/util.h
+---
+ src/shared/util.h | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 66022ed..804bd37 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -104,13 +104,13 @@ size_t page_size(void);
+
+ bool streq_ptr(const char *a, const char *b);
+
+-#define new(t, n) ((t*) malloc(sizeof(t)*(n)))
++#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
+
+ #define new0(t, n) ((t*) calloc((n), sizeof(t)))
+
+ #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_multiply(p, sizeof(t), (n)))
+
+ #define malloc0(n) (calloc((n), 1))
+
+@@ -503,7 +503,7 @@ char *format_bytes(char *buf, size_t l, off_t t);
+
+ int fd_wait_for_event(int fd, int event, usec_t timeout);
+
+-void* memdup(const void *p, size_t l);
++void* memdup(const void *p, size_t l) _malloc_;
+
+ int is_kernel_thread(pid_t pid);
+
+@@ -521,4 +521,18 @@ int can_sleep(const char *type);
+ bool is_valid_documentation_url(const char *url);
+
+ bool in_initrd(void);
++
++_malloc_ static inline void *malloc_multiply(size_t a, size_t b) {
++ if (_unlikely_(a > ((size_t) -1) / b))
++ return NULL;
++
++ return malloc(a * b);
++}
++
++static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
++ if (_unlikely_(a > ((size_t) -1) / b))
++ return NULL;
++
++ return memdup(p, a * b);
++}
+ #endif
diff --git a/0552-util-define-union-dirent_storage-and-make-use-of-it-.patch b/0552-util-define-union-dirent_storage-and-make-use-of-it-.patch
new file mode 100644
index 0000000..a8f7543
--- /dev/null
+++ b/0552-util-define-union-dirent_storage-and-make-use-of-it-.patch
@@ -0,0 +1,322 @@
+From 77add7ed8cfb796a7eed18e2451351cb89e5ef69 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Wed, 19 Sep 2012 22:21:09 +0200
+Subject: [PATCH] util: define union dirent_storage and make use of it
+ everywhere
+
+Make sure to allocate enough space for readdir_r().
+
+https://bugzilla.redhat.com/show_bug.cgi?id=858754
+(cherry picked from commit 7d5e9c0f60cddf01ec803012cbdc02d2f55b78c1)
+
+Conflicts:
+ src/journal/journal-vacuum.c
+ src/journal/sd-journal.c
+ src/shared/util.c
+---
+ src/delta/delta.c | 5 +++--
+ src/journal/journald.c | 5 +++--
+ src/journal/sd-journal.c | 10 ++++++----
+ src/login/sd-login.c | 5 +++--
+ src/shared/conf-files.c | 5 +++--
+ src/shared/hwclock.c | 5 +++--
+ src/shared/install.c | 15 +++++++++------
+ src/shared/util.c | 17 +++++++++++------
+ src/shared/util.h | 7 +++++++
+ src/tmpfiles/tmpfiles.c | 5 +++--
+ 10 files changed, 51 insertions(+), 28 deletions(-)
+
+diff --git a/src/delta/delta.c b/src/delta/delta.c
+index 4694fc8..65dcedd 100644
+--- a/src/delta/delta.c
++++ b/src/delta/delta.c
+@@ -176,11 +176,12 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, const char *path) {
+ }
+
+ for (;;) {
+- struct dirent *de, buf;
++ struct dirent *de;
++ union dirent_storage buf;
+ int k;
+ char *p;
+
+- k = readdir_r(d, &buf, &de);
++ k = readdir_r(d, &buf.de, &de);
+ if (k != 0) {
+ r = -k;
+ goto finish;
+diff --git a/src/journal/journald.c b/src/journal/journald.c
+index a538047..78e3278 100644
+--- a/src/journal/journald.c
++++ b/src/journal/journald.c
+@@ -156,9 +156,10 @@ static uint64_t available_space(Server *s) {
+
+ for (;;) {
+ struct stat st;
+- struct dirent buf, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+
+- r = readdir_r(d, &buf, &de);
++ r = readdir_r(d, &buf.de, &de);
+ if (r != 0)
+ break;
+
+diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
+index c67069a..5a82fbd 100644
+--- a/src/journal/sd-journal.c
++++ b/src/journal/sd-journal.c
+@@ -1064,9 +1064,10 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dir) {
+ free(fn);
+
+ for (;;) {
+- struct dirent buf, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+
+- r = readdir_r(d, &buf, &de);
++ r = readdir_r(d, &buf.de, &de);
+ if (r != 0 || !de)
+ break;
+
+@@ -1201,10 +1202,11 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) {
+ add_root_wd(j, p);
+
+ for (;;) {
+- struct dirent buf, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+ sd_id128_t id;
+
+- r = readdir_r(d, &buf, &de);
++ r = readdir_r(d, &buf.de, &de);
+ if (r != 0 || !de)
+ break;
+
+diff --git a/src/login/sd-login.c b/src/login/sd-login.c
+index d47a49c..a0bcbbd 100644
+--- a/src/login/sd-login.c
++++ b/src/login/sd-login.c
+@@ -641,11 +641,12 @@ _public_ int sd_get_uids(uid_t **users) {
+ return -errno;
+
+ for (;;) {
+- struct dirent buffer, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+ int k;
+ uid_t uid;
+
+- k = readdir_r(d, &buffer, &de);
++ k = readdir_r(d, &buf.de, &de);
+ if (k != 0) {
+ r = -k;
+ goto finish;
+diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c
+index 83e4cce..34b8629 100644
+--- a/src/shared/conf-files.c
++++ b/src/shared/conf-files.c
+@@ -39,7 +39,6 @@
+
+ static int files_add(Hashmap *h, const char *path, const char *suffix) {
+ DIR *dir;
+- struct dirent buffer, *de;
+ int r = 0;
+
+ dir = opendir(path);
+@@ -50,10 +49,12 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
+ }
+
+ for (;;) {
++ struct dirent *de;
++ union dirent_storage buf;
+ int k;
+ char *p;
+
+- k = readdir_r(dir, &buffer, &de);
++ k = readdir_r(dir, &buf.de, &de);
+ if (k != 0) {
+ r = -k;
+ goto finish;
+diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c
+index e536a8d..05be72c 100644
+--- a/src/shared/hwclock.c
++++ b/src/shared/hwclock.c
+@@ -61,10 +61,11 @@ static int rtc_open(int flags) {
+
+ for (;;) {
+ char *p, *v;
+- struct dirent buf, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+ int r;
+
+- r = readdir_r(d, &buf, &de);
++ r = readdir_r(d, &buf.de, &de);
+ if (r != 0)
+ goto fallback;
+
+diff --git a/src/shared/install.c b/src/shared/install.c
+index 6f0e018..c1f7022 100644
+--- a/src/shared/install.c
++++ b/src/shared/install.c
+@@ -200,7 +200,6 @@ static int remove_marked_symlinks_fd(
+
+ int r = 0;
+ DIR *d;
+- struct dirent buffer, *de;
+
+ assert(remove_symlinks_to);
+ assert(fd >= 0);
+@@ -217,9 +216,11 @@ static int remove_marked_symlinks_fd(
+ rewinddir(d);
+
+ for (;;) {
++ struct dirent *de;
++ union dirent_storage buf;
+ int k;
+
+- k = readdir_r(d, &buffer, &de);
++ k = readdir_r(d, &buf.de, &de);
+ if (k != 0) {
+ r = -errno;
+ break;
+@@ -374,7 +375,6 @@ static int find_symlinks_fd(
+
+ int r = 0;
+ DIR *d;
+- struct dirent buffer, *de;
+
+ assert(name);
+ assert(fd >= 0);
+@@ -390,8 +390,10 @@ static int find_symlinks_fd(
+
+ for (;;) {
+ int k;
++ struct dirent *de;
++ union dirent_storage buf;
+
+- k = readdir_r(d, &buffer, &de);
++ k = readdir_r(d, &buf.de, &de);
+ if (k != 0) {
+ r = -errno;
+ break;
+@@ -1913,7 +1915,6 @@ int unit_file_get_list(
+ return r;
+
+ STRV_FOREACH(i, paths.unit_path) {
+- struct dirent buffer, *de;
+ const char *units_dir;
+
+ free(buf);
+@@ -1941,9 +1942,11 @@ int unit_file_get_list(
+ }
+
+ for (;;) {
++ struct dirent *de;
++ union dirent_storage buffer;
+ UnitFileList *f;
+
+- r = readdir_r(d, &buffer, &de);
++ r = readdir_r(d, &buffer.de, &de);
+ if (r != 0) {
+ r = -r;
+ goto finish;
+diff --git a/src/shared/util.c b/src/shared/util.c
+index af1c9c0..de89bf2 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -2969,13 +2969,16 @@ bool is_device_path(const char *path) {
+ int dir_is_empty(const char *path) {
+ DIR *d;
+ int r;
+- struct dirent buf, *de;
+
+ if (!(d = opendir(path)))
+ return -errno;
+
+ for (;;) {
+- if ((r = readdir_r(d, &buf, &de)) > 0) {
++ struct dirent *de;
++ union dirent_storage buf;
++
++ r = readdir_r(d, &buf.de, &de);
++ if (r > 0) {
+ r = -r;
+ break;
+ }
+@@ -3270,12 +3273,13 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root
+ }
+
+ for (;;) {
+- struct dirent buf, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+ bool is_dir, keep_around;
+ struct stat st;
+ int r;
+
+- r = readdir_r(d, &buf, &de);
++ r = readdir_r(d, &buf.de, &de);
+ if (r != 0 && ret == 0) {
+ ret = -r;
+ break;
+@@ -5030,10 +5034,11 @@ int get_files_in_directory(const char *path, char ***list) {
+ return -errno;
+
+ for (;;) {
+- struct dirent buffer, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+ int k;
+
+- k = readdir_r(d, &buffer, &de);
++ k = readdir_r(d, &buf.de, &de);
+ if (k != 0) {
+ r = -k;
+ goto finish;
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 804bd37..9502fcb 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -35,6 +35,7 @@
+ #include <sys/stat.h>
+ #include <dirent.h>
+ #include <sys/resource.h>
++#include <stddef.h>
+
+ #include "macro.h"
+
+@@ -46,6 +47,12 @@ typedef struct dual_timestamp {
+ usec_t monotonic;
+ } dual_timestamp;
+
++union dirent_storage {
++ struct dirent de;
++ uint8_t storage[offsetof(struct dirent, d_name) +
++ ((NAME_MAX + 1 + sizeof(long)) & ~(sizeof(long) - 1))];
++};
++
+ #define MSEC_PER_SEC 1000ULL
+ #define USEC_PER_SEC 1000000ULL
+ #define USEC_PER_MSEC 1000ULL
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index a8f464a..30b0b93 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -530,12 +530,13 @@ static int recursive_relabel_children(Item *i, const char *path) {
+ return errno == ENOENT ? 0 : -errno;
+
+ for (;;) {
+- struct dirent buf, *de;
++ struct dirent *de;
++ union dirent_storage buf;
+ bool is_dir;
+ int r;
+ char *entry_path;
+
+- r = readdir_r(d, &buf, &de);
++ r = readdir_r(d, &buf.de, &de);
+ if (r != 0) {
+ if (ret == 0)
+ ret = -r;
diff --git a/0553-util-overflow-hardening.patch b/0553-util-overflow-hardening.patch
new file mode 100644
index 0000000..034eafb
--- /dev/null
+++ b/0553-util-overflow-hardening.patch
@@ -0,0 +1,72 @@
+From 63e3234a4ab3a654966accbedb14a36433c89afd Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 20 Sep 2012 11:08:27 +0200
+Subject: [PATCH] util: overflow hardening (cherry picked from commit
+ 040f18ea8a682dc80c9f3940cf234ccd1135e115)
+
+Conflicts:
+ TODO
+ src/shared/util.c
+---
+ src/shared/util.c | 14 +++++++++++---
+ src/shared/util.h | 2 +-
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index de89bf2..9c189eb 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -1212,8 +1212,11 @@ char *strnappend(const char *s, const char *suffix, size_t b) {
+ assert(suffix);
+
+ a = strlen(s);
++ if ((size_t) -1 - a > b)
++ return NULL;
+
+- if (!(r = new(char, a+b+1)))
++ r = new(char, a+b+1);
++ if (!r)
+ return NULL;
+
+ memcpy(r, s, a);
+@@ -5104,12 +5107,17 @@ char *join(const char *x, ...) {
+
+ for (;;) {
+ const char *t;
++ size_t n;
+
+ t = va_arg(ap, const char *);
+ if (!t)
+ break;
+
+- l += strlen(t);
++ n = strlen(t);
++ if (n > ((size_t) -1) - l)
++ return NULL;
++
++ l += n;
+ }
+ } else
+ l = 0;
+@@ -5381,7 +5389,7 @@ int signal_from_string(const char *s) {
+ int offset = 0;
+ unsigned u;
+
+- signo =__signal_from_string(s);
++ signo = __signal_from_string(s);
+ if (signo > 0)
+ return signo;
+
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 9502fcb..86f899a 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -536,7 +536,7 @@ _malloc_ static inline void *malloc_multiply(size_t a, size_t b) {
+ return malloc(a * b);
+ }
+
+-static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
++_malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
+ if (_unlikely_(a > ((size_t) -1) / b))
+ return NULL;
+
diff --git a/0554-util-fix-overflow-checks.patch b/0554-util-fix-overflow-checks.patch
new file mode 100644
index 0000000..1eb5979
--- /dev/null
+++ b/0554-util-fix-overflow-checks.patch
@@ -0,0 +1,45 @@
+From 3cdef2b892f2049fd8a4d8c5ad4baf0e28ea73c1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 20 Sep 2012 17:53:03 +0200
+Subject: [PATCH] util: fix overflow checks (cherry picked from commit
+ aa408e7799cf01f048efedf434916544b4badc77)
+
+---
+ src/shared/util.c | 2 +-
+ src/shared/util.h | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 9c189eb..6f2780a 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -1212,7 +1212,7 @@ char *strnappend(const char *s, const char *suffix, size_t b) {
+ assert(suffix);
+
+ a = strlen(s);
+- if ((size_t) -1 - a > b)
++ if (b > ((size_t) -1) - a)
+ return NULL;
+
+ r = new(char, a+b+1);
+diff --git a/src/shared/util.h b/src/shared/util.h
+index 86f899a..5459810 100644
+--- a/src/shared/util.h
++++ b/src/shared/util.h
+@@ -530,14 +530,14 @@ bool is_valid_documentation_url(const char *url);
+ bool in_initrd(void);
+
+ _malloc_ static inline void *malloc_multiply(size_t a, size_t b) {
+- if (_unlikely_(a > ((size_t) -1) / b))
++ if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+ return NULL;
+
+ return malloc(a * b);
+ }
+
+ _malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
+- if (_unlikely_(a > ((size_t) -1) / b))
++ if (_unlikely_(b == 0 || a > ((size_t) -1) / b))
+ return NULL;
+
+ return memdup(p, a * b);
diff --git a/0555-shared-call-va_end-in-all-cases.patch b/0555-shared-call-va_end-in-all-cases.patch
new file mode 100644
index 0000000..5a50a03
--- /dev/null
+++ b/0555-shared-call-va_end-in-all-cases.patch
@@ -0,0 +1,28 @@
+From c51b257db0bc1434f1dedb031a3feb14c2bb4ac6 Mon Sep 17 00:00:00 2001
+From: Lukas Nykryn <lnykryn at redhat.com>
+Date: Fri, 21 Sep 2012 10:22:46 +0200
+Subject: [PATCH] shared: call va_end in all cases (cherry picked from commit
+ e98055de981b568c31f18f470181ae166b56f172)
+
+Conflicts:
+ src/shared/log.c
+---
+ src/shared/util.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/shared/util.c b/src/shared/util.c
+index 6f2780a..0d48691 100644
+--- a/src/shared/util.c
++++ b/src/shared/util.c
+@@ -5114,8 +5114,10 @@ char *join(const char *x, ...) {
+ break;
+
+ n = strlen(t);
+- if (n > ((size_t) -1) - l)
++ if (n > ((size_t) -1) - l) {
++ va_end(ap);
+ return NULL;
++ }
+
+ l += n;
+ }
diff --git a/0556-cgtop-missing.patch b/0556-cgtop-missing.patch
new file mode 100644
index 0000000..431d50f
--- /dev/null
+++ b/0556-cgtop-missing.patch
@@ -0,0 +1,26 @@
+From 40ea553204c855d8eba3bbf3d7a89de33514c030 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= <vpavlin at redhat.com>
+Date: Fri, 21 Sep 2012 12:04:02 +0200
+Subject: [PATCH] cgtop: missing '-'
+
+Return codes in systemd are negated and
+if (r < 0) if (r == ENOENT)
+ was never true.
+(cherry picked from commit 2f29c419b01c104475f04d58a873b181273cfd8b)
+---
+ src/cgtop/cgtop.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
+index a44e59f..cec0c4b 100644
+--- a/src/cgtop/cgtop.c
++++ b/src/cgtop/cgtop.c
+@@ -297,7 +297,7 @@ static int refresh_one(
+
+ r = cg_enumerate_subgroups(controller, path, &d);
+ if (r < 0) {
+- if (r == ENOENT)
++ if (r == -ENOENT)
+ return 0;
+
+ return r;
diff --git a/0557-logind-check-return-value-log-warning-on-error.patch b/0557-logind-check-return-value-log-warning-on-error.patch
new file mode 100644
index 0000000..3ca1742
--- /dev/null
+++ b/0557-logind-check-return-value-log-warning-on-error.patch
@@ -0,0 +1,42 @@
+From 84c6ae205883b8f397fdc7a06f6ed233a9c14e1d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= <vpavlin at redhat.com>
+Date: Fri, 21 Sep 2012 13:01:39 +0200
+Subject: [PATCH] logind: check return value, log warning on error (cherry
+ picked from commit
+ 5a165aa6b9aa921d8b069059026d84e879ac38cc)
+
+---
+ src/login/logind-session.c | 4 +++-
+ src/login/logind-user.c | 4 +++-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/login/logind-session.c b/src/login/logind-session.c
+index e4a7473..80f41df 100644
+--- a/src/login/logind-session.c
++++ b/src/login/logind-session.c
+@@ -529,7 +529,9 @@ static int session_create_cgroup(Session *s) {
+ }
+ }
+
+- hashmap_put(s->manager->session_cgroups, s->cgroup_path, s);
++ r = hashmap_put(s->manager->session_cgroups, s->cgroup_path, s);
++ if (r < 0)
++ log_warning("Failed to create mapping between cgroup and session");
+
+ return 0;
+ }
+diff --git a/src/login/logind-user.c b/src/login/logind-user.c
+index fa12e1d..31c76e3 100644
+--- a/src/login/logind-user.c
++++ b/src/login/logind-user.c
+@@ -315,7 +315,9 @@ static int user_create_cgroup(User *u) {
+ log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r));
+ }
+
+- hashmap_put(u->manager->user_cgroups, u->cgroup_path, u);
++ r = hashmap_put(u->manager->user_cgroups, u->cgroup_path, u);
++ if (r < 0)
++ log_warning("Failed to create mapping between cgroup and user");
+
+ return 0;
+ }
diff --git a/0558-login-check-return-value-of-session_get_idle_hint.patch b/0558-login-check-return-value-of-session_get_idle_hint.patch
new file mode 100644
index 0000000..72cd42a
--- /dev/null
+++ b/0558-login-check-return-value-of-session_get_idle_hint.patch
@@ -0,0 +1,33 @@
+From b42146d68c00544e1a80105931a02210f3025921 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= <vpavlin at redhat.com>
+Date: Fri, 21 Sep 2012 13:38:40 +0200
+Subject: [PATCH] login: check return value of session_get_idle_hint (cherry
+ picked from commit
+ ca4f2b6d6dbecce80d28a4b5126f8e83e1d4093b)
+
+---
+ src/login/logind-session-dbus.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
+index c1704d1..857dc36 100644
+--- a/src/login/logind-session-dbus.c
++++ b/src/login/logind-session-dbus.c
+@@ -183,12 +183,16 @@ static int bus_session_append_idle_hint_since(DBusMessageIter *i, const char *pr
+ Session *s = data;
+ dual_timestamp t;
+ uint64_t u;
++ int r;
+
+ assert(i);
+ assert(property);
+ assert(s);
+
+- session_get_idle_hint(s, &t);
++ r = session_get_idle_hint(s, &t);
++ if (r < 0)
++ return r;
++
+ u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
+
+ if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
diff --git a/0559-locale-make-sure-that-l-is-freed.patch b/0559-locale-make-sure-that-l-is-freed.patch
new file mode 100644
index 0000000..2177c15
--- /dev/null
+++ b/0559-locale-make-sure-that-l-is-freed.patch
@@ -0,0 +1,25 @@
+From 242a2918217e798e04d4eac567552665f84d055c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= <vpavlin at redhat.com>
+Date: Fri, 21 Sep 2012 15:00:43 +0200
+Subject: [PATCH] locale: make sure that l is freed (cherry picked from commit
+ f2cc3753ce0e85960f0299855c3b98ba60efa580)
+
+---
+ src/locale/localed.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/locale/localed.c b/src/locale/localed.c
+index da46106..46fa99a 100644
+--- a/src/locale/localed.c
++++ b/src/locale/localed.c
+@@ -1157,7 +1157,9 @@ static DBusHandlerResult locale_message_handler(
+ "Locale\0");
+ if (!changed)
+ goto oom;
+- }
++ } else
++ strv_free(l);
++
+ } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetVConsoleKeyboard")) {
+
+ const char *keymap, *keymap_toggle;
diff --git a/0560-modules-load-initalize-files-to-null.patch b/0560-modules-load-initalize-files-to-null.patch
new file mode 100644
index 0000000..28eadc0
--- /dev/null
+++ b/0560-modules-load-initalize-files-to-null.patch
@@ -0,0 +1,23 @@
+From 37f6e67a1bf8ab929345bffa3027bd4b33612eb1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?V=C3=A1clav=20Pavl=C3=ADn?= <vpavlin at redhat.com>
+Date: Fri, 21 Sep 2012 15:03:28 +0200
+Subject: [PATCH] modules-load: initalize files to null (cherry picked from
+ commit d42c44fb6dd926271bfd56157114ba9d29935ea7)
+
+---
+ src/modules-load/modules-load.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
+index e228fcf..6995c48 100644
+--- a/src/modules-load/modules-load.c
++++ b/src/modules-load/modules-load.c
+@@ -175,7 +175,7 @@ static int load_module(struct kmod_ctx *ctx, const char *m) {
+
+ int main(int argc, char *argv[]) {
+ int r = EXIT_FAILURE, k;
+- char **files, **fn, **i;
++ char **files = NULL, **fn, **i;
+ struct kmod_ctx *ctx;
+
+ if (argc > 1) {
diff --git a/0561-sysctl-fix-error-code-handling.patch b/0561-sysctl-fix-error-code-handling.patch
new file mode 100644
index 0000000..2d7527b
--- /dev/null
+++ b/0561-sysctl-fix-error-code-handling.patch
@@ -0,0 +1,25 @@
+From 3a5f3e7fbe262754c6efce8853c14a87678340bf Mon Sep 17 00:00:00 2001
+From: Lukas Nykryn <lnykryn at redhat.com>
+Date: Fri, 21 Sep 2012 12:30:56 +0200
+Subject: [PATCH] sysctl: fix error code handling
+
+After if (r <= 0) r can't be 0 so
+if (k < 0 && r == 0) never happens.
+(cherry picked from commit 089d4a08d0cda5bae0bf9bb3273bfdb397200ee8)
+---
+ src/sysctl/sysctl.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
+index 04773a3..961b29b 100644
+--- a/src/sysctl/sysctl.c
++++ b/src/sysctl/sysctl.c
+@@ -264,6 +264,8 @@ int main(int argc, char *argv[]) {
+ if (r <= 0)
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
++ r = 0;
++
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
diff --git a/0562-login-missing-break-for-getopt-ARG_NO_ASK_PASSWORD-i.patch b/0562-login-missing-break-for-getopt-ARG_NO_ASK_PASSWORD-i.patch
new file mode 100644
index 0000000..abca6af
--- /dev/null
+++ b/0562-login-missing-break-for-getopt-ARG_NO_ASK_PASSWORD-i.patch
@@ -0,0 +1,23 @@
+From 5e161f1907cd3b91a142d64bf1af2c22108b98e3 Mon Sep 17 00:00:00 2001
+From: Lukas Nykryn <lnykryn at redhat.com>
+Date: Fri, 21 Sep 2012 12:33:32 +0200
+Subject: [PATCH] login: missing break for getopt ARG_NO_ASK_PASSWORD in
+ loginctl (cherry picked from commit
+ 5d5e98eb8c859d5a85fe6cd5e3cc433bd8a096ba)
+
+---
+ src/login/loginctl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/login/loginctl.c b/src/login/loginctl.c
+index 9a43685..1d548ed 100644
+--- a/src/login/loginctl.c
++++ b/src/login/loginctl.c
+@@ -1768,6 +1768,7 @@ static int parse_argv(int argc, char *argv[]) {
+
+ case ARG_NO_ASK_PASSWORD:
+ arg_ask_password = false;
++ break;
+
+ case ARG_KILL_WHO:
+ arg_kill_who = optarg;
diff --git a/0563-hwclock-add-missing-OOM-check.patch b/0563-hwclock-add-missing-OOM-check.patch
new file mode 100644
index 0000000..57f0cfd
--- /dev/null
+++ b/0563-hwclock-add-missing-OOM-check.patch
@@ -0,0 +1,26 @@
+From 047837464824d68b4d9997fc321286b69cd0b4e1 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 21 Sep 2012 16:29:09 +0200
+Subject: [PATCH] hwclock: add missing OOM check (cherry picked from commit
+ 4eeebf70aa5ac9825899f5a063431329904d37e5)
+
+---
+ src/shared/hwclock.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c
+index 05be72c..9a0d2cf 100644
+--- a/src/shared/hwclock.c
++++ b/src/shared/hwclock.c
+@@ -94,6 +94,11 @@ static int rtc_open(int flags) {
+ continue;
+
+ p = strappend("/dev/", de->d_name);
++ if (!p) {
++ closedir(d);
++ return -ENOMEM;
++ }
++
+ fd = open(p, flags);
+ free(p);
+
diff --git a/0564-sysctl-always-return-the-last-error-we-encountered.patch b/0564-sysctl-always-return-the-last-error-we-encountered.patch
new file mode 100644
index 0000000..44f6582
--- /dev/null
+++ b/0564-sysctl-always-return-the-last-error-we-encountered.patch
@@ -0,0 +1,76 @@
+From ff3b2d707bd1a47ed1594029d2372f880a04d63c Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Fri, 21 Sep 2012 17:01:39 +0200
+Subject: [PATCH] sysctl: always return the last error we encountered (cherry
+ picked from commit
+ 0187f62bb5f785c22952e79c55ef0fdb87f1ad65)
+
+---
+ src/sysctl/sysctl.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
+index 961b29b..be03f78 100644
+--- a/src/sysctl/sysctl.c
++++ b/src/sysctl/sysctl.c
+@@ -256,7 +256,7 @@ static int parse_argv(int argc, char *argv[]) {
+ }
+
+ int main(int argc, char *argv[]) {
+- int r = 0;
++ int r = 0, k;
+ char *property, *value;
+ Iterator it;
+
+@@ -264,8 +264,6 @@ int main(int argc, char *argv[]) {
+ if (r <= 0)
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+- r = 0;
+-
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
+@@ -278,19 +276,18 @@ int main(int argc, char *argv[]) {
+ goto finish;
+ }
+
++ r = 0;
++
+ if (argc > optind) {
+ int i;
+
+ for (i = optind; i < argc; i++) {
+- int k;
+-
+ k = parse_file(argv[i], false);
+- if (k < 0 && r == 0)
++ if (k < 0)
+ r = k;
+ }
+ } else {
+ char **files, **f;
+- int k;
+
+ r = conf_files_list(&files, ".conf",
+ "/etc/sysctl.d",
+@@ -314,14 +311,17 @@ int main(int argc, char *argv[]) {
+ f = files + strv_length(files) - 1;
+ STRV_FOREACH_BACKWARDS(f, files) {
+ k = parse_file(*f, true);
+- if (k < 0 && r == 0)
++ if (k < 0)
+ r = k;
+ }
+
+ strv_free(files);
+ }
+
+- r = apply_all();
++ k = apply_all();
++ if (k < 0)
++ r = k;
++
+ finish:
+ HASHMAP_FOREACH_KEY(value, property, sysctl_options, it) {
+ hashmap_remove(sysctl_options, property);
diff --git a/0565-rules-only-mark-MD-disks-not-partitions-with-SYSTEMD.patch b/0565-rules-only-mark-MD-disks-not-partitions-with-SYSTEMD.patch
new file mode 100644
index 0000000..276d78a
--- /dev/null
+++ b/0565-rules-only-mark-MD-disks-not-partitions-with-SYSTEMD.patch
@@ -0,0 +1,26 @@
+From 9e2345393982a3025b7104dc7e031827d7d4f733 Mon Sep 17 00:00:00 2001
+From: Kay Sievers <kay at vrfy.org>
+Date: Mon, 24 Sep 2012 14:55:25 +0200
+Subject: [PATCH] rules: only mark MD disks, not partitions, with
+ SYSTEMD_READY=0 (cherry picked from commit
+ d2fff1ced447c09c6601a6617300467ccd81660b)
+
+---
+ src/99-systemd.rules.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/99-systemd.rules.in b/src/99-systemd.rules.in
+index 8ef7b8f..a1d6f1b 100644
+--- a/src/99-systemd.rules.in
++++ b/src/99-systemd.rules.in
+@@ -20,8 +20,8 @@ SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=
+ SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0"
+
+ # Ignore raid devices that are not yet assembled and started
+-SUBSYSTEM=="block", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
+-SUBSYSTEM=="block", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
++SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
++SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
+
+ # Ignore nbd devices in the "add" event, with "change" the nbd is ready
+ ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0"
diff --git a/0566-tmpfiles-restore-previous-behavior-for-F-f.patch b/0566-tmpfiles-restore-previous-behavior-for-F-f.patch
new file mode 100644
index 0000000..27f8252
--- /dev/null
+++ b/0566-tmpfiles-restore-previous-behavior-for-F-f.patch
@@ -0,0 +1,28 @@
+From 5b1c033918dbea39c3e9ce5d5e36e1bebec2c4ae Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Thu, 27 Sep 2012 20:48:13 -0400
+Subject: [PATCH] tmpfiles: restore previous behavior for F/f
+
+d4e9eb91ea changed the behavior for the F and f actions, wrongly sending
+them to glob_item(). Restore the old behavior and shortcut straight to
+write_one_file().
+(cherry picked from commit 1845fdd967d3a4c06f895413505de3c2429955b0)
+---
+ src/tmpfiles/tmpfiles.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index 30b0b93..e901ec4 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -652,6 +652,10 @@ static int create_item(Item *i) {
+
+ case CREATE_FILE:
+ case TRUNCATE_FILE:
++ r = write_one_file(i, i->path);
++ if (r < 0)
++ return r;
++ break;
+ case WRITE_FILE:
+ r = glob_item(i, write_one_file);
+ if (r < 0)
diff --git a/0567-shared-fail-mkdir_p-if-the-target-exists-and-is-not-.patch b/0567-shared-fail-mkdir_p-if-the-target-exists-and-is-not-.patch
new file mode 100644
index 0000000..8123663
--- /dev/null
+++ b/0567-shared-fail-mkdir_p-if-the-target-exists-and-is-not-.patch
@@ -0,0 +1,40 @@
+From 85236b1a36f6e58c9dead9a42f7262fc55f9f8b3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek at in.waw.pl>
+Date: Tue, 2 Oct 2012 14:42:10 +0200
+Subject: [PATCH] shared: fail mkdir_p if the target exists and is not a
+ directory
+
+This makes mkdir_p actually behave like mkdir -p.
+(cherry picked from commit 5b585b5380e8e9b7975905989042743911d699e2)
+---
+ src/shared/mkdir.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c
+index d8c3275..c77f090 100644
+--- a/src/shared/mkdir.c
++++ b/src/shared/mkdir.c
+@@ -116,6 +116,13 @@ int mkdir_parents_label(const char *path, mode_t mode) {
+ return makedir_parents(path, mode, true);
+ }
+
++static int is_dir(const char* path) {
++ struct stat st;
++ if (stat(path, &st) < 0)
++ return -errno;
++ return S_ISDIR(st.st_mode);
++}
++
+ static int makedir_p(const char *path, mode_t mode, bool apply) {
+ int r;
+
+@@ -125,7 +132,8 @@ static int makedir_p(const char *path, mode_t mode, bool apply) {
+ if (r < 0)
+ return r;
+
+- if (label_mkdir(path, mode, apply) < 0 && errno != EEXIST)
++ r = label_mkdir(path, mode, apply);
++ if (r < 0 && (errno != EEXIST || is_dir(path) <= 0))
+ return -errno;
+
+ return 0;
diff --git a/0568-sysctl-avoiding-exiting-with-error-on-EEXIST.patch b/0568-sysctl-avoiding-exiting-with-error-on-EEXIST.patch
new file mode 100644
index 0000000..a5e4a8e
--- /dev/null
+++ b/0568-sysctl-avoiding-exiting-with-error-on-EEXIST.patch
@@ -0,0 +1,34 @@
+From 07ea1c26afae48acf33fc1d3240808d902930296 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner at archlinux.org>
+Date: Sat, 6 Oct 2012 16:32:17 -0400
+Subject: [PATCH] sysctl: avoiding exiting with error on -EEXIST
+
+If the final key in any sysctl.d file is a duplicate, systemd-sysctl
+will exit with an error (and no explaination why). Ignore this, as
+duplicate keys are to be expected when overriding settings in the
+directory hierarchy.
+(cherry picked from commit 1a3f40f912670d3dea3811a4560b368412090b81)
+---
+ src/sysctl/sysctl.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
+index be03f78..e64aea7 100644
+--- a/src/sysctl/sysctl.c
++++ b/src/sysctl/sysctl.c
+@@ -169,9 +169,13 @@ static int parse_file(const char *path, bool ignore_enoent) {
+
+ r = hashmap_put(sysctl_options, property, new_value);
+ if (r < 0) {
+- if (r == -EEXIST)
++ if (r == -EEXIST) {
++ /* ignore this "error" to avoid returning it
++ * for the function when this is the last key
++ * in the file being parsed. */
++ r = 0;
+ log_debug("Skipping previously assigned sysctl variable %s", property);
+- else
++ } else
+ log_error("Failed to add sysctl variable %s to hashmap: %s", property, strerror(-r));
+
+ free(property);
diff --git a/systemd.spec b/systemd.spec
index fc04ea4..0a1cba7 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -3,7 +3,7 @@
Name: systemd
Url: http://www.freedesktop.org/wiki/Software/systemd
Version: 44
-Release: 18%{?gitcommit:.git%{gitcommit}}%{?dist}
+Release: 20%{?gitcommit:.git%{gitcommit}}%{?dist}
License: GPLv2+
Group: System Environment/Base
Summary: A System and Service Manager
@@ -559,6 +559,75 @@ Patch0496: 0496-F17-restore-device-units-for-dev-ttyX.patch
Patch0497: 0497-systemd-return-error-when-asked-to-stop-unknown-unit.patch
Patch0498: 0498-modules-load-fix-kernel-cmdline-parsing.patch
Patch0499: 0499-units-add-the-modules-load-cmdline-parameters-to-the.patch
+Patch0500: 0500-F17-fix-fstab-mounts.patch
+Patch0501: 0501-Revert-timedate-uniq-ify-ntp-units-list.patch
+Patch0502: 0502-Revert-timedated-replace-ntp-units-file-with-an-ntp-.patch
+Patch0503: 0503-Revert-timedate-fix-ntp-units-comment.patch
+Patch0504: 0504-Revert-timedated-replace-systemd-timedated-ntp.targe.patch
+Patch0505: 0505-systemd-added-new-dependency-PartOf.patch
+Patch0506: 0506-man-rewrite-the-description-of-PartOf.patch
+Patch0507: 0507-dbus-unit-expose-PartOf-ConsistsOf-properties.patch
+Patch0508: 0508-unit-make-the-table-of-inverse-deps-symmetric.patch
+Patch0509: 0509-unit-add-missing-deps-in-unit_dependency_table.patch
+Patch0510: 0510-systemd-enable-disable-instances-of-template.patch
+Patch0511: 0511-logs-show-fix-OOM-path.patch
+Patch0512: 0512-systemctl-automatically-turn-paths-and-unescaped-uni.patch
+Patch0513: 0513-cryptsetup-fix-escaping-when-generating-cryptsetup-u.patch
+Patch0514: 0514-systemctl-append-.service-to-unit-names-lacking-suff.patch
+Patch0515: 0515-rules-99-systemd.rules.in-ENV-SYSTEMD_READY-0-for-in.patch
+Patch0516: 0516-99-systemd.rules.in-ignore-nbd-in-the-add-uevent.patch
+Patch0517: 0517-automount-print-mount-point-in-debug-message.patch
+Patch0518: 0518-journald-fixed-memory-leak.patch
+Patch0519: 0519-logs-show-fix-off-by-one-error.patch
+Patch0520: 0520-shutdown-allow-to-specify-broadcast-message-when-can.patch
+Patch0521: 0521-sysctl-apply-configuration-at-once.patch
+Patch0522: 0522-systemd-introduced-new-timeout-types.patch
+Patch0523: 0523-fix-a-couple-of-issues-found-with-llvm-analyze.patch
+Patch0524: 0524-shared-utf8-mark-char-as-const.patch
+Patch0525: 0525-shared-util-refactor-fstab_node_to_udev_node.patch
+Patch0526: 0526-shared-util-add-fstab-support-for-partuuid-partlabel.patch
+Patch0527: 0527-login-check-return-of-parse_pid-and-parse_uid.patch
+Patch0528: 0528-unit-don-t-allow-units-to-be-gc-ed-that-still-are-re.patch
+Patch0529: 0529-unit-add-new-ConditionHost-condition-type.patch
+Patch0530: 0530-condition-add-ConditionFileNotEmpty.patch
+Patch0531: 0531-unit-name-rework-unit_name_replace_instance-function.patch
+Patch0532: 0532-pam-Add-session-class-to-the-debug-log.patch
+Patch0533: 0533-tmpfiles-support-globbing-for-w-option.patch
+Patch0534: 0534-systemctl-direct-the-user-to-list-unit-files-from-th.patch
+Patch0535: 0535-tmpfiles-plug-file-descriptor-leak.patch
+Patch0536: 0536-update-utmp-Don-t-error-out-on-runlevel-updates-if-u.patch
+Patch0537: 0537-install-append-.service-when-enable-disable.-is-call.patch
+Patch0538: 0538-systemctl-minor-coding-style-fixes.patch
+Patch0539: 0539-socket-prevent-signed-integer-overflow.patch
+Patch0540: 0540-tmpfiles-use-write-2-for-the-w-action.patch
+Patch0541: 0541-service-don-t-hit-an-assert-if-a-service-unit-change.patch
+Patch0542: 0542-hwclock-always-set-the-kernel-s-timezone.patch
+Patch0543: 0543-conf-parser-don-t-unescape-parsed-configuration-stri.patch
+Patch0544: 0544-log-avoid-function-loop.patch
+Patch0545: 0545-target-imply-default-ordering-for-PartsOf-deps-as-we.patch
+Patch0546: 0546-unit-fix-f-resolving.patch
+Patch0547: 0547-mount-notify-the-user-if-we-over-mount-a-non-empty-d.patch
+Patch0548: 0548-automount-also-whine-if-an-automount-directory-is-no.patch
+Patch0549: 0549-mount-reword-directory-empty-warning-a-bit.patch
+Patch0550: 0550-timedated-unregister-the-right-bus-service.patch
+Patch0551: 0551-util-make-sure-heap-allocators-fail-when-array-alloc.patch
+Patch0552: 0552-util-define-union-dirent_storage-and-make-use-of-it-.patch
+Patch0553: 0553-util-overflow-hardening.patch
+Patch0554: 0554-util-fix-overflow-checks.patch
+Patch0555: 0555-shared-call-va_end-in-all-cases.patch
+Patch0556: 0556-cgtop-missing.patch
+Patch0557: 0557-logind-check-return-value-log-warning-on-error.patch
+Patch0558: 0558-login-check-return-value-of-session_get_idle_hint.patch
+Patch0559: 0559-locale-make-sure-that-l-is-freed.patch
+Patch0560: 0560-modules-load-initalize-files-to-null.patch
+Patch0561: 0561-sysctl-fix-error-code-handling.patch
+Patch0562: 0562-login-missing-break-for-getopt-ARG_NO_ASK_PASSWORD-i.patch
+Patch0563: 0563-hwclock-add-missing-OOM-check.patch
+Patch0564: 0564-sysctl-always-return-the-last-error-we-encountered.patch
+Patch0565: 0565-rules-only-mark-MD-disks-not-partitions-with-SYSTEMD.patch
+Patch0566: 0566-tmpfiles-restore-previous-behavior-for-F-f.patch
+Patch0567: 0567-shared-fail-mkdir_p-if-the-target-exists-and-is-not-.patch
+Patch0568: 0568-sysctl-avoiding-exiting-with-error-on-EEXIST.patch
# For sysvinit tools
Obsoletes: SysVinit < 2.86-24, sysvinit < 2.86-24
@@ -728,6 +797,9 @@ ln -s systemctl %{buildroot}%{_bindir}/systemd-systemctl
find %{buildroot}%{_prefix}/lib -name '*vconsole*' -delete
%endif
+# debug-shell.service is the new name. Provide a compat symlink in F17.
+ln -s debug-shell.service %{buildroot}%{_prefix}/lib/systemd/system/systemd-debug-shell.service
+
%post
/sbin/ldconfig
/usr/bin/systemd-machine-id-setup > /dev/null 2>&1 || :
@@ -944,6 +1016,27 @@ mv /etc/systemd/system/default.target.save /etc/systemd/system/default.target >/
%{_bindir}/systemd-analyze
%changelog
+* Fri Oct 12 2012 Michal Schmidt <mschmidt at redhat.com> - 44-20
+- Revert the ntp migration code. Not going to do it in F17.
+- Backports from upstream v194+:
+- PartOf= dependencies
+- enabling/disabling of instantiated units
+- usability improvements for systemctl:
+ - systemctl status /home
+ - systemctl status /dev/foobar
+ - implied .service suffix
+- new timeouts TimeoutStartSec=, TimeoutStopSec=
+- understand PARTUUID=, PARTLABEL= in fstab
+- new conditions ConditionHost=, ConditionFileNotEmpty=
+- tmpfiles: globbing support with 'w' mode
+- various fixes
+- Resolves: #752774, #767795, #802198, #855863, #856975, #858266, #858754,
+- #858771, #858777, fdo#39386, fdo#54448, fdo#54522, fdo#54766
+
+* Fri Jul 27 2012 Michal Schmidt <mschmidt at redhat.com> - 44-19
+- Fix for broken fstab mounts in 44-18.
+- Add scriptlets to migrate away from systemd-timedated-ntp.target.
+
* Tue Jul 24 2012 Michal Schmidt <mschmidt at redhat.com> - 44-18
- Backports from upstream:
- rework the handling of ntp services in timedated (#821813)
More information about the scm-commits
mailing list